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