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