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