Initial revision
[moodle.git] / lib / moodlelib.php
CommitLineData
f9903ed0 1<?PHP // $Id$
2
3//
4// moodlelib.php
5//
6// Large collection of useful functions used by many parts of Moodle.
7//
8// Martin Dougiamas, 2000
9//
10
11
12/// STANDARD WEB PAGE PARTS ///////////////////////////////////////////////////
13
14function print_header ($title="", $heading="", $navigation="", $focus="", $meta="",$cache=true) {
15// $title - appears top of window
16// $heading - appears top of page
17// $navigation - premade navigation string
18// $focus - indicates form element eg inputform.password
19// $meta - meta tags in the header
20 global $USER, $CFG, $THEME;
21
22 if (file_exists("$CFG->dirroot/theme/$CFG->theme/styles.css")) {
23 $styles = "$CFG->wwwroot/theme/$CFG->theme/styles.css";
24 } else {
25 $styles = "$CFG->wwwroot/theme/standard/styles.css";
26 }
27
28 if (!$cache) { // Do everything we can to prevent clients and proxies caching
29 @header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
30 @header("Pragma: no-cache");
31 $meta .= "\n<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">";
32 $meta .= "\n<META HTTP-EQUIV=\"Expires\" CONTENT=\"0\">";
33 }
34
35 include ("$CFG->dirroot/theme/$CFG->theme/header.html");
36}
37
38function print_footer ($course=NULL) {
39// Can provide a course object to make the footer contain a link to
40// to the course home page, otherwise the link will go to the site home
41 global $USER, $CFG, $THEME;
42
43 if ($course) {
44 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A>";
45 } else {
46 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot\">Home</A>";
47 }
48 include ("$CFG->dirroot/theme/$CFG->theme/footer.html");
49}
50
51function print_navigation ($navigation) {
52 global $CFG;
53
54 if ($navigation) {
55 echo "<A TARGET=_top HREF=\"$CFG->wwwroot/\">Home</A> -> $navigation";
56 }
57}
58
59function print_heading($heading) {
60 echo "<P ALIGN=CENTER><FONT SIZE=4><B>$heading</B></FONT></P>";
61}
62
63function print_simple_box($message, $align="", $width="", $color="#FFFFFF", $padding=5) {
64 print_simple_box_start($align, $width, $color, $padding);
65 echo "<P>$message</P>";
66 print_simple_box_end();
67}
68
69function print_simple_box_start($align="", $width="", $color="#FFFFFF", $padding=5) {
70 global $THEME;
71
72 if ($align) {
73 $tablealign = "ALIGN=\"$align\"";
74 }
75 if ($width) {
76 $tablewidth = "WIDTH=\"$width\"";
77 $innertablewidth = "WIDTH=\"100%\"";
78 }
79 echo "<TABLE $tablealign $tablewidth BORDER=0 CELLPADDING=1 CELLSPACING=0>";
80 echo "<TR><TD BGCOLOR=\"$THEME->borders\">\n";
81 echo "<TABLE $innertablewidth BORDER=0 CELLPADDING=\"$padding\" CELLSPACING=0><TR><TD BGCOLOR=\"$color\">";
82}
83
84function print_simple_box_end() {
85 echo "</TD></TR></TABLE>";
86 echo "</TD></TR></TABLE>";
87}
88
89function print_single_button($link, $options, $label="OK") {
90 echo "<FORM ACTION=\"$link\" METHOD=GET>";
91 foreach ($options as $name => $value) {
92 echo "<INPUT TYPE=hidden NAME=\"$name\" VALUE=\"$value\">";
93 }
94 echo "<INPUT TYPE=submit VALUE=\"$label\"></FORM>";
95}
96
97function print_user_picture($userid, $courseid, $picture, $large=false) {
98 global $CFG;
99
100 echo "<A HREF=\"$CFG->wwwroot/user/view.php?id=$userid&course=$courseid\">";
101 if ($large) {
102 $file = "f1.jpg";
103 $size = 100;
104 } else {
105 $file = "f2.jpg";
106 $size = 35;
107 }
108 if ($picture) {
109 echo "<IMG SRC=\"$CFG->wwwroot/user/pix.php/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
110 } else {
111 echo "<IMG SRC=\"$CFG->wwwroot/user/default/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
112 }
113 echo "</A>";
114}
115
116function print_table($table) {
117// Prints a nicely formatted table.
118// $table is an object with three properties.
119// $table->head is an array of heading names.
120// $table->align is an array of column alignments
121// $table->data[] is an array of arrays containing the data.
122
123 if ( $table->align) {
124 foreach ($table->align as $key => $aa) {
125 if ($aa) {
126 $align[$key] = "ALIGN=\"$aa\"";
127 } else {
128 $align[$key] = "";
129 }
130 }
131 }
132
133 echo "<BR>";
134
135 print_simple_box_start("CENTER","","#FFFFFF",0);
136 echo "<TABLE BORDER=0 valign=top align=center cellpadding=10 cellspacing=1>\n";
137
138 if ($table->head) {
139 echo "<TR>";
140 foreach ($table->head as $heading) {
141 echo "<TH>$heading</TH>";
142 }
143 echo "</TR>\n";
144 }
145
146 foreach ($table->data as $row) {
147 echo "<TR VALIGN=TOP>";
148 foreach ($row as $key => $item) {
149 echo "<TD ".$align[$key].">$item</TD>";
150 }
151 echo "</TR>\n";
152 }
153 echo "</TABLE>\n";
154 print_simple_box_end();
155
156 return true;
157}
158
159
160function moodledate($date) {
161 return date("l, j F Y, g:i A T", $date);
162}
163
164
165function error ($message, $link="") {
166 global $CFG, $SESSION;
167
168 print_header("Error");
169 echo "<BR>";
170 print_simple_box($message, "center", "", "#FFBBBB");
171
172 if (!$link) {
173 if ( !empty($SESSION->fromurl) ) {
174 $link = "$SESSION->fromurl";
175 unset($SESSION->fromurl);
176 } else {
177 $link = "$CFG->wwwroot";
178 }
179 }
180 print_heading("<A HREF=\"$link\">Continue</A>");
181 print_footer();
182 die;
183}
184
185function notice ($message, $link="") {
186 global $THEME, $HTTP_REFERER;
187
188 if (!$link) {
189 $link = $HTTP_REFERER;
190 }
191
192 echo "<BR>";
193 print_simple_box($message, "center", "", "$THEME->cellheading");
194 print_heading("<A HREF=\"$link\">Continue</A>");
195 print_footer();
196 die;
197}
198
199function notice_yesno ($message, $linkyes, $linkno) {
200 global $THEME;
201
202 print_simple_box_start("center", "", "$THEME->cellheading");
203 echo "<P ALIGN=CENTER><FONT SIZE=3>$message</FONT></P>";
204 echo "<P ALIGN=CENTER><FONT SIZE=3><B>";
205 echo "<A HREF=\"$linkyes\">Yes</A>";
206 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
207 echo "<A HREF=\"$linkno\">No</A>";
208 echo "</B></FONT></P>";
209 print_simple_box_end();
210}
211
212function redirect($url, $message="", $delay=0) {
213// Uses META tags to redirect the user, after printing a notice
214 global $THEME;
215
216 echo "<META HTTP-EQUIV='Refresh' CONTENT='$delay; URL=$url'>";
217
218 if (!empty($message)) {
219 print_header();
220 echo "<CENTER>";
221 echo "<P>$message</P>";
222 echo "<P>( <A HREF=\"$url\">Continue</A> )</P>";
223 echo "</CENTER>";
224 }
225 die;
226}
227
228function notify ($message) {
229 echo "<P align=center><B><FONT COLOR=#FF0000>$message</FONT></B></P>\n";
230}
231
232
233
234/// PARAMETER HANDLING ////////////////////////////////////////////////////
235
236function require_variable($var) {
237
238 if (! isset($var)) {
239 error("A required parameter was missing");
240 }
241}
242
243function optional_variable(&$var, $default=0) {
244 if (! isset($var)) {
245 $var = $default;
246 }
247}
248
249
250
251
252/// DATABASE HANDLING ////////////////////////////////////////////////
253
254function execute_sql($command) {
255// Completely general
256
257 global $db;
258
259 $result = $db->Execute("$command");
260
261 if ($result) {
262 echo "<P><FONT COLOR=green>SUCCESS: $command</FONT></P>";
263 return true;
264 } else {
265 echo "<P><FONT COLOR=red>ERROR: $command </FONT></P>";
266 return false;
267 }
268}
269
270function modify_database($sqlfile) {
271// Assumes that the input text file consists of a number
272// of SQL statements ENDING WITH SEMICOLONS. The semicolons
273// MUST be the last character in a line.
274// Lines that are blank or that start with "#" are ignored.
275// Only tested with mysql dump files (mysqldump -p -d moodle)
276
277
278 if (file_exists($sqlfile)) {
279 $success = true;
280 $lines = file($sqlfile);
281 $command = "";
282
283 while ( list($i, $line) = each($lines) ) {
284 $line = chop($line);
285 $length = strlen($line);
286
287 if ($length && substr($line, 0, 1) <> "#") {
288 if (substr($line, $length-1, 1) == ";") {
289 $line = substr($line, 0, $length-1); // strip ;
290 $command .= $line;
291 if (! execute_sql($command)) {
292 $success = false;
293 }
294 $command = "";
295 } else {
296 $command .= $line;
297 }
298 }
299 }
300
301 } else {
302 $success = false;
303 echo "<P>Tried to modify database, but \"$sqlfile\" doesn't exist!</P>";
304 }
305
306 return $success;
307}
308
309
310function record_exists($table, $field, $value) {
311 global $db;
312
313 $rs = $db->Execute("SELECT * FROM $table WHERE $field = '$value' LIMIT 1");
314 if (!$rs) return false;
315
316 if ( $rs->RecordCount() ) {
317 return true;
318 } else {
319 return false;
320 }
321}
322
323function record_exists_sql($sql) {
324 global $db;
325
326 $rs = $db->Execute($sql);
327 if (!$rs) return false;
328
329 if ( $rs->RecordCount() ) {
330 return true;
331 } else {
332 return false;
333 }
334}
335
336
337function count_records($table, $selector, $value) {
338// Get all the records and count them
339 global $db;
340
341 $rs = $db->Execute("SELECT COUNT(*) FROM $table WHERE $selector = '$value'");
342 if (!$rs) return 0;
343
344 return $rs->fields[0];
345}
346
347function count_records_sql($sql) {
348// Get all the records and count them
349 global $db;
350
351 $rs = $db->Execute("$sql");
352 if (!$rs) return 0;
353
354 return $rs->fields[0];
355}
356
357function get_record($table, $selector, $value) {
358// Get a single record as an object
359 global $db;
360
361 $rs = $db->Execute("SELECT * FROM $table WHERE $selector = '$value'");
362 if (!$rs) return false;
363
364 if ( $rs->RecordCount() == 1 ) {
365 return (object)$rs->fields;
366 } else {
367 return false;
368 }
369}
370
371function get_record_sql($sql) {
372// Get a single record as an object
373// The sql statement is provided as a string.
374
375 global $db;
376
377 $rs = $db->Execute("$sql");
378 if (!$rs) return false;
379
380 if ( $rs->RecordCount() == 1 ) {
381 return (object)$rs->fields;
382 } else {
383 return false;
384 }
385}
386
387function get_records($table, $selector, $value, $sort="") {
388// Get a number of records as an array of objects
389// Can optionally be sorted eg "time ASC" or "time DESC"
390// The "key" is the first column returned, eg usually "id"
391 global $db;
392
393 if ($sort) {
394 $sortorder = "ORDER BY $sort";
395 }
396 $sql = "SELECT * FROM $table WHERE $selector = '$value' $sortorder";
397
398 return get_records_sql($sql);
399}
400
401function get_records_sql($sql) {
402// Get a number of records as an array of objects
403// The "key" is the first column returned, eg usually "id"
404// The sql statement is provided as a string.
405
406 global $db;
407
408 $rs = $db->Execute("$sql");
409 if (!$rs) return false;
410
411 if ( $rs->RecordCount() > 0 ) {
412 $records = $rs->GetAssoc(true);
413 foreach ($records as $key => $record) {
414 $objects[$key] = (object) $record;
415 }
416 return $objects;
417 } else {
418 return false;
419 }
420}
421
422function get_records_sql_menu($sql) {
423// Given an SQL select, this function returns an associative
424// array of the first two columns. This is most useful in
425// combination with the choose_from_menu function to create
426// a form menu.
427
428 global $db;
429
430 $rs = $db->Execute("$sql");
431 if (!$rs) return false;
432
433 if ( $rs->RecordCount() > 0 ) {
434 while (!$rs->EOF) {
435 $menu[$rs->fields[0]] = $rs->fields[1];
436 $rs->MoveNext();
437 }
438 return $menu;
439
440 } else {
441 return false;
442 }
443}
444
445function get_field($table, $field, $selector, $value) {
446 global $db;
447
448 $rs = $db->Execute("SELECT $field FROM $table WHERE $selector = '$value'");
449 if (!$rs) return false;
450
451 if ( $rs->RecordCount() == 1 ) {
452 return $rs->fields["$field"];
453 } else {
454 return false;
455 }
456}
457
458function set_field($table, $field, $newvalue, $selector, $value) {
459 global $db;
460
461 return $db->Execute("UPDATE $table SET $field = '$newvalue' WHERE $selector = '$value'");
462}
463
464
465function delete_records($table, $selector, $value) {
466// Delete one or more records from a table
467 global $db;
468
469 return $db->Execute("DELETE FROM $table WHERE $selector = '$value'");
470}
471
472function insert_record($table, $dataobject) {
473// Insert a record into a table and return the "id" field
474// $dataobject is an object containing needed data
475
476 global $db;
477
478 // Determine all the fields needed
479 if (! $columns = $db->MetaColumns("$table")) {
480 return false;
481 }
482
483 $data = (array)$dataobject;
484
485 // Pull out data matching these fields
486 foreach ($columns as $column) {
487 if ($column->name <> "id" && $data[$column->name] ) {
488 $ddd[$column->name] = $data[$column->name];
489 }
490 }
491
492 // Construct SQL queries
493 if (! $numddd = count($ddd)) {
494 return 0;
495 }
496
497 $count = 0;
498 $insert = "";
499 $select = "";
500
501 foreach ($ddd as $key => $value) {
502 $count++;
503 $insert .= "$key = '$value'";
504 $select .= "$key = '$value'";
505 if ($count < $numddd) {
506 $insert .= ", ";
507 $select .= " AND ";
508 }
509 }
510
511 if (! $rs = $db->Execute("INSERT INTO $table SET $insert")) {
512 return false;
513 }
514
515 // Pull it out again to find the id. This is the most cross-platform method.
516 if ($rs = $db->Execute("SELECT id FROM $table WHERE $select")) {
517 return $rs->fields[0];
518 } else {
519 return false;
520 }
521}
522
523
524function update_record($table, $dataobject) {
525// Update a record in a table
526// $dataobject is an object containing needed data
527
528 global $db;
529
530 if (! $dataobject->id) {
531 return false;
532 }
533
534 // Determine all the fields in the table
535 $columns = $db->MetaColumns($table);
536 $data = (array)$dataobject;
537
538 // Pull out data matching these fields
539 foreach ($columns as $column) {
540 if ($column->name <> "id" && $data[$column->name] ) {
541 $ddd[$column->name] = $data[$column->name];
542 }
543 }
544
545 // Construct SQL queries
546 $numddd = count($ddd);
547 $count = 0;
548 $update = "";
549
550 foreach ($ddd as $key => $value) {
551 $count++;
552 $update .= "$key = '$value'";
553 if ($count < $numddd) {
554 $update .= ", ";
555 }
556 }
557
558 if ($rs = $db->Execute("UPDATE $table SET $update WHERE id = '$dataobject->id'")) {
559 return true;
560 } else {
561 return false;
562 }
563}
564
565
566
567/// USER DATABASE ////////////////////////////////////////////////
568
569function get_user_info_from_db($field, $value) {
570
571 global $db;
572
573 if (!$field || !$value)
574 return false;
575
576 $result = $db->Execute("SELECT * FROM user WHERE $field = '$value'");
577
578 if ( $result->RecordCount() == 1 ) {
579 $user = (object)$result->fields;
580
581 $rs = $db->Execute("SELECT course FROM user_students WHERE user = '$user->id' ");
582 while (!$rs->EOF) {
583 $course = $rs->fields["course"];
584 $user->student["$course"] = true;
585 $rs->MoveNext();
586 }
587
588 $rs = $db->Execute("SELECT course FROM user_teachers WHERE user = '$user->id' ");
589 while (!$rs->EOF) {
590 $course = $rs->fields["course"];
591 $user->teacher["$course"] = true;
592 $rs->MoveNext();
593 }
594
595 $rs = $db->Execute("SELECT * FROM user_admins WHERE user = '$user->id' ");
596 while (!$rs->EOF) {
597 $user->admin = true;
598 $rs->MoveNext();
599 }
600
601 if ($course = get_record("course", "category", 0)) {
602 // Everyone is always a member of the top course
603 $user->student["$course->id"] = true;
604 }
605
606 return $user;
607
608 } else {
609 return false;
610 }
611}
612
613function update_user_in_db() {
614
615 global $db, $USER, $REMOTE_ADDR;
616
617 if (!isset($USER->id))
618 return false;
619
620 $timenow = time();
621 if ($db->Execute("UPDATE LOW_PRIORITY user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow'
622 WHERE id = '$USER->id' ")) {
623 return true;
624 } else {
625 return false;
626 }
627}
628
629function require_login($course=0) {
630// if they aren't already logged in, then send them off to login
631// $course is optional - if left out then it just requires that
632// that they have an account on the system.
633
634 global $CFG, $SESSION, $USER, $FULLME, $HTTP_REFERER, $PHPSESSID;
635
636 if (! (isset( $USER->loggedin ) && $USER->confirmed) ) {
637 $SESSION->wantsurl = $FULLME;
638 $SESSION->fromurl = $HTTP_REFERER;
639 if ($PHPSESSID) { // Cookies not enabled.
640 redirect("$CFG->wwwroot/login/?PHPSESSID=$PHPSESSID");
641 } else {
642 redirect("$CFG->wwwroot/login/");
643 }
644 die;
645
646 } else if ($course) {
647 if (! ($USER->student[$course] || $USER->teacher[$course] || $USER->admin ) ) {
648 if (!record_exists("course", "id", $course)) {
649 error("That course doesn't exist");
650 }
651
652 $SESSION->wantsurl = $FULLME;
653 redirect("$CFG->wwwroot/course/login.php?id=$course");
654 die;
655 }
656 }
657
658 update_user_in_db();
659}
660
661
662
663function update_login_count() {
664 global $SESSION;
665
666 $max_logins = 10;
667
668 if (empty($SESSION->logincount)) {
669 $SESSION->logincount = 1;
670 } else {
671 $SESSION->logincount++;
672 }
673
674 if ($SESSION->logincount > $max_logins) {
675 unset($SESSION->wantsurl);
676 error("Sorry, you have exceeded the allowed number of login attempts. Restart your browser.");
677 }
678}
679
680
681function isadmin($userid=0) {
682 global $USER;
683
684 if (!$userid) {
685 return $USER->admin;
686 }
687
688 return record_exists_sql("SELECT * FROM user_admins WHERE user='$userid'");
689}
690
691function isteacher($course, $userid=0) {
692 global $USER;
693
694 if (!$userid) {
695 return $USER->teacher[$course];
696 }
697
698 return record_exists_sql("SELECT * FROM user_teachers WHERE user='$userid' AND course='$course'");
699}
700
701
702function isstudent($course, $userid=0) {
703 global $USER;
704
705 if (!$userid) {
706 return $USER->student[$course];
707 }
708
709 $timenow = time(); // todo: add time check below
710
711 return record_exists_sql("SELECT * FROM user_students WHERE user='$userid' AND course='$course'");
712}
713
714
715function reset_login_count() {
716 global $SESSION;
717
718 $SESSION->logincount = 0;
719}
720
721
722function set_moodle_cookie($thing) {
723
724 $days = 60;
725 $seconds = 60*60*24*$days;
726
727 setCookie ('MOODLEID');
728 setCookie ('MOODLEID', rc4encrypt($thing), time()+$seconds, "/");
729}
730
731
732function get_moodle_cookie() {
733 global $MOODLEID;
734 return rc4decrypt($MOODLEID);
735}
736
737
738
739function verify_login($username, $password) {
740
741 $user = get_user_info_from_db("username", $username);
742
743 if (! $user) {
744 return false;
745 } else if ( $user->password == md5($password) ) {
746 return $user;
747 } else {
748 return false;
749 }
750}
751
752function get_site () {
753// Returns $course object of the top-level site.
754 if ( $course = get_record("course", "category", 0)) {
755 return $course;
756 } else {
757 return false;
758 }
759}
760
761function get_admin () {
762// Returns $user object of the main admin user
763
764 if ( $admins = get_records_sql("SELECT u.* FROM user u, user_admins a WHERE a.user = u.id ORDER BY u.id ASC")) {
765 foreach ($admins as $admin) {
766 return $admin; // ie the first one (yeah I know it's bodgy)
767 }
768 } else {
769 return false;
770 }
771}
772
773function get_teacher($courseid) {
774// Returns $user object of the main teacher for a course
775 if ( $teachers = get_records_sql("SELECT u.* FROM user u, user_teachers t
776 WHERE t.user = u.id AND t.course = '$courseid'
777 ORDER BY t.authority ASC")) {
778 foreach ($teachers as $teacher) {
779 return $teacher; // ie the first one (yeah I know it's bodgy)
780 }
781 } else {
782 return false;
783 }
784}
785
786
787
788/// MODULE FUNCTIONS /////////////////////////////////////////////////
789
790function get_coursemodule_from_instance($modulename, $instance, $course) {
791// Given an instance of a module, finds the coursemodule description
792
793 return get_record_sql("SELECT cm.*, m.name
794 FROM course_modules cm, modules md, $modulename m
795 WHERE cm.course = '$course' AND
796 cm.deleted = '0' AND
797 cm.instance = m.id AND
798 md.name = '$modulename' AND
799 md.id = cm.module AND
800 m.id = '$instance'");
801
802}
803
804function get_all_instances_in_course($modulename, $course, $sort="cw.week") {
805// Returns an array of all the active instances of a particular
806// module in a given course. Returns false on any errors.
807
808 return get_records_sql("SELECT m.*,cw.week,cm.id as coursemodule
809 FROM course_modules cm, course_weeks cw, modules md, $modulename m
810 WHERE cm.course = '$course' AND
811 cm.instance = m.id AND
812 cm.deleted = '0' AND
813 cm.week = cw.id AND
814 md.name = '$modulename' AND
815 md.id = cm.module
816 ORDER BY $sort");
817
818}
819
820function print_update_module_icon($moduleid) {
821 global $CFG;
822
823 echo "&nbsp; &nbsp;
824 <A HREF=\"$CFG->wwwroot/course/mod.php?update=$moduleid\" TARGET=_top><IMG
825 SRC=\"$CFG->wwwroot/pix/t/edit.gif\" ALIGN=right BORDER=0 ALT=\"Update this module\"></A>";
826}
827
828
829
830
831/// CORRESPONDENCE ////////////////////////////////////////////////
832
833
834function email_to_user($user, $from, $subject, $message) {
835 global $CFG;
836
837 include_once("$CFG->libdir/class.smtp.php");
838 include_once("$CFG->libdir/class.phpmailer.php");
839
840 $subject = stripslashes($subject);
841 $message = stripslashes($message);
842
843 $mail = new phpmailer;
844
845 $mail->IsSMTP(); // set mailer to use SMTP
846 $mail->From = "$from->email";
847 $mail->FromName = "$from->firstname $from->lastname";
848 $mail->Host = "$CFG->smtphost;localhost"; // specify main and backup server
849 $mail->AddReplyTo("$from->email","$from->firstname $from->lastname");
850 $mail->AddAddress("$user->email","$user->firstname $user->lastname");
851 $mail->WordWrap = 70; // set word wrap
852 $mail->IsHTML(false); // set email format to HTML
853 $mail->Subject = "$subject";
854
855 $mail->Body = "\n\n$message";
856
857 if (!$mail->Send()) {
858 return false;
859 }
860
861 return true;
862}
863
864
865function email_to_users(&$users, $from, $subject, $message, $link, $footer="") {
866// users is an array of user records as returned by get_records_sql
867
868 global $CFG;
869
870 include_once("$CFG->libdir/class.smtp.php");
871 include_once("$CFG->libdir/class.phpmailer.php");
872
873 if (!$users) {
874 return false;
875 }
876
877 $subject = stripslashes($subject);
878 $message = stripslashes($message);
879
880 $mail = new phpmailer;
881
882 $mail->IsSMTP(); // set mailer to use SMTP
883 $mail->From = "$from->email";
884 $mail->FromName = "$from->firstname $from->lastname";
885 $mail->Host = "$CFG->smtphost;localhost"; // specify main and backup server
886 $mail->AddAddress("","Subscribers");
887
888 foreach ($users as $user) {
889 $mail->AddBCC("$user->email","$user->firstname $user->lastname");
890 }
891
892 $mail->AddReplyTo("$from->email","$from->firstname $from->lastname");
893 $mail->WordWrap = 70; // set word wrap
894 $mail->IsHTML(false); // set email format to HTML
895 $mail->Subject = "$subject";
896
897 $message .= "\n\n--\n$from->firstname $from->lastname";
898
899 if ($footer) {
900 $message .= "\n\n$footer\n";
901 }
902
903 if ($link) {
904 $message .= "Link: $link\n";
905 }
906
907 $mail->Body = "\n\n$message";
908
909 if (!$mail->Send()) {
910 //echo "Message was not sent <p>";
911 //echo "Mailer Error: " . $mail->ErrorInfo;
912 return false;
913 }
914
915 return true;
916}
917
918
919
920function email_to_course($from, $course, $emailall, $subject, $message, $link, $footer="") {
921 global $CFG;
922
923 include_once("$CFG->libdir/class.smtp.php");
924 include_once("$CFG->libdir/class.phpmailer.php");
925
926
927 if (!$students = get_records_sql("SELECT u.* FROM user u, user_students s
928 WHERE s.course = '$course->id'
929 AND s.user = u.id")) {
930 notice("Could not find any students to mail to!");
931 }
932
933 if (!$teachers = get_records_sql("SELECT u.* FROM user u, user_teachers t
934 WHERE t.course = '$course->id'
935 AND t.user = u.id")) {
936 notice("Could not find any teachers to mail to!");
937 }
938
939 if (!$teachers && !$students) {
940 return false;
941 }
942
943 $subject = stripslashes($subject);
944 $message = stripslashes($message);
945
946 $mail = new phpmailer;
947
948 $mail->IsSMTP(); // set mailer to use SMTP
949 $mail->From = "$from->email";
950 $mail->FromName = "$from->firstname $from->lastname";
951 $mail->Host = "$CFG->smtphost;localhost"; // specify main and backup server
952
953 foreach ($students as $student) {
954 if ($emailall || $student->forwardmail) {
955 $mail->AddAddress("$student->email","$student->firstname $student->lastname");
956 }
957 }
958 foreach ($teachers as $teacher) {
959 if ($emailall || $teacher->forwardmail) {
960 $mail->AddAddress("$teacher->email","$teacher->firstname $teacher->lastname");
961 }
962 }
963
964 $mail->AddReplyTo("$from->email","$from->firstname $from->lastname");
965 $mail->WordWrap = 70; // set word wrap
966 $mail->IsHTML(false); // set email format to HTML
967 $mail->Subject = "$course->shortname: $subject";
968
969 $message .= "\n\n--\n$from->firstname $from->lastname";
970
971 if ($footer) {
972 $message .= "\n\n$footer";
973 }
974
975 if ($link) {
976 $message .= "\nLink: $link";
977 }
978
979 $mail->Body = "\n\n$message";
980
981 if (!$mail->Send()) {
982 //echo "Message was not sent <p>";
983 //echo "Mailer Error: " . $mail->ErrorInfo;
984 return false;
985 }
986
987 return true;
988
989}
990
991/// FILE HANDLING /////////////////////////////////////////////
992
993function get_directory_list( $rootdir ) {
994// Returns an array with all the filenames in
995// all subdirectories, relative to the given rootdir.
996
997 $dirs = array();
998
999 $dir = opendir( $rootdir );
1000
1001 while( $file = readdir( $dir ) ) {
1002 $fullfile = $rootdir."/".$file;
1003 if ($file != "." and $file != "..") {
1004 if (filetype($fullfile) == "dir") {
1005 $subdirs = get_directory_list($fullfile);
1006 foreach ($subdirs as $subdir) {
1007 $dirs[] = $file."/".$subdir;
1008 }
1009 } else {
1010 $dirs[] = $file;
1011 }
1012 }
1013 }
1014
1015 return $dirs;
1016}
1017
1018
1019
1020/// ENCRYPTION ////////////////////////////////////////////////
1021
1022function rc4encrypt($data) {
1023 $password = "nfgjeingjk";
1024 return endecrypt($password, $data, "");
1025}
1026
1027function rc4decrypt($data) {
1028 $password = "nfgjeingjk";
1029 return endecrypt($password, $data, "de");
1030}
1031
1032function endecrypt ($pwd, $data, $case) {
1033// Based on a class by Mukul Sabharwal [mukulsabharwal@yahoo.com]
1034
1035 if ($case == 'de') {
1036 $data = urldecode($data);
1037 }
1038
1039 $key[] = "";
1040 $box[] = "";
1041 $temp_swap = "";
1042 $pwd_length = 0;
1043
1044 $pwd_length = strlen($pwd);
1045
1046 for ($i = 0; $i <= 255; $i++) {
1047 $key[$i] = ord(substr($pwd, ($i % $pwd_length), 1));
1048 $box[$i] = $i;
1049 }
1050
1051 $x = 0;
1052
1053 for ($i = 0; $i <= 255; $i++) {
1054 $x = ($x + $box[$i] + $key[$i]) % 256;
1055 $temp_swap = $box[$i];
1056 $box[$i] = $box[$x];
1057 $box[$x] = $temp_swap;
1058 }
1059
1060 $temp = "";
1061 $k = "";
1062
1063 $cipherby = "";
1064 $cipher = "";
1065
1066 $a = 0;
1067 $j = 0;
1068
1069 for ($i = 0; $i < strlen($data); $i++) {
1070 $a = ($a + 1) % 256;
1071 $j = ($j + $box[$a]) % 256;
1072 $temp = $box[$a];
1073 $box[$a] = $box[$j];
1074 $box[$j] = $temp;
1075 $k = $box[(($box[$a] + $box[$j]) % 256)];
1076 $cipherby = ord(substr($data, $i, 1)) ^ $k;
1077 $cipher .= chr($cipherby);
1078 }
1079
1080 if ($case == 'de') {
1081 $cipher = urldecode(urlencode($cipher));
1082 } else {
1083 $cipher = urlencode($cipher);
1084 }
1085
1086 return $cipher;
1087}
1088
1089
1090/// MISCELLANEOUS ////////////////////////////////////////////////////////////////////
1091
1092function getweek ($startdate, $thedate) {
1093// Given dates in seconds, how many weeks is the date from startdate
1094// The first week is 1, the second 2 etc ...
1095
1096 if ($thedate < $startdate) { // error
1097 return 0;
1098 }
1099
1100 return floor(($thedate - $startdate) / 604800.0) + 1;
1101}
1102
1103function add_to_log ($message, $course=0) {
1104 global $db, $USER, $REMOTE_ADDR;
1105
1106 $timenow = time();
1107 $me = me();
1108 $message = addslashes($message);
1109
1110 $result = $db->Execute("INSERT DELAYED INTO logs
1111 SET user = '$USER->id', time = '$timenow', course = '$course',
1112 ip = '$REMOTE_ADDR', url = '$me', message = '$message'");
1113 if (!$result) {
1114 error("Could not insert a new entry to the Moodle log");
1115 }
1116}
1117
1118function generate_password($maxlen=10) {
1119/* returns a randomly generated password of length $maxlen. inspired by
1120 * http://www.phpbuilder.com/columns/jesus19990502.php3 */
1121
1122 global $CFG;
1123
1124 $fillers = "1234567890!$-+";
1125 $wordlist = file($CFG->wordlist);
1126
1127 srand((double) microtime() * 1000000);
1128 $word1 = trim($wordlist[rand(0, count($wordlist) - 1)]);
1129 $word2 = trim($wordlist[rand(0, count($wordlist) - 1)]);
1130 $filler1 = $fillers[rand(0, strlen($fillers) - 1)];
1131
1132 return substr($word1 . $filler1 . $word2, 0, $maxlen);
1133}
1134
1135
1136function format_time($totalsecs) {
1137
1138 $days = floor($totalsecs/86400);
1139 $remainder = $totalsecs - ($days*86400);
1140 $hours = floor($remainder/3600);
1141 $remainder = $remainder - ($hours*3600);
1142 $mins = floor($remainder/60);
1143 $secs = $remainder - ($mins*60);
1144
1145 if ($secs != 1) $ss = "s";
1146 if ($mins != 1) $ms = "s";
1147 if ($hours != 1) $hs = "s";
1148 if ($days != 1) $ds = "s";
1149
1150 if ($days) $odays = "$days day$ds";
1151 if ($hours) $ohours = "$hours hr$hs";
1152 if ($mins) $omins = "$mins min$ms";
1153 if ($secs) $osecs = "$secs sec$ss";
1154
1155 if ($days) return "$odays $ohours";
1156 if ($hours) return "$ohours $omins";
1157 if ($mins) return "$omins $osecs";
1158 if ($secs) return "$osecs";
1159 return "now";
1160}
1161
1162
1163?>