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