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