Removed extra <hr> tag
[moodle.git] / lib / moodlelib.php
CommitLineData
f9903ed0 1<?PHP // $Id$
2
9fa49e22 3///////////////////////////////////////////////////////////////////////////
4// //
5// moodlelib.php //
6// //
7// Main library file of miscellaneous general-purpose Moodle functions //
8// //
9// Other main libraries: //
10// //
11// weblib.php - functions that produce web output //
12// datalib.php - functions that access the database //
13// //
14///////////////////////////////////////////////////////////////////////////
15// //
16// NOTICE OF COPYRIGHT //
17// //
18// Moodle - Modular Object-Oriented Dynamic Learning Environment //
19// http://moodle.com //
20// //
21// Copyright (C) 2001-2003 Martin Dougiamas http://dougiamas.com //
22// //
23// This program is free software; you can redistribute it and/or modify //
24// it under the terms of the GNU General Public License as published by //
25// the Free Software Foundation; either version 2 of the License, or //
26// (at your option) any later version. //
27// //
28// This program is distributed in the hope that it will be useful, //
29// but WITHOUT ANY WARRANTY; without even the implied warranty of //
30// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
31// GNU General Public License for more details: //
32// //
33// http://www.gnu.org/copyleft/gpl.html //
34// //
35///////////////////////////////////////////////////////////////////////////
65ccdd8c 36
f374fb10 37/// CONSTANTS /////////////////////////////////////////////////////////////
38
39define('NOGROUPS', 0);
40define('SEPARATEGROUPS', 1);
41define('VISIBLEGROUPS', 2);
42
f9903ed0 43
9fa49e22 44/// PARAMETER HANDLING ////////////////////////////////////////////////////
6b174680 45
9fa49e22 46function require_variable($var) {
47/// Variable must be present
48 if (! isset($var)) {
49 error("A required parameter was missing");
6b174680 50 }
51}
52
9fa49e22 53function optional_variable(&$var, $default=0) {
54/// Variable may be present, if not then set a default
55 if (! isset($var)) {
56 $var = $default;
6b174680 57 }
58}
59
60
9fa49e22 61function set_config($name, $value) {
62/// No need for get_config because they are usually always available in $CFG
70812e39 63
42282810 64 global $CFG;
65
66 $CFG->$name = $value; // So it's defined for this invocation at least
dfc9ba9b 67
9fa49e22 68 if (get_field("config", "name", "name", $name)) {
69 return set_field("config", "value", $value, "name", $name);
d897cae4 70 } else {
9fa49e22 71 $config->name = $name;
72 $config->value = $value;
73 return insert_record("config", $config);
39917a09 74 }
39917a09 75}
76
39917a09 77
70812e39 78function reload_user_preferences() {
79/// Refresh current USER with all their current preferences
80
81 global $USER;
82
83 unset($USER->preference);
84
85 if ($preferences = get_records('user_preferences', 'userid', $USER->id)) {
86 foreach ($preferences as $preference) {
87 $USER->preference[$preference->name] = $preference->value;
88 }
89 }
90}
91
92function set_user_preference($name, $value) {
93/// Sets a preference for the current user
94
95 global $USER;
96
97 if (empty($name)) {
98 return false;
99 }
100
101 if ($preference = get_record('user_preferences', 'userid', $USER->id, 'name', $name)) {
066af654 102 if (set_field("user_preferences", "value", $value, "id", $preference->id)) {
103 $USER->preference[$name] = $value;
104 return true;
105 } else {
106 return false;
107 }
70812e39 108
109 } else {
110 $preference->userid = $USER->id;
111 $preference->name = $name;
112 $preference->value = (string)$value;
066af654 113 if (insert_record('user_preferences', $preference)) {
70812e39 114 $USER->preference[$name] = $value;
115 return true;
116 } else {
117 return false;
118 }
119 }
120}
121
122function set_user_preferences($prefarray) {
123/// Sets a whole array of preferences for the current user
124
125 if (!is_array($prefarray) or empty($prefarray)) {
126 return false;
127 }
128
129 $return = true;
130 foreach ($prefarray as $name => $value) {
131 // The order is important; if the test for return is done first,
132 // then if one function call fails all the remaining ones will
133 // be "optimized away"
134 $return = set_user_preference($name, $value) and $return;
135 }
136 return $return;
137}
138
139function get_user_preferences($name=NULL, $default=NULL) {
140/// Without arguments, returns all the current user preferences
141/// as an array. If a name is specified, then this function
142/// attempts to return that particular preference value. If
143/// none is found, then the optional value $default is returned,
144/// otherwise NULL.
145
146 global $USER;
147
148 if (empty($USER->preference)) {
149 return $default; // Default value (or NULL)
150 }
151 if (empty($name)) {
152 return $USER->preference; // Whole array
153 }
154 if (!isset($USER->preference[$name])) {
155 return $default; // Default value (or NULL)
156 }
157 return $USER->preference[$name]; // The single value
158}
159
160
9fa49e22 161/// FUNCTIONS FOR HANDLING TIME ////////////////////////////////////////////
39917a09 162
3db75c62 163function make_timestamp($year, $month=1, $day=1, $hour=0, $minute=0, $second=0, $timezone=99) {
9fa49e22 164/// Given date parts in user time, produce a GMT timestamp
39917a09 165
94e34118 166 global $USER;
167
03c17ddf 168 if ($timezone == 99) {
94e34118 169 $timezone = (float)$USER->timezone;
170 }
171
172 if (abs($timezone) > 13) {
03c17ddf 173 return mktime((int)$hour,(int)$minute,(int)$second,(int)$month,(int)$day,(int)$year);
174 } else {
175 $time = gmmktime((int)$hour,(int)$minute,(int)$second,(int)$month,(int)$day,(int)$year);
176 return usertime($time, $timezone); // This is GMT
177 }
39917a09 178}
179
8dbed6be 180function format_time($totalsecs, $str=NULL) {
9fa49e22 181/// Given an amount of time in seconds, returns string
182/// formatted nicely as months, days, hours etc as needed
c7e3ac2a 183
6b174680 184 $totalsecs = abs($totalsecs);
c7e3ac2a 185
8dbed6be 186 if (!$str) { // Create the str structure the slow way
187 $str->day = get_string("day");
188 $str->days = get_string("days");
189 $str->hour = get_string("hour");
190 $str->hours = get_string("hours");
191 $str->min = get_string("min");
192 $str->mins = get_string("mins");
193 $str->sec = get_string("sec");
194 $str->secs = get_string("secs");
195 }
196
197 $days = floor($totalsecs/86400);
6b174680 198 $remainder = $totalsecs - ($days*86400);
8dbed6be 199 $hours = floor($remainder/3600);
6b174680 200 $remainder = $remainder - ($hours*3600);
8dbed6be 201 $mins = floor($remainder/60);
202 $secs = $remainder - ($mins*60);
203
204 $ss = ($secs == 1) ? $str->sec : $str->secs;
205 $sm = ($mins == 1) ? $str->min : $str->mins;
206 $sh = ($hours == 1) ? $str->hour : $str->hours;
207 $sd = ($days == 1) ? $str->day : $str->days;
208
9c9f7d77 209 $odays = "";
210 $ohours = "";
211 $omins = "";
212 $osecs = "";
213
8dbed6be 214 if ($days) $odays = "$days $sd";
215 if ($hours) $ohours = "$hours $sh";
216 if ($mins) $omins = "$mins $sm";
217 if ($secs) $osecs = "$secs $ss";
6b174680 218
219 if ($days) return "$odays $ohours";
220 if ($hours) return "$ohours $omins";
221 if ($mins) return "$omins $osecs";
222 if ($secs) return "$osecs";
223 return get_string("now");
224}
f9903ed0 225
61ae5d36 226function userdate($date, $format="", $timezone=99, $fixday = true) {
9fa49e22 227/// Returns a formatted string that represents a date in user time
228/// WARNING: note that the format is for strftime(), not date().
229/// Because of a bug in most Windows time libraries, we can't use
230/// the nicer %e, so we have to use %d which has leading zeroes.
231/// A lot of the fuss below is just getting rid of these leading
232/// zeroes as efficiently as possible.
61ae5d36 233///
234/// If parammeter fixday = true (default), then take off leading
235/// zero from %d, else mantain it.
7a302afc 236
90207a06 237 global $USER, $CFG;
873960de 238
5fa51a39 239 if ($format == "") {
dcde9f02 240 $format = get_string("strftimedaydatetime");
5fa51a39 241 }
035cdbff 242
dcde9f02 243 $formatnoday = str_replace("%d", "DD", $format);
61ae5d36 244 if ($fixday) {
245 $fixday = ($formatnoday != $format);
246 }
dcde9f02 247
90207a06 248 if ($timezone == 99) { // Work out the best timezone to use
249 if (isset($USER->timezone)) { // A user is logged in
ab247495 250 $timezone = (float)$USER->timezone;
90207a06 251 } else if (isset($CFG->timezone)) { // Use site's default timezone
252 $timezone = (float)$CFG->timezone;
ab247495 253 }
5fa51a39 254 }
90207a06 255
0431bd7c 256 if (abs($timezone) > 13) {
035cdbff 257 if ($fixday) {
258 $datestring = strftime($formatnoday, $date);
259 $daystring = str_replace(" 0", "", strftime(" %d", $date));
260 $datestring = str_replace("DD", $daystring, $datestring);
261 } else {
262 $datestring = strftime($format, $date);
263 }
bea7a51e 264 } else {
70d4cf82 265 $date = $date + (int)($timezone * 3600);
035cdbff 266 if ($fixday) {
70d4cf82 267 $datestring = gmstrftime($formatnoday, $date);
9fa49e22 268 $daystring = str_replace(" 0", "", gmstrftime(" %d", $date));
035cdbff 269 $datestring = str_replace("DD", $daystring, $datestring);
270 } else {
70d4cf82 271 $datestring = gmstrftime($format, $date);
035cdbff 272 }
873960de 273 }
bea7a51e 274
035cdbff 275 return $datestring;
873960de 276}
277
5fa51a39 278function usergetdate($date, $timezone=99) {
9fa49e22 279/// Given a $date timestamp in GMT, returns an array
280/// that represents the date in user time
6b174680 281
873960de 282 global $USER;
283
5fa51a39 284 if ($timezone == 99) {
285 $timezone = (float)$USER->timezone;
286 }
0431bd7c 287 if (abs($timezone) > 13) {
873960de 288 return getdate($date);
289 }
d2d6171f 290 //There is no gmgetdate so I have to fake it...
291 $date = $date + (int)($timezone * 3600);
292 $getdate["seconds"] = gmstrftime("%S", $date);
293 $getdate["minutes"] = gmstrftime("%M", $date);
294 $getdate["hours"] = gmstrftime("%H", $date);
295 $getdate["mday"] = gmstrftime("%d", $date);
296 $getdate["wday"] = gmstrftime("%u", $date);
297 $getdate["mon"] = gmstrftime("%m", $date);
298 $getdate["year"] = gmstrftime("%Y", $date);
299 $getdate["yday"] = gmstrftime("%j", $date);
300 $getdate["weekday"] = gmstrftime("%A", $date);
301 $getdate["month"] = gmstrftime("%B", $date);
302 return $getdate;
d552ead0 303}
304
305function usertime($date, $timezone=99) {
9fa49e22 306/// Given a GMT timestamp (seconds since epoch), offsets it by
307/// the timezone. eg 3pm in India is 3pm GMT - 7 * 3600 seconds
d552ead0 308 global $USER;
309
310 if ($timezone == 99) {
311 $timezone = (float)$USER->timezone;
312 }
0431bd7c 313 if (abs($timezone) > 13) {
d552ead0 314 return $date;
315 }
316 return $date - (int)($timezone * 3600);
317}
318
edf7fe8c 319function usergetmidnight($date, $timezone=99) {
9fa49e22 320/// Given a time, return the GMT timestamp of the most recent midnight
321/// for the current user.
edf7fe8c 322 global $USER;
323
4606d9bb 324 if ($timezone == 99) {
325 $timezone = (float)$USER->timezone;
326 }
327
edf7fe8c 328 $userdate = usergetdate($date, $timezone);
4606d9bb 329
0431bd7c 330 if (abs($timezone) > 13) {
4606d9bb 331 return mktime(0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
332 }
333
edf7fe8c 334 $timemidnight = gmmktime (0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
335 return usertime($timemidnight, $timezone); // Time of midnight of this user's day, in GMT
336
337}
338
d552ead0 339function usertimezone($timezone=99) {
9fa49e22 340/// Returns a string that prints the user's timezone
d552ead0 341 global $USER;
342
343 if ($timezone == 99) {
344 $timezone = (float)$USER->timezone;
345 }
0431bd7c 346 if (abs($timezone) > 13) {
d552ead0 347 return "server time";
348 }
349 if (abs($timezone) < 0.5) {
350 return "GMT";
351 }
352 if ($timezone > 0) {
353 return "GMT+$timezone";
354 } else {
355 return "GMT$timezone";
356 }
f9903ed0 357}
358
359
9fa49e22 360/// USER AUTHENTICATION AND LOGIN ////////////////////////////////////////
f9903ed0 361
da5c172a 362function require_login($courseid=0) {
9fa49e22 363/// This function checks that the current user is logged in, and optionally
364/// whether they are "logged in" or allowed to be in a particular course.
365/// If not, then it redirects them to the site login or course enrolment.
f9903ed0 366
73047f2f 367 global $CFG, $SESSION, $USER, $FULLME, $MoodleSession;
f9903ed0 368
da5c172a 369 // First check that the user is logged in to the site.
c21c671d 370 if (! (isset($USER->loggedin) and $USER->confirmed and ($USER->site == $CFG->wwwroot)) ) { // They're not
f9903ed0 371 $SESSION->wantsurl = $FULLME;
9f44d972 372 if (!empty($_SERVER["HTTP_REFERER"])) {
373 $SESSION->fromurl = $_SERVER["HTTP_REFERER"];
374 }
c21c671d 375 $USER = NULL;
73047f2f 376 redirect("$CFG->wwwroot/login/index.php");
f9903ed0 377 die;
f9903ed0 378 }
808a3baa 379
380 // Check that the user account is properly set up
381 if (user_not_fully_set_up($USER)) {
382 $site = get_site();
383 redirect("$CFG->wwwroot/user/edit.php?id=$USER->id&course=$site->id");
384 die;
385 }
da5c172a 386
387 // Next, check if the user can be in a particular course
388 if ($courseid) {
9c9f7d77 389 if (!empty($USER->student[$courseid]) or !empty($USER->teacher[$courseid]) or !empty($USER->admin)) {
cb909d74 390 if (isset($USER->realuser)) { // Make sure the REAL person can also access this course
391 if (!isteacher($courseid, $USER->realuser)) {
392 print_header();
0b4c5822 393 notice(get_string("studentnotallowed", "", fullname($USER, true)), $CFG->wwwroot);
cb909d74 394 }
395
396 } else { // just update their last login time
3ce2f1e0 397 update_user_in_db();
398 }
da5c172a 399 return; // user is a member of this course.
400 }
401 if (! $course = get_record("course", "id", $courseid)) {
402 error("That course doesn't exist");
403 }
1efa27fd 404 if (!$course->visible) {
405 print_header();
0b4c5822 406 notice(get_string("studentnotallowed", "", fullname($USER, true)), $CFG->wwwroot);
1efa27fd 407 }
7363ff91 408 if ($USER->username == "guest") {
409 switch ($course->guest) {
410 case 0: // Guests not allowed
411 print_header();
412 notice(get_string("guestsnotallowed", "", $course->fullname));
413 break;
414 case 1: // Guests allowed
415 update_user_in_db();
416 return;
417 case 2: // Guests allowed with key (drop through)
418 break;
419 }
da5c172a 420 }
f9903ed0 421
7363ff91 422 // Currently not enrolled in the course, so see if they want to enrol
da5c172a 423 $SESSION->wantsurl = $FULLME;
424 redirect("$CFG->wwwroot/course/enrol.php?id=$courseid");
425 die;
426 }
f9903ed0 427}
428
1d881d92 429function update_user_login_times() {
430 global $USER;
431
432 $USER->lastlogin = $user->lastlogin = $USER->currentlogin;
433 $USER->currentlogin = $user->currentlogin = time();
1d881d92 434
435 $user->id = $USER->id;
436
437 return update_record("user", $user);
438}
439
808a3baa 440function user_not_fully_set_up($user) {
ac5d88eb 441 return ($user->username != "guest" and (empty($user->firstname) or empty($user->lastname) or empty($user->email)));
808a3baa 442}
f9903ed0 443
f9903ed0 444function update_login_count() {
9fa49e22 445/// Keeps track of login attempts
446
f9903ed0 447 global $SESSION;
448
449 $max_logins = 10;
450
451 if (empty($SESSION->logincount)) {
452 $SESSION->logincount = 1;
453 } else {
454 $SESSION->logincount++;
455 }
456
457 if ($SESSION->logincount > $max_logins) {
9fa49e22 458 unset($SESSION->wantsurl);
1d881d92 459 error(get_string("errortoomanylogins"));
d578afc8 460 }
461}
462
9fa49e22 463function reset_login_count() {
464/// Resets login attempts
465 global $SESSION;
d578afc8 466
9fa49e22 467 $SESSION->logincount = 0;
d578afc8 468}
469
cb98d312 470function check_for_restricted_user($username=NULL, $redirect="") {
471 global $CFG, $USER;
472
473 if (!$username) {
474 if (!empty($USER->username)) {
475 $username = $USER->username;
476 } else {
477 return false;
478 }
479 }
480
481 if (!empty($CFG->restrictusers)) {
482 $names = explode(',', $CFG->restrictusers);
483 if (in_array($username, $names)) {
9b591be6 484 error(get_string("restricteduser", "error", fullname($USER)), $redirect);
cb98d312 485 }
486 }
487}
488
581d7b49 489function isadmin($userid=0) {
9fa49e22 490/// Is the user an admin?
f9903ed0 491 global $USER;
aa095969 492 static $admins = array();
493 static $nonadmins = array();
f9903ed0 494
581d7b49 495 if (!$userid){
496 if (empty($USER->id)) {
497 return false;
498 }
499 $userid = $USER->id;
9bd2c874 500 }
501
581d7b49 502 if (in_array($userid, $admins)) {
aa095969 503 return true;
581d7b49 504 } else if (in_array($userid, $nonadmins)) {
aa095969 505 return false;
581d7b49 506 } else if (record_exists("user_admins", "userid", $userid)){
507 $admins[] = $userid;
aa095969 508 return true;
509 } else {
581d7b49 510 $nonadmins[] = $userid;
aa095969 511 return false;
f9903ed0 512 }
f9903ed0 513}
514
9788367b 515function isteacher($courseid, $userid=0, $includeadmin=true) {
9fa49e22 516/// Is the user a teacher or admin?
f9903ed0 517 global $USER;
518
9788367b 519 if ($includeadmin and isadmin($userid)) { // admins can do anything the teacher can
d115a57f 520 return true;
521 }
522
f9903ed0 523 if (!$userid) {
9bd2c874 524 return !empty($USER->teacher[$courseid]);
f9903ed0 525 }
526
ebc3bd2b 527 return record_exists("user_teachers", "userid", $userid, "course", $courseid);
f9903ed0 528}
529
73047f2f 530function isteacheredit($courseid, $userid=0) {
531/// Is the user allowed to edit this course?
532 global $USER;
533
534 if (isadmin($userid)) { // admins can do anything
535 return true;
536 }
537
538 if (!$userid) {
539 return !empty($USER->teacheredit[$courseid]);
540 }
541
542 return get_field("user_teachers", "editall", "userid", $userid, "course", $courseid);
543}
544
1924074c 545function iscreator ($userid=0) {
546/// Can user create new courses?
547 global $USER;
8a205861 548 if (empty($USER->id)) {
549 return false;
550 }
1924074c 551 if (isadmin($userid)) { // admins can do anything
552 return true;
553 }
8a205861 554 if (empty($userid)) {
1924074c 555 return record_exists("user_coursecreators", "userid", $USER->id);
556 }
557
558 return record_exists("user_coursecreators", "userid", $userid);
559}
560
8a9e3fd7 561function isstudent($courseid, $userid=0) {
9fa49e22 562/// Is the user a student in this course?
f9903ed0 563 global $USER;
564
565 if (!$userid) {
346b1a24 566 return !empty($USER->student[$courseid]);
f9903ed0 567 }
568
ebc3bd2b 569 // $timenow = time(); // todo: add time check below
f9903ed0 570
ebc3bd2b 571 return record_exists("user_students", "userid", $userid, "course", $courseid);
f9903ed0 572}
573
da5c172a 574function isguest($userid=0) {
9fa49e22 575/// Is the user a guest?
da5c172a 576 global $USER;
577
578 if (!$userid) {
b35e8568 579 if (empty($USER->username)) {
580 return false;
581 }
da5c172a 582 return ($USER->username == "guest");
583 }
584
9fa49e22 585 return record_exists("user", "id", $userid, "username", "guest");
da5c172a 586}
587
9fa49e22 588
2c309dc2 589function isediting($courseid, $user=NULL) {
9fa49e22 590/// Is the current user in editing mode?
2c309dc2 591 global $USER;
592 if (!$user){
593 $user = $USER;
594 }
9c9f7d77 595 if (empty($user->editing)) {
596 return false;
597 }
2c309dc2 598 return ($user->editing and isteacher($courseid, $user->id));
599}
600
7977cffd 601function ismoving($courseid) {
602/// Is the current user currently moving an activity?
603 global $USER;
604
605 if (!empty($USER->activitycopy)) {
606 return ($USER->activitycopycourse == $courseid);
607 }
608 return false;
609}
610
e2cd5065 611function fullname($user, $override=false) {
b5cbb64d 612/// Given an object containing firstname and lastname
613/// values, this function returns a string with the
614/// full name of the person.
e2cd5065 615/// The result may depend on system settings
b5cbb64d 616/// or language. 'override' will force both names
e2cd5065 617/// to be used even if system settings specify one.
b5cbb64d 618
f374fb10 619 global $CFG, $SESSION;
620
621 if (!empty($SESSION->fullnamedisplay)) {
622 $CFG->fullnamedisplay = $SESSION->fullnamedisplay;
623 }
e2cd5065 624
b5cbb64d 625 if ($CFG->fullnamedisplay == 'firstname lastname') {
626 return "$user->firstname $user->lastname";
627
628 } else if ($CFG->fullnamedisplay == 'lastname firstname') {
629 return "$user->lastname $user->firstname";
e2cd5065 630
b5cbb64d 631 } else if ($CFG->fullnamedisplay == 'firstname') {
632 if ($override) {
633 return get_string('fullnamedisplay', '', $user);
634 } else {
635 return $user->firstname;
636 }
637 }
e2cd5065 638
b5cbb64d 639 return get_string('fullnamedisplay', '', $user);
e2cd5065 640}
641
f9903ed0 642
643function set_moodle_cookie($thing) {
9fa49e22 644/// Sets a moodle cookie with an encrypted string
7185e073 645 global $CFG;
482b6e6e 646
647 $cookiename = 'MOODLEID_'.$CFG->sessioncookie;
f9903ed0 648
649 $days = 60;
650 $seconds = 60*60*24*$days;
651
7185e073 652 setCookie($cookiename, "", time() - 3600, "/");
653 setCookie($cookiename, rc4encrypt($thing), time()+$seconds, "/");
f9903ed0 654}
655
656
657function get_moodle_cookie() {
9fa49e22 658/// Gets a moodle cookie with an encrypted string
7185e073 659 global $CFG;
660
482b6e6e 661 $cookiename = 'MOODLEID_'.$CFG->sessioncookie;
7185e073 662
1079c8a8 663 if (empty($_COOKIE[$cookiename])) {
664 return "";
665 } else {
666 return rc4decrypt($_COOKIE[$cookiename]);
667 }
f9903ed0 668}
669
ba7166c3 670function is_internal_auth() {
671/// Returns true if an internal authentication method is being used.
672
673 global $CFG;
674
675 return ($CFG->auth == "email" || $CFG->auth == "none" || $CFG->auth == "manual");
676}
f9903ed0 677
faebaf0f 678function create_user_record($username, $password) {
9fa49e22 679/// Creates a bare-bones user record
e858f9da 680 global $REMOTE_ADDR, $CFG;
1e22bc9c 681 //just in case check text case
682 $username = trim(moodle_strtolower($username));
6ae24de0 683 if (function_exists(auth_get_userinfo)) {
e858f9da 684 if ($newinfo = auth_get_userinfo($username)) {
34daec9b 685 foreach ($newinfo as $key => $value){
9f44d972 686 $newuser->$key = addslashes(stripslashes($value)); // Just in case
e858f9da 687 }
688 }
689 }
f9903ed0 690
faebaf0f 691 $newuser->username = $username;
692 $newuser->password = md5($password);
a0bac19d 693 $newuser->lang = $CFG->lang;
faebaf0f 694 $newuser->confirmed = 1;
695 $newuser->lastIP = $REMOTE_ADDR;
696 $newuser->timemodified = time();
f9903ed0 697
faebaf0f 698 if (insert_record("user", $newuser)) {
699 return get_user_info_from_db("username", $username);
700 }
701 return false;
702}
703
0609562b 704
705function guest_user() {
706 global $CFG;
707
708 if ($newuser = get_record("user", "username", "guest")) {
709 $newuser->loggedin = true;
710 $newuser->confirmed = 1;
711 $newuser->site = $CFG->wwwroot;
712 $newuser->lang = $CFG->lang;
713 }
714
715 return $newuser;
716}
717
faebaf0f 718function authenticate_user_login($username, $password) {
9fa49e22 719/// Given a username and password, this function looks them
720/// up using the currently selected authentication mechanism,
721/// and if the authentication is successful, it returns a
722/// valid $user object from the 'user' table.
723///
724/// Uses auth_ functions from the currently active auth module
faebaf0f 725
726 global $CFG;
727
466558e3 728 $md5password = md5($password);
729
14217044 730 if (empty($CFG->auth)) {
faebaf0f 731 $CFG->auth = "email"; // Default authentication module
732 }
733
466558e3 734 if ($username == "guest") {
735 $CFG->auth = "none"; // Guest account always internal
736 }
737
738 // If this is the admin, then just use internal methods
92710226 739 // Doing this first (even though it's less efficient) because
740 // the chosen authentication method might hang and lock the
741 // admin out.
9fa49e22 742 if (adminlogin($username, $md5password)) {
466558e3 743 return get_user_info_from_db("username", $username);
744 }
745
92710226 746 // OK, the user is a normal user, so try and authenticate them
e858f9da 747 require_once("$CFG->dirroot/auth/$CFG->auth/lib.php");
faebaf0f 748
749 if (auth_user_login($username, $password)) { // Successful authentication
faebaf0f 750 if ($user = get_user_info_from_db("username", $username)) {
92710226 751 if ($md5password <> $user->password) { // Update local copy of password for reference
466558e3 752 set_field("user", "password", $md5password, "username", $username);
faebaf0f 753 }
faebaf0f 754 } else {
e582b65e 755 $user = create_user_record($username, $password);
faebaf0f 756 }
89b54325 757
e582b65e 758 if (function_exists('auth_iscreator')) { // Check if the user is a creator
759 if (auth_iscreator($username)) {
760 if (! record_exists("user_coursecreators", "userid", $user->id)) {
761 $cdata['userid']=$user->id;
762 $creator = insert_record("user_coursecreators",$cdata);
763 if (! $creator) {
764 error("Cannot add user to course creators.");
765 }
766 }
767 } else {
768 if ( record_exists("user_coursecreators", "userid", $user->id)) {
f5cdd4d1 769 $creator = delete_records("user_coursecreators", "userid", $user->id);
e582b65e 770 if (! $creator) {
771 error("Cannot remove user from course creators.");
772 }
773 }
774 }
775 }
776
777 return $user;
778 } else {
779 return false;
780 }
f9903ed0 781}
782
4d312bbe 783function enrol_student($userid, $courseid) {
9fa49e22 784/// Enrols a student in a given course
f9903ed0 785
4d312bbe 786 if (!record_exists("user_students", "userid", $userid, "course", $courseid)) {
3041b0f8 787 if (record_exists("user", "id", $userid)) {
788 $student->userid = $userid;
789 $student->course = $courseid;
790 $student->start = 0;
791 $student->end = 0;
792 $student->time = time();
793 return insert_record("user_students", $student);
794 }
795 return false;
4d312bbe 796 }
797 return true;
d7facad8 798}
799
9fa62805 800function unenrol_student($userid, $courseid=0) {
9fa49e22 801/// Unenrols a student from a given course
d7facad8 802
9fa62805 803 if ($courseid) {
9fa49e22 804 /// First delete any crucial stuff that might still send mail
9fa62805 805 if ($forums = get_records("forum", "course", $courseid)) {
9fa49e22 806 foreach ($forums as $forum) {
9fa62805 807 delete_records("forum_subscriptions", "forum", $forum->id, "userid", $userid);
808 }
809 }
810 if ($groups = get_groups($courseid, $userid)) {
811 foreach ($groups as $group) {
812 delete_records("groups_members", "groupid", $group->id, "userid", $userid);
bb09fb11 813 }
f9903ed0 814 }
9fa62805 815 return delete_records("user_students", "userid", $userid, "course", $courseid);
9fa49e22 816
f9903ed0 817 } else {
9fa62805 818 delete_records("forum_subscriptions", "userid", $userid);
819 return delete_records("user_students", "userid", $userid);
f9903ed0 820 }
821}
822
3041b0f8 823function add_teacher($userid, $courseid) {
824/// Add a teacher to a given course
825
826 if (!record_exists("user_teachers", "userid", $userid, "course", $courseid)) {
827 if (record_exists("user", "id", $userid)) {
828 $teacher->userid = $userid;
829 $teacher->course = $courseid;
830 $teacher->editall = 1;
831 $teacher->role = "";
832 if (record_exists("user_teachers", "course", $courseid)) {
833 $teacher->authority = 2;
834 } else {
835 $teacher->authority = 1;
836 }
bb8c3631 837 delete_records("user_students", "userid", $userid, "course", $courseid); // Unenrol as student
838
3041b0f8 839 return insert_record("user_teachers", $teacher);
840 }
841 return false;
842 }
843 return true;
844}
845
846function remove_teacher($userid, $courseid=0) {
9fa49e22 847/// Removes a teacher from a given course (or ALL courses)
848/// Does not delete the user account
3041b0f8 849 if ($courseid) {
9fa49e22 850 /// First delete any crucial stuff that might still send mail
3041b0f8 851 if ($forums = get_records("forum", "course", $courseid)) {
9fa49e22 852 foreach ($forums as $forum) {
3041b0f8 853 delete_records("forum_subscriptions", "forum", $forum->id, "userid", $userid);
9fa49e22 854 }
855 }
3041b0f8 856 return delete_records("user_teachers", "userid", $userid, "course", $courseid);
57507290 857 } else {
3041b0f8 858 delete_records("forum_subscriptions", "userid", $userid);
859 return delete_records("user_teachers", "userid", $userid);
57507290 860 }
f9903ed0 861}
862
3041b0f8 863
864function add_creator($userid) {
865/// Add a creator to the site
866
867 if (!record_exists("user_admins", "userid", $userid)) {
868 if (record_exists("user", "id", $userid)) {
869 $creator->userid = $userid;
870 return insert_record("user_coursecreators", $creator);
871 }
872 return false;
873 }
874 return true;
875}
876
877function remove_creator($userid) {
878/// Removes a creator from a site
879 global $db;
880
881 return delete_records("user_coursecreators", "userid", $userid);
882}
883
884function add_admin($userid) {
885/// Add an admin to the site
886
887 if (!record_exists("user_admins", "userid", $userid)) {
888 if (record_exists("user", "id", $userid)) {
889 $admin->userid = $userid;
890 return insert_record("user_admins", $admin);
891 }
892 return false;
893 }
894 return true;
895}
896
897function remove_admin($userid) {
9fa49e22 898/// Removes an admin from a site
899 global $db;
f9903ed0 900
3041b0f8 901 return delete_records("user_admins", "userid", $userid);
f9903ed0 902}
903
f9903ed0 904
07aeb7b0 905function remove_course_contents($courseid, $showfeedback=true) {
906/// Clear a course out completely, deleting all content
907/// but don't delete the course itself
908
ee23f384 909 global $CFG, $THEME, $USER, $SESSION;
07aeb7b0 910
911 $result = true;
912
913 if (! $course = get_record("course", "id", $courseid)) {
914 error("Course ID was incorrect (can't find it)");
915 }
916
917 $strdeleted = get_string("deleted");
918
919 // First delete every instance of every module
920
921 if ($allmods = get_records("modules") ) {
922 foreach ($allmods as $mod) {
923 $modname = $mod->name;
924 $modfile = "$CFG->dirroot/mod/$modname/lib.php";
ca952b03 925 $moddelete = $modname."_delete_instance"; // Delete everything connected to an instance
926 $moddeletecourse = $modname."_delete_course"; // Delete other stray stuff (uncommon)
07aeb7b0 927 $count=0;
928 if (file_exists($modfile)) {
929 include_once($modfile);
930 if (function_exists($moddelete)) {
931 if ($instances = get_records($modname, "course", $course->id)) {
932 foreach ($instances as $instance) {
933 if ($moddelete($instance->id)) {
934 $count++;
935 } else {
936 notify("Could not delete $modname instance $instance->id ($instance->name)");
937 $result = false;
938 }
939 }
940 }
941 } else {
942 notify("Function $moddelete() doesn't exist!");
943 $result = false;
944 }
945
ca952b03 946 if (function_exists($moddeletecourse)) {
947 $moddeletecourse($course);
948 }
07aeb7b0 949 }
950 if ($showfeedback) {
951 notify("$strdeleted $count x $modname");
952 }
953 }
954 } else {
955 error("No modules are installed!");
956 }
957
958 // Delete any user stuff
959
960 if (delete_records("user_students", "course", $course->id)) {
961 if ($showfeedback) {
962 notify("$strdeleted user_students");
963 }
964 } else {
965 $result = false;
966 }
967
968 if (delete_records("user_teachers", "course", $course->id)) {
969 if ($showfeedback) {
970 notify("$strdeleted user_teachers");
971 }
972 } else {
973 $result = false;
974 }
975
082e3ebc 976 // Delete any groups
977
978 if ($groups = get_records("groups", "courseid", $course->id)) {
979 foreach ($groups as $group) {
980 if (delete_records("groups_members", "groupid", $group->id)) {
981 if ($showfeedback) {
982 notify("$strdeleted groups_members");
983 }
984 } else {
985 $result = false;
986 }
987 if (delete_records("groups", "id", $group->id)) {
988 if ($showfeedback) {
989 notify("$strdeleted groups");
990 }
991 } else {
992 $result = false;
993 }
994 }
995 }
996
997 // Delete events
998
999 if (delete_records("event", "courseid", $course->id)) {
1000 if ($showfeedback) {
1001 notify("$strdeleted event");
1002 }
1003 } else {
1004 $result = false;
1005 }
1006
07aeb7b0 1007 // Delete logs
1008
1009 if (delete_records("log", "course", $course->id)) {
1010 if ($showfeedback) {
1011 notify("$strdeleted log");
1012 }
1013 } else {
1014 $result = false;
1015 }
1016
1017 // Delete any course stuff
1018
1019 if (delete_records("course_sections", "course", $course->id)) {
1020 if ($showfeedback) {
1021 notify("$strdeleted course_sections");
1022 }
1023 } else {
1024 $result = false;
1025 }
1026
1027 if (delete_records("course_modules", "course", $course->id)) {
1028 if ($showfeedback) {
1029 notify("$strdeleted course_modules");
1030 }
1031 } else {
1032 $result = false;
1033 }
1034
1035 return $result;
1036
1037}
1038
f9903ed0 1039
f374fb10 1040/// GROUPS /////////////////////////////////////////////////////////
0d67c514 1041
f374fb10 1042
1043/**
1044* Returns a boolean: is the user a member of the given group?
1045*
1046* @param type description
1047*/
1048function ismember($groupid, $userid=0) {
1049 global $USER;
1050
8a2c9076 1051 if (!$groupid) { // No point doing further checks
1052 return false;
1053 }
1054
f374fb10 1055 if (!$userid) {
0d67c514 1056 if (empty($USER->groupmember)) {
1057 return false;
1058 }
1059 foreach ($USER->groupmember as $courseid => $mgroupid) {
1060 if ($mgroupid == $groupid) {
1061 return true;
1062 }
1063 }
1064 return false;
f374fb10 1065 }
1066
0da33e07 1067 return record_exists("groups_members", "groupid", $groupid, "userid", $userid);
f374fb10 1068}
1069
0d67c514 1070/**
1071* Returns the group ID of the current user in the given course
1072*
1073* @param type description
1074*/
1075function mygroupid($courseid) {
1076 global $USER;
1077
1078 if (empty($USER->groupmember[$courseid])) {
1079 return 0;
1080 } else {
1081 return $USER->groupmember[$courseid];
1082 }
1083}
1084
f374fb10 1085/**
1086* For a given course, and possibly course module, determine
1087* what the current default groupmode is:
1088* NOGROUPS, SEPARATEGROUPS or VISIBLEGROUPS
1089*
1090* @param type description
1091*/
1092function groupmode($course, $cm=null) {
1093
1094 if ($cm and !$course->groupmodeforce) {
1095 return $cm->groupmode;
1096 }
1097 return $course->groupmode;
1098}
1099
1100
1101/**
1102* Sets the current group in the session variable
1103*
1104* @param type description
1105*/
1106function set_current_group($courseid, $groupid) {
1107 global $SESSION;
1108
1109 return $SESSION->currentgroup[$courseid] = $groupid;
1110}
1111
1112
1113/**
1114* Gets the current group for the current user as an id or an object
1115*
1116* @param type description
1117*/
1118function get_current_group($courseid, $full=false) {
1119 global $SESSION, $USER;
1120
1121 if (empty($SESSION->currentgroup[$courseid])) {
1122 if (empty($USER->groupmember[$courseid])) {
8a2c9076 1123 return 0;
f374fb10 1124 } else {
1125 $SESSION->currentgroup[$courseid] = $USER->groupmember[$courseid];
1126 }
1127 }
1128
1129 if ($full) {
0da33e07 1130 return get_record('groups', 'id', $SESSION->currentgroup[$courseid]);
f374fb10 1131 } else {
1132 return $SESSION->currentgroup[$courseid];
1133 }
1134}
1135
0d67c514 1136/**
1137* A combination function to make it easier for modules
1138* to set up groups.
1139*
1140* It will use a given "groupid" parameter and try to use
1141* that to reset the current group for the user.
1142*
1143* @param type description
1144*/
1145function get_and_set_current_group($course, $groupmode, $groupid=0) {
1146
1147 if (!$groupmode) { // Groups don't even apply
1148 return false;
1149 }
1150
1151 $currentgroupid = get_current_group($course->id);
1152
1153 if ($groupid) { // Try to change the current group
1154 if ($group = get_record('groups', 'id', $groupid, 'courseid', $course->id)) { // Exists
1155 if (isteacheredit($course->id)) { // Sets current default group
1156 $currentgroupid = set_current_group($course->id, $group->id);
1157
1158 } else if ($groupmode == VISIBLEGROUPS) { // All groups are visible
1159 $currentgroupid = $group->id;
1160 }
1161 }
1162 }
1163
1164 return $currentgroupid;
1165}
1166
1167
1168
f374fb10 1169
1170
f9903ed0 1171/// CORRESPONDENCE ////////////////////////////////////////////////
1172
5fa51a39 1173function email_to_user($user, $from, $subject, $messagetext, $messagehtml="", $attachment="", $attachname="") {
9fa49e22 1174/// user - a user record as an object
1175/// from - a user record as an object
1176/// subject - plain text subject line of the email
1177/// messagetext - plain text version of the message
1178/// messagehtml - complete html version of the message (optional)
1179/// attachment - a file on the filesystem, relative to $CFG->dataroot
1180/// attachname - the name of the file (extension indicates MIME)
f9903ed0 1181
4216daa6 1182 global $CFG, $_SERVER;
f9903ed0 1183
0cc6fa6a 1184 global $course; // This is a bit of an ugly hack to be gotten rid of later
1185 if (!empty($course->lang)) { // Course language is defined
1186 $CFG->courselang = $course->lang;
1187 }
1188
136dabd8 1189 include_once("$CFG->libdir/phpmailer/class.phpmailer.php");
f9903ed0 1190
5fa51a39 1191 if (!$user) {
f9903ed0 1192 return false;
1193 }
1194
f9903ed0 1195 $mail = new phpmailer;
1196
72c578ca 1197 $mail->Version = "Moodle $CFG->version"; // mailer version
136dabd8 1198 $mail->PluginDir = "$CFG->libdir/phpmailer/"; // plugin directory (eg smtp plugin)
562bbe90 1199
98c4eae3 1200
d483bcd3 1201 if (current_language() != "en") {
1202 $mail->CharSet = get_string("thischarset");
98c4eae3 1203 }
1204
62740736 1205 if ($CFG->smtphosts == "qmail") {
1206 $mail->IsQmail(); // use Qmail system
1207
1208 } else if (empty($CFG->smtphosts)) {
1209 $mail->IsMail(); // use PHP mail() = sendmail
1210
1211 } else {
1e411ffc 1212 $mail->IsSMTP(); // use SMTP directly
57ef3480 1213 if ($CFG->debug > 7) {
1214 echo "<pre>\n";
1215 $mail->SMTPDebug = true;
1216 }
1e411ffc 1217 $mail->Host = "$CFG->smtphosts"; // specify main and backup servers
9f58537a 1218
1219 if ($CFG->smtpuser) { // Use SMTP authentication
1220 $mail->SMTPAuth = true;
1221 $mail->Username = $CFG->smtpuser;
1222 $mail->Password = $CFG->smtppass;
1223 }
7f86ce17 1224 }
f9903ed0 1225
2b97bd71 1226 $adminuser = get_admin();
1227
1228 $mail->Sender = "$adminuser->email";
1229
136dabd8 1230 $mail->From = "$from->email";
0b4c5822 1231 $mail->FromName = fullname($from);
136dabd8 1232 $mail->Subject = stripslashes($subject);
f9903ed0 1233
0b4c5822 1234 $mail->AddAddress("$user->email", fullname($user) );
f9903ed0 1235
f9903ed0 1236 $mail->WordWrap = 70; // set word wrap
f9903ed0 1237
136dabd8 1238 if ($messagehtml) {
1239 $mail->IsHTML(true);
125898af 1240 $mail->Encoding = "quoted-printable"; // Encoding to use
136dabd8 1241 $mail->Body = $messagehtml;
78681899 1242 $mail->AltBody = "\n$messagetext\n";
136dabd8 1243 } else {
1244 $mail->IsHTML(false);
78681899 1245 $mail->Body = "\n$messagetext\n";
f9903ed0 1246 }
1247
136dabd8 1248 if ($attachment && $attachname) {
1249 if (ereg( "\\.\\." ,$attachment )) { // Security check for ".." in dir path
0b4c5822 1250 $mail->AddAddress("$adminuser->email", fullname($adminuser) );
4216daa6 1251 $mail->AddStringAttachment("Error in attachment. User attempted to attach a filename with a unsafe name.", "error.txt", "8bit", "text/plain");
136dabd8 1252 } else {
1253 include_once("$CFG->dirroot/files/mimetypes.php");
1254 $mimetype = mimeinfo("type", $attachname);
1255 $mail->AddAttachment("$CFG->dataroot/$attachment", "$attachname", "base64", "$mimetype");
1256 }
f9903ed0 1257 }
1258
136dabd8 1259 if ($mail->Send()) {
1260 return true;
1261 } else {
4216daa6 1262 echo "ERROR: $mail->ErrorInfo\n";
1263 $site = get_site();
1264 add_to_log($site->id, "library", "mailer", $_SERVER["REQUEST_URI"], "ERROR: $mail->ErrorInfo");
f9903ed0 1265 return false;
1266 }
f9903ed0 1267}
1268
1d881d92 1269function reset_password_and_mail($user) {
1270
1271 global $CFG;
1272
1273 $site = get_site();
1274 $from = get_admin();
1275
1276 $newpassword = generate_password();
1277
1278 if (! set_field("user", "password", md5($newpassword), "id", $user->id) ) {
1279 error("Could not set user password!");
1280 }
1281
1282 $a->firstname = $user->firstname;
1283 $a->sitename = $site->fullname;
1284 $a->username = $user->username;
1285 $a->newpassword = $newpassword;
1286 $a->link = "$CFG->wwwroot/login/change_password.php";
0b4c5822 1287 $a->signoff = fullname($from, true)." ($from->email)";
1d881d92 1288
1289 $message = get_string("newpasswordtext", "", $a);
1290
1291 $subject = "$site->fullname: ".get_string("changedpassword");
1292
1293 return email_to_user($user, $from, $subject, $message);
1294
1295}
1296
1297function send_confirmation_email($user) {
1298
1299 global $CFG;
1300
1301 $site = get_site();
1302 $from = get_admin();
1303
1304 $data->firstname = $user->firstname;
1305 $data->sitename = $site->fullname;
1306 $data->link = "$CFG->wwwroot/login/confirm.php?p=$user->secret&s=$user->username";
0b4c5822 1307 $data->admin = fullname($from)." ($from->email)";
1d881d92 1308
1309 $message = get_string("emailconfirmation", "", $data);
eb347b6b 1310 $subject = get_string("emailconfirmationsubject", "", $site->fullname);
1d881d92 1311
1312 return email_to_user($user, $from, $subject, $message);
1313
1314}
1315
eb347b6b 1316function send_password_change_confirmation_email($user) {
1317
1318 global $CFG;
1319
1320 $site = get_site();
1321 $from = get_admin();
1322
1323 $data->firstname = $user->firstname;
1324 $data->sitename = $site->fullname;
1325 $data->link = "$CFG->wwwroot/login/forgot_password.php?p=$user->secret&s=$user->username";
0b4c5822 1326 $data->admin = fullname($from)." ($from->email)";
eb347b6b 1327
1328 $message = get_string("emailpasswordconfirmation", "", $data);
1329 $subject = get_string("emailpasswordconfirmationsubject", "", $site->fullname);
1330
1331 return email_to_user($user, $from, $subject, $message);
1332
1333}
1334
1335
1d881d92 1336
136dabd8 1337
f9903ed0 1338/// FILE HANDLING /////////////////////////////////////////////
1339
6b174680 1340function make_upload_directory($directory) {
9fa49e22 1341/// $directory = a string of directory names under $CFG->dataroot
1342/// eg stuff/assignment/1
1343/// Returns full directory if successful, false if not
6b174680 1344
1345 global $CFG;
1346
1347 $currdir = $CFG->dataroot;
fe287429 1348
2e6d4273 1349 umask(0000);
1350
6b174680 1351 if (!file_exists($currdir)) {
2e6d4273 1352 if (! mkdir($currdir, $CFG->directorypermissions)) {
6b174680 1353 notify("ERROR: You need to create the directory $currdir with web server write access");
1354 return false;
1355 }
1356 }
1357
1358 $dirarray = explode("/", $directory);
1359
1360 foreach ($dirarray as $dir) {
1361 $currdir = "$currdir/$dir";
1362 if (! file_exists($currdir)) {
2e6d4273 1363 if (! mkdir($currdir, $CFG->directorypermissions)) {
6b174680 1364 notify("ERROR: Could not find or create a directory ($currdir)");
1365 return false;
1366 }
feffa4e6 1367 @chmod($currdir, $CFG->directorypermissions); // Just in case mkdir didn't do it
6b174680 1368 }
1369 }
1370
1371 return $currdir;
1372}
1373
ca4f8eb8 1374function make_mod_upload_directory($courseid) {
9fa49e22 1375/// Makes an upload directory for a particular module
ca4f8eb8 1376 global $CFG;
1377
1378 if (! $moddata = make_upload_directory("$courseid/$CFG->moddata")) {
1379 return false;
1380 }
1381
1382 $strreadme = get_string("readme");
1383
1384 if (file_exists("$CFG->dirroot/lang/$CFG->lang/docs/module_files.txt")) {
1385 copy("$CFG->dirroot/lang/$CFG->lang/docs/module_files.txt", "$moddata/$strreadme.txt");
1386 } else {
1387 copy("$CFG->dirroot/lang/en/docs/module_files.txt", "$moddata/$strreadme.txt");
1388 }
1389 return $moddata;
1390}
1391
6b174680 1392
44e2d2bb 1393function valid_uploaded_file($newfile) {
9fa49e22 1394/// Returns current name of file on disk if true
9c9f7d77 1395 if (empty($newfile)) {
1396 return "";
1397 }
44e2d2bb 1398 if (is_uploaded_file($newfile['tmp_name']) and $newfile['size'] > 0) {
1399 return $newfile['tmp_name'];
1400 } else {
1401 return "";
1402 }
1403}
1404
4909e176 1405function get_max_upload_file_size($sitebytes=0, $coursebytes=0, $modulebytes=0) {
9fa49e22 1406/// Returns the maximum size for uploading files
316ebf78 1407/// There are seven possible upload limits:
4909e176 1408///
1409/// 1) in Apache using LimitRequestBody (no way of checking or changing this)
1410/// 2) in php.ini for 'upload_max_filesize' (can not be changed inside PHP)
1411/// 3) in .htaccess for 'upload_max_filesize' (can not be changed inside PHP)
316ebf78 1412/// 4) in php.ini for 'post_max_size' (can not be changed inside PHP)
1413/// 5) by the Moodle admin in $CFG->maxbytes
1414/// 6) by the teacher in the current course $course->maxbytes
1415/// 7) by the teacher for the current module, eg $assignment->maxbytes
4909e176 1416///
1417/// These last two are passed to this function as arguments (in bytes).
1418/// Anything defined as 0 is ignored.
1419/// The smallest of all the non-zero numbers is returned.
1420
44e2d2bb 1421 if (! $filesize = ini_get("upload_max_filesize")) {
1422 $filesize = "5M";
1423 }
4909e176 1424 $minimumsize = get_real_size($filesize);
1425
316ebf78 1426 if ($postsize = ini_get("post_max_size")) {
1427 $postsize = get_real_size($postsize);
1428 if ($postsize < $minimumsize) {
1429 $minimumsize = $postsize;
1430 }
1431 }
1432
4909e176 1433 if ($sitebytes and $sitebytes < $minimumsize) {
1434 $minimumsize = $sitebytes;
1435 }
1436
1437 if ($coursebytes and $coursebytes < $minimumsize) {
1438 $minimumsize = $coursebytes;
1439 }
1440
1441 if ($modulebytes and $modulebytes < $minimumsize) {
1442 $minimumsize = $modulebytes;
1443 }
1444
1445 return $minimumsize;
1446}
1447
1448function get_max_upload_sizes($sitebytes=0, $coursebytes=0, $modulebytes=0) {
1449/// Related to the above function - this function returns an
1450/// array of possible sizes in an array, translated to the
1451/// local language.
1452
1453 if (!$maxsize = get_max_upload_file_size($sitebytes, $coursebytes, $modulebytes)) {
1454 return array();
1455 }
1456
1457 $filesize[$maxsize] = display_size($maxsize);
1458
1459 $sizelist = array(10240, 51200, 102400, 512000, 1048576, 2097152,
1460 5242880, 10485760, 20971520, 52428800, 104857600);
1461
1462 foreach ($sizelist as $sizebytes) {
1463 if ($sizebytes < $maxsize) {
1464 $filesize[$sizebytes] = display_size($sizebytes);
1465 }
1466 }
1467
1468 krsort($filesize, SORT_NUMERIC);
1469
1470 return $filesize;
44e2d2bb 1471}
1472
774ab660 1473function get_directory_list($rootdir, $excludefile="", $descend=true) {
9fa49e22 1474/// Returns an array with all the filenames in
1475/// all subdirectories, relative to the given rootdir.
1476/// If excludefile is defined, then that file/directory is ignored
f9903ed0 1477
1478 $dirs = array();
f9903ed0 1479
12407705 1480 if (!is_dir($rootdir)) {
1481 return $dirs;
1482 }
1483
487c1711 1484 if (!$dir = opendir($rootdir)) {
d897cae4 1485 return $dirs;
1486 }
1487
ca4f8eb8 1488 while ($file = readdir($dir)) {
b35e8568 1489 $firstchar = substr($file, 0, 1);
1490 if ($firstchar == "." or $file == "CVS" or $file == $excludefile) {
1491 continue;
1492 }
1493 $fullfile = $rootdir."/".$file;
1494 if ($descend and filetype($fullfile) == "dir") {
1495 $subdirs = get_directory_list($fullfile, $excludefile, $descend);
1496 foreach ($subdirs as $subdir) {
1497 $dirs[] = $file."/".$subdir;
f9903ed0 1498 }
b35e8568 1499 } else {
1500 $dirs[] = $file;
f9903ed0 1501 }
1502 }
44e2d2bb 1503 closedir($dir);
f9903ed0 1504
774ab660 1505 asort($dirs);
1506
f9903ed0 1507 return $dirs;
1508}
1509
989bfa9d 1510function get_real_size($size=0) {
9fa49e22 1511/// Converts numbers like 10M into bytes
989bfa9d 1512 if (!$size) {
1513 return 0;
1514 }
1515 $scan['MB'] = 1048576;
64efda84 1516 $scan['Mb'] = 1048576;
989bfa9d 1517 $scan['M'] = 1048576;
266a416e 1518 $scan['m'] = 1048576;
989bfa9d 1519 $scan['KB'] = 1024;
64efda84 1520 $scan['Kb'] = 1024;
989bfa9d 1521 $scan['K'] = 1024;
266a416e 1522 $scan['k'] = 1024;
989bfa9d 1523
1524 while (list($key) = each($scan)) {
1525 if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) {
1526 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
1527 break;
1528 }
1529 }
1530 return $size;
1531}
1532
44e2d2bb 1533function display_size($size) {
9fa49e22 1534/// Converts bytes into display form
4909e176 1535
1536 static $gb,$mb,$kb,$b;
1537
1538 if (empty($gb)) {
1539 $gb = get_string('sizegb');
1540 $mb = get_string('sizemb');
1541 $kb = get_string('sizekb');
1542 $b = get_string('sizeb');
1543 }
1544
44e2d2bb 1545 if ($size >= 1073741824) {
4909e176 1546 $size = round($size / 1073741824 * 10) / 10 . $gb;
44e2d2bb 1547 } else if ($size >= 1048576) {
4909e176 1548 $size = round($size / 1048576 * 10) / 10 . $mb;
44e2d2bb 1549 } else if ($size >= 1024) {
4909e176 1550 $size = round($size / 1024 * 10) / 10 . $kb;
44e2d2bb 1551 } else {
4909e176 1552 $size = $size ." $b";
44e2d2bb 1553 }
1554 return $size;
1555}
1556
6b174680 1557function clean_filename($string) {
9fa49e22 1558/// Cleans a given filename by removing suspicious or troublesome characters
fc05fccb 1559 $string = stripslashes($string);
6b174680 1560 $string = eregi_replace("\.\.", "", $string);
5c219ea4 1561 $string = eregi_replace("[^(-|[:alnum:]|\.)]", "_", $string);
e9f3e715 1562 $string = eregi_replace(",", "_", $string);
6b174680 1563 return eregi_replace("_+", "_", $string);
1564}
1565
1566
1180c6dc 1567/// STRING TRANSLATION ////////////////////////////////////////
1568
4bfa92e7 1569function current_language() {
9fa49e22 1570/// Returns the code for the current language
3db3acfb 1571 global $CFG, $USER, $SESSION;
4bfa92e7 1572
b3153e4b 1573 if (isset($CFG->courselang)) { // Course language can override all other settings for this page
1574 return $CFG->courselang;
1575
1576 } else if (isset($SESSION->lang)) { // Session language can override other settings
3db3acfb 1577 return $SESSION->lang;
1578
1579 } else if (isset($USER->lang)) { // User language can override site language
4bfa92e7 1580 return $USER->lang;
3db3acfb 1581
4bfa92e7 1582 } else {
1583 return $CFG->lang;
1584 }
1585}
bcc83c41 1586
9fa49e22 1587function print_string($identifier, $module="", $a=NULL) {
1588/// Given a string to translate - prints it out.
1589 echo get_string($identifier, $module, $a);
1590}
1591
a83fded1 1592function get_string($identifier, $module="", $a=NULL) {
9fa49e22 1593/// Return the translated string specified by $identifier as
1594/// for $module. Uses the same format files as STphp.
1595/// $a is an object, string or number that can be used
1596/// within translation strings
1597///
1598/// eg "hello \$a->firstname \$a->lastname"
1599/// or "hello \$a"
1180c6dc 1600
4bfa92e7 1601 global $CFG;
1180c6dc 1602
e11dc9b6 1603 global $course; /// Not a nice hack, but quick
1604 if (!empty($course->lang)) {
1605 $CFG->courselang = $course->lang;
1606 }
1607
4bfa92e7 1608 $lang = current_language();
1180c6dc 1609
058eec18 1610 if ($module == "") {
1611 $module = "moodle";
1180c6dc 1612 }
1613
058eec18 1614 $langpath = "$CFG->dirroot/lang";
1615 $langfile = "$langpath/$lang/$module.php";
1180c6dc 1616
b947c69a 1617 // Look for the string - if found then return it
1618
1619 if (file_exists($langfile)) {
1620 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1621 eval($result);
1622 return $resultstring;
1180c6dc 1623 }
1624 }
1625
b947c69a 1626 // If the preferred language was English we can abort now
1180c6dc 1627
b947c69a 1628 if ($lang == "en") {
1629 return "[[$identifier]]";
1630 }
1180c6dc 1631
b947c69a 1632 // Is a parent language defined? If so, try it.
1633
1634 if ($result = get_string_from_file("parentlanguage", "$langpath/$lang/moodle.php", "\$parentlang")) {
1635 eval($result);
1636 if (!empty($parentlang)) {
1637 $langfile = "$langpath/$parentlang/$module.php";
1638 if (file_exists($langfile)) {
1639 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1640 eval($result);
1641 return $resultstring;
1642 }
1180c6dc 1643 }
1644 }
1645 }
b947c69a 1646
1647 // Our only remaining option is to try English
1648
1649 $langfile = "$langpath/en/$module.php";
1650 if (!file_exists($langfile)) {
1651 return "ERROR: No lang file ($langpath/en/$module.php)!";
1652 }
1653 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1654 eval($result);
1655 return $resultstring;
1656 }
1657
1658 return "[[$identifier]]"; // Last resort
1180c6dc 1659}
1660
1661
1180c6dc 1662function get_string_from_file($identifier, $langfile, $destination) {
9fa49e22 1663/// This function is only used from get_string().
2b32bddd 1664
1665 static $strings; // Keep the strings cached in memory.
1666
1667 if (empty($strings[$langfile])) {
1668 include ($langfile);
1669 $strings[$langfile] = $string;
1670 } else {
1671 $string = &$strings[$langfile];
1672 }
1180c6dc 1673
1674 if (!isset ($string[$identifier])) {
1675 return false;
1676 }
1677
a83fded1 1678 return "$destination = sprintf(\"".$string[$identifier]."\");";
1180c6dc 1679}
f9903ed0 1680
1681
1a72314d 1682function get_list_of_languages() {
1683/// Returns a list of language codes and their full names
1684 global $CFG;
1685
984a8bf3 1686 $languages = array();
1687
1688 if (!empty($CFG->langlist)) { // use admin's list of languages
1689 $langlist = explode(',', $CFG->langlist);
1690 foreach ($langlist as $lang) {
1691 if (file_exists("$CFG->dirroot/lang/$lang/moodle.php")) {
1692 include("$CFG->dirroot/lang/$lang/moodle.php");
1693 $languages[$lang] = $string["thislanguage"]." ($lang)";
1694 unset($string);
1695 }
1696 }
1697 } else {
1698 if (!$langdirs = get_list_of_plugins("lang")) {
1699 return false;
1700 }
1701 foreach ($langdirs as $lang) {
1702 include("$CFG->dirroot/lang/$lang/moodle.php");
1703 $languages[$lang] = $string["thislanguage"]." ($lang)";
1704 unset($string);
1705 }
1a72314d 1706 }
1707
1a72314d 1708 return $languages;
1709}
1710
5833a6c8 1711function get_list_of_countries() {
1712/// Returns a list of country names in the current language
1713 global $CFG, $USER;
1714
1715 $lang = current_language();
1716
1717 if (!file_exists("$CFG->dirroot/lang/$lang/countries.php")) {
aa3eb050 1718 if ($parentlang = get_string("parentlanguage")) {
1719 if (file_exists("$CFG->dirroot/lang/$parentlang/countries.php")) {
1720 $lang = $parentlang;
1721 } else {
1722 $lang = "en"; // countries.php must exist in this pack
1723 }
1724 } else {
1725 $lang = "en"; // countries.php must exist in this pack
1726 }
5833a6c8 1727 }
1728
0180f73f 1729 include("$CFG->dirroot/lang/$lang/countries.php");
5833a6c8 1730
f8dbffb1 1731 if (!empty($string)) {
1732 asort($string);
1733 }
5833a6c8 1734
1735 return $string;
1736}
1737
82196932 1738function get_list_of_pixnames() {
1739/// Returns a list of picture names in the current language
1740 global $CFG;
1741
1742 $lang = current_language();
1743
1744 if (!file_exists("$CFG->dirroot/lang/$lang/pix.php")) {
1745 if ($parentlang = get_string("parentlanguage")) {
1746 if (file_exists("$CFG->dirroot/lang/$parentlang/pix.php")) {
1747 $lang = $parentlang;
1748 } else {
1749 $lang = "en"; // countries.php must exist in this pack
1750 }
1751 } else {
1752 $lang = "en"; // countries.php must exist in this pack
1753 }
1754 }
1755
1756 include_once("$CFG->dirroot/lang/$lang/pix.php");
1757
1758 return $string;
1759}
1760
9bd2c874 1761function document_file($file, $include=true) {
1762/// Can include a given document file (depends on second
1763/// parameter) or just return info about it
1764
c9d4e6da 1765 global $CFG;
9bd2c874 1766
db356340 1767 $file = clean_filename($file);
1768
9bd2c874 1769 if (empty($file)) {
9bd2c874 1770 return false;
1771 }
1772
db356340 1773 $langs = array(current_language(), get_string("parentlanguage"), "en");
9bd2c874 1774
db356340 1775 foreach ($langs as $lang) {
1776 $info->filepath = "$CFG->dirroot/lang/$lang/docs/$file";
1777 $info->urlpath = "$CFG->wwwroot/lang/$lang/docs/$file";
9bd2c874 1778
db356340 1779 if (file_exists($info->filepath)) {
1780 if ($include) {
1781 include($info->filepath);
1782 }
1783 return $info;
0c106cd3 1784 }
9bd2c874 1785 }
1786
db356340 1787 return false;
9bd2c874 1788}
1789
1a72314d 1790
f9903ed0 1791/// ENCRYPTION ////////////////////////////////////////////////
1792
1793function rc4encrypt($data) {
1794 $password = "nfgjeingjk";
1795 return endecrypt($password, $data, "");
1796}
1797
1798function rc4decrypt($data) {
1799 $password = "nfgjeingjk";
1800 return endecrypt($password, $data, "de");
1801}
1802
1803function endecrypt ($pwd, $data, $case) {
9fa49e22 1804/// Based on a class by Mukul Sabharwal [mukulsabharwal@yahoo.com]
f9903ed0 1805
1806 if ($case == 'de') {
1807 $data = urldecode($data);
1808 }
1809
1810 $key[] = "";
1811 $box[] = "";
1812 $temp_swap = "";
1813 $pwd_length = 0;
1814
1815 $pwd_length = strlen($pwd);
1816
1817 for ($i = 0; $i <= 255; $i++) {
1818 $key[$i] = ord(substr($pwd, ($i % $pwd_length), 1));
1819 $box[$i] = $i;
1820 }
1821
1822 $x = 0;
1823
1824 for ($i = 0; $i <= 255; $i++) {
1825 $x = ($x + $box[$i] + $key[$i]) % 256;
1826 $temp_swap = $box[$i];
1827 $box[$i] = $box[$x];
1828 $box[$x] = $temp_swap;
1829 }
1830
1831 $temp = "";
1832 $k = "";
1833
1834 $cipherby = "";
1835 $cipher = "";
1836
1837 $a = 0;
1838 $j = 0;
1839
1840 for ($i = 0; $i < strlen($data); $i++) {
1841 $a = ($a + 1) % 256;
1842 $j = ($j + $box[$a]) % 256;
1843 $temp = $box[$a];
1844 $box[$a] = $box[$j];
1845 $box[$j] = $temp;
1846 $k = $box[(($box[$a] + $box[$j]) % 256)];
1847 $cipherby = ord(substr($data, $i, 1)) ^ $k;
1848 $cipher .= chr($cipherby);
1849 }
1850
1851 if ($case == 'de') {
1852 $cipher = urldecode(urlencode($cipher));
1853 } else {
1854 $cipher = urlencode($cipher);
1855 }
1856
1857 return $cipher;
1858}
1859
1860
5fba04fb 1861/// CALENDAR MANAGEMENT ////////////////////////////////////////////////////////////////
1862
1863
1864function add_event($event) {
1865/// call this function to add an event to the calendar table
1866/// and to call any calendar plugins
1867/// The function returns the id number of the resulting record
1868/// The object event should include the following:
1869/// $event->name Name for the event
1870/// $event->description Description of the event (defaults to '')
1871/// $event->courseid The id of the course this event belongs to (0 = all courses)
1872/// $event->groupid The id of the group this event belongs to (0 = no group)
1873/// $event->userid The id of the user this event belongs to (0 = no user)
1874/// $event->modulename Name of the module that creates this event
1875/// $event->instance Instance of the module that owns this event
1876/// $event->eventtype The type info together with the module info could
1877/// be used by calendar plugins to decide how to display event
1878/// $event->timestart Timestamp for start of event
1879/// $event->timeduration Duration (defaults to zero)
1880
1881 global $CFG;
1882
1883 $event->timemodified = time();
1884
1885 if (!$event->id = insert_record("event", $event)) {
1886 return false;
1887 }
1888
1889 if (!empty($CFG->calendar)) { // call the add_event function of the selected calendar
1890 if (file_exists("$CFG->dirroot/calendar/$CFG->calendar/lib.php")) {
1891 include_once("$CFG->dirroot/calendar/$CFG->calendar/lib.php");
1892 $calendar_add_event = $CFG->calendar.'_add_event';
1893 if (function_exists($calendar_add_event)) {
1894 $calendar_add_event($event);
1895 }
1896 }
1897 }
1898
1899 return $event->id;
1900}
1901
1902
1903function update_event($event) {
1904/// call this function to update an event in the calendar table
1905/// the event will be identified by the id field of the $event object
1906
1907 global $CFG;
1908
1909 $event->timemodified = time();
1910
1911 if (!empty($CFG->calendar)) { // call the update_event function of the selected calendar
1912 if (file_exists("$CFG->dirroot/calendar/$CFG->calendar/lib.php")) {
1913 include_once("$CFG->dirroot/calendar/$CFG->calendar/lib.php");
1914 $calendar_update_event = $CFG->calendar.'_update_event';
1915 if (function_exists($calendar_update_event)) {
1916 $calendar_update_event($event);
1917 }
1918 }
1919 }
1920 return update_record("event", $event);
1921}
1922
1923
1924function delete_event($id) {
1925/// call this function to delete the event with id $id from calendar table
1926
1927 global $CFG;
1928
1929 if (!empty($CFG->calendar)) { // call the delete_event function of the selected calendar
1930 if (file_exists("$CFG->dirroot/calendar/$CFG->calendar/lib.php")) {
1931 include_once("$CFG->dirroot/calendar/$CFG->calendar/lib.php");
1932 $calendar_delete_event = $CFG->calendar.'_delete_event';
1933 if (function_exists($calendar_delete_event)) {
1934 $calendar_delete_event($id);
1935 }
1936 }
1937 }
1938 return delete_records("event", 'id', $id);
1939}
1940
1941
1942
1943
9fa49e22 1944/// ENVIRONMENT CHECKING ////////////////////////////////////////////////////////////
1e3e716f 1945
1d881d92 1946function get_list_of_plugins($plugin="mod") {
1947/// Lists plugin directories within some directory
1948
1949 global $CFG;
1950
1951 $basedir = opendir("$CFG->dirroot/$plugin");
1952 while ($dir = readdir($basedir)) {
b35e8568 1953 $firstchar = substr($dir, 0, 1);
bb9cf93d 1954 if ($firstchar == "." or $dir == "CVS" or $dir == "_vti_cnf") {
1d881d92 1955 continue;
1956 }
1957 if (filetype("$CFG->dirroot/$plugin/$dir") != "dir") {
1958 continue;
1959 }
1960 $plugins[] = $dir;
1961 }
1962 if ($plugins) {
1963 asort($plugins);
1964 }
1965 return $plugins;
1966}
1967
b0cb5e22 1968function check_php_version($version="4.1.0") {
9fa49e22 1969/// Returns true is the current version of PHP is greater that the specified one
b0cb5e22 1970 $minversion = intval(str_replace(".", "", $version));
1971 $curversion = intval(str_replace(".", "", phpversion()));
1972 return ($curversion >= $minversion);
1973}
1974
0095d5cd 1975function check_browser_version($brand="MSIE", $version=5.5) {
9fa49e22 1976/// Checks to see if is a browser matches the specified
1977/// brand and is equal or better version.
0095d5cd 1978
4c46c425 1979 $agent = $_SERVER["HTTP_USER_AGENT"];
1980
1981 if (empty($agent)) {
0095d5cd 1982 return false;
1983 }
4c46c425 1984
1985 switch ($brand) {
1986
1987 case "Gecko": /// Gecko based browsers
1988
1989 if (substr_count($agent, "Camino")) { // MacOS X Camino not supported.
1990 return false;
1991 }
1992
1993 // the proper string - Gecko/CCYYMMDD Vendor/Version
1994 if (ereg("^([a-zA-Z]+)/([0-9]+\.[0-9]+) \((.*)\) (.*)$", $agent, $match)) {
1995 if (ereg("^([Gecko]+)/([0-9]+)",$match[4], $reldate)) {
1996 if ($reldate[2] > $version) {
1997 return true;
1998 }
1999 }
2000 }
2001 break;
2002
2003
2004 case "MSIE": /// Internet Explorer
2005
0e2585ac 2006 if (strpos($agent, 'Opera')) { // Reject Opera
2007 return false;
2008 }
4c46c425 2009 $string = explode(";", $agent);
2010 if (!isset($string[1])) {
2011 return false;
2012 }
2013 $string = explode(" ", trim($string[1]));
2014 if (!isset($string[0]) and !isset($string[1])) {
2015 return false;
2016 }
2017 if ($string[0] == $brand and (float)$string[1] >= $version ) {
2018 return true;
2019 }
2020 break;
2021
0095d5cd 2022 }
4c46c425 2023
0095d5cd 2024 return false;
2025}
2026
c39c66a5 2027function ini_get_bool($ini_get_arg) {
2028/// This function makes the return value of ini_get consistent if you are
2029/// setting server directives through the .htaccess file in apache.
2030/// Current behavior for value set from php.ini On = 1, Off = [blank]
2031/// Current behavior for value set from .htaccess On = On, Off = Off
2032/// Contributed by jdell@unr.edu
2033
2034 $temp = ini_get($ini_get_arg);
2035
2036 if ($temp == "1" or strtolower($temp) == "on") {
2037 return true;
2038 }
2039 return false;
2040}
2041
0095d5cd 2042function can_use_richtext_editor() {
47037513 2043/// Compatibility stub to provide backward compatibility
2044 return can_use_html_editor();
2045}
2046
2047function can_use_html_editor() {
4c46c425 2048/// Is the HTML editor enabled? This depends on site and user
2049/// settings, as well as the current browser being used.
47037513 2050/// Returns false is editor is not being used, otherwise
2051/// returns "MSIE" or "Gecko"
4c46c425 2052
0095d5cd 2053 global $USER, $CFG;
4c46c425 2054
ce78926d 2055 if (!empty($USER->htmleditor) and !empty($CFG->htmleditor)) {
4c46c425 2056 if (check_browser_version("MSIE", 5.5)) {
47037513 2057 return "MSIE";
2058 } else if (check_browser_version("Gecko", 20030516)) {
2059 return "Gecko";
4c46c425 2060 }
7ce20f09 2061 }
2062 return false;
0095d5cd 2063}
2064
47037513 2065
74944b73 2066function check_gd_version() {
9fa49e22 2067/// Hack to find out the GD version by parsing phpinfo output
aa095969 2068 $gdversion = 0;
74944b73 2069
aa095969 2070 if (function_exists('gd_info')){
2071 $gd_info = gd_info();
3ee23682 2072 if (substr_count($gd_info['GD Version'], "2.")) {
aa095969 2073 $gdversion = 2;
3ee23682 2074 } else if (substr_count($gd_info['GD Version'], "1.")) {
2075 $gdversion = 1;
aa095969 2076 }
3ee23682 2077
aa095969 2078 } else {
2079 ob_start();
2080 phpinfo(8);
2081 $phpinfo = ob_get_contents();
2082 ob_end_clean();
74944b73 2083
aa095969 2084 $phpinfo = explode("\n",$phpinfo);
74944b73 2085
92a4b0f1 2086
aa095969 2087 foreach ($phpinfo as $text) {
2088 $parts = explode('</td>',$text);
2089 foreach ($parts as $key => $val) {
2090 $parts[$key] = trim(strip_tags($val));
2091 }
2092 if ($parts[0] == "GD Version") {
2093 if (substr_count($parts[1], "2.0")) {
2094 $parts[1] = "2.0";
2095 }
2096 $gdversion = intval($parts[1]);
92a4b0f1 2097 }
74944b73 2098 }
2099 }
2100
2101 return $gdversion; // 1, 2 or 0
2102}
f9903ed0 2103
0095d5cd 2104
9fa49e22 2105function moodle_needs_upgrading() {
2106/// Checks version numbers of Main code and all modules to see
2107/// if there are any mismatches ... returns true or false
2108 global $CFG;
2109
2110 include_once("$CFG->dirroot/version.php"); # defines $version and upgrades
2111 if ($CFG->version) {
2112 if ($version > $CFG->version) {
2113 return true;
2114 }
2115 if ($mods = get_list_of_plugins("mod")) {
2116 foreach ($mods as $mod) {
2117 $fullmod = "$CFG->dirroot/mod/$mod";
2118 unset($module);
1079c8a8 2119 if (!is_readable("$fullmod/version.php")) {
2120 notify("Module '$mod' is not readable - check permissions");
2121 continue;
2122 }
9fa49e22 2123 include_once("$fullmod/version.php"); # defines $module with version etc
2124 if ($currmodule = get_record("modules", "name", $mod)) {
2125 if ($module->version > $currmodule->version) {
2126 return true;
2127 }
2128 }
2129 }
2130 }
2131 } else {
2132 return true;
2133 }
2134 return false;
2135}
2136
2137
2138/// MISCELLANEOUS ////////////////////////////////////////////////////////////////////
2139
7d6cac54 2140function moodle_strtolower ($string, $encoding='') {
2141/// Converts string to lowercase using most compatible function available
2142 if (function_exists('mb_strtolower')) {
2143 if($encoding===''){
2144 return mb_strtolower($string); //use multibyte support with default encoding
2145 } else {
dbe0be00 2146 return mb_strtolower($string,$encoding); //use given encoding
7d6cac54 2147 }
2148 } else {
2149 return strtolower($string); // use common function what rely on current locale setting
2150 }
2151}
2152
9fa49e22 2153function count_words($string) {
2154/// Words are defined as things between whitespace
2155 $string = strip_tags($string);
2156 return count(preg_split("/\w\b/", $string)) - 1;
2157}
2158
1d881d92 2159function random_string ($length=15) {
2160 $pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2161 $pool .= "abcdefghijklmnopqrstuvwxyz";
2162 $pool .= "0123456789";
2163 $poollen = strlen($pool);
2164 mt_srand ((double) microtime() * 1000000);
2165 $string = "";
2166 for ($i = 0; $i < $length; $i++) {
2167 $string .= substr($pool, (mt_rand()%($poollen)), 1);
2168 }
2169 return $string;
2170}
2171
2172
9fa49e22 2173function getweek ($startdate, $thedate) {
2174/// Given dates in seconds, how many weeks is the date from startdate
2175/// The first week is 1, the second 2 etc ...
2176
2177 if ($thedate < $startdate) { // error
2178 return 0;
2179 }
2180
2181 return floor(($thedate - $startdate) / 604800.0) + 1;
2182}
2183
2184function generate_password($maxlen=10) {
2185/// returns a randomly generated password of length $maxlen. inspired by
2186/// http://www.phpbuilder.com/columns/jesus19990502.php3
2187
2188 global $CFG;
2189
2190 $fillers = "1234567890!$-+";
2191 $wordlist = file($CFG->wordlist);
2192
2193 srand((double) microtime() * 1000000);
2194 $word1 = trim($wordlist[rand(0, count($wordlist) - 1)]);
2195 $word2 = trim($wordlist[rand(0, count($wordlist) - 1)]);
2196 $filler1 = $fillers[rand(0, strlen($fillers) - 1)];
2197
2198 return substr($word1 . $filler1 . $word2, 0, $maxlen);
2199}
2200
2201function format_float($num, $places=0) {
2202/// Given a float, prints it nicely
2203 return sprintf("%.$places"."f", $num);
2204}
2205
ee0e5d57 2206function swapshuffle($array) {
2207/// Given a simple array, this shuffles it up just like shuffle()
2208/// Unlike PHP's shuffle() ihis function works on any machine.
2209
2210 srand ((double) microtime() * 10000000);
2211 $last = count($array) - 1;
2212 for ($i=0;$i<=$last;$i++) {
2213 $from = rand(0,$last);
2214 $curr = $array[$i];
2215 $array[$i] = $array[$from];
2216 $array[$from] = $curr;
2217 }
2218 return $array;
2219}
2220
bc700e65 2221function swapshuffle_assoc($array) {
2222/// Like swapshuffle, but works on associative arrays
2223
2224 $newkeys = swapshuffle(array_keys($array));
2225 foreach ($newkeys as $newkey) {
2226 $newarray[$newkey] = $array[$newkey];
2227 }
2228 return $newarray;
2229}
2230
ee0e5d57 2231function draw_rand_array($array, $draws) {
2232/// Given an arbitrary array, and a number of draws,
2233/// this function returns an array with that amount
2234/// of items. The indexes are retained.
2235
2236 srand ((double) microtime() * 10000000);
2237
2238 $return = array();
2239
2240 $last = count($array);
2241
2242 if ($draws > $last) {
2243 $draws = $last;
2244 }
2245
2246 while ($draws > 0) {
2247 $last--;
2248
2249 $keys = array_keys($array);
2250 $rand = rand(0, $last);
2251
2252 $return[$keys[$rand]] = $array[$keys[$rand]];
2253 unset($array[$keys[$rand]]);
2254
2255 $draws--;
2256 }
2257
2258 return $return;
2259}
9fa49e22 2260
f5e82bc7 2261function microtime_diff($a, $b) {
2262 list($a_dec, $a_sec) = explode(" ", $a);
2263 list($b_dec, $b_sec) = explode(" ", $b);
2264 return $b_sec - $a_sec + $b_dec - $a_dec;
2265}
2266
02ebf404 2267function make_menu_from_list($list, $separator=",") {
2268/// Given a list (eg a,b,c,d,e) this function returns
2269/// an array of 1->a, 2->b, 3->c etc
2270
2271 $array = array_reverse(explode($separator, $list), true);
2272 foreach ($array as $key => $item) {
2273 $outarray[$key+1] = trim($item);
2274 }
2275 return $outarray;
2276}
2277
fdc47ee6 2278function make_grades_menu($gradingtype) {
2279/// Creates an array that represents all the current grades that
2280/// can be chosen using the given grading type. Negative numbers
2281/// are scales, zero is no grade, and positive numbers are maximum
2282/// grades.
2283
2284 $grades = array();
2285 if ($gradingtype < 0) {
2286 if ($scale = get_record("scale", "id", - $gradingtype)) {
2287 return make_menu_from_list($scale->scale);
2288 }
2289 } else if ($gradingtype > 0) {
2290 for ($i=$gradingtype; $i>=0; $i--) {
62ca135d 2291 $grades[$i] = "$i / $gradingtype";
fdc47ee6 2292 }
2293 return $grades;
2294 }
2295 return $grades;
2296}
2297
757a0abd 2298function make_unique_id_code($extra="") {
280faf9f 2299
2300 $hostname = "unknownhost";
2301 if (!empty($_SERVER["HTTP_HOST"])) {
2302 $hostname = $_SERVER["HTTP_HOST"];
2303 } else if (!empty($_ENV["HTTP_HOST"])) {
2304 $hostname = $_ENV["HTTP_HOST"];
2305 } else if (!empty($_SERVER["SERVER_NAME"])) {
2306 $hostname = $_SERVER["SERVER_NAME"];
2307 } else if (!empty($_ENV["SERVER_NAME"])) {
2308 $hostname = $_ENV["SERVER_NAME"];
2309 }
2310
1ccc73ac 2311 $date = gmdate("ymdHis");
280faf9f 2312
2313 $random = random_string(6);
2314
757a0abd 2315 if ($extra) {
2316 return "$hostname+$date+$random+$extra";
2317 } else {
2318 return "$hostname+$date+$random";
2319 }
280faf9f 2320}
2321
0095d5cd 2322
9d5b689c 2323// vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
f9903ed0 2324?>