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