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