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 | |
14 | function 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 | |
38 | function 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 | |
51 | function print_navigation ($navigation) { |
52 | global $CFG; |
53 | |
54 | if ($navigation) { |
55 | echo "<A TARGET=_top HREF=\"$CFG->wwwroot/\">Home</A> -> $navigation"; |
56 | } |
57 | } |
58 | |
59 | function print_heading($heading) { |
60 | echo "<P ALIGN=CENTER><FONT SIZE=4><B>$heading</B></FONT></P>"; |
61 | } |
62 | |
63 | function 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 | |
69 | function 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 | |
84 | function print_simple_box_end() { |
85 | echo "</TD></TR></TABLE>"; |
86 | echo "</TD></TR></TABLE>"; |
87 | } |
88 | |
89 | function 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 | |
97 | function 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 | |
116 | function 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 | |
160 | function moodledate($date) { |
161 | return date("l, j F Y, g:i A T", $date); |
162 | } |
163 | |
164 | |
165 | function 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 | |
185 | function 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 | |
199 | function 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 " "; |
207 | echo "<A HREF=\"$linkno\">No</A>"; |
208 | echo "</B></FONT></P>"; |
209 | print_simple_box_end(); |
210 | } |
211 | |
212 | function 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 | |
228 | function notify ($message) { |
229 | echo "<P align=center><B><FONT COLOR=#FF0000>$message</FONT></B></P>\n"; |
230 | } |
231 | |
232 | |
233 | |
234 | /// PARAMETER HANDLING //////////////////////////////////////////////////// |
235 | |
236 | function require_variable($var) { |
237 | |
238 | if (! isset($var)) { |
239 | error("A required parameter was missing"); |
240 | } |
241 | } |
242 | |
243 | function optional_variable(&$var, $default=0) { |
244 | if (! isset($var)) { |
245 | $var = $default; |
246 | } |
247 | } |
248 | |
249 | |
250 | |
251 | |
252 | /// DATABASE HANDLING //////////////////////////////////////////////// |
253 | |
254 | function 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 | |
270 | function 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 | |
310 | function 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 | |
323 | function 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 | |
337 | function 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 | |
347 | function 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 | |
357 | function 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 | |
371 | function 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 | |
387 | function 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 | |
401 | function 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 | |
422 | function 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 | |
445 | function 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 | |
458 | function 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 | |
465 | function 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 | |
472 | function 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 | |
524 | function 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 | |
569 | function 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 | |
613 | function 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 | |
629 | function 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 | |
663 | function 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 | |
681 | function 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 | |
691 | function 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 | |
702 | function 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 | |
715 | function reset_login_count() { |
716 | global $SESSION; |
717 | |
718 | $SESSION->logincount = 0; |
719 | } |
720 | |
721 | |
722 | function 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 | |
732 | function get_moodle_cookie() { |
733 | global $MOODLEID; |
734 | return rc4decrypt($MOODLEID); |
735 | } |
736 | |
737 | |
738 | |
739 | function 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 | |
752 | function 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 | |
761 | function 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 | |
773 | function 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 | |
790 | function 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 | |
804 | function 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 | |
820 | function print_update_module_icon($moduleid) { |
821 | global $CFG; |
822 | |
823 | echo " |
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 | |
834 | function 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 | |
865 | function 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 | |
920 | function 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 | |
993 | function 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 | |
1022 | function rc4encrypt($data) { |
1023 | $password = "nfgjeingjk"; |
1024 | return endecrypt($password, $data, ""); |
1025 | } |
1026 | |
1027 | function rc4decrypt($data) { |
1028 | $password = "nfgjeingjk"; |
1029 | return endecrypt($password, $data, "de"); |
1030 | } |
1031 | |
1032 | function 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 | |
1092 | function 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 | |
1103 | function 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 | |
1118 | function 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 | |
1136 | function 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 | ?> |