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