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