Ordinary teachers can assign students
[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
f9903ed0 37
9fa49e22 38/// PARAMETER HANDLING ////////////////////////////////////////////////////
6b174680 39
9fa49e22 40function require_variable($var) {
41/// Variable must be present
42 if (! isset($var)) {
43 error("A required parameter was missing");
6b174680 44 }
45}
46
9fa49e22 47function optional_variable(&$var, $default=0) {
48/// Variable may be present, if not then set a default
49 if (! isset($var)) {
50 $var = $default;
6b174680 51 }
52}
53
54
9fa49e22 55function set_config($name, $value) {
56/// No need for get_config because they are usually always available in $CFG
dfc9ba9b 57
9fa49e22 58 if (get_field("config", "name", "name", $name)) {
59 return set_field("config", "value", $value, "name", $name);
d897cae4 60 } else {
9fa49e22 61 $config->name = $name;
62 $config->value = $value;
63 return insert_record("config", $config);
39917a09 64 }
39917a09 65}
66
39917a09 67
9fa49e22 68/// FUNCTIONS FOR HANDLING TIME ////////////////////////////////////////////
39917a09 69
3db75c62 70function make_timestamp($year, $month=1, $day=1, $hour=0, $minute=0, $second=0, $timezone=99) {
9fa49e22 71/// Given date parts in user time, produce a GMT timestamp
39917a09 72
94e34118 73 global $USER;
74
03c17ddf 75 if ($timezone == 99) {
94e34118 76 $timezone = (float)$USER->timezone;
77 }
78
79 if (abs($timezone) > 13) {
03c17ddf 80 return mktime((int)$hour,(int)$minute,(int)$second,(int)$month,(int)$day,(int)$year);
81 } else {
82 $time = gmmktime((int)$hour,(int)$minute,(int)$second,(int)$month,(int)$day,(int)$year);
83 return usertime($time, $timezone); // This is GMT
84 }
39917a09 85}
86
8dbed6be 87function format_time($totalsecs, $str=NULL) {
9fa49e22 88/// Given an amount of time in seconds, returns string
89/// formatted nicely as months, days, hours etc as needed
c7e3ac2a 90
6b174680 91 $totalsecs = abs($totalsecs);
c7e3ac2a 92
8dbed6be 93 if (!$str) { // Create the str structure the slow way
94 $str->day = get_string("day");
95 $str->days = get_string("days");
96 $str->hour = get_string("hour");
97 $str->hours = get_string("hours");
98 $str->min = get_string("min");
99 $str->mins = get_string("mins");
100 $str->sec = get_string("sec");
101 $str->secs = get_string("secs");
102 }
103
104 $days = floor($totalsecs/86400);
6b174680 105 $remainder = $totalsecs - ($days*86400);
8dbed6be 106 $hours = floor($remainder/3600);
6b174680 107 $remainder = $remainder - ($hours*3600);
8dbed6be 108 $mins = floor($remainder/60);
109 $secs = $remainder - ($mins*60);
110
111 $ss = ($secs == 1) ? $str->sec : $str->secs;
112 $sm = ($mins == 1) ? $str->min : $str->mins;
113 $sh = ($hours == 1) ? $str->hour : $str->hours;
114 $sd = ($days == 1) ? $str->day : $str->days;
115
9c9f7d77 116 $odays = "";
117 $ohours = "";
118 $omins = "";
119 $osecs = "";
120
8dbed6be 121 if ($days) $odays = "$days $sd";
122 if ($hours) $ohours = "$hours $sh";
123 if ($mins) $omins = "$mins $sm";
124 if ($secs) $osecs = "$secs $ss";
6b174680 125
126 if ($days) return "$odays $ohours";
127 if ($hours) return "$ohours $omins";
128 if ($mins) return "$omins $osecs";
129 if ($secs) return "$osecs";
130 return get_string("now");
131}
f9903ed0 132
61ae5d36 133function userdate($date, $format="", $timezone=99, $fixday = true) {
9fa49e22 134/// Returns a formatted string that represents a date in user time
135/// WARNING: note that the format is for strftime(), not date().
136/// Because of a bug in most Windows time libraries, we can't use
137/// the nicer %e, so we have to use %d which has leading zeroes.
138/// A lot of the fuss below is just getting rid of these leading
139/// zeroes as efficiently as possible.
61ae5d36 140///
141/// If parammeter fixday = true (default), then take off leading
142/// zero from %d, else mantain it.
7a302afc 143
873960de 144 global $USER;
145
5fa51a39 146 if ($format == "") {
dcde9f02 147 $format = get_string("strftimedaydatetime");
5fa51a39 148 }
035cdbff 149
dcde9f02 150 $formatnoday = str_replace("%d", "DD", $format);
61ae5d36 151 if ($fixday) {
152 $fixday = ($formatnoday != $format);
153 }
dcde9f02 154
5fa51a39 155 if ($timezone == 99) {
ab247495 156 if (isset($USER->timezone)) {
157 $timezone = (float)$USER->timezone;
158 }
5fa51a39 159 }
0431bd7c 160 if (abs($timezone) > 13) {
035cdbff 161 if ($fixday) {
162 $datestring = strftime($formatnoday, $date);
163 $daystring = str_replace(" 0", "", strftime(" %d", $date));
164 $datestring = str_replace("DD", $daystring, $datestring);
165 } else {
166 $datestring = strftime($format, $date);
167 }
bea7a51e 168 } else {
70d4cf82 169 $date = $date + (int)($timezone * 3600);
035cdbff 170 if ($fixday) {
70d4cf82 171 $datestring = gmstrftime($formatnoday, $date);
9fa49e22 172 $daystring = str_replace(" 0", "", gmstrftime(" %d", $date));
035cdbff 173 $datestring = str_replace("DD", $daystring, $datestring);
174 } else {
70d4cf82 175 $datestring = gmstrftime($format, $date);
035cdbff 176 }
873960de 177 }
bea7a51e 178
035cdbff 179 return $datestring;
873960de 180}
181
5fa51a39 182function usergetdate($date, $timezone=99) {
9fa49e22 183/// Given a $date timestamp in GMT, returns an array
184/// that represents the date in user time
6b174680 185
873960de 186 global $USER;
187
5fa51a39 188 if ($timezone == 99) {
189 $timezone = (float)$USER->timezone;
190 }
0431bd7c 191 if (abs($timezone) > 13) {
873960de 192 return getdate($date);
193 }
d2d6171f 194 //There is no gmgetdate so I have to fake it...
195 $date = $date + (int)($timezone * 3600);
196 $getdate["seconds"] = gmstrftime("%S", $date);
197 $getdate["minutes"] = gmstrftime("%M", $date);
198 $getdate["hours"] = gmstrftime("%H", $date);
199 $getdate["mday"] = gmstrftime("%d", $date);
200 $getdate["wday"] = gmstrftime("%u", $date);
201 $getdate["mon"] = gmstrftime("%m", $date);
202 $getdate["year"] = gmstrftime("%Y", $date);
203 $getdate["yday"] = gmstrftime("%j", $date);
204 $getdate["weekday"] = gmstrftime("%A", $date);
205 $getdate["month"] = gmstrftime("%B", $date);
206 return $getdate;
d552ead0 207}
208
209function usertime($date, $timezone=99) {
9fa49e22 210/// Given a GMT timestamp (seconds since epoch), offsets it by
211/// the timezone. eg 3pm in India is 3pm GMT - 7 * 3600 seconds
d552ead0 212 global $USER;
213
214 if ($timezone == 99) {
215 $timezone = (float)$USER->timezone;
216 }
0431bd7c 217 if (abs($timezone) > 13) {
d552ead0 218 return $date;
219 }
220 return $date - (int)($timezone * 3600);
221}
222
edf7fe8c 223function usergetmidnight($date, $timezone=99) {
9fa49e22 224/// Given a time, return the GMT timestamp of the most recent midnight
225/// for the current user.
edf7fe8c 226 global $USER;
227
4606d9bb 228 if ($timezone == 99) {
229 $timezone = (float)$USER->timezone;
230 }
231
edf7fe8c 232 $userdate = usergetdate($date, $timezone);
4606d9bb 233
0431bd7c 234 if (abs($timezone) > 13) {
4606d9bb 235 return mktime(0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
236 }
237
edf7fe8c 238 $timemidnight = gmmktime (0, 0, 0, $userdate["mon"], $userdate["mday"], $userdate["year"]);
239 return usertime($timemidnight, $timezone); // Time of midnight of this user's day, in GMT
240
241}
242
d552ead0 243function usertimezone($timezone=99) {
9fa49e22 244/// Returns a string that prints the user's timezone
d552ead0 245 global $USER;
246
247 if ($timezone == 99) {
248 $timezone = (float)$USER->timezone;
249 }
0431bd7c 250 if (abs($timezone) > 13) {
d552ead0 251 return "server time";
252 }
253 if (abs($timezone) < 0.5) {
254 return "GMT";
255 }
256 if ($timezone > 0) {
257 return "GMT+$timezone";
258 } else {
259 return "GMT$timezone";
260 }
f9903ed0 261}
262
263
9fa49e22 264/// USER AUTHENTICATION AND LOGIN ////////////////////////////////////////
f9903ed0 265
da5c172a 266function require_login($courseid=0) {
9fa49e22 267/// This function checks that the current user is logged in, and optionally
268/// whether they are "logged in" or allowed to be in a particular course.
269/// If not, then it redirects them to the site login or course enrolment.
f9903ed0 270
73047f2f 271 global $CFG, $SESSION, $USER, $FULLME, $MoodleSession;
f9903ed0 272
da5c172a 273 // First check that the user is logged in to the site.
c21c671d 274 if (! (isset($USER->loggedin) and $USER->confirmed and ($USER->site == $CFG->wwwroot)) ) { // They're not
f9903ed0 275 $SESSION->wantsurl = $FULLME;
9f44d972 276 if (!empty($_SERVER["HTTP_REFERER"])) {
277 $SESSION->fromurl = $_SERVER["HTTP_REFERER"];
278 }
c21c671d 279 $USER = NULL;
73047f2f 280 redirect("$CFG->wwwroot/login/index.php");
f9903ed0 281 die;
f9903ed0 282 }
808a3baa 283
284 // Check that the user account is properly set up
285 if (user_not_fully_set_up($USER)) {
286 $site = get_site();
287 redirect("$CFG->wwwroot/user/edit.php?id=$USER->id&course=$site->id");
288 die;
289 }
da5c172a 290
291 // Next, check if the user can be in a particular course
292 if ($courseid) {
9c9f7d77 293 if (!empty($USER->student[$courseid]) or !empty($USER->teacher[$courseid]) or !empty($USER->admin)) {
cb909d74 294 if (isset($USER->realuser)) { // Make sure the REAL person can also access this course
295 if (!isteacher($courseid, $USER->realuser)) {
296 print_header();
5ebe27e2 297 notice(get_string("studentnotallowed", "", "$USER->firstname $USER->lastname"), $CFG->wwwroot);
cb909d74 298 }
299
300 } else { // just update their last login time
3ce2f1e0 301 update_user_in_db();
302 }
da5c172a 303 return; // user is a member of this course.
304 }
305 if (! $course = get_record("course", "id", $courseid)) {
306 error("That course doesn't exist");
307 }
1efa27fd 308 if (!$course->visible) {
309 print_header();
310 notice(get_string("studentnotallowed", "", "$USER->firstname $USER->lastname"), $CFG->wwwroot);
311 }
7363ff91 312 if ($USER->username == "guest") {
313 switch ($course->guest) {
314 case 0: // Guests not allowed
315 print_header();
316 notice(get_string("guestsnotallowed", "", $course->fullname));
317 break;
318 case 1: // Guests allowed
319 update_user_in_db();
320 return;
321 case 2: // Guests allowed with key (drop through)
322 break;
323 }
da5c172a 324 }
f9903ed0 325
7363ff91 326 // Currently not enrolled in the course, so see if they want to enrol
da5c172a 327 $SESSION->wantsurl = $FULLME;
328 redirect("$CFG->wwwroot/course/enrol.php?id=$courseid");
329 die;
330 }
f9903ed0 331}
332
1d881d92 333function update_user_login_times() {
334 global $USER;
335
336 $USER->lastlogin = $user->lastlogin = $USER->currentlogin;
337 $USER->currentlogin = $user->currentlogin = time();
1d881d92 338
339 $user->id = $USER->id;
340
341 return update_record("user", $user);
342}
343
808a3baa 344function user_not_fully_set_up($user) {
ac5d88eb 345 return ($user->username != "guest" and (empty($user->firstname) or empty($user->lastname) or empty($user->email)));
808a3baa 346}
f9903ed0 347
f9903ed0 348function update_login_count() {
9fa49e22 349/// Keeps track of login attempts
350
f9903ed0 351 global $SESSION;
352
353 $max_logins = 10;
354
355 if (empty($SESSION->logincount)) {
356 $SESSION->logincount = 1;
357 } else {
358 $SESSION->logincount++;
359 }
360
361 if ($SESSION->logincount > $max_logins) {
9fa49e22 362 unset($SESSION->wantsurl);
1d881d92 363 error(get_string("errortoomanylogins"));
d578afc8 364 }
365}
366
9fa49e22 367function reset_login_count() {
368/// Resets login attempts
369 global $SESSION;
d578afc8 370
9fa49e22 371 $SESSION->logincount = 0;
d578afc8 372}
373
581d7b49 374function isadmin($userid=0) {
9fa49e22 375/// Is the user an admin?
f9903ed0 376 global $USER;
aa095969 377 static $admins = array();
378 static $nonadmins = array();
f9903ed0 379
581d7b49 380 if (!$userid){
381 if (empty($USER->id)) {
382 return false;
383 }
384 $userid = $USER->id;
9bd2c874 385 }
386
581d7b49 387 if (in_array($userid, $admins)) {
aa095969 388 return true;
581d7b49 389 } else if (in_array($userid, $nonadmins)) {
aa095969 390 return false;
581d7b49 391 } else if (record_exists("user_admins", "userid", $userid)){
392 $admins[] = $userid;
aa095969 393 return true;
394 } else {
581d7b49 395 $nonadmins[] = $userid;
aa095969 396 return false;
f9903ed0 397 }
f9903ed0 398}
399
8a9e3fd7 400function isteacher($courseid, $userid=0) {
9fa49e22 401/// Is the user a teacher or admin?
f9903ed0 402 global $USER;
403
d115a57f 404 if (isadmin($userid)) { // admins can do anything the teacher can
405 return true;
406 }
407
f9903ed0 408 if (!$userid) {
9bd2c874 409 return !empty($USER->teacher[$courseid]);
f9903ed0 410 }
411
ebc3bd2b 412 return record_exists("user_teachers", "userid", $userid, "course", $courseid);
f9903ed0 413}
414
73047f2f 415function isteacheredit($courseid, $userid=0) {
416/// Is the user allowed to edit this course?
417 global $USER;
418
419 if (isadmin($userid)) { // admins can do anything
420 return true;
421 }
422
423 if (!$userid) {
424 return !empty($USER->teacheredit[$courseid]);
425 }
426
427 return get_field("user_teachers", "editall", "userid", $userid, "course", $courseid);
428}
429
1924074c 430function iscreator ($userid=0) {
431/// Can user create new courses?
432 global $USER;
8a205861 433 if (empty($USER->id)) {
434 return false;
435 }
1924074c 436 if (isadmin($userid)) { // admins can do anything
437 return true;
438 }
8a205861 439 if (empty($userid)) {
1924074c 440 return record_exists("user_coursecreators", "userid", $USER->id);
441 }
442
443 return record_exists("user_coursecreators", "userid", $userid);
444}
445
8a9e3fd7 446function isstudent($courseid, $userid=0) {
9fa49e22 447/// Is the user a student in this course?
f9903ed0 448 global $USER;
449
450 if (!$userid) {
346b1a24 451 return !empty($USER->student[$courseid]);
f9903ed0 452 }
453
ebc3bd2b 454 // $timenow = time(); // todo: add time check below
f9903ed0 455
ebc3bd2b 456 return record_exists("user_students", "userid", $userid, "course", $courseid);
f9903ed0 457}
458
da5c172a 459function isguest($userid=0) {
9fa49e22 460/// Is the user a guest?
da5c172a 461 global $USER;
462
463 if (!$userid) {
b35e8568 464 if (empty($USER->username)) {
465 return false;
466 }
da5c172a 467 return ($USER->username == "guest");
468 }
469
9fa49e22 470 return record_exists("user", "id", $userid, "username", "guest");
da5c172a 471}
472
9fa49e22 473
2c309dc2 474function isediting($courseid, $user=NULL) {
9fa49e22 475/// Is the current user in editing mode?
2c309dc2 476 global $USER;
477 if (!$user){
478 $user = $USER;
479 }
9c9f7d77 480 if (empty($user->editing)) {
481 return false;
482 }
2c309dc2 483 return ($user->editing and isteacher($courseid, $user->id));
484}
485
7977cffd 486function ismoving($courseid) {
487/// Is the current user currently moving an activity?
488 global $USER;
489
490 if (!empty($USER->activitycopy)) {
491 return ($USER->activitycopycourse == $courseid);
492 }
493 return false;
494}
495
f9903ed0 496
497function set_moodle_cookie($thing) {
9fa49e22 498/// Sets a moodle cookie with an encrypted string
7185e073 499 global $CFG;
500
501 $cookiename = "MOODLEID{$CFG->prefix}";
f9903ed0 502
503 $days = 60;
504 $seconds = 60*60*24*$days;
505
7185e073 506 setCookie($cookiename, "", time() - 3600, "/");
507 setCookie($cookiename, rc4encrypt($thing), time()+$seconds, "/");
f9903ed0 508}
509
510
511function get_moodle_cookie() {
9fa49e22 512/// Gets a moodle cookie with an encrypted string
7185e073 513 global $CFG;
514
4fe04be0 515 $cookiename = "MOODLEID{$CFG->prefix}";
7185e073 516
1079c8a8 517 if (empty($_COOKIE[$cookiename])) {
518 return "";
519 } else {
520 return rc4decrypt($_COOKIE[$cookiename]);
521 }
f9903ed0 522}
523
524
faebaf0f 525function create_user_record($username, $password) {
9fa49e22 526/// Creates a bare-bones user record
e858f9da 527 global $REMOTE_ADDR, $CFG;
1e22bc9c 528 //just in case check text case
529 $username = trim(moodle_strtolower($username));
6ae24de0 530 if (function_exists(auth_get_userinfo)) {
e858f9da 531 if ($newinfo = auth_get_userinfo($username)) {
34daec9b 532 foreach ($newinfo as $key => $value){
9f44d972 533 $newuser->$key = addslashes(stripslashes($value)); // Just in case
e858f9da 534 }
535 }
536 }
f9903ed0 537
faebaf0f 538 $newuser->username = $username;
539 $newuser->password = md5($password);
a0bac19d 540 $newuser->lang = $CFG->lang;
faebaf0f 541 $newuser->confirmed = 1;
542 $newuser->lastIP = $REMOTE_ADDR;
543 $newuser->timemodified = time();
f9903ed0 544
faebaf0f 545 if (insert_record("user", $newuser)) {
546 return get_user_info_from_db("username", $username);
547 }
548 return false;
549}
550
551function authenticate_user_login($username, $password) {
9fa49e22 552/// Given a username and password, this function looks them
553/// up using the currently selected authentication mechanism,
554/// and if the authentication is successful, it returns a
555/// valid $user object from the 'user' table.
556///
557/// Uses auth_ functions from the currently active auth module
faebaf0f 558
559 global $CFG;
560
466558e3 561 $md5password = md5($password);
562
14217044 563 if (empty($CFG->auth)) {
faebaf0f 564 $CFG->auth = "email"; // Default authentication module
565 }
566
466558e3 567 if ($username == "guest") {
568 $CFG->auth = "none"; // Guest account always internal
569 }
570
571 // If this is the admin, then just use internal methods
92710226 572 // Doing this first (even though it's less efficient) because
573 // the chosen authentication method might hang and lock the
574 // admin out.
9fa49e22 575 if (adminlogin($username, $md5password)) {
466558e3 576 return get_user_info_from_db("username", $username);
577 }
578
92710226 579 // OK, the user is a normal user, so try and authenticate them
e858f9da 580 require_once("$CFG->dirroot/auth/$CFG->auth/lib.php");
faebaf0f 581
582 if (auth_user_login($username, $password)) { // Successful authentication
faebaf0f 583 if ($user = get_user_info_from_db("username", $username)) {
92710226 584 if ($md5password <> $user->password) { // Update local copy of password for reference
466558e3 585 set_field("user", "password", $md5password, "username", $username);
faebaf0f 586 }
faebaf0f 587 } else {
e582b65e 588 $user = create_user_record($username, $password);
faebaf0f 589 }
89b54325 590
e582b65e 591 if (function_exists('auth_iscreator')) { // Check if the user is a creator
592 if (auth_iscreator($username)) {
593 if (! record_exists("user_coursecreators", "userid", $user->id)) {
594 $cdata['userid']=$user->id;
595 $creator = insert_record("user_coursecreators",$cdata);
596 if (! $creator) {
597 error("Cannot add user to course creators.");
598 }
599 }
600 } else {
601 if ( record_exists("user_coursecreators", "userid", $user->id)) {
f5cdd4d1 602 $creator = delete_records("user_coursecreators", "userid", $user->id);
e582b65e 603 if (! $creator) {
604 error("Cannot remove user from course creators.");
605 }
606 }
607 }
608 }
609
610 return $user;
611 } else {
612 return false;
613 }
f9903ed0 614}
615
faebaf0f 616
4d312bbe 617function enrol_student($userid, $courseid) {
9fa49e22 618/// Enrols a student in a given course
619 global $db;
f9903ed0 620
4d312bbe 621 if (!record_exists("user_students", "userid", $userid, "course", $courseid)) {
622 $student->userid = $userid;
623 $student->course = $courseid;
624 $student->start = 0;
625 $student->end = 0;
626 $student->time = time();
627 return insert_record("user_students", $student);
628 }
629 return true;
d7facad8 630}
631
9fa49e22 632function unenrol_student($user, $course=0) {
633/// Unenrols a student from a given course
634 global $db;
d7facad8 635
9fa49e22 636 if ($course) {
637 /// First delete any crucial stuff that might still send mail
638 if ($forums = get_records("forum", "course", $course)) {
639 foreach ($forums as $forum) {
ebc3bd2b 640 delete_records("forum_subscriptions", "forum", $forum->id, "userid", $user);
bb09fb11 641 }
f9903ed0 642 }
ebc3bd2b 643 return delete_records("user_students", "userid", $user, "course", $course);
9fa49e22 644
f9903ed0 645 } else {
ebc3bd2b 646 delete_records("forum_subscriptions", "userid", $user);
647 return delete_records("user_students", "userid", $user);
f9903ed0 648 }
649}
650
9fa49e22 651function remove_teacher($user, $course=0) {
652/// Removes a teacher from a given course (or ALL courses)
653/// Does not delete the user account
654 global $db;
57507290 655
9fa49e22 656 if ($course) {
657 /// First delete any crucial stuff that might still send mail
658 if ($forums = get_records("forum", "course", $course)) {
659 foreach ($forums as $forum) {
ebc3bd2b 660 delete_records("forum_subscriptions", "forum", $forum->id, "userid", $user);
9fa49e22 661 }
662 }
ebc3bd2b 663 return delete_records("user_teachers", "userid", $user, "course", $course);
57507290 664 } else {
ebc3bd2b 665 delete_records("forum_subscriptions", "userid", $user);
666 return delete_records("user_teachers", "userid", $user);
57507290 667 }
f9903ed0 668}
669
9fa49e22 670function remove_admin($user) {
671/// Removes an admin from a site
672 global $db;
f9903ed0 673
ebc3bd2b 674 return delete_records("user_admins", "userid", $user);
f9903ed0 675}
676
f9903ed0 677
07aeb7b0 678function remove_course_contents($courseid, $showfeedback=true) {
679/// Clear a course out completely, deleting all content
680/// but don't delete the course itself
681
ee23f384 682 global $CFG, $THEME, $USER, $SESSION;
07aeb7b0 683
684 $result = true;
685
686 if (! $course = get_record("course", "id", $courseid)) {
687 error("Course ID was incorrect (can't find it)");
688 }
689
690 $strdeleted = get_string("deleted");
691
692 // First delete every instance of every module
693
694 if ($allmods = get_records("modules") ) {
695 foreach ($allmods as $mod) {
696 $modname = $mod->name;
697 $modfile = "$CFG->dirroot/mod/$modname/lib.php";
698 $moddelete = $modname."_delete_instance";
699 $count=0;
700 if (file_exists($modfile)) {
701 include_once($modfile);
702 if (function_exists($moddelete)) {
703 if ($instances = get_records($modname, "course", $course->id)) {
704 foreach ($instances as $instance) {
705 if ($moddelete($instance->id)) {
706 $count++;
707 } else {
708 notify("Could not delete $modname instance $instance->id ($instance->name)");
709 $result = false;
710 }
711 }
712 }
713 } else {
714 notify("Function $moddelete() doesn't exist!");
715 $result = false;
716 }
717
718 }
719 if ($showfeedback) {
720 notify("$strdeleted $count x $modname");
721 }
722 }
723 } else {
724 error("No modules are installed!");
725 }
726
727 // Delete any user stuff
728
729 if (delete_records("user_students", "course", $course->id)) {
730 if ($showfeedback) {
731 notify("$strdeleted user_students");
732 }
733 } else {
734 $result = false;
735 }
736
737 if (delete_records("user_teachers", "course", $course->id)) {
738 if ($showfeedback) {
739 notify("$strdeleted user_teachers");
740 }
741 } else {
742 $result = false;
743 }
744
745 // Delete logs
746
747 if (delete_records("log", "course", $course->id)) {
748 if ($showfeedback) {
749 notify("$strdeleted log");
750 }
751 } else {
752 $result = false;
753 }
754
755 // Delete any course stuff
756
757 if (delete_records("course_sections", "course", $course->id)) {
758 if ($showfeedback) {
759 notify("$strdeleted course_sections");
760 }
761 } else {
762 $result = false;
763 }
764
765 if (delete_records("course_modules", "course", $course->id)) {
766 if ($showfeedback) {
767 notify("$strdeleted course_modules");
768 }
769 } else {
770 $result = false;
771 }
772
773 return $result;
774
775}
776
f9903ed0 777
f9903ed0 778/// CORRESPONDENCE ////////////////////////////////////////////////
779
5fa51a39 780function email_to_user($user, $from, $subject, $messagetext, $messagehtml="", $attachment="", $attachname="") {
9fa49e22 781/// user - a user record as an object
782/// from - a user record as an object
783/// subject - plain text subject line of the email
784/// messagetext - plain text version of the message
785/// messagehtml - complete html version of the message (optional)
786/// attachment - a file on the filesystem, relative to $CFG->dataroot
787/// attachname - the name of the file (extension indicates MIME)
f9903ed0 788
4216daa6 789 global $CFG, $_SERVER;
f9903ed0 790
136dabd8 791 include_once("$CFG->libdir/phpmailer/class.phpmailer.php");
f9903ed0 792
5fa51a39 793 if (!$user) {
f9903ed0 794 return false;
795 }
796
f9903ed0 797 $mail = new phpmailer;
798
72c578ca 799 $mail->Version = "Moodle $CFG->version"; // mailer version
136dabd8 800 $mail->PluginDir = "$CFG->libdir/phpmailer/"; // plugin directory (eg smtp plugin)
562bbe90 801
98c4eae3 802
d483bcd3 803 if (current_language() != "en") {
804 $mail->CharSet = get_string("thischarset");
98c4eae3 805 }
806
7f86ce17 807 if ($CFG->smtphosts) {
1e411ffc 808 $mail->IsSMTP(); // use SMTP directly
809 $mail->Host = "$CFG->smtphosts"; // specify main and backup servers
9f58537a 810
811 if ($CFG->smtpuser) { // Use SMTP authentication
812 $mail->SMTPAuth = true;
813 $mail->Username = $CFG->smtpuser;
814 $mail->Password = $CFG->smtppass;
815 }
7f86ce17 816 } else {
1e411ffc 817 $mail->IsMail(); // use PHP mail() = sendmail
7f86ce17 818 }
f9903ed0 819
2b97bd71 820 $adminuser = get_admin();
821
822 $mail->Sender = "$adminuser->email";
823
136dabd8 824 $mail->From = "$from->email";
825 $mail->FromName = "$from->firstname $from->lastname";
826 $mail->Subject = stripslashes($subject);
f9903ed0 827
6b174680 828 $mail->AddAddress("$user->email", "$user->firstname $user->lastname");
f9903ed0 829
f9903ed0 830 $mail->WordWrap = 70; // set word wrap
f9903ed0 831
136dabd8 832 if ($messagehtml) {
833 $mail->IsHTML(true);
125898af 834 $mail->Encoding = "quoted-printable"; // Encoding to use
136dabd8 835 $mail->Body = $messagehtml;
78681899 836 $mail->AltBody = "\n$messagetext\n";
136dabd8 837 } else {
838 $mail->IsHTML(false);
78681899 839 $mail->Body = "\n$messagetext\n";
f9903ed0 840 }
841
136dabd8 842 if ($attachment && $attachname) {
843 if (ereg( "\\.\\." ,$attachment )) { // Security check for ".." in dir path
4216daa6 844 $mail->AddAddress("$adminuser->email", "$adminuser->firstname $adminuser->lastname");
845 $mail->AddStringAttachment("Error in attachment. User attempted to attach a filename with a unsafe name.", "error.txt", "8bit", "text/plain");
136dabd8 846 } else {
847 include_once("$CFG->dirroot/files/mimetypes.php");
848 $mimetype = mimeinfo("type", $attachname);
849 $mail->AddAttachment("$CFG->dataroot/$attachment", "$attachname", "base64", "$mimetype");
850 }
f9903ed0 851 }
852
136dabd8 853 if ($mail->Send()) {
854 return true;
855 } else {
4216daa6 856 echo "ERROR: $mail->ErrorInfo\n";
857 $site = get_site();
858 add_to_log($site->id, "library", "mailer", $_SERVER["REQUEST_URI"], "ERROR: $mail->ErrorInfo");
f9903ed0 859 return false;
860 }
f9903ed0 861}
862
1d881d92 863function reset_password_and_mail($user) {
864
865 global $CFG;
866
867 $site = get_site();
868 $from = get_admin();
869
870 $newpassword = generate_password();
871
872 if (! set_field("user", "password", md5($newpassword), "id", $user->id) ) {
873 error("Could not set user password!");
874 }
875
876 $a->firstname = $user->firstname;
877 $a->sitename = $site->fullname;
878 $a->username = $user->username;
879 $a->newpassword = $newpassword;
880 $a->link = "$CFG->wwwroot/login/change_password.php";
881 $a->signoff = "$from->firstname $from->lastname ($from->email)";
882
883 $message = get_string("newpasswordtext", "", $a);
884
885 $subject = "$site->fullname: ".get_string("changedpassword");
886
887 return email_to_user($user, $from, $subject, $message);
888
889}
890
891function send_confirmation_email($user) {
892
893 global $CFG;
894
895 $site = get_site();
896 $from = get_admin();
897
898 $data->firstname = $user->firstname;
899 $data->sitename = $site->fullname;
900 $data->link = "$CFG->wwwroot/login/confirm.php?p=$user->secret&s=$user->username";
901 $data->admin = "$from->firstname $from->lastname ($from->email)";
902
903 $message = get_string("emailconfirmation", "", $data);
eb347b6b 904 $subject = get_string("emailconfirmationsubject", "", $site->fullname);
1d881d92 905
906 return email_to_user($user, $from, $subject, $message);
907
908}
909
eb347b6b 910function send_password_change_confirmation_email($user) {
911
912 global $CFG;
913
914 $site = get_site();
915 $from = get_admin();
916
917 $data->firstname = $user->firstname;
918 $data->sitename = $site->fullname;
919 $data->link = "$CFG->wwwroot/login/forgot_password.php?p=$user->secret&s=$user->username";
920 $data->admin = "$from->firstname $from->lastname ($from->email)";
921
922 $message = get_string("emailpasswordconfirmation", "", $data);
923 $subject = get_string("emailpasswordconfirmationsubject", "", $site->fullname);
924
925 return email_to_user($user, $from, $subject, $message);
926
927}
928
929
1d881d92 930
136dabd8 931
f9903ed0 932/// FILE HANDLING /////////////////////////////////////////////
933
6b174680 934function make_upload_directory($directory) {
9fa49e22 935/// $directory = a string of directory names under $CFG->dataroot
936/// eg stuff/assignment/1
937/// Returns full directory if successful, false if not
6b174680 938
939 global $CFG;
940
941 $currdir = $CFG->dataroot;
fe287429 942
2e6d4273 943 umask(0000);
944
6b174680 945 if (!file_exists($currdir)) {
2e6d4273 946 if (! mkdir($currdir, $CFG->directorypermissions)) {
6b174680 947 notify("ERROR: You need to create the directory $currdir with web server write access");
948 return false;
949 }
950 }
951
952 $dirarray = explode("/", $directory);
953
954 foreach ($dirarray as $dir) {
955 $currdir = "$currdir/$dir";
956 if (! file_exists($currdir)) {
2e6d4273 957 if (! mkdir($currdir, $CFG->directorypermissions)) {
6b174680 958 notify("ERROR: Could not find or create a directory ($currdir)");
959 return false;
960 }
feffa4e6 961 @chmod($currdir, $CFG->directorypermissions); // Just in case mkdir didn't do it
6b174680 962 }
963 }
964
965 return $currdir;
966}
967
ca4f8eb8 968function make_mod_upload_directory($courseid) {
9fa49e22 969/// Makes an upload directory for a particular module
ca4f8eb8 970 global $CFG;
971
972 if (! $moddata = make_upload_directory("$courseid/$CFG->moddata")) {
973 return false;
974 }
975
976 $strreadme = get_string("readme");
977
978 if (file_exists("$CFG->dirroot/lang/$CFG->lang/docs/module_files.txt")) {
979 copy("$CFG->dirroot/lang/$CFG->lang/docs/module_files.txt", "$moddata/$strreadme.txt");
980 } else {
981 copy("$CFG->dirroot/lang/en/docs/module_files.txt", "$moddata/$strreadme.txt");
982 }
983 return $moddata;
984}
985
6b174680 986
44e2d2bb 987function valid_uploaded_file($newfile) {
9fa49e22 988/// Returns current name of file on disk if true
9c9f7d77 989 if (empty($newfile)) {
990 return "";
991 }
44e2d2bb 992 if (is_uploaded_file($newfile['tmp_name']) and $newfile['size'] > 0) {
993 return $newfile['tmp_name'];
994 } else {
995 return "";
996 }
997}
998
999function get_max_upload_file_size() {
9fa49e22 1000/// Returns the maximum size for uploading files
44e2d2bb 1001 if (! $filesize = ini_get("upload_max_filesize")) {
1002 $filesize = "5M";
1003 }
1004 return get_real_size($filesize);
1005}
1006
774ab660 1007function get_directory_list($rootdir, $excludefile="", $descend=true) {
9fa49e22 1008/// Returns an array with all the filenames in
1009/// all subdirectories, relative to the given rootdir.
1010/// If excludefile is defined, then that file/directory is ignored
f9903ed0 1011
1012 $dirs = array();
1013
44e2d2bb 1014 $dir = opendir($rootdir);
f9903ed0 1015
d897cae4 1016 if (!$dir) {
1017 notify("Error: unable to read this directory! : $rootdir");
1018 return $dirs;
1019 }
1020
ca4f8eb8 1021 while ($file = readdir($dir)) {
b35e8568 1022 $firstchar = substr($file, 0, 1);
1023 if ($firstchar == "." or $file == "CVS" or $file == $excludefile) {
1024 continue;
1025 }
1026 $fullfile = $rootdir."/".$file;
1027 if ($descend and filetype($fullfile) == "dir") {
1028 $subdirs = get_directory_list($fullfile, $excludefile, $descend);
1029 foreach ($subdirs as $subdir) {
1030 $dirs[] = $file."/".$subdir;
f9903ed0 1031 }
b35e8568 1032 } else {
1033 $dirs[] = $file;
f9903ed0 1034 }
1035 }
44e2d2bb 1036 closedir($dir);
f9903ed0 1037
774ab660 1038 asort($dirs);
1039
f9903ed0 1040 return $dirs;
1041}
1042
989bfa9d 1043function get_real_size($size=0) {
9fa49e22 1044/// Converts numbers like 10M into bytes
989bfa9d 1045 if (!$size) {
1046 return 0;
1047 }
1048 $scan['MB'] = 1048576;
64efda84 1049 $scan['Mb'] = 1048576;
989bfa9d 1050 $scan['M'] = 1048576;
1051 $scan['KB'] = 1024;
64efda84 1052 $scan['Kb'] = 1024;
989bfa9d 1053 $scan['K'] = 1024;
1054
1055 while (list($key) = each($scan)) {
1056 if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) {
1057 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
1058 break;
1059 }
1060 }
1061 return $size;
1062}
1063
44e2d2bb 1064function display_size($size) {
9fa49e22 1065/// Converts bytes into display form
44e2d2bb 1066 if ($size >= 1073741824) {
1067 $size = round($size / 1073741824 * 10) / 10 . "Gb";
1068 } else if ($size >= 1048576) {
1069 $size = round($size / 1048576 * 10) / 10 . "Mb";
1070 } else if ($size >= 1024) {
1071 $size = round($size / 1024 * 10) / 10 . "Kb";
1072 } else {
1073 $size = $size . "b";
1074 }
1075 return $size;
1076}
1077
6b174680 1078function clean_filename($string) {
9fa49e22 1079/// Cleans a given filename by removing suspicious or troublesome characters
fc05fccb 1080 $string = stripslashes($string);
6b174680 1081 $string = eregi_replace("\.\.", "", $string);
5c219ea4 1082 $string = eregi_replace("[^(-|[:alnum:]|\.)]", "_", $string);
6b174680 1083 return eregi_replace("_+", "_", $string);
1084}
1085
1086
1180c6dc 1087/// STRING TRANSLATION ////////////////////////////////////////
1088
4bfa92e7 1089function current_language() {
9fa49e22 1090/// Returns the code for the current language
3db3acfb 1091 global $CFG, $USER, $SESSION;
4bfa92e7 1092
3db3acfb 1093 if (isset($SESSION->lang)) { // Session language can override other settings
1094 return $SESSION->lang;
1095
1096 } else if (isset($USER->lang)) { // User language can override site language
4bfa92e7 1097 return $USER->lang;
3db3acfb 1098
4bfa92e7 1099 } else {
1100 return $CFG->lang;
1101 }
1102}
bcc83c41 1103
9fa49e22 1104function print_string($identifier, $module="", $a=NULL) {
1105/// Given a string to translate - prints it out.
1106 echo get_string($identifier, $module, $a);
1107}
1108
a83fded1 1109function get_string($identifier, $module="", $a=NULL) {
9fa49e22 1110/// Return the translated string specified by $identifier as
1111/// for $module. Uses the same format files as STphp.
1112/// $a is an object, string or number that can be used
1113/// within translation strings
1114///
1115/// eg "hello \$a->firstname \$a->lastname"
1116/// or "hello \$a"
1180c6dc 1117
4bfa92e7 1118 global $CFG;
1180c6dc 1119
4bfa92e7 1120 $lang = current_language();
1180c6dc 1121
058eec18 1122 if ($module == "") {
1123 $module = "moodle";
1180c6dc 1124 }
1125
058eec18 1126 $langpath = "$CFG->dirroot/lang";
1127 $langfile = "$langpath/$lang/$module.php";
1180c6dc 1128
b947c69a 1129 // Look for the string - if found then return it
1130
1131 if (file_exists($langfile)) {
1132 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1133 eval($result);
1134 return $resultstring;
1180c6dc 1135 }
1136 }
1137
b947c69a 1138 // If the preferred language was English we can abort now
1180c6dc 1139
b947c69a 1140 if ($lang == "en") {
1141 return "[[$identifier]]";
1142 }
1180c6dc 1143
b947c69a 1144 // Is a parent language defined? If so, try it.
1145
1146 if ($result = get_string_from_file("parentlanguage", "$langpath/$lang/moodle.php", "\$parentlang")) {
1147 eval($result);
1148 if (!empty($parentlang)) {
1149 $langfile = "$langpath/$parentlang/$module.php";
1150 if (file_exists($langfile)) {
1151 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1152 eval($result);
1153 return $resultstring;
1154 }
1180c6dc 1155 }
1156 }
1157 }
b947c69a 1158
1159 // Our only remaining option is to try English
1160
1161 $langfile = "$langpath/en/$module.php";
1162 if (!file_exists($langfile)) {
1163 return "ERROR: No lang file ($langpath/en/$module.php)!";
1164 }
1165 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
1166 eval($result);
1167 return $resultstring;
1168 }
1169
1170 return "[[$identifier]]"; // Last resort
1180c6dc 1171}
1172
1173
1180c6dc 1174function get_string_from_file($identifier, $langfile, $destination) {
9fa49e22 1175/// This function is only used from get_string().
2b32bddd 1176
1177 static $strings; // Keep the strings cached in memory.
1178
1179 if (empty($strings[$langfile])) {
1180 include ($langfile);
1181 $strings[$langfile] = $string;
1182 } else {
1183 $string = &$strings[$langfile];
1184 }
1180c6dc 1185
1186 if (!isset ($string[$identifier])) {
1187 return false;
1188 }
1189
a83fded1 1190 return "$destination = sprintf(\"".$string[$identifier]."\");";
1180c6dc 1191}
f9903ed0 1192
1193
1a72314d 1194function get_list_of_languages() {
1195/// Returns a list of language codes and their full names
1196 global $CFG;
1197
984a8bf3 1198 $languages = array();
1199
1200 if (!empty($CFG->langlist)) { // use admin's list of languages
1201 $langlist = explode(',', $CFG->langlist);
1202 foreach ($langlist as $lang) {
1203 if (file_exists("$CFG->dirroot/lang/$lang/moodle.php")) {
1204 include("$CFG->dirroot/lang/$lang/moodle.php");
1205 $languages[$lang] = $string["thislanguage"]." ($lang)";
1206 unset($string);
1207 }
1208 }
1209 } else {
1210 if (!$langdirs = get_list_of_plugins("lang")) {
1211 return false;
1212 }
1213 foreach ($langdirs as $lang) {
1214 include("$CFG->dirroot/lang/$lang/moodle.php");
1215 $languages[$lang] = $string["thislanguage"]." ($lang)";
1216 unset($string);
1217 }
1a72314d 1218 }
1219
1a72314d 1220 return $languages;
1221}
1222
9bd2c874 1223function document_file($file, $include=true) {
1224/// Can include a given document file (depends on second
1225/// parameter) or just return info about it
1226
c9d4e6da 1227 global $CFG;
9bd2c874 1228
db356340 1229 $file = clean_filename($file);
1230
9bd2c874 1231 if (empty($file)) {
9bd2c874 1232 return false;
1233 }
1234
db356340 1235 $langs = array(current_language(), get_string("parentlanguage"), "en");
9bd2c874 1236
db356340 1237 foreach ($langs as $lang) {
1238 $info->filepath = "$CFG->dirroot/lang/$lang/docs/$file";
1239 $info->urlpath = "$CFG->wwwroot/lang/$lang/docs/$file";
9bd2c874 1240
db356340 1241 if (file_exists($info->filepath)) {
1242 if ($include) {
1243 include($info->filepath);
1244 }
1245 return $info;
0c106cd3 1246 }
9bd2c874 1247 }
1248
db356340 1249 return false;
9bd2c874 1250}
1251
1a72314d 1252
f9903ed0 1253/// ENCRYPTION ////////////////////////////////////////////////
1254
1255function rc4encrypt($data) {
1256 $password = "nfgjeingjk";
1257 return endecrypt($password, $data, "");
1258}
1259
1260function rc4decrypt($data) {
1261 $password = "nfgjeingjk";
1262 return endecrypt($password, $data, "de");
1263}
1264
1265function endecrypt ($pwd, $data, $case) {
9fa49e22 1266/// Based on a class by Mukul Sabharwal [mukulsabharwal@yahoo.com]
f9903ed0 1267
1268 if ($case == 'de') {
1269 $data = urldecode($data);
1270 }
1271
1272 $key[] = "";
1273 $box[] = "";
1274 $temp_swap = "";
1275 $pwd_length = 0;
1276
1277 $pwd_length = strlen($pwd);
1278
1279 for ($i = 0; $i <= 255; $i++) {
1280 $key[$i] = ord(substr($pwd, ($i % $pwd_length), 1));
1281 $box[$i] = $i;
1282 }
1283
1284 $x = 0;
1285
1286 for ($i = 0; $i <= 255; $i++) {
1287 $x = ($x + $box[$i] + $key[$i]) % 256;
1288 $temp_swap = $box[$i];
1289 $box[$i] = $box[$x];
1290 $box[$x] = $temp_swap;
1291 }
1292
1293 $temp = "";
1294 $k = "";
1295
1296 $cipherby = "";
1297 $cipher = "";
1298
1299 $a = 0;
1300 $j = 0;
1301
1302 for ($i = 0; $i < strlen($data); $i++) {
1303 $a = ($a + 1) % 256;
1304 $j = ($j + $box[$a]) % 256;
1305 $temp = $box[$a];
1306 $box[$a] = $box[$j];
1307 $box[$j] = $temp;
1308 $k = $box[(($box[$a] + $box[$j]) % 256)];
1309 $cipherby = ord(substr($data, $i, 1)) ^ $k;
1310 $cipher .= chr($cipherby);
1311 }
1312
1313 if ($case == 'de') {
1314 $cipher = urldecode(urlencode($cipher));
1315 } else {
1316 $cipher = urlencode($cipher);
1317 }
1318
1319 return $cipher;
1320}
1321
1322
9fa49e22 1323/// ENVIRONMENT CHECKING ////////////////////////////////////////////////////////////
1e3e716f 1324
1d881d92 1325function get_list_of_plugins($plugin="mod") {
1326/// Lists plugin directories within some directory
1327
1328 global $CFG;
1329
1330 $basedir = opendir("$CFG->dirroot/$plugin");
1331 while ($dir = readdir($basedir)) {
b35e8568 1332 $firstchar = substr($dir, 0, 1);
6815044f 1333 if ($firstchar == "." or $dir == "CVS" or $dir == "vti_cnf") {
1d881d92 1334 continue;
1335 }
1336 if (filetype("$CFG->dirroot/$plugin/$dir") != "dir") {
1337 continue;
1338 }
1339 $plugins[] = $dir;
1340 }
1341 if ($plugins) {
1342 asort($plugins);
1343 }
1344 return $plugins;
1345}
1346
b0cb5e22 1347function check_php_version($version="4.1.0") {
9fa49e22 1348/// Returns true is the current version of PHP is greater that the specified one
b0cb5e22 1349 $minversion = intval(str_replace(".", "", $version));
1350 $curversion = intval(str_replace(".", "", phpversion()));
1351 return ($curversion >= $minversion);
1352}
1353
0095d5cd 1354function check_browser_version($brand="MSIE", $version=5.5) {
9fa49e22 1355/// Checks to see if is a browser matches the specified
1356/// brand and is equal or better version.
0095d5cd 1357
607809b3 1358 if (empty($_SERVER["HTTP_USER_AGENT"])) {
0095d5cd 1359 return false;
1360 }
607809b3 1361 $string = explode(";", $_SERVER["HTTP_USER_AGENT"]);
0095d5cd 1362 if (!isset($string[1])) {
1363 return false;
1364 }
1365 $string = explode(" ", trim($string[1]));
1366 if (!isset($string[0]) and !isset($string[1])) {
1367 return false;
1368 }
1369 if ($string[0] == $brand and (float)$string[1] >= $version ) {
1370 return true;
1371 }
1372 return false;
1373}
1374
c39c66a5 1375function ini_get_bool($ini_get_arg) {
1376/// This function makes the return value of ini_get consistent if you are
1377/// setting server directives through the .htaccess file in apache.
1378/// Current behavior for value set from php.ini On = 1, Off = [blank]
1379/// Current behavior for value set from .htaccess On = On, Off = Off
1380/// Contributed by jdell@unr.edu
1381
1382 $temp = ini_get($ini_get_arg);
1383
1384 if ($temp == "1" or strtolower($temp) == "on") {
1385 return true;
1386 }
1387 return false;
1388}
1389
0095d5cd 1390function can_use_richtext_editor() {
9fa49e22 1391/// Is the richedit editor enabled?
0095d5cd 1392 global $USER, $CFG;
ce78926d 1393 if (!empty($USER->htmleditor) and !empty($CFG->htmleditor)) {
7ce20f09 1394 return check_browser_version("MSIE", 5.5);
1395 }
1396 return false;
0095d5cd 1397}
1398
74944b73 1399function check_gd_version() {
9fa49e22 1400/// Hack to find out the GD version by parsing phpinfo output
aa095969 1401 $gdversion = 0;
74944b73 1402
aa095969 1403 if (function_exists('gd_info')){
1404 $gd_info = gd_info();
3ee23682 1405 if (substr_count($gd_info['GD Version'], "2.")) {
aa095969 1406 $gdversion = 2;
3ee23682 1407 } else if (substr_count($gd_info['GD Version'], "1.")) {
1408 $gdversion = 1;
aa095969 1409 }
3ee23682 1410
aa095969 1411 } else {
1412 ob_start();
1413 phpinfo(8);
1414 $phpinfo = ob_get_contents();
1415 ob_end_clean();
74944b73 1416
aa095969 1417 $phpinfo = explode("\n",$phpinfo);
74944b73 1418
92a4b0f1 1419
aa095969 1420 foreach ($phpinfo as $text) {
1421 $parts = explode('</td>',$text);
1422 foreach ($parts as $key => $val) {
1423 $parts[$key] = trim(strip_tags($val));
1424 }
1425 if ($parts[0] == "GD Version") {
1426 if (substr_count($parts[1], "2.0")) {
1427 $parts[1] = "2.0";
1428 }
1429 $gdversion = intval($parts[1]);
92a4b0f1 1430 }
74944b73 1431 }
1432 }
1433
1434 return $gdversion; // 1, 2 or 0
1435}
f9903ed0 1436
0095d5cd 1437
9fa49e22 1438function moodle_needs_upgrading() {
1439/// Checks version numbers of Main code and all modules to see
1440/// if there are any mismatches ... returns true or false
1441 global $CFG;
1442
1443 include_once("$CFG->dirroot/version.php"); # defines $version and upgrades
1444 if ($CFG->version) {
1445 if ($version > $CFG->version) {
1446 return true;
1447 }
1448 if ($mods = get_list_of_plugins("mod")) {
1449 foreach ($mods as $mod) {
1450 $fullmod = "$CFG->dirroot/mod/$mod";
1451 unset($module);
1079c8a8 1452 if (!is_readable("$fullmod/version.php")) {
1453 notify("Module '$mod' is not readable - check permissions");
1454 continue;
1455 }
9fa49e22 1456 include_once("$fullmod/version.php"); # defines $module with version etc
1457 if ($currmodule = get_record("modules", "name", $mod)) {
1458 if ($module->version > $currmodule->version) {
1459 return true;
1460 }
1461 }
1462 }
1463 }
1464 } else {
1465 return true;
1466 }
1467 return false;
1468}
1469
1470
1471/// MISCELLANEOUS ////////////////////////////////////////////////////////////////////
1472
7d6cac54 1473function moodle_strtolower ($string, $encoding='') {
1474/// Converts string to lowercase using most compatible function available
1475 if (function_exists('mb_strtolower')) {
1476 if($encoding===''){
1477 return mb_strtolower($string); //use multibyte support with default encoding
1478 } else {
dbe0be00 1479 return mb_strtolower($string,$encoding); //use given encoding
7d6cac54 1480 }
1481 } else {
1482 return strtolower($string); // use common function what rely on current locale setting
1483 }
1484}
1485
9fa49e22 1486function count_words($string) {
1487/// Words are defined as things between whitespace
1488 $string = strip_tags($string);
1489 return count(preg_split("/\w\b/", $string)) - 1;
1490}
1491
1d881d92 1492function random_string ($length=15) {
1493 $pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1494 $pool .= "abcdefghijklmnopqrstuvwxyz";
1495 $pool .= "0123456789";
1496 $poollen = strlen($pool);
1497 mt_srand ((double) microtime() * 1000000);
1498 $string = "";
1499 for ($i = 0; $i < $length; $i++) {
1500 $string .= substr($pool, (mt_rand()%($poollen)), 1);
1501 }
1502 return $string;
1503}
1504
1505
9fa49e22 1506function getweek ($startdate, $thedate) {
1507/// Given dates in seconds, how many weeks is the date from startdate
1508/// The first week is 1, the second 2 etc ...
1509
1510 if ($thedate < $startdate) { // error
1511 return 0;
1512 }
1513
1514 return floor(($thedate - $startdate) / 604800.0) + 1;
1515}
1516
1517function generate_password($maxlen=10) {
1518/// returns a randomly generated password of length $maxlen. inspired by
1519/// http://www.phpbuilder.com/columns/jesus19990502.php3
1520
1521 global $CFG;
1522
1523 $fillers = "1234567890!$-+";
1524 $wordlist = file($CFG->wordlist);
1525
1526 srand((double) microtime() * 1000000);
1527 $word1 = trim($wordlist[rand(0, count($wordlist) - 1)]);
1528 $word2 = trim($wordlist[rand(0, count($wordlist) - 1)]);
1529 $filler1 = $fillers[rand(0, strlen($fillers) - 1)];
1530
1531 return substr($word1 . $filler1 . $word2, 0, $maxlen);
1532}
1533
1534function format_float($num, $places=0) {
1535/// Given a float, prints it nicely
1536 return sprintf("%.$places"."f", $num);
1537}
1538
ee0e5d57 1539function swapshuffle($array) {
1540/// Given a simple array, this shuffles it up just like shuffle()
1541/// Unlike PHP's shuffle() ihis function works on any machine.
1542
1543 srand ((double) microtime() * 10000000);
1544 $last = count($array) - 1;
1545 for ($i=0;$i<=$last;$i++) {
1546 $from = rand(0,$last);
1547 $curr = $array[$i];
1548 $array[$i] = $array[$from];
1549 $array[$from] = $curr;
1550 }
1551 return $array;
1552}
1553
bc700e65 1554function swapshuffle_assoc($array) {
1555/// Like swapshuffle, but works on associative arrays
1556
1557 $newkeys = swapshuffle(array_keys($array));
1558 foreach ($newkeys as $newkey) {
1559 $newarray[$newkey] = $array[$newkey];
1560 }
1561 return $newarray;
1562}
1563
ee0e5d57 1564function draw_rand_array($array, $draws) {
1565/// Given an arbitrary array, and a number of draws,
1566/// this function returns an array with that amount
1567/// of items. The indexes are retained.
1568
1569 srand ((double) microtime() * 10000000);
1570
1571 $return = array();
1572
1573 $last = count($array);
1574
1575 if ($draws > $last) {
1576 $draws = $last;
1577 }
1578
1579 while ($draws > 0) {
1580 $last--;
1581
1582 $keys = array_keys($array);
1583 $rand = rand(0, $last);
1584
1585 $return[$keys[$rand]] = $array[$keys[$rand]];
1586 unset($array[$keys[$rand]]);
1587
1588 $draws--;
1589 }
1590
1591 return $return;
1592}
9fa49e22 1593
f5e82bc7 1594function microtime_diff($a, $b) {
1595 list($a_dec, $a_sec) = explode(" ", $a);
1596 list($b_dec, $b_sec) = explode(" ", $b);
1597 return $b_sec - $a_sec + $b_dec - $a_dec;
1598}
1599
02ebf404 1600function make_menu_from_list($list, $separator=",") {
1601/// Given a list (eg a,b,c,d,e) this function returns
1602/// an array of 1->a, 2->b, 3->c etc
1603
1604 $array = array_reverse(explode($separator, $list), true);
1605 foreach ($array as $key => $item) {
1606 $outarray[$key+1] = trim($item);
1607 }
1608 return $outarray;
1609}
1610
0095d5cd 1611
9d5b689c 1612// vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
f9903ed0 1613?>