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