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