Slight change to get rid of leading zeroes in dates
[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
f9903ed0 11/// STANDARD WEB PAGE PARTS ///////////////////////////////////////////////////
12
a15803d3 13function print_header ($title="", $heading="", $navigation="", $focus="", $meta="", $cache=true, $button="&nbsp;", $menu="") {
f9903ed0 14// $title - appears top of window
15// $heading - appears top of page
16// $navigation - premade navigation string
17// $focus - indicates form element eg inputform.password
18// $meta - meta tags in the header
c7e3ac2a 19// $cache - should this page be cacheable?
d897cae4 20// $button - HTML code for a button (usually for module editing)
21// $menu - HTML code for a popup menu
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
a28af1fe 30 if ($navigation == "home") {
31 $home = true;
32 $navigation = "";
33 }
34
d897cae4 35 if (!$menu and $navigation) {
4efeb8c3 36 if (isset($USER->id)) {
d897cae4 37 $menu = "<FONT SIZE=2><A TARGET=_parent HREF=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</A></FONT>";
4efeb8c3 38 } else {
d897cae4 39 $menu = "<FONT SIZE=2><A TARGET=_parent HREF=\"$CFG->wwwroot/login/index.php\">".get_string("login")."</A></FONT>";
4efeb8c3 40 }
41 }
4bfa92e7 42
43 // Specify character set ... default is iso-8859-1 but some languages might need something else
44 // Could be optimised by carrying the charset variable around in $USER
45 if (current_language() == "en") {
46 $meta .= "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\n";
47 } else {
48 $meta .= "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=".get_string("thischarset")."\">\n";
49 }
541117b6 50
51 if ($CFG->langdir == "RTL") {
52 $direction = " DIR=\"RTL\"";
53 } else {
54 $direction = " DIR=\"LTR\"";
55 }
f9903ed0 56
57 if (!$cache) { // Do everything we can to prevent clients and proxies caching
58 @header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
59 @header("Pragma: no-cache");
60 $meta .= "\n<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">";
61 $meta .= "\n<META HTTP-EQUIV=\"Expires\" CONTENT=\"0\">";
62 }
4bfa92e7 63
f9903ed0 64 include ("$CFG->dirroot/theme/$CFG->theme/header.html");
65}
66
67function print_footer ($course=NULL) {
68// Can provide a course object to make the footer contain a link to
69// to the course home page, otherwise the link will go to the site home
70 global $USER, $CFG, $THEME;
71
65ccdd8c 72
73/// Course links
f9903ed0 74 if ($course) {
28b1e3ec 75 if ($course == "home") { // special case for site home page - please do not remove
a28af1fe 76 $homelink = "<P ALIGN=center><A TITLE=\"Moodle $CFG->release ($CFG->version)\" HREF=\"http://moodle.com/\">";
87a2fa03 77 $homelink .= "<BR><IMG WIDTH=130 HEIGHT=19 SRC=\"pix/madewithmoodle2.gif\" BORDER=0></A></P>";
65ccdd8c 78 $course = get_site();
6f3ba7c9 79 $homepage = true;
d82c8545 80 } else {
81 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A>";
82 }
f9903ed0 83 } else {
d82c8545 84 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot\">".get_string("home")."</A>";
65ccdd8c 85 $course = get_site();
f9903ed0 86 }
65ccdd8c 87
88/// User links
3ce2f1e0 89 if ($USER->realuser) {
90 if ($realuser = get_record("user", "id", $USER->realuser)) {
65ccdd8c 91 $realuserinfo = " [<A HREF=\"$CFG->wwwroot/course/loginas.php?id=$course->id&return=$realuser->id\">$realuser->firstname $realuser->lastname</A>] ";
3ce2f1e0 92 }
93 }
65ccdd8c 94
3ce2f1e0 95 if ($USER->id) {
65ccdd8c 96 $username = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$USER->id&course=$course->id\">$USER->firstname $USER->lastname</A>";
7d95ed97 97 $loggedinas = $realuserinfo.get_string("loggedinas", "moodle", "$username").
3ce2f1e0 98 " (<A HREF=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</A>)";
65ccdd8c 99 } else {
3ce2f1e0 100 $loggedinas = get_string("loggedinnot", "moodle").
a7b9e8bc 101 " (<A HREF=\"$CFG->wwwroot/login/index.php\">".get_string("login")."</A>)";
65ccdd8c 102 }
3ce2f1e0 103
f9903ed0 104 include ("$CFG->dirroot/theme/$CFG->theme/footer.html");
105}
106
65ccdd8c 107
108
f9903ed0 109function print_navigation ($navigation) {
110 global $CFG;
111
112 if ($navigation) {
a83fded1 113 if (! $site = get_site()) {
bcc83c41 114 $site->shortname = get_string("home");;
115 }
a2eaeb91 116 echo "<A TARGET=_top HREF=\"$CFG->wwwroot/\">$site->shortname</A> -> $navigation";
f9903ed0 117 }
118}
119
2a46a71b 120function print_heading($text, $align="CENTER", $size=3) {
08beb332 121 echo "<P ALIGN=\"$align\"><FONT SIZE=\"$size\"><B>".stripslashes($text)."</B></FONT></P>";
f9903ed0 122}
123
377f3c9e 124function print_heading_with_help($text, $helppage, $module="moodle") {
125// Centered heading with attached help button (same title text)
126 echo "<P ALIGN=\"CENTER\"><FONT SIZE=\"3\"><B>".stripslashes($text);
127 helpbutton($helppage, $text, $module);
128 echo "</B></FONT></P>";
129}
130
dbcb136a 131function print_continue($link) {
132 global $HTTP_REFERER;
133
134 if (!$link) {
135 $link = $HTTP_REFERER;
136 }
137
138 print_heading("<A HREF=\"$link\">".get_string("continue")."</A>");
139}
140
141
4216daa6 142function print_simple_box($message, $align="", $width="", $color="#FFFFFF", $padding=5, $border=1) {
143 print_simple_box_start($align, $width, $color, $padding, $border);
16c0beb0 144 echo "<P>".stripslashes($message)."</P>";
f9903ed0 145 print_simple_box_end();
146}
147
4216daa6 148function print_simple_box_start($align="", $width="", $color="#FFFFFF", $padding=5, $border=1) {
f9903ed0 149 global $THEME;
150
151 if ($align) {
152 $tablealign = "ALIGN=\"$align\"";
153 }
154 if ($width) {
155 $tablewidth = "WIDTH=\"$width\"";
156 $innertablewidth = "WIDTH=\"100%\"";
157 }
4216daa6 158 echo "<TABLE $tablealign $tablewidth BORDER=0 CELLPADDING=\"$border\" CELLSPACING=0>";
f9903ed0 159 echo "<TR><TD BGCOLOR=\"$THEME->borders\">\n";
160 echo "<TABLE $innertablewidth BORDER=0 CELLPADDING=\"$padding\" CELLSPACING=0><TR><TD BGCOLOR=\"$color\">";
161}
162
163function print_simple_box_end() {
164 echo "</TD></TR></TABLE>";
165 echo "</TD></TR></TABLE>";
166}
167
168function print_single_button($link, $options, $label="OK") {
169 echo "<FORM ACTION=\"$link\" METHOD=GET>";
dbcb136a 170 if ($options) {
171 foreach ($options as $name => $value) {
172 echo "<INPUT TYPE=hidden NAME=\"$name\" VALUE=\"$value\">";
173 }
f9903ed0 174 }
175 echo "<INPUT TYPE=submit VALUE=\"$label\"></FORM>";
176}
177
19a55d67 178function print_spacer($height=1, $width=1, $br=true) {
179 global $CFG;
180 echo "<IMG HEIGHT=\"$height\" WIDTH=\"$width\" SRC=\"$CFG->wwwroot/pix/spacer.gif\" ALT=\"\">";
181 if ($br) {
182 echo "<BR>\n";
183 }
184}
185
f8e4809a 186function print_file_picture($path, $courseid=0, $height="", $width="", $link="") {
187// Given the path to a picture file in a course, or a URL,
188// this function includes the picture in the page.
189 global $CFG;
190
191 if ($height) {
192 $height = "HEIGHT=\"$height\"";
193 }
194 if ($width) {
195 $width = "WIDTH=\"$width\"";
196 }
197 if ($link) {
198 echo "<A HREF=\"$link\">";
199 }
200 if (substr(strtolower($path), 0, 7) == "http://") {
201 echo "<IMG BORDER=0 $height $width SRC=\"$path\">";
55c26207 202
f8e4809a 203 } else if ($courseid) {
204 echo "<IMG BORDER=0 $height $width SRC=\"";
205 if ($CFG->slasharguments) { // Use this method if possible for better caching
206 echo "$CFG->wwwroot/file.php/$courseid/$path";
207 } else {
208 echo "$CFG->wwwroot/file.php?file=$courseid/$path";
209 }
210 echo "\">";
211 } else {
212 echo "Error: must pass URL or course";
213 }
214 if ($link) {
215 echo "</A>";
216 }
217}
218
15e4b2ec 219function print_user_picture($userid, $courseid, $picture, $large=false, $returnstring=false, $link=true) {
f9903ed0 220 global $CFG;
221
15e4b2ec 222 if ($link) {
223 $output = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$userid&course=$courseid\">";
224 } else {
225 $output = "";
226 }
f9903ed0 227 if ($large) {
228 $file = "f1.jpg";
229 $size = 100;
230 } else {
231 $file = "f2.jpg";
232 $size = 35;
233 }
234 if ($picture) {
3f8247c2 235 if ($CFG->slasharguments) { // Use this method if possible for better caching
2447921f 236 $output .= "<IMG SRC=\"$CFG->wwwroot/user/pix.php/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
3f8247c2 237 } else {
238 $output .= "<IMG SRC=\"$CFG->wwwroot/user/pix.php?file=/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
2447921f 239 }
f9903ed0 240 } else {
136dabd8 241 $output .= "<IMG SRC=\"$CFG->wwwroot/user/default/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
242 }
15e4b2ec 243 if ($link) {
244 $output .= "</A>";
245 }
136dabd8 246
247 if ($returnstring) {
248 return $output;
249 } else {
250 echo $output;
f9903ed0 251 }
f9903ed0 252}
253
274f62e6 254function print_table($table) {
f9903ed0 255// Prints a nicely formatted table.
5b54db6e 256// $table is an object with several properties.
f9903ed0 257// $table->head is an array of heading names.
258// $table->align is an array of column alignments
5b54db6e 259// $table->size is an array of column sizes
f9903ed0 260// $table->data[] is an array of arrays containing the data.
1e3e716f 261// $table->width is an percentage of the page
274f62e6 262// $table->cellpadding padding on each cell
263// $table->cellspacing spacing between cells
f9903ed0 264
5b54db6e 265 if (isset($table->align)) {
f9903ed0 266 foreach ($table->align as $key => $aa) {
267 if ($aa) {
5b54db6e 268 $align[$key] = " ALIGN=\"$aa\"";
f9903ed0 269 } else {
270 $align[$key] = "";
271 }
272 }
273 }
5b54db6e 274 if (isset($table->size)) {
275 foreach ($table->size as $key => $ss) {
276 if ($ss) {
277 $size[$key] = " WIDTH=\"$ss\"";
278 } else {
279 $size[$key] = "";
280 }
281 }
282 }
f9903ed0 283
1e3e716f 284 if (!$table->width) {
285 $table->width = "80%";
286 }
287
1e22462d 288 if (!$table->cellpadding) {
289 $table->cellpadding = "5";
290 }
291
292 if (!$table->cellspacing) {
293 $table->cellspacing = "1";
294 }
295
1e3e716f 296 print_simple_box_start("CENTER", "$table->width", "#FFFFFF", 0);
dccd1671 297 echo "<TABLE WIDTH=100% BORDER=0 valign=top align=center ";
1e22462d 298 echo " cellpadding=\"$table->cellpadding\" cellspacing=\"$table->cellspacing\">\n";
f9903ed0 299
300 if ($table->head) {
301 echo "<TR>";
909f539d 302 foreach ($table->head as $key => $heading) {
be025399 303 echo "<TH VALIGN=top ".$align[$key].$size[$key].">$heading</TH>";
f9903ed0 304 }
305 echo "</TR>\n";
306 }
307
308 foreach ($table->data as $row) {
309 echo "<TR VALIGN=TOP>";
310 foreach ($row as $key => $item) {
5b54db6e 311 echo "<TD ".$align[$key].$size[$key].">$item</TD>";
f9903ed0 312 }
313 echo "</TR>\n";
314 }
315 echo "</TABLE>\n";
316 print_simple_box_end();
317
318 return true;
319}
320
21ddaf60 321function print_editing_switch($courseid) {
322 global $CFG, $USER;
323
c7e3ac2a 324 if (isteacher($courseid)) {
21ddaf60 325 if ($USER->editing) {
326 echo "<A HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=off\">Turn editing off</A>";
327 } else {
328 echo "<A HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=on\">Turn editing on</A>";
329 }
330 }
331}
332
55c26207 333function format_float($num, $places=0) {
334 return sprintf("%.$places"."f", $num);
335}
336
e1947876 337function print_textarea($richedit, $rows, $cols, $width, $height, $name, $value="") {
338 global $CFG, $THEME;
339
340 if ($richedit) {
341 echo "<object id=richedit style=\"BACKGROUND-COLOR: buttonface\"";
342 echo " data=\"$CFG->wwwroot/lib/rte/richedit.html\"";
343 echo " width=\"$width\" height=\"$height\" ";
3df49694 344 echo " type=\"text/x-scriptlet\" VIEWASTEXT></object>\n";
e1947876 345 echo "<TEXTAREA style=\"display:none\" NAME=\"$name\" ROWS=1 COLS=1>";
346 p($value);
3df49694 347 echo "</TEXTAREA>\n";
e1947876 348 } else {
349 echo "<TEXTAREA name=\"$name\" rows=\"$rows\" cols=\"$cols\" wrap=virtual>";
350 p($value);
3df49694 351 echo "</TEXTAREA>\n";
e1947876 352 }
353}
354
3df49694 355function print_richedit_javascript($form, $name, $source="no") {
356 echo "<SCRIPT language=\"JavaScript\" event=\"onload\" for=\"window\">\n";
357 echo " document.richedit.options = \"history=no;source=$source\";";
358 echo " document.richedit.docHtml = $form.$name.innerText;";
359 echo "</SCRIPT>";
360}
361
e1947876 362
6b174680 363function update_course_icon($courseid) {
55c26207 364// Used to be an icon, but it's now a simple form button
6b174680 365 global $CFG, $USER;
366
367 if (isteacher($courseid)) {
368 if ($USER->editing) {
55c26207 369 $string = get_string("turneditingoff");
370 $edit = "off";
6b174680 371 } else {
55c26207 372 $string = get_string("turneditingon");
373 $edit = "on";
6b174680 374 }
7ce20f09 375 return "<FORM TARGET=_parent METHOD=GET ACTION=\"$CFG->wwwroot/course/view.php\">".
376 "<INPUT TYPE=hidden NAME=id VALUE=\"$courseid\">".
377 "<INPUT TYPE=hidden NAME=edit VALUE=\"$edit\">".
378 "<INPUT TYPE=submit VALUE=\"$string\"></FORM>";
6b174680 379 }
380}
381
7ce20f09 382function update_module_button($moduleid, $courseid, $string) {
383// Prints the editing button on a module "view" page
6b174680 384 global $CFG;
385
386 if (isteacher($courseid)) {
7ce20f09 387 $string = get_string("updatethis", "", $string);
388 return "<FORM TARGET=_parent METHOD=GET ACTION=\"$CFG->wwwroot/course/mod.php\">".
389 "<INPUT TYPE=hidden NAME=update VALUE=\"$moduleid\">".
390 "<INPUT TYPE=hidden NAME=return VALUE=\"true\">".
391 "<INPUT TYPE=submit VALUE=\"$string\"></FORM>";
6b174680 392 }
393}
394
395
dfc9ba9b 396function navmenu($course, $cm=NULL) {
d897cae4 397// Given a course and a (current) coursemodule
398// This function returns a small popup menu with all the
399// course activity modules in it, as a navigation menu
400// The data is taken from the serialised array stored in
401// the course record
402
403 global $CFG;
404
dfc9ba9b 405 if ($cm) {
406 $cm = $cm->id;
407 }
408
4359e8f7 409 if ($course->format == 'weeks') {
d897cae4 410 $strsection = get_string("week");
411 } else {
412 $strsection = get_string("topic");
413 }
414
7bee16d4 415 if (!$modinfo = unserialize($course->modinfo)) {
d897cae4 416 return "";
417 }
418 $section = -1;
419 $selected = "";
7bee16d4 420 foreach ($modinfo as $mod) {
d897cae4 421 if ($mod->section > 0 and $section <> $mod->section) {
422 $menu[] = "-------------- $strsection $mod->section --------------";
423 }
424 $section = $mod->section;
425 $url = "$mod->mod/view.php?id=$mod->cm";
dfc9ba9b 426 if ($cm == $mod->cm) {
d897cae4 427 $selected = $url;
428 }
429 $mod->name = urldecode($mod->name);
430 if (strlen($mod->name) > 55) {
431 $mod->name = substr($mod->name, 0, 50)."...";
432 }
433 $menu[$url] = $mod->name;
434 }
435
436 return popup_form("$CFG->wwwroot/mod/", $menu, "navmenu", $selected, get_string("jumpto"), "", "", true);
437}
438
439
39917a09 440function print_date_selector($day, $month, $year, $currenttime=0) {
441// Currenttime is a default timestamp in GMT
442// Prints form items with the names $day, $month and $year
443
444 if (!$currenttime) {
445 $currenttime = time();
446 }
447 $currentdate = usergetdate($currenttime);
448
449 for ($i=1; $i<=31; $i++) {
450 $days[$i] = "$i";
451 }
452 for ($i=1; $i<=12; $i++) {
453 $months[$i] = date("F", mktime(0,0,0,$i,1,2000));
454 }
455 for ($i=2000; $i<=2010; $i++) {
456 $years[$i] = $i;
457 }
458 choose_from_menu($days, $day, $currentdate[mday], "");
459 choose_from_menu($months, $month, $currentdate[mon], "");
460 choose_from_menu($years, $year, $currentdate[year], "");
461}
462
463function print_time_selector($hour, $minute, $currenttime=0) {
464// Currenttime is a default timestamp in GMT
465// Prints form items with the names $hour and $minute
466
467 if (!$currenttime) {
468 $currenttime = time();
469 }
470 $currentdate = usergetdate($currenttime);
471 for ($i=0; $i<=23; $i++) {
472 $hours[$i] = sprintf("%02d",$i);
473 }
474 for ($i=0; $i<=59; $i++) {
475 $minutes[$i] = sprintf("%02d",$i);
476 }
477 choose_from_menu($hours, $hour, $currentdate[hours], "");
478 choose_from_menu($minutes, $minute, $currentdate[minutes], "");
479}
480
481function make_timestamp($year, $month=1, $day=1, $hour=0, $minute=0, $second=0) {
482// Given date parts in user time, produce a GMT timestamp
483
484 return mktime((int)$hour,(int)$minute,(int)$second,(int)$month,(int)$day,(int)$year);
485}
486
d897cae4 487
8dbed6be 488function format_time($totalsecs, $str=NULL) {
6b174680 489// Given an amount of time in seconds, prints it
490// nicely as months, days, hours etc as needed
c7e3ac2a 491
6b174680 492 $totalsecs = abs($totalsecs);
c7e3ac2a 493
8dbed6be 494 if (!$str) { // Create the str structure the slow way
495 $str->day = get_string("day");
496 $str->days = get_string("days");
497 $str->hour = get_string("hour");
498 $str->hours = get_string("hours");
499 $str->min = get_string("min");
500 $str->mins = get_string("mins");
501 $str->sec = get_string("sec");
502 $str->secs = get_string("secs");
503 }
504
505 $days = floor($totalsecs/86400);
6b174680 506 $remainder = $totalsecs - ($days*86400);
8dbed6be 507 $hours = floor($remainder/3600);
6b174680 508 $remainder = $remainder - ($hours*3600);
8dbed6be 509 $mins = floor($remainder/60);
510 $secs = $remainder - ($mins*60);
511
512 $ss = ($secs == 1) ? $str->sec : $str->secs;
513 $sm = ($mins == 1) ? $str->min : $str->mins;
514 $sh = ($hours == 1) ? $str->hour : $str->hours;
515 $sd = ($days == 1) ? $str->day : $str->days;
516
517 if ($days) $odays = "$days $sd";
518 if ($hours) $ohours = "$hours $sh";
519 if ($mins) $omins = "$mins $sm";
520 if ($secs) $osecs = "$secs $ss";
6b174680 521
522 if ($days) return "$odays $ohours";
523 if ($hours) return "$ohours $omins";
524 if ($mins) return "$omins $osecs";
525 if ($secs) return "$osecs";
526 return get_string("now");
527}
f9903ed0 528
5fa51a39 529function userdate($date, $format="", $timezone=99) {
d552ead0 530// Returns a formatted string that represents a date in user time
7a302afc 531// WARNING: note that the format is for strftime(), not date().
532
873960de 533 global $USER;
534
5fa51a39 535 if ($format == "") {
62c13a2f 536 $format = "%A, %d %B %Y, %I:%M %p";
5fa51a39 537 }
538 if ($timezone == 99) {
ab247495 539 if (isset($USER->timezone)) {
540 $timezone = (float)$USER->timezone;
541 }
5fa51a39 542 }
0431bd7c 543 if (abs($timezone) > 13) {
bea7a51e 544 $datestring = strftime("$format", $date);
545 } else {
546 $datestring = gmstrftime($format, $date + (int)($timezone * 3600));
873960de 547 }
bea7a51e 548
549 return str_replace(" 0", " ", $datestring); // gets rid of unwanted zeroes
873960de 550}
551
5fa51a39 552function usergetdate($date, $timezone=99) {
6b174680 553// Given a $date timestamp in GMT, returns an array
554// that represents the date in user time
555
873960de 556 global $USER;
557
5fa51a39 558 if ($timezone == 99) {
559 $timezone = (float)$USER->timezone;
560 }
0431bd7c 561 if (abs($timezone) > 13) {
873960de 562 return getdate($date);
563 }
d2d6171f 564 //There is no gmgetdate so I have to fake it...
565 $date = $date + (int)($timezone * 3600);
566 $getdate["seconds"] = gmstrftime("%S", $date);
567 $getdate["minutes"] = gmstrftime("%M", $date);
568 $getdate["hours"] = gmstrftime("%H", $date);
569 $getdate["mday"] = gmstrftime("%d", $date);
570 $getdate["wday"] = gmstrftime("%u", $date);
571 $getdate["mon"] = gmstrftime("%m", $date);
572 $getdate["year"] = gmstrftime("%Y", $date);
573 $getdate["yday"] = gmstrftime("%j", $date);
574 $getdate["weekday"] = gmstrftime("%A", $date);
575 $getdate["month"] = gmstrftime("%B", $date);
576 return $getdate;
d552ead0 577}
578
579function usertime($date, $timezone=99) {
580// Given a GMT timestamp (seconds since epoch), offsets it by
581// the timezone. eg 3pm in India is 3pm GMT - 7 * 3600 seconds
582 global $USER;
583
584 if ($timezone == 99) {
585 $timezone = (float)$USER->timezone;
586 }
0431bd7c 587 if (abs($timezone) > 13) {
d552ead0 588 return $date;
589 }
590 return $date - (int)($timezone * 3600);
591}
592
edf7fe8c 593function usergetmidnight($date, $timezone=99) {
594// Given a time, return the GMT timestamp of the most recent midnight
595// for the current user.
edf7fe8c 596 global $USER;
597
4606d9bb 598 if ($timezone == 99) {
599 $timezone = (float)$USER->timezone;
600 }
601
edf7fe8c 602 $userdate = usergetdate($date, $timezone);
4606d9bb 603
0431bd7c 604 if (abs($timezone) > 13) {
4606d9bb 605 return mktime(0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
606 }
607
edf7fe8c 608 $timemidnight = gmmktime (0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
609 return usertime($timemidnight, $timezone); // Time of midnight of this user's day, in GMT
610
611}
612
d552ead0 613function usertimezone($timezone=99) {
614// returns a string that prints the user's timezone
615 global $USER;
616
617 if ($timezone == 99) {
618 $timezone = (float)$USER->timezone;
619 }
0431bd7c 620 if (abs($timezone) > 13) {
d552ead0 621 return "server time";
622 }
623 if (abs($timezone) < 0.5) {
624 return "GMT";
625 }
626 if ($timezone > 0) {
627 return "GMT+$timezone";
628 } else {
629 return "GMT$timezone";
630 }
f9903ed0 631}
632
633
634function error ($message, $link="") {
635 global $CFG, $SESSION;
636
ae350059 637 print_header(get_string("error"));
f9903ed0 638 echo "<BR>";
639 print_simple_box($message, "center", "", "#FFBBBB");
640
641 if (!$link) {
642 if ( !empty($SESSION->fromurl) ) {
643 $link = "$SESSION->fromurl";
644 unset($SESSION->fromurl);
8223d271 645 save_session("SESSION");
f9903ed0 646 } else {
647 $link = "$CFG->wwwroot";
648 }
649 }
dbcb136a 650 print_continue($link);
f9903ed0 651 print_footer();
652 die;
653}
654
65cf9fc3 655function helpbutton ($page, $title="", $module="moodle", $image=true, $text="") {
656 // $page = the keyword that defines a help page
657 // $title = the title of links, rollover tips, alt tags etc
658 // $module = which module is the page defined in
659 // $image = use a help image for the link? (otherwise uses text)
660 // $text = if defined then this text is used in the page, and
661 // the $page variable is ignored.
34c8915d 662 global $CFG;
ff80e012 663
65cf9fc3 664 if ($module == "") {
665 $module = "moodle";
666 }
667 if ($image) {
e5dfd0f3 668 $linkobject = "<IMG BORDER=0 HEIGHT=17 WIDTH=22 ALT=\"$title\" SRC=\"$CFG->wwwroot/pix/help.gif\">";
65cf9fc3 669 } else {
670 $linkobject = $title;
671 }
672 if ($text) {
673 $url = "/help.php?module=$module&text=$text";
674 } else {
6ee45796 675 $url = "/help.php?module=$module&file=$page.html";
65cf9fc3 676 }
677 link_to_popup_window ($url, "popup", $linkobject, 400, 500, $title);
34c8915d 678}
679
f9903ed0 680function notice ($message, $link="") {
681 global $THEME, $HTTP_REFERER;
682
683 if (!$link) {
684 $link = $HTTP_REFERER;
685 }
686
687 echo "<BR>";
688 print_simple_box($message, "center", "", "$THEME->cellheading");
ae350059 689 print_heading("<A HREF=\"$link\">".get_string("continue")."</A>");
5ebe27e2 690 print_footer(get_site());
f9903ed0 691 die;
692}
693
694function notice_yesno ($message, $linkyes, $linkno) {
695 global $THEME;
696
697 print_simple_box_start("center", "", "$THEME->cellheading");
698 echo "<P ALIGN=CENTER><FONT SIZE=3>$message</FONT></P>";
699 echo "<P ALIGN=CENTER><FONT SIZE=3><B>";
ae350059 700 echo "<A HREF=\"$linkyes\">".get_string("yes")."</A>";
f9903ed0 701 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
ae350059 702 echo "<A HREF=\"$linkno\">".get_string("no")."</A>";
f9903ed0 703 echo "</B></FONT></P>";
704 print_simple_box_end();
705}
706
707function redirect($url, $message="", $delay=0) {
708// Uses META tags to redirect the user, after printing a notice
f9903ed0 709
710 echo "<META HTTP-EQUIV='Refresh' CONTENT='$delay; URL=$url'>";
711
712 if (!empty($message)) {
713 print_header();
714 echo "<CENTER>";
715 echo "<P>$message</P>";
ae350059 716 echo "<P>( <A HREF=\"$url\">".get_string("continue")."</A> )</P>";
f9903ed0 717 echo "</CENTER>";
718 }
719 die;
720}
721
722function notify ($message) {
723 echo "<P align=center><B><FONT COLOR=#FF0000>$message</FONT></B></P>\n";
724}
725
726
727
728/// PARAMETER HANDLING ////////////////////////////////////////////////////
729
730function require_variable($var) {
f9903ed0 731 if (! isset($var)) {
732 error("A required parameter was missing");
733 }
734}
735
736function optional_variable(&$var, $default=0) {
737 if (! isset($var)) {
738 $var = $default;
739 }
740}
741
742
743
744
745/// DATABASE HANDLING ////////////////////////////////////////////////
746
c74a0ca5 747function execute_sql($command, $feedback=true) {
f9903ed0 748// Completely general
749
750 global $db;
751
752 $result = $db->Execute("$command");
753
754 if ($result) {
c74a0ca5 755 if ($feedback) {
756 echo "<P><FONT COLOR=green><B>".get_string("success")."</B></FONT></P>";
757 }
f9903ed0 758 return true;
759 } else {
c74a0ca5 760 if ($feedback) {
761 echo "<P><FONT COLOR=red><B>".get_string("error")."</B></FONT></P>";
762 }
f9903ed0 763 return false;
764 }
765}
766
767function modify_database($sqlfile) {
768// Assumes that the input text file consists of a number
769// of SQL statements ENDING WITH SEMICOLONS. The semicolons
770// MUST be the last character in a line.
771// Lines that are blank or that start with "#" are ignored.
772// Only tested with mysql dump files (mysqldump -p -d moodle)
773
774
775 if (file_exists($sqlfile)) {
776 $success = true;
777 $lines = file($sqlfile);
778 $command = "";
779
780 while ( list($i, $line) = each($lines) ) {
781 $line = chop($line);
782 $length = strlen($line);
783
784 if ($length && substr($line, 0, 1) <> "#") {
785 if (substr($line, $length-1, 1) == ";") {
786 $line = substr($line, 0, $length-1); // strip ;
787 $command .= $line;
788 if (! execute_sql($command)) {
789 $success = false;
790 }
791 $command = "";
792 } else {
793 $command .= $line;
794 }
795 }
796 }
797
798 } else {
799 $success = false;
800 echo "<P>Tried to modify database, but \"$sqlfile\" doesn't exist!</P>";
801 }
802
803 return $success;
804}
805
806
807function record_exists($table, $field, $value) {
808 global $db;
809
810 $rs = $db->Execute("SELECT * FROM $table WHERE $field = '$value' LIMIT 1");
811 if (!$rs) return false;
812
813 if ( $rs->RecordCount() ) {
814 return true;
815 } else {
816 return false;
817 }
818}
819
820function record_exists_sql($sql) {
821 global $db;
822
823 $rs = $db->Execute($sql);
824 if (!$rs) return false;
825
826 if ( $rs->RecordCount() ) {
827 return true;
828 } else {
829 return false;
830 }
831}
832
833
834function count_records($table, $selector, $value) {
835// Get all the records and count them
836 global $db;
837
838 $rs = $db->Execute("SELECT COUNT(*) FROM $table WHERE $selector = '$value'");
839 if (!$rs) return 0;
840
841 return $rs->fields[0];
842}
843
844function count_records_sql($sql) {
845// Get all the records and count them
846 global $db;
847
848 $rs = $db->Execute("$sql");
849 if (!$rs) return 0;
850
851 return $rs->fields[0];
852}
853
854function get_record($table, $selector, $value) {
855// Get a single record as an object
856 global $db;
857
858 $rs = $db->Execute("SELECT * FROM $table WHERE $selector = '$value'");
859 if (!$rs) return false;
860
861 if ( $rs->RecordCount() == 1 ) {
862 return (object)$rs->fields;
863 } else {
864 return false;
865 }
866}
867
868function get_record_sql($sql) {
869// Get a single record as an object
870// The sql statement is provided as a string.
871
872 global $db;
873
874 $rs = $db->Execute("$sql");
875 if (!$rs) return false;
876
877 if ( $rs->RecordCount() == 1 ) {
878 return (object)$rs->fields;
879 } else {
880 return false;
881 }
882}
883
0095d5cd 884function get_records($table, $selector, $value, $sort="", $fields="*") {
885// Get a number of records as an array of objects
886// Can optionally be sorted eg "time ASC" or "time DESC"
887// If "fields" is specified, only those fields are returned
888// The "key" is the first column returned, eg usually "id"
889 global $db;
890
891 if ($sort) {
892 $sortorder = "ORDER BY $sort";
893 }
894 $sql = "SELECT $fields FROM $table WHERE $selector = '$value' $sortorder";
895
896 return get_records_sql($sql);
897}
898
899
900function get_records_list($table, $selector, $values, $sort="", $fields="*") {
f9903ed0 901// Get a number of records as an array of objects
0095d5cd 902// Differs from get_records() in that the values variable
903// can be a comma-separated list of values eg "4,5,6,10"
f9903ed0 904// Can optionally be sorted eg "time ASC" or "time DESC"
905// The "key" is the first column returned, eg usually "id"
906 global $db;
907
908 if ($sort) {
909 $sortorder = "ORDER BY $sort";
910 }
0095d5cd 911 $sql = "SELECT $fields FROM $table WHERE $selector in ($values) $sortorder";
f9903ed0 912
913 return get_records_sql($sql);
914}
915
0095d5cd 916
f9903ed0 917function get_records_sql($sql) {
918// Get a number of records as an array of objects
919// The "key" is the first column returned, eg usually "id"
920// The sql statement is provided as a string.
921
922 global $db;
923
924 $rs = $db->Execute("$sql");
925 if (!$rs) return false;
926
927 if ( $rs->RecordCount() > 0 ) {
5c0bef5d 928 if ($records = $rs->GetAssoc(true)) {
929 foreach ($records as $key => $record) {
930 $objects[$key] = (object) $record;
931 }
932 return $objects;
933 } else {
934 return false;
f9903ed0 935 }
f9903ed0 936 } else {
937 return false;
938 }
939}
940
941function get_records_sql_menu($sql) {
942// Given an SQL select, this function returns an associative
943// array of the first two columns. This is most useful in
944// combination with the choose_from_menu function to create
945// a form menu.
946
947 global $db;
948
949 $rs = $db->Execute("$sql");
950 if (!$rs) return false;
951
952 if ( $rs->RecordCount() > 0 ) {
953 while (!$rs->EOF) {
954 $menu[$rs->fields[0]] = $rs->fields[1];
955 $rs->MoveNext();
956 }
957 return $menu;
958
959 } else {
960 return false;
961 }
962}
963
964function get_field($table, $field, $selector, $value) {
965 global $db;
966
967 $rs = $db->Execute("SELECT $field FROM $table WHERE $selector = '$value'");
968 if (!$rs) return false;
969
970 if ( $rs->RecordCount() == 1 ) {
971 return $rs->fields["$field"];
972 } else {
973 return false;
974 }
975}
976
977function set_field($table, $field, $newvalue, $selector, $value) {
978 global $db;
979
980 return $db->Execute("UPDATE $table SET $field = '$newvalue' WHERE $selector = '$value'");
981}
982
a28af1fe 983function set_config($name, $value) {
984// No need for get_config because they are usually always available in $CFG
985
466558e3 986 if (get_field("config", "name", "name", $name)) {
a28af1fe 987 return set_field("config", "value", $value, "name", $name);
988 } else {
989 $config->name = $name;
990 $config->value = $value;
991 return insert_record("config", $config);
992 }
993}
f9903ed0 994
995function delete_records($table, $selector, $value) {
996// Delete one or more records from a table
997 global $db;
998
999 return $db->Execute("DELETE FROM $table WHERE $selector = '$value'");
1000}
1001
1002function insert_record($table, $dataobject) {
1003// Insert a record into a table and return the "id" field
1004// $dataobject is an object containing needed data
1005
1006 global $db;
1007
1008 // Determine all the fields needed
1009 if (! $columns = $db->MetaColumns("$table")) {
1010 return false;
1011 }
1012
1013 $data = (array)$dataobject;
1014
1015 // Pull out data matching these fields
1016 foreach ($columns as $column) {
e5a57e85 1017 if ($column->name <> "id" && isset($data[$column->name]) ) {
f9903ed0 1018 $ddd[$column->name] = $data[$column->name];
1019 }
1020 }
1021
1022 // Construct SQL queries
1023 if (! $numddd = count($ddd)) {
1024 return 0;
1025 }
1026
1027 $count = 0;
1028 $insert = "";
1029 $select = "";
1030
1031 foreach ($ddd as $key => $value) {
1032 $count++;
1033 $insert .= "$key = '$value'";
1034 $select .= "$key = '$value'";
1035 if ($count < $numddd) {
1036 $insert .= ", ";
1037 $select .= " AND ";
1038 }
1039 }
1040
1041 if (! $rs = $db->Execute("INSERT INTO $table SET $insert")) {
1042 return false;
1043 }
1044
1045 // Pull it out again to find the id. This is the most cross-platform method.
1046 if ($rs = $db->Execute("SELECT id FROM $table WHERE $select")) {
1047 return $rs->fields[0];
1048 } else {
1049 return false;
1050 }
1051}
1052
1053
1054function update_record($table, $dataobject) {
1055// Update a record in a table
1056// $dataobject is an object containing needed data
1057
1058 global $db;
1059
5c0bef5d 1060 if (! isset($dataobject->id) ) {
f9903ed0 1061 return false;
1062 }
1063
1064 // Determine all the fields in the table
1afd014e 1065 if (!$columns = $db->MetaColumns($table)) {
1066 return false;
1067 }
f9903ed0 1068 $data = (array)$dataobject;
1069
1070 // Pull out data matching these fields
1071 foreach ($columns as $column) {
5c0bef5d 1072 if ($column->name <> "id" && isset($data[$column->name]) ) {
f9903ed0 1073 $ddd[$column->name] = $data[$column->name];
1074 }
1075 }
1076
1077 // Construct SQL queries
1078 $numddd = count($ddd);
1079 $count = 0;
1080 $update = "";
1081
1082 foreach ($ddd as $key => $value) {
1083 $count++;
1084 $update .= "$key = '$value'";
1085 if ($count < $numddd) {
1086 $update .= ", ";
1087 }
1088 }
1089
1090 if ($rs = $db->Execute("UPDATE $table SET $update WHERE id = '$dataobject->id'")) {
1091 return true;
1092 } else {
1093 return false;
1094 }
1095}
1096
1097
f93f848a 1098function print_object($object) {
1099// Mostly just for debugging
1100
1101 $array = (array)$object;
1102 foreach ($array as $key => $item) {
1103 echo "$key -> $item <BR>";
1104 }
1105}
1106
1107
f9903ed0 1108/// USER DATABASE ////////////////////////////////////////////////
1109
1110function get_user_info_from_db($field, $value) {
1111
1112 global $db;
1113
1114 if (!$field || !$value)
1115 return false;
1116
91ac0405 1117 if (! $result = $db->Execute("SELECT * FROM user WHERE $field = '$value' AND deleted <> '1'")) {
1118 error("Could not find any active users!");
1119 }
f9903ed0 1120
1121 if ( $result->RecordCount() == 1 ) {
1122 $user = (object)$result->fields;
1123
1124 $rs = $db->Execute("SELECT course FROM user_students WHERE user = '$user->id' ");
1125 while (!$rs->EOF) {
1126 $course = $rs->fields["course"];
1127 $user->student["$course"] = true;
1128 $rs->MoveNext();
1129 }
1130
1131 $rs = $db->Execute("SELECT course FROM user_teachers WHERE user = '$user->id' ");
1132 while (!$rs->EOF) {
1133 $course = $rs->fields["course"];
1134 $user->teacher["$course"] = true;
1135 $rs->MoveNext();
1136 }
1137
1138 $rs = $db->Execute("SELECT * FROM user_admins WHERE user = '$user->id' ");
1139 while (!$rs->EOF) {
1140 $user->admin = true;
1141 $rs->MoveNext();
1142 }
1143
a83fded1 1144 if ($course = get_site()) {
f9903ed0 1145 // Everyone is always a member of the top course
1146 $user->student["$course->id"] = true;
1147 }
1148
1149 return $user;
1150
1151 } else {
1152 return false;
1153 }
1154}
1155
1156function update_user_in_db() {
1157
1158 global $db, $USER, $REMOTE_ADDR;
1159
1160 if (!isset($USER->id))
1161 return false;
1162
1163 $timenow = time();
faebaf0f 1164 if ($db->Execute("UPDATE user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow' WHERE id = '$USER->id' ")) {
f9903ed0 1165 return true;
1166 } else {
1167 return false;
1168 }
1169}
1170
da5c172a 1171function require_login($courseid=0) {
1172// This function checks that the current user is logged in, and optionally
1173// whether they are "logged in" or allowed to be in a particular course.
1174// If not, then it redirects them to the site login or course enrolment.
f9903ed0 1175
1176 global $CFG, $SESSION, $USER, $FULLME, $HTTP_REFERER, $PHPSESSID;
1177
da5c172a 1178 // First check that the user is logged in to the site.
7363ff91 1179
c21c671d 1180 if (! (isset($USER->loggedin) and $USER->confirmed and ($USER->site == $CFG->wwwroot)) ) { // They're not
f9903ed0 1181 $SESSION->wantsurl = $FULLME;
7363ff91 1182 $SESSION->fromurl = $HTTP_REFERER;
8223d271 1183 save_session("SESSION");
c21c671d 1184 $USER = NULL;
1185 save_session("USER");
f9903ed0 1186 if ($PHPSESSID) { // Cookies not enabled.
a7b9e8bc 1187 redirect("$CFG->wwwroot/login/index.php?PHPSESSID=$PHPSESSID");
f9903ed0 1188 } else {
a7b9e8bc 1189 redirect("$CFG->wwwroot/login/index.php");
f9903ed0 1190 }
1191 die;
f9903ed0 1192 }
da5c172a 1193
1194 // Next, check if the user can be in a particular course
1195 if ($courseid) {
1196 if ($USER->student[$courseid] || $USER->teacher[$courseid] || $USER->admin) {
cb909d74 1197 if (isset($USER->realuser)) { // Make sure the REAL person can also access this course
1198 if (!isteacher($courseid, $USER->realuser)) {
1199 print_header();
5ebe27e2 1200 notice(get_string("studentnotallowed", "", "$USER->firstname $USER->lastname"), $CFG->wwwroot);
cb909d74 1201 }
1202
1203 } else { // just update their last login time
3ce2f1e0 1204 update_user_in_db();
1205 }
ab998e5d 1206 if (!$USER->email) { // User logged in, but has not set up profile!
1207 // This can occur with external authentication
ab998e5d 1208 redirect("$CFG->wwwroot/user/edit.php?id=$USER->id&course=$courseid");
1209 die;
1210 }
da5c172a 1211 return; // user is a member of this course.
1212 }
1213 if (! $course = get_record("course", "id", $courseid)) {
1214 error("That course doesn't exist");
1215 }
7363ff91 1216 if ($USER->username == "guest") {
1217 switch ($course->guest) {
1218 case 0: // Guests not allowed
1219 print_header();
1220 notice(get_string("guestsnotallowed", "", $course->fullname));
1221 break;
1222 case 1: // Guests allowed
1223 update_user_in_db();
1224 return;
1225 case 2: // Guests allowed with key (drop through)
1226 break;
1227 }
da5c172a 1228 }
f9903ed0 1229
7363ff91 1230 // Currently not enrolled in the course, so see if they want to enrol
da5c172a 1231 $SESSION->wantsurl = $FULLME;
8223d271 1232 save_session("SESSION");
da5c172a 1233 redirect("$CFG->wwwroot/course/enrol.php?id=$courseid");
1234 die;
1235 }
f9903ed0 1236}
1237
1238
1239
1240function update_login_count() {
1241 global $SESSION;
1242
1243 $max_logins = 10;
1244
1245 if (empty($SESSION->logincount)) {
1246 $SESSION->logincount = 1;
1247 } else {
1248 $SESSION->logincount++;
1249 }
8223d271 1250 save_session("SESSION");
f9903ed0 1251
1252 if ($SESSION->logincount > $max_logins) {
1253 unset($SESSION->wantsurl);
8223d271 1254 save_session("SESSION");
f9903ed0 1255 error("Sorry, you have exceeded the allowed number of login attempts. Restart your browser.");
1256 }
1257}
1258
d578afc8 1259function remove_admin($user) {
1260 global $db;
1261
1262 return $db->Execute("DELETE FROM user_admins WHERE user = '$user'");
1263}
1264
1265function remove_teacher($user, $course=0) {
1266 global $db;
1267
1268 if ($course) {
45aa6d56 1269 /// First delete any crucial stuff that might still send mail
1270 if ($forums = get_records("forum", "course", $course)) {
1271 foreach ($forums as $forum) {
1272 $db->Execute("DELETE FROM forum_subscriptions WHERE forum = '$forum->id' AND user = '$user'");
1273 }
1274 }
d578afc8 1275 return $db->Execute("DELETE FROM user_teachers WHERE user = '$user' AND course = '$course'");
1276 } else {
45aa6d56 1277 delete_records("forum_subscriptions", "user", $user);
1278 return delete_records("user_teachers", "user", $user);
d578afc8 1279 }
1280}
1281
1282
1283function enrol_student($user, $course) {
1284 global $db;
1285
1286 $timenow = time();
1287
1288 $rs = $db->Execute("INSERT INTO user_students (user, course, start, end, time)
1289 VALUES ($user, $course, 0, 0, $timenow)");
1290 if ($rs) {
1291 return true;
1292 } else {
1293 return false;
1294 }
1295}
1296
1297function unenrol_student($user, $course=0) {
1298 global $db;
1299
1300 if ($course) {
45aa6d56 1301 /// First delete any crucial stuff that might still send mail
1302 if ($forums = get_records("forum", "course", $course)) {
1303 foreach ($forums as $forum) {
1304 $db->Execute("DELETE FROM forum_subscriptions WHERE forum = '$forum->id' AND user = '$user'");
1305 }
1306 }
d578afc8 1307 return $db->Execute("DELETE FROM user_students WHERE user = '$user' AND course = '$course'");
45aa6d56 1308
d578afc8 1309 } else {
45aa6d56 1310 delete_records("forum_subscriptions", "user", $user);
1311 return delete_records("user_students", "user", $user);
d578afc8 1312 }
1313}
1314
f9903ed0 1315
1316function isadmin($userid=0) {
1317 global $USER;
1318
1319 if (!$userid) {
1320 return $USER->admin;
1321 }
1322
1323 return record_exists_sql("SELECT * FROM user_admins WHERE user='$userid'");
1324}
1325
8a9e3fd7 1326function isteacher($courseid, $userid=0) {
f9903ed0 1327 global $USER;
1328
d115a57f 1329 if (isadmin($userid)) { // admins can do anything the teacher can
1330 return true;
1331 }
1332
f9903ed0 1333 if (!$userid) {
8a9e3fd7 1334 return $USER->teacher[$courseid];
f9903ed0 1335 }
1336
8a9e3fd7 1337 return record_exists_sql("SELECT * FROM user_teachers WHERE user='$userid' AND course='$courseid'");
f9903ed0 1338}
1339
1340
8a9e3fd7 1341function isstudent($courseid, $userid=0) {
f9903ed0 1342 global $USER;
1343
1344 if (!$userid) {
8a9e3fd7 1345 return $USER->student[$courseid];
f9903ed0 1346 }
1347
1348 $timenow = time(); // todo: add time check below
1349
8a9e3fd7 1350 return record_exists_sql("SELECT * FROM user_students WHERE user='$userid' AND course='$courseid'");
f9903ed0 1351}
1352
da5c172a 1353function isguest($userid=0) {
1354 global $USER;
1355
1356 if (!$userid) {
1357 return ($USER->username == "guest");
1358 }
1359
a3447e10 1360 return record_exists_sql("SELECT * FROM user WHERE id='$userid' AND username = 'guest' ");
da5c172a 1361}
1362
2c309dc2 1363function isediting($courseid, $user=NULL) {
1364 global $USER;
1365 if (!$user){
1366 $user = $USER;
1367 }
1368 return ($user->editing and isteacher($courseid, $user->id));
1369}
1370
f9903ed0 1371function reset_login_count() {
1372 global $SESSION;
1373
1374 $SESSION->logincount = 0;
8223d271 1375 save_session("SESSION");
f9903ed0 1376}
1377
1378
1379function set_moodle_cookie($thing) {
1380
1381 $days = 60;
1382 $seconds = 60*60*24*$days;
1383
d115a57f 1384 setCookie ('MOODLEID', "", time() - 3600, "/");
f9903ed0 1385 setCookie ('MOODLEID', rc4encrypt($thing), time()+$seconds, "/");
1386}
1387
1388
1389function get_moodle_cookie() {
1390 global $MOODLEID;
1391 return rc4decrypt($MOODLEID);
1392}
1393
1394
8223d271 1395function save_session($VAR) {
1396// Copies temporary session variable to permanent sesson variable
1397// eg $_SESSION["USER"] = $USER;
1398 global $$VAR;
1399 $_SESSION[$VAR] = $$VAR;
1400}
1401
f9903ed0 1402
faebaf0f 1403function create_user_record($username, $password) {
1404// Creates a bare-bones user record
e858f9da 1405 global $REMOTE_ADDR, $CFG;
1406
6ae24de0 1407 if (function_exists(auth_get_userinfo)) {
e858f9da 1408 if ($newinfo = auth_get_userinfo($username)) {
34daec9b 1409 foreach ($newinfo as $key => $value){
e858f9da 1410 $newuser->$key = $value;
1411 }
1412 }
1413 }
f9903ed0 1414
faebaf0f 1415 $newuser->username = $username;
1416 $newuser->password = md5($password);
a0bac19d 1417 $newuser->lang = $CFG->lang;
faebaf0f 1418 $newuser->confirmed = 1;
1419 $newuser->lastIP = $REMOTE_ADDR;
1420 $newuser->timemodified = time();
f9903ed0 1421
faebaf0f 1422 if (insert_record("user", $newuser)) {
1423 return get_user_info_from_db("username", $username);
1424 }
1425 return false;
1426}
1427
1428function authenticate_user_login($username, $password) {
1429// Given a username and password, this function looks them
1430// up using the currently selected authentication mechanism,
1431// and if the authentication is successful, it returns a
1432// valid $user object from the 'user' table.
1433//
1434// Uses auth_ functions from the currently active auth module
1435
1436 global $CFG;
1437
466558e3 1438 $md5password = md5($password);
1439
faebaf0f 1440 if (!isset($CFG->auth)) {
1441 $CFG->auth = "email"; // Default authentication module
1442 }
1443
466558e3 1444 if ($username == "guest") {
1445 $CFG->auth = "none"; // Guest account always internal
1446 }
1447
1448 // If this is the admin, then just use internal methods
92710226 1449 // Doing this first (even though it's less efficient) because
1450 // the chosen authentication method might hang and lock the
1451 // admin out.
466558e3 1452 if ($user = get_record_sql("SELECT u.id FROM user u, user_admins a
1453 WHERE u.id = a.user
1454 AND u.username = '$username'
1455 AND u.password = '$md5password'")) {
1456 return get_user_info_from_db("username", $username);
1457 }
1458
92710226 1459 // OK, the user is a normal user, so try and authenticate them
e858f9da 1460 require_once("$CFG->dirroot/auth/$CFG->auth/lib.php");
faebaf0f 1461
1462 if (auth_user_login($username, $password)) { // Successful authentication
1463
1464 if ($user = get_user_info_from_db("username", $username)) {
92710226 1465 if ($md5password <> $user->password) { // Update local copy of password for reference
466558e3 1466 set_field("user", "password", $md5password, "username", $username);
faebaf0f 1467 }
1468 return $user;
1469
1470 } else {
1471 return create_user_record($username, $password);
1472 }
f9903ed0 1473 }
89b54325 1474
faebaf0f 1475 return false;
f9903ed0 1476}
1477
faebaf0f 1478
f9903ed0 1479function get_site () {
1480// Returns $course object of the top-level site.
1481 if ( $course = get_record("course", "category", 0)) {
1482 return $course;
1483 } else {
1484 return false;
1485 }
1486}
1487
1488function get_admin () {
1489// Returns $user object of the main admin user
1490
1491 if ( $admins = get_records_sql("SELECT u.* FROM user u, user_admins a WHERE a.user = u.id ORDER BY u.id ASC")) {
1492 foreach ($admins as $admin) {
bb09fb11 1493 return $admin; // ie the first one
f9903ed0 1494 }
1495 } else {
1496 return false;
1497 }
1498}
1499
1500function get_teacher($courseid) {
1501// Returns $user object of the main teacher for a course
1502 if ( $teachers = get_records_sql("SELECT u.* FROM user u, user_teachers t
1503 WHERE t.user = u.id AND t.course = '$courseid'
1504 ORDER BY t.authority ASC")) {
1505 foreach ($teachers as $teacher) {
bb09fb11 1506 if ($teacher->authority) {
1507 return $teacher; // the highest authority teacher
1508 }
f9903ed0 1509 }
1510 } else {
1511 return false;
1512 }
1513}
1514
3c720cce 1515function get_course_students($courseid, $sort="u.lastaccess DESC") {
1516 return get_records_sql("SELECT u.* FROM user u, user_students s
bb09fb11 1517 WHERE s.course = '$courseid' AND s.user = u.id AND u.deleted = '0'
3c720cce 1518 ORDER BY $sort");
1519}
1520
1521function get_course_teachers($courseid, $sort="t.authority ASC") {
b4d7002e 1522 return get_records_sql("SELECT u.*,t.authority,t.role FROM user u, user_teachers t
bb09fb11 1523 WHERE t.course = '$courseid' AND t.user = u.id AND u.deleted = '0'
3c720cce 1524 ORDER BY $sort");
1525}
1526
1527function get_course_users($courseid, $sort="u.lastaccess DESC") {
57507290 1528// Using this method because the direct SQL just would not always work!
1529
1530 $teachers = get_course_teachers($courseid, $sort);
1531 $students = get_course_students($courseid, $sort);
1532
1533 if ($teachers and $students) {
1534 return array_merge($teachers, $students);
1535 } else if ($teachers) {
1536 return $teachers;
1537 } else {
1538 return $students;
1539 }
1540
1541// return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t
1542// WHERE (s.course = '$courseid' AND s.user = u.id) OR
1543// (t.course = '$courseid' AND t.user = u.id)
1544// ORDER BY $sort");
3c720cce 1545}
1546
f9903ed0 1547
1548
1549/// MODULE FUNCTIONS /////////////////////////////////////////////////
1550
1ea8303c 1551function get_coursemodule_from_instance($modulename, $instance, $courseid) {
f9903ed0 1552// Given an instance of a module, finds the coursemodule description
1553
1554 return get_record_sql("SELECT cm.*, m.name
1555 FROM course_modules cm, modules md, $modulename m
1ea8303c 1556 WHERE cm.course = '$courseid' AND
f9903ed0 1557 cm.deleted = '0' AND
1558 cm.instance = m.id AND
1559 md.name = '$modulename' AND
1560 md.id = cm.module AND
1561 m.id = '$instance'");
1562
1563}
1564
1ea8303c 1565function get_all_instances_in_course($modulename, $courseid, $sort="cw.section") {
f9903ed0 1566// Returns an array of all the active instances of a particular
1567// module in a given course. Returns false on any errors.
1568
9ccbad71 1569 return get_records_sql("SELECT m.*,cw.section,cm.id as coursemodule
1570 FROM course_modules cm, course_sections cw, modules md, $modulename m
1ea8303c 1571 WHERE cm.course = '$courseid' AND
f9903ed0 1572 cm.instance = m.id AND
1573 cm.deleted = '0' AND
9ccbad71 1574 cm.section = cw.id AND
f9903ed0 1575 md.name = '$modulename' AND
1576 md.id = cm.module
1577 ORDER BY $sort");
1578
1579}
1580
f9903ed0 1581
1582
1583
f9903ed0 1584/// CORRESPONDENCE ////////////////////////////////////////////////
1585
5fa51a39 1586function email_to_user($user, $from, $subject, $messagetext, $messagehtml="", $attachment="", $attachname="") {
1587// user - a user record as an object
1588// from - a user record as an object
1589// subject - plain text subject line of the email
136dabd8 1590// messagetext - plain text version of the message
1591// messagehtml - complete html version of the message (optional)
1592// attachment - a file on the filesystem, relative to $CFG->dataroot
1593// attachname - the name of the file (extension indicates MIME)
f9903ed0 1594
4216daa6 1595 global $CFG, $_SERVER;
f9903ed0 1596
136dabd8 1597 include_once("$CFG->libdir/phpmailer/class.phpmailer.php");
f9903ed0 1598
5fa51a39 1599 if (!$user) {
f9903ed0 1600 return false;
1601 }
1602
f9903ed0 1603 $mail = new phpmailer;
1604
72c578ca 1605 $mail->Version = "Moodle $CFG->version"; // mailer version
136dabd8 1606 $mail->PluginDir = "$CFG->libdir/phpmailer/"; // plugin directory (eg smtp plugin)
562bbe90 1607
98c4eae3 1608
d483bcd3 1609 if (current_language() != "en") {
1610 $mail->CharSet = get_string("thischarset");
98c4eae3 1611 }
1612
7f86ce17 1613 if ($CFG->smtphosts) {
1e411ffc 1614 $mail->IsSMTP(); // use SMTP directly
1615 $mail->Host = "$CFG->smtphosts"; // specify main and backup servers
9f58537a 1616
1617 if ($CFG->smtpuser) { // Use SMTP authentication
1618 $mail->SMTPAuth = true;
1619 $mail->Username = $CFG->smtpuser;
1620 $mail->Password = $CFG->smtppass;
1621 }
7f86ce17 1622 } else {
1e411ffc 1623 $mail->IsMail(); // use PHP mail() = sendmail
7f86ce17 1624 }
f9903ed0 1625
136dabd8 1626 $mail->From = "$from->email";
1627 $mail->FromName = "$from->firstname $from->lastname";
1628 $mail->Subject = stripslashes($subject);
f9903ed0 1629
6b174680 1630 $mail->AddAddress("$user->email", "$user->firstname $user->lastname");
f9903ed0 1631
f9903ed0 1632 $mail->WordWrap = 70; // set word wrap
f9903ed0 1633
136dabd8 1634 if ($messagehtml) {
1635 $mail->IsHTML(true);
1636 $mail->Body = $messagehtml;
78681899 1637 $mail->AltBody = "\n$messagetext\n";
136dabd8 1638 } else {
1639 $mail->IsHTML(false);
78681899 1640 $mail->Body = "\n$messagetext\n";
f9903ed0 1641 }
1642
136dabd8 1643 if ($attachment && $attachname) {
1644 if (ereg( "\\.\\." ,$attachment )) { // Security check for ".." in dir path
4216daa6 1645 $adminuser = get_admin();
1646 $mail->AddAddress("$adminuser->email", "$adminuser->firstname $adminuser->lastname");
1647 $mail->AddStringAttachment("Error in attachment. User attempted to attach a filename with a unsafe name.", "error.txt", "8bit", "text/plain");
136dabd8 1648 } else {
1649 include_once("$CFG->dirroot/files/mimetypes.php");
1650 $mimetype = mimeinfo("type", $attachname);
1651 $mail->AddAttachment("$CFG->dataroot/$attachment", "$attachname", "base64", "$mimetype");
1652 }
f9903ed0 1653 }
1654
136dabd8 1655 if ($mail->Send()) {
1656 return true;
1657 } else {
4216daa6 1658 echo "ERROR: $mail->ErrorInfo\n";
1659 $site = get_site();
1660 add_to_log($site->id, "library", "mailer", $_SERVER["REQUEST_URI"], "ERROR: $mail->ErrorInfo");
f9903ed0 1661 return false;
1662 }
f9903ed0 1663}
1664
136dabd8 1665
f9903ed0 1666/// FILE HANDLING /////////////////////////////////////////////
1667
6b174680 1668function make_upload_directory($directory) {
1669// $directory = a string of directory names under $CFG->dataroot
1670// eg stuff/assignment/1
1671// Returns full directory if successful, false if not
1672
1673 global $CFG;
1674
1675 $currdir = $CFG->dataroot;
1676 if (!file_exists($currdir)) {
1677 if (! mkdir($currdir, 0750)) {
1678 notify("ERROR: You need to create the directory $currdir with web server write access");
1679 return false;
1680 }
1681 }
1682
1683 $dirarray = explode("/", $directory);
1684
1685 foreach ($dirarray as $dir) {
1686 $currdir = "$currdir/$dir";
1687 if (! file_exists($currdir)) {
1688 if (! mkdir($currdir, 0750)) {
1689 notify("ERROR: Could not find or create a directory ($currdir)");
1690 return false;
1691 }
1692 }
1693 }
1694
1695 return $currdir;
1696}
1697
ca4f8eb8 1698function make_mod_upload_directory($courseid) {
1699 global $CFG;
1700
1701 if (! $moddata = make_upload_directory("$courseid/$CFG->moddata")) {
1702 return false;
1703 }
1704
1705 $strreadme = get_string("readme");
1706
1707 if (file_exists("$CFG->dirroot/lang/$CFG->lang/docs/module_files.txt")) {
1708 copy("$CFG->dirroot/lang/$CFG->lang/docs/module_files.txt", "$moddata/$strreadme.txt");
1709 } else {
1710 copy("$CFG->dirroot/lang/en/docs/module_files.txt", "$moddata/$strreadme.txt");
1711 }
1712 return $moddata;
1713}
1714
6b174680 1715
44e2d2bb 1716function valid_uploaded_file($newfile) {
1717// Returns current name of file on disk if true
1718 if (is_uploaded_file($newfile['tmp_name']) and $newfile['size'] > 0) {
1719 return $newfile['tmp_name'];
1720 } else {
1721 return "";
1722 }
1723}
1724
1725function get_max_upload_file_size() {
1726 if (! $filesize = ini_get("upload_max_filesize")) {
1727 $filesize = "5M";
1728 }
1729 return get_real_size($filesize);
1730}
1731
774ab660 1732function get_directory_list($rootdir, $excludefile="", $descend=true) {
f9903ed0 1733// Returns an array with all the filenames in
1734// all subdirectories, relative to the given rootdir.
ca4f8eb8 1735// If excludefile is defined, then that file/directory is ignored
f9903ed0 1736
1737 $dirs = array();
1738
44e2d2bb 1739 $dir = opendir($rootdir);
f9903ed0 1740
d897cae4 1741 if (!$dir) {
1742 notify("Error: unable to read this directory! : $rootdir");
1743 return $dirs;
1744 }
1745
ca4f8eb8 1746 while ($file = readdir($dir)) {
774ab660 1747 if ($file != "." and $file != ".." and $file != "CVS" and $file != $excludefile) {
ca4f8eb8 1748 $fullfile = $rootdir."/".$file;
774ab660 1749 if ($descend and filetype($fullfile) == "dir") {
1750 $subdirs = get_directory_list($fullfile, $excludefile, $descend);
f9903ed0 1751 foreach ($subdirs as $subdir) {
1752 $dirs[] = $file."/".$subdir;
1753 }
1754 } else {
1755 $dirs[] = $file;
1756 }
1757 }
1758 }
44e2d2bb 1759 closedir($dir);
f9903ed0 1760
774ab660 1761 asort($dirs);
1762
f9903ed0 1763 return $dirs;
1764}
1765
989bfa9d 1766function get_real_size($size=0) {
1767// Converts numbers like 10M into bytes
1768 if (!$size) {
1769 return 0;
1770 }
1771 $scan['MB'] = 1048576;
64efda84 1772 $scan['Mb'] = 1048576;
989bfa9d 1773 $scan['M'] = 1048576;
1774 $scan['KB'] = 1024;
64efda84 1775 $scan['Kb'] = 1024;
989bfa9d 1776 $scan['K'] = 1024;
1777
1778 while (list($key) = each($scan)) {
1779 if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) {
1780 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
1781 break;
1782 }
1783 }
1784 return $size;
1785}
1786
44e2d2bb 1787function display_size($size) {
1788// Converts bytes into display form
1789 if ($size >= 1073741824) {
1790 $size = round($size / 1073741824 * 10) / 10 . "Gb";
1791 } else if ($size >= 1048576) {
1792 $size = round($size / 1048576 * 10) / 10 . "Mb";
1793 } else if ($size >= 1024) {
1794 $size = round($size / 1024 * 10) / 10 . "Kb";
1795 } else {
1796 $size = $size . "b";
1797 }
1798 return $size;
1799}
1800
6b174680 1801function clean_filename($string) {
fc05fccb 1802 $string = stripslashes($string);
6b174680 1803 $string = eregi_replace("\.\.", "", $string);
1804 $string = eregi_replace("[^([:alnum:]|\.)]", "_", $string);
1805 return eregi_replace("_+", "_", $string);
1806}
1807
1808
1180c6dc 1809/// STRING TRANSLATION ////////////////////////////////////////
1810
a83fded1 1811function print_string($identifier, $module="", $a=NULL) {
1812 echo get_string($identifier, $module, $a);
bcc83c41 1813}
1814
4bfa92e7 1815function current_language() {
1816// Returns the code for the current language
1817 global $CFG, $USER;
1818
1819 if (isset($USER->lang)) { // User language can override site language
1820 return $USER->lang;
1821 } else {
1822 return $CFG->lang;
1823 }
1824}
bcc83c41 1825
a83fded1 1826function get_string($identifier, $module="", $a=NULL) {
1180c6dc 1827// Return the translated string specified by $identifier as
1828// for $module. Uses the same format files as STphp.
a83fded1 1829// $a is an object, string or number that can be used
1180c6dc 1830// within translation strings
a83fded1 1831//
1832// eg "hello \$a->firstname \$a->lastname"
1833// or "hello \$a"
1180c6dc 1834
4bfa92e7 1835 global $CFG;
1180c6dc 1836
4bfa92e7 1837 $lang = current_language();
1180c6dc 1838
058eec18 1839 if ($module == "") {
1840 $module = "moodle";
1180c6dc 1841 }
1842
058eec18 1843 $langpath = "$CFG->dirroot/lang";
1844 $langfile = "$langpath/$lang/$module.php";
1180c6dc 1845
1846 if (!file_exists($langfile)) { // try English instead
058eec18 1847 $langfile = "$langpath/en/$module.php";
1180c6dc 1848 if (!file_exists($langfile)) {
058eec18 1849 return "ERROR: No lang file ($langpath/en/$module.php)!";
1180c6dc 1850 }
1851 }
1852
1853 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1854
1855 eval($result);
1856 return $resultstring;
1857
1858 } else {
1859 if ($lang == "en") {
44e2d2bb 1860 return "[['$identifier']]";
1180c6dc 1861
1862 } else { // Try looking in the english file.
058eec18 1863 $langfile = "$langpath/en/$module.php";
1180c6dc 1864 if (!file_exists($langfile)) {
058eec18 1865 return "ERROR: No lang file ($langpath/en/$module.php)!";
1180c6dc 1866 }
1867 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1868 eval($result);
1869 return $resultstring;
1870 } else {
44e2d2bb 1871 return "[['$identifier']]";
1180c6dc 1872 }
1873 }
1874 }
1875}
1876
1877
1180c6dc 1878function get_string_from_file($identifier, $langfile, $destination) {
1879// This function is only used from get_string().
1880 include ($langfile);
1881
1882 if (!isset ($string[$identifier])) {
1883 return false;
1884 }
1885
a83fded1 1886 return "$destination = sprintf(\"".$string[$identifier]."\");";
1180c6dc 1887}
f9903ed0 1888
1889
1a72314d 1890function get_list_of_languages() {
1891/// Returns a list of language codes and their full names
1892 global $CFG;
1893
1894 if (!$langdirs = get_list_of_plugins("lang")) {
1895 return false;
1896 }
1897
1898 foreach ($langdirs as $lang) {
1899 include("$CFG->dirroot/lang/$lang/moodle.php");
1900 $languages[$lang] = $string["thislanguage"]." ($lang)";
1901 unset($string);
1902 }
1903 return $languages;
1904}
1905
1906
f9903ed0 1907/// ENCRYPTION ////////////////////////////////////////////////
1908
1909function rc4encrypt($data) {
1910 $password = "nfgjeingjk";
1911 return endecrypt($password, $data, "");
1912}
1913
1914function rc4decrypt($data) {
1915 $password = "nfgjeingjk";
1916 return endecrypt($password, $data, "de");
1917}
1918
1919function endecrypt ($pwd, $data, $case) {
1920// Based on a class by Mukul Sabharwal [mukulsabharwal@yahoo.com]
1921
1922 if ($case == 'de') {
1923 $data = urldecode($data);
1924 }
1925
1926 $key[] = "";
1927 $box[] = "";
1928 $temp_swap = "";
1929 $pwd_length = 0;
1930
1931 $pwd_length = strlen($pwd);
1932
1933 for ($i = 0; $i <= 255; $i++) {
1934 $key[$i] = ord(substr($pwd, ($i % $pwd_length), 1));
1935 $box[$i] = $i;
1936 }
1937
1938 $x = 0;
1939
1940 for ($i = 0; $i <= 255; $i++) {
1941 $x = ($x + $box[$i] + $key[$i]) % 256;
1942 $temp_swap = $box[$i];
1943 $box[$i] = $box[$x];
1944 $box[$x] = $temp_swap;
1945 }
1946
1947 $temp = "";
1948 $k = "";
1949
1950 $cipherby = "";
1951 $cipher = "";
1952
1953 $a = 0;
1954 $j = 0;
1955
1956 for ($i = 0; $i < strlen($data); $i++) {
1957 $a = ($a + 1) % 256;
1958 $j = ($j + $box[$a]) % 256;
1959 $temp = $box[$a];
1960 $box[$a] = $box[$j];
1961 $box[$j] = $temp;
1962 $k = $box[(($box[$a] + $box[$j]) % 256)];
1963 $cipherby = ord(substr($data, $i, 1)) ^ $k;
1964 $cipher .= chr($cipherby);
1965 }
1966
1967 if ($case == 'de') {
1968 $cipher = urldecode(urlencode($cipher));
1969 } else {
1970 $cipher = urlencode($cipher);
1971 }
1972
1973 return $cipher;
1974}
1975
1976
1977/// MISCELLANEOUS ////////////////////////////////////////////////////////////////////
1978
39917a09 1979function count_words($string) {
1980 $string = strip_tags($string);
1981 return count(preg_split("/\w\b/", $string)) - 1;
1982}
1983
f9903ed0 1984function getweek ($startdate, $thedate) {
1985// Given dates in seconds, how many weeks is the date from startdate
1986// The first week is 1, the second 2 etc ...
1987
1988 if ($thedate < $startdate) { // error
1989 return 0;
1990 }
1991
1992 return floor(($thedate - $startdate) / 604800.0) + 1;
1993}
1994
4216daa6 1995function add_to_log($course, $module, $action, $url="", $info="") {
1996// Add an entry to the log table. These are "action" focussed rather
1997// than web server hits, and provide a way to easily reconstruct what
1998// any particular student has been doing.
1999//
2000// course = the course id
2a439ba7 2001// module = forum, journal, resource, course, user etc
4216daa6 2002// action = view, edit, post (often but not always the same as the file.php)
2003// url = the file and parameters used to see the results of the action
2004// info = additional description information
2005
2006
f9903ed0 2007 global $db, $USER, $REMOTE_ADDR;
2008
9132e866 2009 if (isset($USER->realuser)) { // Don't log
2010 return;
2011 }
2012
f9903ed0 2013 $timenow = time();
4216daa6 2014 $info = addslashes($info);
2015
2016 $result = $db->Execute("INSERT INTO log
2017 SET time = '$timenow',
2018 user = '$USER->id',
2019 course = '$course',
2020 ip = '$REMOTE_ADDR',
2021 module = '$module',
2022 action = '$action',
2023 url = '$url',
2024 info = '$info'");
f9903ed0 2025 if (!$result) {
4216daa6 2026 echo "<P>Error: Could not insert a new entry to the Moodle log</P>"; // Don't throw an error
f9903ed0 2027 }
2028}
2029
2030function generate_password($maxlen=10) {
53bfe78c 2031// returns a randomly generated password of length $maxlen. inspired by
2032// http://www.phpbuilder.com/columns/jesus19990502.php3
f9903ed0 2033
2034 global $CFG;
2035
2036 $fillers = "1234567890!$-+";
2037 $wordlist = file($CFG->wordlist);
2038
2039 srand((double) microtime() * 1000000);
2040 $word1 = trim($wordlist[rand(0, count($wordlist) - 1)]);
2041 $word2 = trim($wordlist[rand(0, count($wordlist) - 1)]);
2042 $filler1 = $fillers[rand(0, strlen($fillers) - 1)];
2043
2044 return substr($word1 . $filler1 . $word2, 0, $maxlen);
2045}
2046
53bfe78c 2047function moodle_needs_upgrading() {
2048// Checks version numbers of Main code and all modules to see
2049// if there are any mismatches ... returns true or false
2050 global $CFG;
2051
2052 include_once("$CFG->dirroot/version.php"); # defines $version and upgrades
a28af1fe 2053 if ($CFG->version) {
2054 if ($version > $CFG->version) {
53bfe78c 2055 return true;
2056 }
1e3e716f 2057 if ($mods = get_list_of_plugins("mod")) {
53bfe78c 2058 foreach ($mods as $mod) {
2059 $fullmod = "$CFG->dirroot/mod/$mod";
2060 unset($module);
2061 include_once("$fullmod/version.php"); # defines $module with version etc
2062 if ($currmodule = get_record("modules", "name", $mod)) {
2063 if ($module->version > $currmodule->version) {
2064 return true;
2065 }
2066 }
2067 }
2068 }
2069 } else {
2070 return true;
2071 }
2072 return false;
53bfe78c 2073}
2074
2075
1e3e716f 2076function get_list_of_plugins($plugin="mod") {
2077// Lists plugin directories within some directory
2078
53bfe78c 2079 global $CFG;
2080
1e3e716f 2081 $basedir = opendir("$CFG->dirroot/$plugin");
2082 while ($dir = readdir($basedir)) {
2083 if ($dir == "." || $dir == ".." || $dir == "CVS") {
53bfe78c 2084 continue;
2085 }
1e3e716f 2086 if (filetype("$CFG->dirroot/$plugin/$dir") != "dir") {
53bfe78c 2087 continue;
2088 }
1e3e716f 2089 $plugins[] = $dir;
53bfe78c 2090 }
1e3e716f 2091 if ($plugins) {
2092 asort($plugins);
2093 }
2094 return $plugins;
53bfe78c 2095}
2096
1e3e716f 2097
b0cb5e22 2098function check_php_version($version="4.1.0") {
2099// Returns true is the current version of PHP is greater that the specified one
2100 $minversion = intval(str_replace(".", "", $version));
2101 $curversion = intval(str_replace(".", "", phpversion()));
2102 return ($curversion >= $minversion);
2103}
2104
0095d5cd 2105function check_browser_version($brand="MSIE", $version=5.5) {
2106// Checks to see if is a browser matches the specified
2107// brand and is equal or better version.
2108 global $HTTP_USER_AGENT;
2109
2110 if (!$HTTP_USER_AGENT) {
2111 return false;
2112 }
2113 $string = explode(";", $HTTP_USER_AGENT);
2114 if (!isset($string[1])) {
2115 return false;
2116 }
2117 $string = explode(" ", trim($string[1]));
2118 if (!isset($string[0]) and !isset($string[1])) {
2119 return false;
2120 }
2121 if ($string[0] == $brand and (float)$string[1] >= $version ) {
2122 return true;
2123 }
2124 return false;
2125}
2126
2127function can_use_richtext_editor() {
2128 global $USER, $CFG;
7ce20f09 2129 if ($USER->htmleditor and $CFG->htmleditor) {
2130 return check_browser_version("MSIE", 5.5);
2131 }
2132 return false;
0095d5cd 2133}
2134
f9903ed0 2135
74944b73 2136function check_gd_version() {
2137 ob_start();
2138 phpinfo();
2139 $phpinfo = ob_get_contents();
2140 ob_end_clean();
2141
2142 $phpinfo = explode("\n",$phpinfo);
2143
2144 $gdversion = 0;
2145
2146 foreach ($phpinfo as $text) {
2147 $parts = explode('</b>',$text);
2148 foreach ($parts as $key => $val) {
2149 $parts[$key] = strip_tags($val);
2150 }
2151 if ($parts[0]=="GD Version") {
2152 $gdversion = intval($parts[1]);
2153 }
2154 }
2155
2156 return $gdversion; // 1, 2 or 0
2157}
f9903ed0 2158
0095d5cd 2159
2160
f9903ed0 2161?>