Improved explanations
[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 }
4efeb8c3 29
30 if (!$button and $navigation) {
31 if (isset($USER->id)) {
32 $button = "<FONT SIZE=2><A HREF=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</A></FONT>";
33 } else {
34 $button = "<FONT SIZE=2><A HREF=\"$CFG->wwwroot/login\">".get_string("login")."</A></FONT>";
35 }
36 }
f9903ed0 37
38 if (!$cache) { // Do everything we can to prevent clients and proxies caching
39 @header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
40 @header("Pragma: no-cache");
41 $meta .= "\n<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">";
42 $meta .= "\n<META HTTP-EQUIV=\"Expires\" CONTENT=\"0\">";
43 }
44
45 include ("$CFG->dirroot/theme/$CFG->theme/header.html");
46}
47
48function print_footer ($course=NULL) {
49// Can provide a course object to make the footer contain a link to
50// to the course home page, otherwise the link will go to the site home
51 global $USER, $CFG, $THEME;
52
53 if ($course) {
d82c8545 54 if ($course == "home") { // special case for site home page
55 if (!$dversion = get_field("config", "value", "name", "version")) {
56 $dversion = "unknown!";
57 }
58 $homelink = "<P ALIGN=center><A TITLE=\"Version $dversion: Click to visit moodle.com\" HREF=\"http://moodle.com/\">";
59 $homelink .= "<IMG WIDTH=85 HEIGHT=25 SRC=\"pix/madewithmoodle.gif\" BORDER=0></A></P>";
60 } else {
61 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A>";
62 }
f9903ed0 63 } else {
d82c8545 64 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot\">".get_string("home")."</A>";
f9903ed0 65 }
3ce2f1e0 66 if ($USER->realuser) {
67 if ($realuser = get_record("user", "id", $USER->realuser)) {
68 $realuserinfo = " [$realuser->firstname $realuser->lastname] ";
69 }
70 }
71 if ($USER->id) {
72 $loggedinas = $realuserinfo.get_string("loggedinas", "moodle", "$USER->firstname $USER->lastname").
73 " (<A HREF=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</A>)";
74 } else {
75 $loggedinas = get_string("loggedinnot", "moodle").
76 " (<A HREF=\"$CFG->wwwroot/login/\">".get_string("login")."</A>)";
77 }
78
f9903ed0 79 include ("$CFG->dirroot/theme/$CFG->theme/footer.html");
80}
81
82function print_navigation ($navigation) {
83 global $CFG;
84
85 if ($navigation) {
a83fded1 86 if (! $site = get_site()) {
bcc83c41 87 $site->shortname = get_string("home");;
88 }
a2eaeb91 89 echo "<A TARGET=_top HREF=\"$CFG->wwwroot/\">$site->shortname</A> -> $navigation";
f9903ed0 90 }
91}
92
2a46a71b 93function print_heading($text, $align="CENTER", $size=3) {
94 echo "<P ALIGN=\"$align\"><FONT SIZE=\"$size\"><B>$text</B></FONT></P>";
f9903ed0 95}
96
dbcb136a 97function print_continue($link) {
98 global $HTTP_REFERER;
99
100 if (!$link) {
101 $link = $HTTP_REFERER;
102 }
103
104 print_heading("<A HREF=\"$link\">".get_string("continue")."</A>");
105}
106
107
4216daa6 108function print_simple_box($message, $align="", $width="", $color="#FFFFFF", $padding=5, $border=1) {
109 print_simple_box_start($align, $width, $color, $padding, $border);
f9903ed0 110 echo "<P>$message</P>";
111 print_simple_box_end();
112}
113
4216daa6 114function print_simple_box_start($align="", $width="", $color="#FFFFFF", $padding=5, $border=1) {
f9903ed0 115 global $THEME;
116
117 if ($align) {
118 $tablealign = "ALIGN=\"$align\"";
119 }
120 if ($width) {
121 $tablewidth = "WIDTH=\"$width\"";
122 $innertablewidth = "WIDTH=\"100%\"";
123 }
4216daa6 124 echo "<TABLE $tablealign $tablewidth BORDER=0 CELLPADDING=\"$border\" CELLSPACING=0>";
f9903ed0 125 echo "<TR><TD BGCOLOR=\"$THEME->borders\">\n";
126 echo "<TABLE $innertablewidth BORDER=0 CELLPADDING=\"$padding\" CELLSPACING=0><TR><TD BGCOLOR=\"$color\">";
127}
128
129function print_simple_box_end() {
130 echo "</TD></TR></TABLE>";
131 echo "</TD></TR></TABLE>";
132}
133
134function print_single_button($link, $options, $label="OK") {
135 echo "<FORM ACTION=\"$link\" METHOD=GET>";
dbcb136a 136 if ($options) {
137 foreach ($options as $name => $value) {
138 echo "<INPUT TYPE=hidden NAME=\"$name\" VALUE=\"$value\">";
139 }
f9903ed0 140 }
141 echo "<INPUT TYPE=submit VALUE=\"$label\"></FORM>";
142}
143
136dabd8 144function print_user_picture($userid, $courseid, $picture, $large=false, $returnstring=false) {
f9903ed0 145 global $CFG;
146
136dabd8 147 $output = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$userid&course=$courseid\">";
f9903ed0 148 if ($large) {
149 $file = "f1.jpg";
150 $size = 100;
151 } else {
152 $file = "f2.jpg";
153 $size = 35;
154 }
155 if ($picture) {
2447921f 156 if (iswindows()) { // Workaround for a PATH_INFO problem on Windows PHP
157 $output .= "<IMG SRC=\"$CFG->wwwroot/user/pix.php?file=/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
158 } else { // Use this method if possible for better caching
159 $output .= "<IMG SRC=\"$CFG->wwwroot/user/pix.php/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
160 }
f9903ed0 161 } else {
136dabd8 162 $output .= "<IMG SRC=\"$CFG->wwwroot/user/default/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
163 }
164 $output .= "</A>";
165
166 if ($returnstring) {
167 return $output;
168 } else {
169 echo $output;
f9903ed0 170 }
f9903ed0 171}
172
173function print_table($table) {
174// Prints a nicely formatted table.
175// $table is an object with three properties.
176// $table->head is an array of heading names.
177// $table->align is an array of column alignments
178// $table->data[] is an array of arrays containing the data.
1e3e716f 179// $table->width is an percentage of the page
f9903ed0 180
37b15514 181 if ($table->align) {
f9903ed0 182 foreach ($table->align as $key => $aa) {
183 if ($aa) {
184 $align[$key] = "ALIGN=\"$aa\"";
185 } else {
186 $align[$key] = "";
187 }
188 }
189 }
190
1e3e716f 191 if (!$table->width) {
192 $table->width = "80%";
193 }
194
195 print_simple_box_start("CENTER", "$table->width", "#FFFFFF", 0);
37b15514 196 echo "<TABLE WIDTH=100% BORDER=0 valign=top align=center cellpadding=10 cellspacing=1>\n";
f9903ed0 197
198 if ($table->head) {
199 echo "<TR>";
909f539d 200 foreach ($table->head as $key => $heading) {
201 echo "<TH ".$align[$key].">$heading</TH>";
f9903ed0 202 }
203 echo "</TR>\n";
204 }
205
206 foreach ($table->data as $row) {
207 echo "<TR VALIGN=TOP>";
208 foreach ($row as $key => $item) {
209 echo "<TD ".$align[$key].">$item</TD>";
210 }
211 echo "</TR>\n";
212 }
213 echo "</TABLE>\n";
214 print_simple_box_end();
215
216 return true;
217}
218
21ddaf60 219function print_editing_switch($courseid) {
220 global $CFG, $USER;
221
c7e3ac2a 222 if (isteacher($courseid)) {
21ddaf60 223 if ($USER->editing) {
224 echo "<A HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=off\">Turn editing off</A>";
225 } else {
226 echo "<A HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=on\">Turn editing on</A>";
227 }
228 }
229}
230
6b174680 231function update_course_icon($courseid) {
232 global $CFG, $USER;
233
234 if (isteacher($courseid)) {
235 if ($USER->editing) {
2c0411e2 236 return "<A TITLE=\"".get_string("turneditingoff")."\"
237 HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=off\"
6b174680 238 TARGET=_top><IMG SRC=\"$CFG->wwwroot/pix/i/edit.gif\" ALIGN=right BORDER=0></A>";
239 } else {
2c0411e2 240 return "<A TITLE=\"".get_string("turneditingon")."\"
241 HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=on\"
6b174680 242 TARGET=_top><IMG SRC=\"$CFG->wwwroot/pix/i/edit.gif\" ALIGN=right BORDER=0></A>";
243 }
244 }
245}
246
247function update_module_icon($moduleid, $courseid) {
248 global $CFG;
249
250 if (isteacher($courseid)) {
2c0411e2 251 return "<A TITLE=\"".get_string("editthisactivity")."\" HREF=\"$CFG->wwwroot/course/mod.php?update=$moduleid&return=true\" TARGET=_top><IMG SRC=\"$CFG->wwwroot/pix/i/edit.gif\" ALIGN=right BORDER=0></A>";
6b174680 252 }
253}
254
255
39917a09 256function print_date_selector($day, $month, $year, $currenttime=0) {
257// Currenttime is a default timestamp in GMT
258// Prints form items with the names $day, $month and $year
259
260 if (!$currenttime) {
261 $currenttime = time();
262 }
263 $currentdate = usergetdate($currenttime);
264
265 for ($i=1; $i<=31; $i++) {
266 $days[$i] = "$i";
267 }
268 for ($i=1; $i<=12; $i++) {
269 $months[$i] = date("F", mktime(0,0,0,$i,1,2000));
270 }
271 for ($i=2000; $i<=2010; $i++) {
272 $years[$i] = $i;
273 }
274 choose_from_menu($days, $day, $currentdate[mday], "");
275 choose_from_menu($months, $month, $currentdate[mon], "");
276 choose_from_menu($years, $year, $currentdate[year], "");
277}
278
279function print_time_selector($hour, $minute, $currenttime=0) {
280// Currenttime is a default timestamp in GMT
281// Prints form items with the names $hour and $minute
282
283 if (!$currenttime) {
284 $currenttime = time();
285 }
286 $currentdate = usergetdate($currenttime);
287 for ($i=0; $i<=23; $i++) {
288 $hours[$i] = sprintf("%02d",$i);
289 }
290 for ($i=0; $i<=59; $i++) {
291 $minutes[$i] = sprintf("%02d",$i);
292 }
293 choose_from_menu($hours, $hour, $currentdate[hours], "");
294 choose_from_menu($minutes, $minute, $currentdate[minutes], "");
295}
296
297function make_timestamp($year, $month=1, $day=1, $hour=0, $minute=0, $second=0) {
298// Given date parts in user time, produce a GMT timestamp
299
300 return mktime((int)$hour,(int)$minute,(int)$second,(int)$month,(int)$day,(int)$year);
301}
302
6b174680 303function format_time($totalsecs) {
304// Given an amount of time in seconds, prints it
305// nicely as months, days, hours etc as needed
c7e3ac2a 306
6b174680 307 $totalsecs = abs($totalsecs);
c7e3ac2a 308
6b174680 309 $days = floor($totalsecs/86400);
310 $remainder = $totalsecs - ($days*86400);
311 $hours = floor($remainder/3600);
312 $remainder = $remainder - ($hours*3600);
313 $mins = floor($remainder/60);
314 $secs = $remainder - ($mins*60);
c7e3ac2a 315
6b174680 316 if ($secs != 1) $ss = "s";
317 if ($mins != 1) $ms = "s";
318 if ($hours != 1) $hs = "s";
319 if ($days != 1) $ds = "s";
c7e3ac2a 320
6b174680 321 if ($days) $odays = "$days day$ds";
322 if ($hours) $ohours = "$hours hr$hs";
323 if ($mins) $omins = "$mins min$ms";
324 if ($secs) $osecs = "$secs sec$ss";
325
326 if ($days) return "$odays $ohours";
327 if ($hours) return "$ohours $omins";
328 if ($mins) return "$omins $osecs";
329 if ($secs) return "$osecs";
330 return get_string("now");
331}
f9903ed0 332
5fa51a39 333function userdate($date, $format="", $timezone=99) {
d552ead0 334// Returns a formatted string that represents a date in user time
7a302afc 335// WARNING: note that the format is for strftime(), not date().
336
873960de 337 global $USER;
338
5fa51a39 339 if ($format == "") {
7a302afc 340 $format = "%A, %e %B %Y, %I:%M %p";
5fa51a39 341 }
342 if ($timezone == 99) {
343 $timezone = (float)$USER->timezone;
344 }
345 if (abs($timezone) > 12) {
6d9d8344 346 return strftime("$format", $date);
873960de 347 }
7a302afc 348 return gmstrftime($format, $date + (int)($timezone * 3600));
873960de 349}
350
5fa51a39 351function usergetdate($date, $timezone=99) {
6b174680 352// Given a $date timestamp in GMT, returns an array
353// that represents the date in user time
354
873960de 355 global $USER;
356
5fa51a39 357 if ($timezone == 99) {
358 $timezone = (float)$USER->timezone;
359 }
360 if (abs($timezone) > 12) {
873960de 361 return getdate($date);
362 }
d2d6171f 363 //There is no gmgetdate so I have to fake it...
364 $date = $date + (int)($timezone * 3600);
365 $getdate["seconds"] = gmstrftime("%S", $date);
366 $getdate["minutes"] = gmstrftime("%M", $date);
367 $getdate["hours"] = gmstrftime("%H", $date);
368 $getdate["mday"] = gmstrftime("%d", $date);
369 $getdate["wday"] = gmstrftime("%u", $date);
370 $getdate["mon"] = gmstrftime("%m", $date);
371 $getdate["year"] = gmstrftime("%Y", $date);
372 $getdate["yday"] = gmstrftime("%j", $date);
373 $getdate["weekday"] = gmstrftime("%A", $date);
374 $getdate["month"] = gmstrftime("%B", $date);
375 return $getdate;
d552ead0 376}
377
378function usertime($date, $timezone=99) {
379// Given a GMT timestamp (seconds since epoch), offsets it by
380// the timezone. eg 3pm in India is 3pm GMT - 7 * 3600 seconds
381 global $USER;
382
383 if ($timezone == 99) {
384 $timezone = (float)$USER->timezone;
385 }
386 if (abs($timezone) > 12) {
387 return $date;
388 }
389 return $date - (int)($timezone * 3600);
390}
391
edf7fe8c 392function usergetmidnight($date, $timezone=99) {
393// Given a time, return the GMT timestamp of the most recent midnight
394// for the current user.
edf7fe8c 395 global $USER;
396
4606d9bb 397 if ($timezone == 99) {
398 $timezone = (float)$USER->timezone;
399 }
400
edf7fe8c 401 $userdate = usergetdate($date, $timezone);
4606d9bb 402
403 if (abs($timezone) > 12) {
404 return mktime(0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
405 }
406
edf7fe8c 407 $timemidnight = gmmktime (0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
408 return usertime($timemidnight, $timezone); // Time of midnight of this user's day, in GMT
409
410}
411
d552ead0 412function usertimezone($timezone=99) {
413// returns a string that prints the user's timezone
414 global $USER;
415
416 if ($timezone == 99) {
417 $timezone = (float)$USER->timezone;
418 }
419 if (abs($timezone) > 12) {
420 return "server time";
421 }
422 if (abs($timezone) < 0.5) {
423 return "GMT";
424 }
425 if ($timezone > 0) {
426 return "GMT+$timezone";
427 } else {
428 return "GMT$timezone";
429 }
f9903ed0 430}
431
432
433function error ($message, $link="") {
434 global $CFG, $SESSION;
435
ae350059 436 print_header(get_string("error"));
f9903ed0 437 echo "<BR>";
438 print_simple_box($message, "center", "", "#FFBBBB");
439
440 if (!$link) {
441 if ( !empty($SESSION->fromurl) ) {
442 $link = "$SESSION->fromurl";
443 unset($SESSION->fromurl);
8223d271 444 save_session("SESSION");
f9903ed0 445 } else {
446 $link = "$CFG->wwwroot";
447 }
448 }
dbcb136a 449 print_continue($link);
f9903ed0 450 print_footer();
451 die;
452}
453
65cf9fc3 454function helpbutton ($page, $title="", $module="moodle", $image=true, $text="") {
455 // $page = the keyword that defines a help page
456 // $title = the title of links, rollover tips, alt tags etc
457 // $module = which module is the page defined in
458 // $image = use a help image for the link? (otherwise uses text)
459 // $text = if defined then this text is used in the page, and
460 // the $page variable is ignored.
34c8915d 461 global $CFG;
65cf9fc3 462 if ($module == "") {
463 $module = "moodle";
464 }
465 if ($image) {
466 $linkobject = "<IMG BORDER=0 ALT=\"$title\" SRC=\"$CFG->wwwroot/pix/help.gif\">";
467 } else {
468 $linkobject = $title;
469 }
470 if ($text) {
471 $url = "/help.php?module=$module&text=$text";
472 } else {
6ee45796 473 $url = "/help.php?module=$module&file=$page.html";
65cf9fc3 474 }
475 link_to_popup_window ($url, "popup", $linkobject, 400, 500, $title);
34c8915d 476}
477
f9903ed0 478function notice ($message, $link="") {
479 global $THEME, $HTTP_REFERER;
480
481 if (!$link) {
482 $link = $HTTP_REFERER;
483 }
484
485 echo "<BR>";
486 print_simple_box($message, "center", "", "$THEME->cellheading");
ae350059 487 print_heading("<A HREF=\"$link\">".get_string("continue")."</A>");
f9903ed0 488 print_footer();
489 die;
490}
491
492function notice_yesno ($message, $linkyes, $linkno) {
493 global $THEME;
494
495 print_simple_box_start("center", "", "$THEME->cellheading");
496 echo "<P ALIGN=CENTER><FONT SIZE=3>$message</FONT></P>";
497 echo "<P ALIGN=CENTER><FONT SIZE=3><B>";
ae350059 498 echo "<A HREF=\"$linkyes\">".get_string("yes")."</A>";
f9903ed0 499 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
ae350059 500 echo "<A HREF=\"$linkno\">".get_string("no")."</A>";
f9903ed0 501 echo "</B></FONT></P>";
502 print_simple_box_end();
503}
504
505function redirect($url, $message="", $delay=0) {
506// Uses META tags to redirect the user, after printing a notice
f9903ed0 507
508 echo "<META HTTP-EQUIV='Refresh' CONTENT='$delay; URL=$url'>";
509
510 if (!empty($message)) {
511 print_header();
512 echo "<CENTER>";
513 echo "<P>$message</P>";
ae350059 514 echo "<P>( <A HREF=\"$url\">".get_string("continue")."</A> )</P>";
f9903ed0 515 echo "</CENTER>";
516 }
517 die;
518}
519
520function notify ($message) {
521 echo "<P align=center><B><FONT COLOR=#FF0000>$message</FONT></B></P>\n";
522}
523
524
525
526/// PARAMETER HANDLING ////////////////////////////////////////////////////
527
528function require_variable($var) {
f9903ed0 529 if (! isset($var)) {
530 error("A required parameter was missing");
531 }
532}
533
534function optional_variable(&$var, $default=0) {
535 if (! isset($var)) {
536 $var = $default;
537 }
538}
539
540
541
542
543/// DATABASE HANDLING ////////////////////////////////////////////////
544
545function execute_sql($command) {
546// Completely general
547
548 global $db;
549
550 $result = $db->Execute("$command");
551
552 if ($result) {
ae350059 553 echo "<P><FONT COLOR=green><B>".get_string("success")."</B></FONT></P>";
f9903ed0 554 return true;
555 } else {
ae350059 556 echo "<P><FONT COLOR=red><B>".get_string("error")."</B></FONT></P>";
f9903ed0 557 return false;
558 }
559}
560
561function modify_database($sqlfile) {
562// Assumes that the input text file consists of a number
563// of SQL statements ENDING WITH SEMICOLONS. The semicolons
564// MUST be the last character in a line.
565// Lines that are blank or that start with "#" are ignored.
566// Only tested with mysql dump files (mysqldump -p -d moodle)
567
568
569 if (file_exists($sqlfile)) {
570 $success = true;
571 $lines = file($sqlfile);
572 $command = "";
573
574 while ( list($i, $line) = each($lines) ) {
575 $line = chop($line);
576 $length = strlen($line);
577
578 if ($length && substr($line, 0, 1) <> "#") {
579 if (substr($line, $length-1, 1) == ";") {
580 $line = substr($line, 0, $length-1); // strip ;
581 $command .= $line;
582 if (! execute_sql($command)) {
583 $success = false;
584 }
585 $command = "";
586 } else {
587 $command .= $line;
588 }
589 }
590 }
591
592 } else {
593 $success = false;
594 echo "<P>Tried to modify database, but \"$sqlfile\" doesn't exist!</P>";
595 }
596
597 return $success;
598}
599
600
601function record_exists($table, $field, $value) {
602 global $db;
603
604 $rs = $db->Execute("SELECT * FROM $table WHERE $field = '$value' LIMIT 1");
605 if (!$rs) return false;
606
607 if ( $rs->RecordCount() ) {
608 return true;
609 } else {
610 return false;
611 }
612}
613
614function record_exists_sql($sql) {
615 global $db;
616
617 $rs = $db->Execute($sql);
618 if (!$rs) return false;
619
620 if ( $rs->RecordCount() ) {
621 return true;
622 } else {
623 return false;
624 }
625}
626
627
628function count_records($table, $selector, $value) {
629// Get all the records and count them
630 global $db;
631
632 $rs = $db->Execute("SELECT COUNT(*) FROM $table WHERE $selector = '$value'");
633 if (!$rs) return 0;
634
635 return $rs->fields[0];
636}
637
638function count_records_sql($sql) {
639// Get all the records and count them
640 global $db;
641
642 $rs = $db->Execute("$sql");
643 if (!$rs) return 0;
644
645 return $rs->fields[0];
646}
647
648function get_record($table, $selector, $value) {
649// Get a single record as an object
650 global $db;
651
652 $rs = $db->Execute("SELECT * FROM $table WHERE $selector = '$value'");
653 if (!$rs) return false;
654
655 if ( $rs->RecordCount() == 1 ) {
656 return (object)$rs->fields;
657 } else {
658 return false;
659 }
660}
661
662function get_record_sql($sql) {
663// Get a single record as an object
664// The sql statement is provided as a string.
665
666 global $db;
667
668 $rs = $db->Execute("$sql");
669 if (!$rs) return false;
670
671 if ( $rs->RecordCount() == 1 ) {
672 return (object)$rs->fields;
673 } else {
674 return false;
675 }
676}
677
678function get_records($table, $selector, $value, $sort="") {
679// Get a number of records as an array of objects
680// Can optionally be sorted eg "time ASC" or "time DESC"
681// The "key" is the first column returned, eg usually "id"
682 global $db;
683
684 if ($sort) {
685 $sortorder = "ORDER BY $sort";
686 }
687 $sql = "SELECT * FROM $table WHERE $selector = '$value' $sortorder";
688
689 return get_records_sql($sql);
690}
691
692function get_records_sql($sql) {
693// Get a number of records as an array of objects
694// The "key" is the first column returned, eg usually "id"
695// The sql statement is provided as a string.
696
697 global $db;
698
699 $rs = $db->Execute("$sql");
700 if (!$rs) return false;
701
702 if ( $rs->RecordCount() > 0 ) {
5c0bef5d 703 if ($records = $rs->GetAssoc(true)) {
704 foreach ($records as $key => $record) {
705 $objects[$key] = (object) $record;
706 }
707 return $objects;
708 } else {
709 return false;
f9903ed0 710 }
f9903ed0 711 } else {
712 return false;
713 }
714}
715
716function get_records_sql_menu($sql) {
717// Given an SQL select, this function returns an associative
718// array of the first two columns. This is most useful in
719// combination with the choose_from_menu function to create
720// a form menu.
721
722 global $db;
723
724 $rs = $db->Execute("$sql");
725 if (!$rs) return false;
726
727 if ( $rs->RecordCount() > 0 ) {
728 while (!$rs->EOF) {
729 $menu[$rs->fields[0]] = $rs->fields[1];
730 $rs->MoveNext();
731 }
732 return $menu;
733
734 } else {
735 return false;
736 }
737}
738
739function get_field($table, $field, $selector, $value) {
740 global $db;
741
742 $rs = $db->Execute("SELECT $field FROM $table WHERE $selector = '$value'");
743 if (!$rs) return false;
744
745 if ( $rs->RecordCount() == 1 ) {
746 return $rs->fields["$field"];
747 } else {
748 return false;
749 }
750}
751
752function set_field($table, $field, $newvalue, $selector, $value) {
753 global $db;
754
755 return $db->Execute("UPDATE $table SET $field = '$newvalue' WHERE $selector = '$value'");
756}
757
758
759function delete_records($table, $selector, $value) {
760// Delete one or more records from a table
761 global $db;
762
763 return $db->Execute("DELETE FROM $table WHERE $selector = '$value'");
764}
765
766function insert_record($table, $dataobject) {
767// Insert a record into a table and return the "id" field
768// $dataobject is an object containing needed data
769
770 global $db;
771
772 // Determine all the fields needed
773 if (! $columns = $db->MetaColumns("$table")) {
774 return false;
775 }
776
777 $data = (array)$dataobject;
778
779 // Pull out data matching these fields
780 foreach ($columns as $column) {
e5a57e85 781 if ($column->name <> "id" && isset($data[$column->name]) ) {
f9903ed0 782 $ddd[$column->name] = $data[$column->name];
783 }
784 }
785
786 // Construct SQL queries
787 if (! $numddd = count($ddd)) {
788 return 0;
789 }
790
791 $count = 0;
792 $insert = "";
793 $select = "";
794
795 foreach ($ddd as $key => $value) {
796 $count++;
797 $insert .= "$key = '$value'";
798 $select .= "$key = '$value'";
799 if ($count < $numddd) {
800 $insert .= ", ";
801 $select .= " AND ";
802 }
803 }
804
805 if (! $rs = $db->Execute("INSERT INTO $table SET $insert")) {
806 return false;
807 }
808
809 // Pull it out again to find the id. This is the most cross-platform method.
810 if ($rs = $db->Execute("SELECT id FROM $table WHERE $select")) {
811 return $rs->fields[0];
812 } else {
813 return false;
814 }
815}
816
817
818function update_record($table, $dataobject) {
819// Update a record in a table
820// $dataobject is an object containing needed data
821
822 global $db;
823
5c0bef5d 824 if (! isset($dataobject->id) ) {
f9903ed0 825 return false;
826 }
827
828 // Determine all the fields in the table
1afd014e 829 if (!$columns = $db->MetaColumns($table)) {
830 return false;
831 }
f9903ed0 832 $data = (array)$dataobject;
833
834 // Pull out data matching these fields
835 foreach ($columns as $column) {
5c0bef5d 836 if ($column->name <> "id" && isset($data[$column->name]) ) {
f9903ed0 837 $ddd[$column->name] = $data[$column->name];
838 }
839 }
840
841 // Construct SQL queries
842 $numddd = count($ddd);
843 $count = 0;
844 $update = "";
845
846 foreach ($ddd as $key => $value) {
847 $count++;
848 $update .= "$key = '$value'";
849 if ($count < $numddd) {
850 $update .= ", ";
851 }
852 }
853
854 if ($rs = $db->Execute("UPDATE $table SET $update WHERE id = '$dataobject->id'")) {
855 return true;
856 } else {
857 return false;
858 }
859}
860
861
f93f848a 862function print_object($object) {
863// Mostly just for debugging
864
865 $array = (array)$object;
866 foreach ($array as $key => $item) {
867 echo "$key -> $item <BR>";
868 }
869}
870
871
f9903ed0 872
873/// USER DATABASE ////////////////////////////////////////////////
874
875function get_user_info_from_db($field, $value) {
876
877 global $db;
878
879 if (!$field || !$value)
880 return false;
881
882 $result = $db->Execute("SELECT * FROM user WHERE $field = '$value'");
883
884 if ( $result->RecordCount() == 1 ) {
885 $user = (object)$result->fields;
886
887 $rs = $db->Execute("SELECT course FROM user_students WHERE user = '$user->id' ");
888 while (!$rs->EOF) {
889 $course = $rs->fields["course"];
890 $user->student["$course"] = true;
891 $rs->MoveNext();
892 }
893
894 $rs = $db->Execute("SELECT course FROM user_teachers WHERE user = '$user->id' ");
895 while (!$rs->EOF) {
896 $course = $rs->fields["course"];
897 $user->teacher["$course"] = true;
898 $rs->MoveNext();
899 }
900
901 $rs = $db->Execute("SELECT * FROM user_admins WHERE user = '$user->id' ");
902 while (!$rs->EOF) {
903 $user->admin = true;
904 $rs->MoveNext();
905 }
906
a83fded1 907 if ($course = get_site()) {
f9903ed0 908 // Everyone is always a member of the top course
909 $user->student["$course->id"] = true;
910 }
911
912 return $user;
913
914 } else {
915 return false;
916 }
917}
918
919function update_user_in_db() {
920
921 global $db, $USER, $REMOTE_ADDR;
922
923 if (!isset($USER->id))
924 return false;
925
926 $timenow = time();
927 if ($db->Execute("UPDATE LOW_PRIORITY user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow'
928 WHERE id = '$USER->id' ")) {
929 return true;
930 } else {
931 return false;
932 }
933}
934
da5c172a 935function require_login($courseid=0) {
936// This function checks that the current user is logged in, and optionally
937// whether they are "logged in" or allowed to be in a particular course.
938// If not, then it redirects them to the site login or course enrolment.
f9903ed0 939
940 global $CFG, $SESSION, $USER, $FULLME, $HTTP_REFERER, $PHPSESSID;
941
da5c172a 942 // First check that the user is logged in to the site.
f9903ed0 943 if (! (isset( $USER->loggedin ) && $USER->confirmed) ) {
944 $SESSION->wantsurl = $FULLME;
945 $SESSION->fromurl = $HTTP_REFERER;
8223d271 946 save_session("SESSION");
f9903ed0 947 if ($PHPSESSID) { // Cookies not enabled.
948 redirect("$CFG->wwwroot/login/?PHPSESSID=$PHPSESSID");
949 } else {
950 redirect("$CFG->wwwroot/login/");
951 }
952 die;
f9903ed0 953 }
da5c172a 954
955 // Next, check if the user can be in a particular course
956 if ($courseid) {
957 if ($USER->student[$courseid] || $USER->teacher[$courseid] || $USER->admin) {
3ce2f1e0 958 if (!isset($USER->realuser)) { // Don't log if this isn't a realuser
959 update_user_in_db();
960 }
da5c172a 961 return; // user is a member of this course.
962 }
963 if (! $course = get_record("course", "id", $courseid)) {
964 error("That course doesn't exist");
965 }
966 if ($course->guest && ($USER->username == "guest")) {
967 update_user_in_db();
968 return; // user is a guest and this course allows guests
969 }
f9903ed0 970
da5c172a 971 // Not allowed in the course, so see if they want to enrol
972
973 $SESSION->wantsurl = $FULLME;
8223d271 974 save_session("SESSION");
da5c172a 975 redirect("$CFG->wwwroot/course/enrol.php?id=$courseid");
976 die;
977 }
f9903ed0 978}
979
980
981
982function update_login_count() {
983 global $SESSION;
984
985 $max_logins = 10;
986
987 if (empty($SESSION->logincount)) {
988 $SESSION->logincount = 1;
989 } else {
990 $SESSION->logincount++;
991 }
8223d271 992 save_session("SESSION");
f9903ed0 993
994 if ($SESSION->logincount > $max_logins) {
995 unset($SESSION->wantsurl);
8223d271 996 save_session("SESSION");
f9903ed0 997 error("Sorry, you have exceeded the allowed number of login attempts. Restart your browser.");
998 }
999}
1000
1001
1002function isadmin($userid=0) {
1003 global $USER;
1004
1005 if (!$userid) {
1006 return $USER->admin;
1007 }
1008
1009 return record_exists_sql("SELECT * FROM user_admins WHERE user='$userid'");
1010}
1011
8a9e3fd7 1012function isteacher($courseid, $userid=0) {
f9903ed0 1013 global $USER;
1014
d115a57f 1015 if (isadmin($userid)) { // admins can do anything the teacher can
1016 return true;
1017 }
1018
f9903ed0 1019 if (!$userid) {
8a9e3fd7 1020 return $USER->teacher[$courseid];
f9903ed0 1021 }
1022
8a9e3fd7 1023 return record_exists_sql("SELECT * FROM user_teachers WHERE user='$userid' AND course='$courseid'");
f9903ed0 1024}
1025
1026
8a9e3fd7 1027function isstudent($courseid, $userid=0) {
f9903ed0 1028 global $USER;
1029
1030 if (!$userid) {
8a9e3fd7 1031 return $USER->student[$courseid];
f9903ed0 1032 }
1033
1034 $timenow = time(); // todo: add time check below
1035
8a9e3fd7 1036 return record_exists_sql("SELECT * FROM user_students WHERE user='$userid' AND course='$courseid'");
f9903ed0 1037}
1038
da5c172a 1039function isguest($userid=0) {
1040 global $USER;
1041
1042 if (!$userid) {
1043 return ($USER->username == "guest");
1044 }
1045
a3447e10 1046 return record_exists_sql("SELECT * FROM user WHERE id='$userid' AND username = 'guest' ");
da5c172a 1047}
1048
2c309dc2 1049function isediting($courseid, $user=NULL) {
1050 global $USER;
1051 if (!$user){
1052 $user = $USER;
1053 }
1054 return ($user->editing and isteacher($courseid, $user->id));
1055}
1056
f9903ed0 1057function reset_login_count() {
1058 global $SESSION;
1059
1060 $SESSION->logincount = 0;
8223d271 1061 save_session("SESSION");
f9903ed0 1062}
1063
1064
1065function set_moodle_cookie($thing) {
1066
1067 $days = 60;
1068 $seconds = 60*60*24*$days;
1069
d115a57f 1070 setCookie ('MOODLEID', "", time() - 3600, "/");
f9903ed0 1071 setCookie ('MOODLEID', rc4encrypt($thing), time()+$seconds, "/");
1072}
1073
1074
1075function get_moodle_cookie() {
1076 global $MOODLEID;
1077 return rc4decrypt($MOODLEID);
1078}
1079
1080
8223d271 1081function save_session($VAR) {
1082// Copies temporary session variable to permanent sesson variable
1083// eg $_SESSION["USER"] = $USER;
1084 global $$VAR;
1085 $_SESSION[$VAR] = $$VAR;
1086}
1087
f9903ed0 1088
1089function verify_login($username, $password) {
1090
1091 $user = get_user_info_from_db("username", $username);
1092
1093 if (! $user) {
1094 return false;
1095 } else if ( $user->password == md5($password) ) {
1096 return $user;
1097 } else {
1098 return false;
1099 }
1100}
1101
1102function get_site () {
1103// Returns $course object of the top-level site.
1104 if ( $course = get_record("course", "category", 0)) {
1105 return $course;
1106 } else {
1107 return false;
1108 }
1109}
1110
1111function get_admin () {
1112// Returns $user object of the main admin user
1113
1114 if ( $admins = get_records_sql("SELECT u.* FROM user u, user_admins a WHERE a.user = u.id ORDER BY u.id ASC")) {
1115 foreach ($admins as $admin) {
1116 return $admin; // ie the first one (yeah I know it's bodgy)
1117 }
1118 } else {
1119 return false;
1120 }
1121}
1122
1123function get_teacher($courseid) {
1124// Returns $user object of the main teacher for a course
1125 if ( $teachers = get_records_sql("SELECT u.* FROM user u, user_teachers t
1126 WHERE t.user = u.id AND t.course = '$courseid'
1127 ORDER BY t.authority ASC")) {
1128 foreach ($teachers as $teacher) {
1129 return $teacher; // ie the first one (yeah I know it's bodgy)
1130 }
1131 } else {
1132 return false;
1133 }
1134}
1135
3c720cce 1136function get_course_students($courseid, $sort="u.lastaccess DESC") {
1137 return get_records_sql("SELECT u.* FROM user u, user_students s
1138 WHERE s.course = '$courseid' AND s.user = u.id
1139 ORDER BY $sort");
1140}
1141
1142function get_course_teachers($courseid, $sort="t.authority ASC") {
1143 return get_records_sql("SELECT u.* FROM user u, user_teachers t
1144 WHERE t.course = '$courseid' AND t.user = u.id
1145 ORDER BY $sort");
1146}
1147
1148function get_course_users($courseid, $sort="u.lastaccess DESC") {
57507290 1149// Using this method because the direct SQL just would not always work!
1150
1151 $teachers = get_course_teachers($courseid, $sort);
1152 $students = get_course_students($courseid, $sort);
1153
1154 if ($teachers and $students) {
1155 return array_merge($teachers, $students);
1156 } else if ($teachers) {
1157 return $teachers;
1158 } else {
1159 return $students;
1160 }
1161
1162// return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t
1163// WHERE (s.course = '$courseid' AND s.user = u.id) OR
1164// (t.course = '$courseid' AND t.user = u.id)
1165// ORDER BY $sort");
3c720cce 1166}
1167
f9903ed0 1168
1169
1170/// MODULE FUNCTIONS /////////////////////////////////////////////////
1171
1ea8303c 1172function get_coursemodule_from_instance($modulename, $instance, $courseid) {
f9903ed0 1173// Given an instance of a module, finds the coursemodule description
1174
1175 return get_record_sql("SELECT cm.*, m.name
1176 FROM course_modules cm, modules md, $modulename m
1ea8303c 1177 WHERE cm.course = '$courseid' AND
f9903ed0 1178 cm.deleted = '0' AND
1179 cm.instance = m.id AND
1180 md.name = '$modulename' AND
1181 md.id = cm.module AND
1182 m.id = '$instance'");
1183
1184}
1185
1ea8303c 1186function get_all_instances_in_course($modulename, $courseid, $sort="cw.section") {
f9903ed0 1187// Returns an array of all the active instances of a particular
1188// module in a given course. Returns false on any errors.
1189
9ccbad71 1190 return get_records_sql("SELECT m.*,cw.section,cm.id as coursemodule
1191 FROM course_modules cm, course_sections cw, modules md, $modulename m
1ea8303c 1192 WHERE cm.course = '$courseid' AND
f9903ed0 1193 cm.instance = m.id AND
1194 cm.deleted = '0' AND
9ccbad71 1195 cm.section = cw.id AND
f9903ed0 1196 md.name = '$modulename' AND
1197 md.id = cm.module
1198 ORDER BY $sort");
1199
1200}
1201
f9903ed0 1202
1203
1204
f9903ed0 1205/// CORRESPONDENCE ////////////////////////////////////////////////
1206
5fa51a39 1207function email_to_user($user, $from, $subject, $messagetext, $messagehtml="", $attachment="", $attachname="") {
1208// user - a user record as an object
1209// from - a user record as an object
1210// subject - plain text subject line of the email
136dabd8 1211// messagetext - plain text version of the message
1212// messagehtml - complete html version of the message (optional)
1213// attachment - a file on the filesystem, relative to $CFG->dataroot
1214// attachname - the name of the file (extension indicates MIME)
f9903ed0 1215
4216daa6 1216 global $CFG, $_SERVER;
f9903ed0 1217
136dabd8 1218 include_once("$CFG->libdir/phpmailer/class.phpmailer.php");
f9903ed0 1219
5fa51a39 1220 if (!$user) {
f9903ed0 1221 return false;
1222 }
1223
f9903ed0 1224 $mail = new phpmailer;
1225
1e411ffc 1226 $mail->Version = "Moodle $CFG->moodleversion"; // mailer version
136dabd8 1227 $mail->PluginDir = "$CFG->libdir/phpmailer/"; // plugin directory (eg smtp plugin)
7f86ce17 1228 if ($CFG->smtphosts) {
1e411ffc 1229 $mail->IsSMTP(); // use SMTP directly
1230 $mail->Host = "$CFG->smtphosts"; // specify main and backup servers
7f86ce17 1231 } else {
1e411ffc 1232 $mail->IsMail(); // use PHP mail() = sendmail
7f86ce17 1233 }
f9903ed0 1234
136dabd8 1235 $mail->From = "$from->email";
1236 $mail->FromName = "$from->firstname $from->lastname";
1237 $mail->Subject = stripslashes($subject);
f9903ed0 1238
6b174680 1239 $mail->AddAddress("$user->email", "$user->firstname $user->lastname");
f9903ed0 1240
f9903ed0 1241 $mail->WordWrap = 70; // set word wrap
f9903ed0 1242
136dabd8 1243 if ($messagehtml) {
1244 $mail->IsHTML(true);
1245 $mail->Body = $messagehtml;
78681899 1246 $mail->AltBody = "\n$messagetext\n";
136dabd8 1247 } else {
1248 $mail->IsHTML(false);
78681899 1249 $mail->Body = "\n$messagetext\n";
f9903ed0 1250 }
1251
136dabd8 1252 if ($attachment && $attachname) {
1253 if (ereg( "\\.\\." ,$attachment )) { // Security check for ".." in dir path
4216daa6 1254 $adminuser = get_admin();
1255 $mail->AddAddress("$adminuser->email", "$adminuser->firstname $adminuser->lastname");
1256 $mail->AddStringAttachment("Error in attachment. User attempted to attach a filename with a unsafe name.", "error.txt", "8bit", "text/plain");
136dabd8 1257 } else {
1258 include_once("$CFG->dirroot/files/mimetypes.php");
1259 $mimetype = mimeinfo("type", $attachname);
1260 $mail->AddAttachment("$CFG->dataroot/$attachment", "$attachname", "base64", "$mimetype");
1261 }
f9903ed0 1262 }
1263
136dabd8 1264 if ($mail->Send()) {
1265 return true;
1266 } else {
4216daa6 1267 echo "ERROR: $mail->ErrorInfo\n";
1268 $site = get_site();
1269 add_to_log($site->id, "library", "mailer", $_SERVER["REQUEST_URI"], "ERROR: $mail->ErrorInfo");
f9903ed0 1270 return false;
1271 }
f9903ed0 1272}
1273
136dabd8 1274
f9903ed0 1275/// FILE HANDLING /////////////////////////////////////////////
1276
6b174680 1277function make_upload_directory($directory) {
1278// $directory = a string of directory names under $CFG->dataroot
1279// eg stuff/assignment/1
1280// Returns full directory if successful, false if not
1281
1282 global $CFG;
1283
1284 $currdir = $CFG->dataroot;
1285 if (!file_exists($currdir)) {
1286 if (! mkdir($currdir, 0750)) {
1287 notify("ERROR: You need to create the directory $currdir with web server write access");
1288 return false;
1289 }
1290 }
1291
1292 $dirarray = explode("/", $directory);
1293
1294 foreach ($dirarray as $dir) {
1295 $currdir = "$currdir/$dir";
1296 if (! file_exists($currdir)) {
1297 if (! mkdir($currdir, 0750)) {
1298 notify("ERROR: Could not find or create a directory ($currdir)");
1299 return false;
1300 }
1301 }
1302 }
1303
1304 return $currdir;
1305}
1306
1307
f9903ed0 1308function get_directory_list( $rootdir ) {
1309// Returns an array with all the filenames in
1310// all subdirectories, relative to the given rootdir.
1311
1312 $dirs = array();
1313
1314 $dir = opendir( $rootdir );
1315
1316 while( $file = readdir( $dir ) ) {
1317 $fullfile = $rootdir."/".$file;
1318 if ($file != "." and $file != "..") {
1319 if (filetype($fullfile) == "dir") {
1320 $subdirs = get_directory_list($fullfile);
1321 foreach ($subdirs as $subdir) {
1322 $dirs[] = $file."/".$subdir;
1323 }
1324 } else {
1325 $dirs[] = $file;
1326 }
1327 }
1328 }
1329
1330 return $dirs;
1331}
1332
989bfa9d 1333function get_real_size($size=0) {
1334// Converts numbers like 10M into bytes
1335 if (!$size) {
1336 return 0;
1337 }
1338 $scan['MB'] = 1048576;
1339 $scan['M'] = 1048576;
1340 $scan['KB'] = 1024;
1341 $scan['K'] = 1024;
1342
1343 while (list($key) = each($scan)) {
1344 if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) {
1345 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
1346 break;
1347 }
1348 }
1349 return $size;
1350}
1351
6b174680 1352function clean_filename($string) {
1353 $string = eregi_replace("\.\.", "", $string);
1354 $string = eregi_replace("[^([:alnum:]|\.)]", "_", $string);
1355 return eregi_replace("_+", "_", $string);
1356}
1357
1358
1180c6dc 1359/// STRING TRANSLATION ////////////////////////////////////////
1360
a83fded1 1361function print_string($identifier, $module="", $a=NULL) {
1362 echo get_string($identifier, $module, $a);
bcc83c41 1363}
1364
1365
a83fded1 1366function get_string($identifier, $module="", $a=NULL) {
1180c6dc 1367// Return the translated string specified by $identifier as
1368// for $module. Uses the same format files as STphp.
a83fded1 1369// $a is an object, string or number that can be used
1180c6dc 1370// within translation strings
a83fded1 1371//
1372// eg "hello \$a->firstname \$a->lastname"
1373// or "hello \$a"
1180c6dc 1374
1375 global $CFG, $USER;
1376
1377 if (isset($USER->lang)) { // User language can override site language
1378 $lang = $USER->lang;
1379 } else {
1380 $lang = $CFG->lang;
1381 }
1382
058eec18 1383 if ($module == "") {
1384 $module = "moodle";
1180c6dc 1385 }
1386
058eec18 1387 $langpath = "$CFG->dirroot/lang";
1388 $langfile = "$langpath/$lang/$module.php";
1180c6dc 1389
1390 if (!file_exists($langfile)) { // try English instead
058eec18 1391 $langfile = "$langpath/en/$module.php";
1180c6dc 1392 if (!file_exists($langfile)) {
058eec18 1393 return "ERROR: No lang file ($langpath/en/$module.php)!";
1180c6dc 1394 }
1395 }
1396
1397 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1398
1399 eval($result);
1400 return $resultstring;
1401
1402 } else {
1403 if ($lang == "en") {
7a302afc 1404 return "ERROR: '$identifier' is missing!";
1180c6dc 1405
1406 } else { // Try looking in the english file.
058eec18 1407 $langfile = "$langpath/en/$module.php";
1180c6dc 1408 if (!file_exists($langfile)) {
058eec18 1409 return "ERROR: No lang file ($langpath/en/$module.php)!";
1180c6dc 1410 }
1411 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1412 eval($result);
1413 return $resultstring;
1414 } else {
7a302afc 1415 return "ERROR: '$identifier' is missing!";
1180c6dc 1416 }
1417 }
1418 }
1419}
1420
1421
1180c6dc 1422function get_string_from_file($identifier, $langfile, $destination) {
1423// This function is only used from get_string().
1424 include ($langfile);
1425
1426 if (!isset ($string[$identifier])) {
1427 return false;
1428 }
1429
a83fded1 1430 return "$destination = sprintf(\"".$string[$identifier]."\");";
1180c6dc 1431}
f9903ed0 1432
1433
1434/// ENCRYPTION ////////////////////////////////////////////////
1435
1436function rc4encrypt($data) {
1437 $password = "nfgjeingjk";
1438 return endecrypt($password, $data, "");
1439}
1440
1441function rc4decrypt($data) {
1442 $password = "nfgjeingjk";
1443 return endecrypt($password, $data, "de");
1444}
1445
1446function endecrypt ($pwd, $data, $case) {
1447// Based on a class by Mukul Sabharwal [mukulsabharwal@yahoo.com]
1448
1449 if ($case == 'de') {
1450 $data = urldecode($data);
1451 }
1452
1453 $key[] = "";
1454 $box[] = "";
1455 $temp_swap = "";
1456 $pwd_length = 0;
1457
1458 $pwd_length = strlen($pwd);
1459
1460 for ($i = 0; $i <= 255; $i++) {
1461 $key[$i] = ord(substr($pwd, ($i % $pwd_length), 1));
1462 $box[$i] = $i;
1463 }
1464
1465 $x = 0;
1466
1467 for ($i = 0; $i <= 255; $i++) {
1468 $x = ($x + $box[$i] + $key[$i]) % 256;
1469 $temp_swap = $box[$i];
1470 $box[$i] = $box[$x];
1471 $box[$x] = $temp_swap;
1472 }
1473
1474 $temp = "";
1475 $k = "";
1476
1477 $cipherby = "";
1478 $cipher = "";
1479
1480 $a = 0;
1481 $j = 0;
1482
1483 for ($i = 0; $i < strlen($data); $i++) {
1484 $a = ($a + 1) % 256;
1485 $j = ($j + $box[$a]) % 256;
1486 $temp = $box[$a];
1487 $box[$a] = $box[$j];
1488 $box[$j] = $temp;
1489 $k = $box[(($box[$a] + $box[$j]) % 256)];
1490 $cipherby = ord(substr($data, $i, 1)) ^ $k;
1491 $cipher .= chr($cipherby);
1492 }
1493
1494 if ($case == 'de') {
1495 $cipher = urldecode(urlencode($cipher));
1496 } else {
1497 $cipher = urlencode($cipher);
1498 }
1499
1500 return $cipher;
1501}
1502
1503
1504/// MISCELLANEOUS ////////////////////////////////////////////////////////////////////
1505
39917a09 1506function count_words($string) {
1507 $string = strip_tags($string);
1508 return count(preg_split("/\w\b/", $string)) - 1;
1509}
1510
f9903ed0 1511function getweek ($startdate, $thedate) {
1512// Given dates in seconds, how many weeks is the date from startdate
1513// The first week is 1, the second 2 etc ...
1514
1515 if ($thedate < $startdate) { // error
1516 return 0;
1517 }
1518
1519 return floor(($thedate - $startdate) / 604800.0) + 1;
1520}
1521
4216daa6 1522function add_to_log($course, $module, $action, $url="", $info="") {
1523// Add an entry to the log table. These are "action" focussed rather
1524// than web server hits, and provide a way to easily reconstruct what
1525// any particular student has been doing.
1526//
1527// course = the course id
501cdbd8 1528// module = forum, journal, reading, course, user etc
4216daa6 1529// action = view, edit, post (often but not always the same as the file.php)
1530// url = the file and parameters used to see the results of the action
1531// info = additional description information
1532
1533
f9903ed0 1534 global $db, $USER, $REMOTE_ADDR;
1535
9132e866 1536 if (isset($USER->realuser)) { // Don't log
1537 return;
1538 }
1539
f9903ed0 1540 $timenow = time();
4216daa6 1541 $info = addslashes($info);
1542
1543 $result = $db->Execute("INSERT INTO log
1544 SET time = '$timenow',
1545 user = '$USER->id',
1546 course = '$course',
1547 ip = '$REMOTE_ADDR',
1548 module = '$module',
1549 action = '$action',
1550 url = '$url',
1551 info = '$info'");
f9903ed0 1552 if (!$result) {
4216daa6 1553 echo "<P>Error: Could not insert a new entry to the Moodle log</P>"; // Don't throw an error
f9903ed0 1554 }
1555}
1556
1557function generate_password($maxlen=10) {
53bfe78c 1558// returns a randomly generated password of length $maxlen. inspired by
1559// http://www.phpbuilder.com/columns/jesus19990502.php3
f9903ed0 1560
1561 global $CFG;
1562
1563 $fillers = "1234567890!$-+";
1564 $wordlist = file($CFG->wordlist);
1565
1566 srand((double) microtime() * 1000000);
1567 $word1 = trim($wordlist[rand(0, count($wordlist) - 1)]);
1568 $word2 = trim($wordlist[rand(0, count($wordlist) - 1)]);
1569 $filler1 = $fillers[rand(0, strlen($fillers) - 1)];
1570
1571 return substr($word1 . $filler1 . $word2, 0, $maxlen);
1572}
1573
53bfe78c 1574function moodle_needs_upgrading() {
1575// Checks version numbers of Main code and all modules to see
1576// if there are any mismatches ... returns true or false
1577 global $CFG;
1578
1579 include_once("$CFG->dirroot/version.php"); # defines $version and upgrades
1580 if ($dversion = get_field("config", "value", "name", "version")) {
1581 if ($version > $dversion) {
1582 return true;
1583 }
1e3e716f 1584 if ($mods = get_list_of_plugins("mod")) {
53bfe78c 1585 foreach ($mods as $mod) {
1586 $fullmod = "$CFG->dirroot/mod/$mod";
1587 unset($module);
1588 include_once("$fullmod/version.php"); # defines $module with version etc
1589 if ($currmodule = get_record("modules", "name", $mod)) {
1590 if ($module->version > $currmodule->version) {
1591 return true;
1592 }
1593 }
1594 }
1595 }
1596 } else {
1597 return true;
1598 }
1599 return false;
53bfe78c 1600}
1601
1602
1e3e716f 1603function get_list_of_plugins($plugin="mod") {
1604// Lists plugin directories within some directory
1605
53bfe78c 1606 global $CFG;
1607
1e3e716f 1608 $basedir = opendir("$CFG->dirroot/$plugin");
1609 while ($dir = readdir($basedir)) {
1610 if ($dir == "." || $dir == ".." || $dir == "CVS") {
53bfe78c 1611 continue;
1612 }
1e3e716f 1613 if (filetype("$CFG->dirroot/$plugin/$dir") != "dir") {
53bfe78c 1614 continue;
1615 }
1e3e716f 1616 $plugins[] = $dir;
53bfe78c 1617 }
1e3e716f 1618 if ($plugins) {
1619 asort($plugins);
1620 }
1621 return $plugins;
53bfe78c 1622}
1623
1e3e716f 1624
2447921f 1625function iswindows() {
1626// True if this is Windows, False if not.
1627
1628 global $WINDIR;
1629
b0ccbd92 1630 return isset($WINDIR);
2447921f 1631}
1632
f9903ed0 1633
f9903ed0 1634
f9903ed0 1635?>