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