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