MDL-14617 removed some legacy group code
[moodle.git] / lib / deprecatedlib.php
CommitLineData
c4d0753b 1<?php // $Id$
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.org //
9// //
b7064779 10// Copyright (C) 1999 onwards Martin Dougiamas, Moodle http://moodle.com //
c4d0753b 11// //
12// This program is free software; you can redistribute it and/or modify //
13// it under the terms of the GNU General Public License as published by //
14// the Free Software Foundation; either version 2 of the License, or //
15// (at your option) any later version. //
16// //
17// This program is distributed in the hope that it will be useful, //
18// but WITHOUT ANY WARRANTY; without even the implied warranty of //
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
20// GNU General Public License for more details: //
21// //
22// http://www.gnu.org/copyleft/gpl.html //
23// //
24///////////////////////////////////////////////////////////////////////////
25
26/**
27 * deprecatedlib.php - Old functions retained only for backward compatibility
28 *
29 * Old functions retained only for backward compatibility. New code should not
30 * use any of these functions.
31 *
32 * @author Martin Dougiamas
33 * @version $Id$
34 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
35 * @package moodlecore
36 */
37
38
c4d0753b 39/**
40 * Determines if a user an admin
41 *
42 * @uses $USER
43 * @param int $userid The id of the user as is found in the 'user' table
44 * @staticvar array $admins List of users who have been found to be admins by user id
45 * @staticvar array $nonadmins List of users who have been found not to be admins by user id
46 * @return bool
47 */
48function isadmin($userid=0) {
49 global $USER, $CFG;
50
51 if (empty($CFG->rolesactive)) { // Then the user is likely to be upgrading NOW
52 if (!$userid) {
53 if (empty($USER->id)) {
54 return false;
55 }
56 if (!empty($USER->admin)) {
57 return true;
58 }
59 $userid = $USER->id;
60 }
61
62 return record_exists('user_admins', 'userid', $userid);
63 }
64
12d06877 65 $context = get_context_instance(CONTEXT_SYSTEM);
364fffda 66
c2da0757 67 return has_capability('moodle/legacy:admin', $context, $userid, false);
c4d0753b 68}
69
70/**
71 * Determines if a user is a teacher (or better)
72 *
c4d0753b 73 * @uses $CFG
74 * @param int $courseid The id of the course that is being viewed, if any
75 * @param int $userid The id of the user that is being tested against. Set this to 0 if you would just like to test against the currently logged in user.
76 * @param bool $obsolete_includeadmin Not used any more
77 * @return bool
78 */
79
80function isteacher($courseid=0, $userid=0, $obsolete_includeadmin=true) {
81/// Is the user able to access this course as a teacher?
c2da0757 82 global $CFG;
c4d0753b 83
84 if (empty($CFG->rolesactive)) { // Teachers are locked out during an upgrade to 1.7
85 return false;
86 }
87
88 if ($courseid) {
89 $context = get_context_instance(CONTEXT_COURSE, $courseid);
90 } else {
12d06877 91 $context = get_context_instance(CONTEXT_SYSTEM);
c4d0753b 92 }
93
c2da0757 94 return (has_capability('moodle/legacy:teacher', $context, $userid, false)
95 or has_capability('moodle/legacy:editingteacher', $context, $userid, false)
96 or has_capability('moodle/legacy:admin', $context, $userid, false));
c4d0753b 97}
98
99/**
100 * Determines if a user is a teacher in any course, or an admin
101 *
102 * @uses $USER
103 * @param int $userid The id of the user that is being tested against. Set this to 0 if you would just like to test against the currently logged in user.
c2da0757 104 * @param bool $includeadmin Include anyone wo is an admin as well
c4d0753b 105 * @return bool
106 */
c2da0757 107function isteacherinanycourse($userid=0, $includeadmin=true) {
c4d0753b 108 global $USER, $CFG;
109
110 if (empty($CFG->rolesactive)) { // Teachers are locked out during an upgrade to 1.7
111 return false;
112 }
113
114 if (!$userid) {
115 if (empty($USER->id)) {
116 return false;
117 }
118 $userid = $USER->id;
119 }
120
121 if (!record_exists('role_assignments', 'userid', $userid)) { // Has no roles anywhere
122 return false;
123 }
124
125/// If this user is assigned as an editing teacher anywhere then return true
126 if ($roles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW)) {
127 foreach ($roles as $role) {
128 if (record_exists('role_assignments', 'roleid', $role->id, 'userid', $userid)) {
129 return true;
130 }
131 }
132 }
133
134/// If this user is assigned as a non-editing teacher anywhere then return true
135 if ($roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW)) {
136 foreach ($roles as $role) {
137 if (record_exists('role_assignments', 'roleid', $role->id, 'userid', $userid)) {
138 return true;
139 }
140 }
141 }
142
c2da0757 143/// Include admins if required
144 if ($includeadmin) {
12d06877 145 $context = get_context_instance(CONTEXT_SYSTEM);
c2da0757 146 if (has_capability('moodle/legacy:admin', $context, $userid, false)) {
147 return true;
148 }
149 }
c4d0753b 150
151 return false;
152}
153
c4d0753b 154/**
155 * Determines if a user is allowed to edit a given course
156 *
c4d0753b 157 * @param int $courseid The id of the course that is being edited
158 * @param int $userid The id of the user that is being tested against. Set this to 0 if you would just like to test against the currently logged in user.
159 * @return bool
160 */
161function isteacheredit($courseid, $userid=0, $obsolete_ignorestudentview=false) {
c2da0757 162 global $CFG;
c4d0753b 163
164 if (empty($CFG->rolesactive)) {
165 return false;
166 }
167
168 if (empty($courseid)) {
12d06877 169 $context = get_context_instance(CONTEXT_SYSTEM);
c4d0753b 170 } else {
171 $context = get_context_instance(CONTEXT_COURSE, $courseid);
172 }
173
c2da0757 174 return (has_capability('moodle/legacy:editingteacher', $context, $userid, false)
175 or has_capability('moodle/legacy:admin', $context, $userid, false));
c4d0753b 176}
177
178/**
179 * Determines if a user can create new courses
180 *
c4d0753b 181 * @param int $userid The user being tested. You can set this to 0 or leave it blank to test the currently logged in user.
182 * @return bool
183 */
184function iscreator ($userid=0) {
c2da0757 185 global $CFG;
c4d0753b 186
187 if (empty($CFG->rolesactive)) {
188 return false;
189 }
190
12d06877 191 $context = get_context_instance(CONTEXT_SYSTEM);
c4d0753b 192
c2da0757 193 return (has_capability('moodle/legacy:coursecreator', $context, $userid, false)
194 or has_capability('moodle/legacy:admin', $context, $userid, false));
c4d0753b 195}
196
197/**
198 * Determines if a user is a student in the specified course
199 *
200 * If the course id specifies the site then this determines
201 * if the user is a confirmed and valid user of this site.
202 *
c4d0753b 203 * @uses $CFG
204 * @uses SITEID
205 * @param int $courseid The id of the course being tested
206 * @param int $userid The user being tested. You can set this to 0 or leave it blank to test the currently logged in user.
207 * @return bool
208 */
209function isstudent($courseid=0, $userid=0) {
c2da0757 210 global $CFG;
c4d0753b 211
212 if (empty($CFG->rolesactive)) {
213 return false;
214 }
215
216 if ($courseid == 0) {
12d06877 217 $context = get_context_instance(CONTEXT_SYSTEM);
c4d0753b 218 } else {
219 $context = get_context_instance(CONTEXT_COURSE, $courseid);
220 }
221
c2da0757 222 return has_capability('moodle/legacy:student', $context, $userid, false);
c4d0753b 223}
224
225/**
226 * Determines if the specified user is logged in as guest.
227 *
c4d0753b 228 * @param int $userid The user being tested. You can set this to 0 or leave it blank to test the currently logged in user.
229 * @return bool
230 */
231function isguest($userid=0) {
c2da0757 232 global $CFG;
c4d0753b 233
234 if (empty($CFG->rolesactive)) {
235 return false;
236 }
237
364fffda 238 $context = get_context_instance(CONTEXT_SYSTEM);
c4d0753b 239
c2da0757 240 return has_capability('moodle/legacy:guest', $context, $userid, false);
c4d0753b 241}
242
613bbd7c 243
244/**
245 * Get the guest user information from the database
246 *
247 * @return object(user) An associative array with the details of the guest user account.
248 * @todo Is object(user) a correct return type? Or is array the proper return type with a note that the contents include all details for a user.
249 */
250function get_guest() {
251 return get_complete_user_data('username', 'guest');
252}
253
613bbd7c 254/**
255 * Returns $user object of the main teacher for a course
256 *
257 * @uses $CFG
258 * @param int $courseid The course in question.
259 * @return user|false A {@link $USER} record of the main teacher for the specified course or false if error.
260 * @todo Finish documenting this function
261 */
262function get_teacher($courseid) {
263
264 global $CFG;
265
888fb649 266 $context = get_context_instance(CONTEXT_COURSE, $courseid);
267
1113f800 268 // Pass $view=true to filter hidden caps if the user cannot see them
269 if ($users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC',
270 '', '', '', '', false, true)) {
b1469317 271 $users = sort_by_roleassignment_authority($users, $context);
1113f800 272 return array_shift($users);
613bbd7c 273 }
888fb649 274
275 return false;
613bbd7c 276}
277
278/**
279 * Searches logs to find all enrolments since a certain date
280 *
281 * used to print recent activity
282 *
283 * @uses $CFG
284 * @param int $courseid The course in question.
285 * @return object|false {@link $USER} records or false if error.
286 * @todo Finish documenting this function
287 */
288function get_recent_enrolments($courseid, $timestart) {
289
290 global $CFG;
364fffda 291
71dea306 292 $context = get_context_instance(CONTEXT_COURSE, $courseid);
613bbd7c 293
294 return get_records_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, l.time
295 FROM {$CFG->prefix}user u,
71dea306 296 {$CFG->prefix}role_assignments ra,
613bbd7c 297 {$CFG->prefix}log l
298 WHERE l.time > '$timestart'
299 AND l.course = '$courseid'
300 AND l.module = 'course'
301 AND l.action = 'enrol'
302 AND l.info = u.id
71dea306 303 AND u.id = ra.userid
304 AND ra.contextid ".get_related_contexts_string($context)."
613bbd7c 305 ORDER BY l.time ASC");
306}
307
308/**
309 * Returns array of userinfo of all students in this course
310 * or on this site if courseid is id of site
311 *
312 * @uses $CFG
313 * @uses SITEID
314 * @param int $courseid The course in question.
315 * @param string $sort ?
316 * @param string $dir ?
317 * @param int $page ?
318 * @param int $recordsperpage ?
319 * @param string $firstinitial ?
320 * @param string $lastinitial ?
321 * @param ? $group ?
322 * @param string $search ?
323 * @param string $fields A comma separated list of fields to be returned from the chosen table.
324 * @param string $exceptions ?
325 * @return object
326 * @todo Finish documenting this function
327 */
36075e09 328function get_course_students($courseid, $sort='ul.timeaccess', $dir='', $page='', $recordsperpage='',
613bbd7c 329 $firstinitial='', $lastinitial='', $group=NULL, $search='', $fields='', $exceptions='') {
330
331 global $CFG;
332
b069fbd9 333 // make sure it works on the site course
334 $context = get_context_instance(CONTEXT_COURSE, $courseid);
71dea306 335
364fffda 336 /// For the site course, old way was to check if $CFG->allusersaresitestudents was set to true.
b069fbd9 337 /// The closest comparible method using roles is if the $CFG->defaultuserroleid is set to the legacy
364fffda 338 /// student role. This function should be replaced where it is used with something more meaningful.
b069fbd9 339 if (($courseid == SITEID) && !empty($CFG->defaultuserroleid) && empty($CFG->nodefaultuserrolelists)) {
340 if ($roles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW, $context)) {
341 $hascap = false;
342 foreach ($roles as $role) {
343 if ($role->id == $CFG->defaultuserroleid) {
344 $hascap = true;
345 break;
346 }
613bbd7c 347 }
b069fbd9 348 if ($hascap) {
349 // return users with confirmed, undeleted accounts who are not site teachers
350 // the following is a mess because of different conventions in the different user functions
351 $sort = str_replace('s.timeaccess', 'lastaccess', $sort); // site users can't be sorted by timeaccess
352 $sort = str_replace('timeaccess', 'lastaccess', $sort); // site users can't be sorted by timeaccess
353 $sort = str_replace('u.', '', $sort); // the get_user function doesn't use the u. prefix to fields
354 $fields = str_replace('u.', '', $fields);
355 if ($sort) {
356 $sort = $sort .' '. $dir;
357 }
358 // Now we have to make sure site teachers are excluded
364fffda 359
b069fbd9 360 if ($teachers = get_course_teachers(SITEID)) {
361 foreach ($teachers as $teacher) {
362 $exceptions .= ','. $teacher->userid;
363 }
364fffda 364 $exceptions = ltrim($exceptions, ',');
365
366 }
367
b069fbd9 368 return get_users(true, $search, true, $exceptions, $sort, $firstinitial, $lastinitial,
369 $page, $recordsperpage, $fields ? $fields : '*');
370 }
371 }
613bbd7c 372 }
373
613bbd7c 374 $LIKE = sql_ilike();
375 $fullname = sql_fullname('u.firstname','u.lastname');
376
377 $groupmembers = '';
378
acf2052b 379 $select = "c.contextlevel=".CONTEXT_COURSE." AND "; // Must be on a course
380 if ($courseid != SITEID) {
381 // If not site, require specific course
382 $select.= "c.instanceid=$courseid AND ";
613bbd7c 383 }
364fffda 384 $select.="rc.capability='moodle/legacy:student' AND rc.permission=".CAP_ALLOW." AND ";
613bbd7c 385
71dea306 386 $select .= ' u.deleted = \'0\' ';
613bbd7c 387
388 if (!$fields) {
389 $fields = 'u.id, u.confirmed, u.username, u.firstname, u.lastname, '.
390 'u.maildisplay, u.mailformat, u.maildigest, u.email, u.city, '.
391 'u.country, u.picture, u.idnumber, u.department, u.institution, '.
71dea306 392 'u.emailstop, u.lang, u.timezone, ul.timeaccess as lastaccess';
613bbd7c 393 }
394
395 if ($search) {
396 $search = ' AND ('. $fullname .' '. $LIKE .'\'%'. $search .'%\' OR email '. $LIKE .'\'%'. $search .'%\') ';
397 }
398
399 if ($firstinitial) {
400 $select .= ' AND u.firstname '. $LIKE .'\''. $firstinitial .'%\' ';
401 }
402
403 if ($lastinitial) {
404 $select .= ' AND u.lastname '. $LIKE .'\''. $lastinitial .'%\' ';
405 }
406
407 if ($group === 0) { /// Need something here to get all students not in a group
408 return array();
409
410 } else if ($group !== NULL) {
71dea306 411 $groupmembers = "INNER JOIN {$CFG->prefix}groups_members gm on u.id=gm.userid";
412 $select .= ' AND gm.groupid = \''. $group .'\'';
613bbd7c 413 }
414
415 if (!empty($exceptions)) {
416 $select .= ' AND u.id NOT IN ('. $exceptions .')';
417 }
418
419 if ($sort) {
420 $sort = ' ORDER BY '. $sort .' ';
421 }
422
423 $students = get_records_sql("SELECT $fields
acf2052b 424 FROM {$CFG->prefix}user u INNER JOIN
425 {$CFG->prefix}role_assignments ra on u.id=ra.userid INNER JOIN
426 {$CFG->prefix}role_capabilities rc ON ra.roleid=rc.roleid INNER JOIN
427 {$CFG->prefix}context c ON c.id=ra.contextid LEFT OUTER JOIN
428 {$CFG->prefix}user_lastaccess ul on ul.userid=ra.userid
429 $groupmembers
364fffda 430 WHERE $select $search $sort $dir", $page, $recordsperpage);
613bbd7c 431
71dea306 432 return $students;
613bbd7c 433}
434
613bbd7c 435/**
436 * Counts the students in a given course (or site), or a subset of them
437 *
438 * @param object $course The course in question as a course object.
439 * @param string $search ?
364fffda 440 * @param string $firstinitial ?
613bbd7c 441 * @param string $lastinitial ?
442 * @param ? $group ?
364fffda 443 * @param string $exceptions ?
613bbd7c 444 * @return int
445 * @todo Finish documenting this function
446 */
447function count_course_students($course, $search='', $firstinitial='', $lastinitial='', $group=NULL, $exceptions='') {
448
449 if ($students = get_course_students($course->id, '', '', 0, 999999, $firstinitial, $lastinitial, $group, $search, '', $exceptions)) {
450 return count($students);
451 }
452 return 0;
453}
454
613bbd7c 455/**
456 * Returns list of all teachers in this course
457 *
458 * If $courseid matches the site id then this function
459 * returns a list of all teachers for the site.
460 *
461 * @uses $CFG
462 * @param int $courseid The course in question.
463 * @param string $sort ?
364fffda 464 * @param string $exceptions ?
613bbd7c 465 * @return object
466 * @todo Finish documenting this function
467 */
468function get_course_teachers($courseid, $sort='t.authority ASC', $exceptions='') {
469
470 global $CFG;
364fffda 471
71dea306 472 $sort = 'ul.timeaccess DESC';
364fffda 473
71dea306 474 $context = get_context_instance(CONTEXT_COURSE, $courseid);
b069fbd9 475
476 /// For the site course, if the $CFG->defaultuserroleid is set to the legacy teacher role, then all
364fffda 477 /// users are teachers. This function should be replaced where it is used with something more
478 /// meaningful.
b069fbd9 479 if (($courseid == SITEID) && !empty($CFG->defaultuserroleid) && empty($CFG->nodefaultuserrolelists)) {
480 if ($roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW, $context)) {
481 $hascap = false;
482 foreach ($roles as $role) {
483 if ($role->id == $CFG->defaultuserroleid) {
484 $hascap = true;
485 break;
486 }
487 }
488 if ($hascap) {
489 if (empty($fields)) {
490 $fields = '*';
491 }
492 return get_users(true, '', true, $exceptions, 'lastname ASC', '', '', '', '', $fields);
493 }
494 }
495 }
496
b1469317 497 $users = get_users_by_capability($context, 'moodle/course:update',
498 'u.*, ul.timeaccess as lastaccess',
499 $sort, '','','',$exceptions, false);
500 return sort_by_roleassignment_authority($users, $context);
501
71dea306 502 /// some fields will be missing, like authority, editall
503 /*
613bbd7c 504 return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat, u.maildigest,
505 u.email, u.city, u.country, u.lastlogin, u.picture, u.lang, u.timezone,
506 u.emailstop, t.authority,t.role,t.editall,t.timeaccess as lastaccess
507 FROM {$CFG->prefix}user u,
508 {$CFG->prefix}user_teachers t
509 WHERE t.course = '$courseid' AND t.userid = u.id
510 AND u.deleted = '0' AND u.confirmed = '1' $exceptions $sort");
71dea306 511 */
613bbd7c 512}
513
514/**
515 * Returns all the users of a course: students and teachers
516 *
517 * @param int $courseid The course in question.
518 * @param string $sort ?
519 * @param string $exceptions ?
520 * @param string $fields A comma separated list of fields to be returned from the chosen table.
521 * @return object
522 * @todo Finish documenting this function
523 */
47b18c1c 524function get_course_users($courseid, $sort='ul.timeaccess DESC', $exceptions='', $fields='u.*, ul.timeaccess as lastaccess') {
b069fbd9 525 global $CFG;
613bbd7c 526
71dea306 527 $context = get_context_instance(CONTEXT_COURSE, $courseid);
b069fbd9 528
529 /// If the course id is the SITEID, we need to return all the users if the "defaultuserroleid"
364fffda 530 /// has the capbility of accessing the site course. $CFG->nodefaultuserrolelists set to true can
b069fbd9 531 /// over-rule using this.
532 if (($courseid == SITEID) && !empty($CFG->defaultuserroleid) && empty($CFG->nodefaultuserrolelists)) {
533 if ($roles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context)) {
534 $hascap = false;
535 foreach ($roles as $role) {
536 if ($role->id == $CFG->defaultuserroleid) {
537 $hascap = true;
538 break;
539 }
540 }
541 if ($hascap) {
542 if (empty($fields)) {
543 $fields = '*';
544 }
545 return get_users(true, '', true, $exceptions, 'lastname ASC', '', '', '', '', $fields);
546 }
547 }
548 }
47b18c1c 549 return get_users_by_capability($context, 'moodle/course:view', $fields, $sort, '','','',$exceptions, false);
613bbd7c 550
551}
552
613bbd7c 553/**
554 * Returns an array of user objects
555 *
556 * @uses $CFG
557 * @param int $groupid The group(s) in question.
558 * @param string $sort How to sort the results
559 * @return object (changed to groupids)
560 */
7b6a42f5 561function get_group_students($groupids, $sort='ul.timeaccess DESC') {
364fffda 562
613bbd7c 563 if (is_array($groupids)){
564 $groups = $groupids;
7b6a42f5 565 // all groups must be from one course anyway...
f3f7610c 566 $group = groups_get_group(array_shift($groups));
7b6a42f5 567 } else {
f3f7610c 568 $group = groups_get_group($groupids);
613bbd7c 569 }
7b6a42f5 570 if (!$group) {
571 return NULL;
613bbd7c 572 }
573
7b6a42f5 574 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
1d546bb1 575 return get_users_by_capability($context, 'moodle/legacy:student', 'u.*, ul.timeaccess as lastaccess', $sort, '','',$groupids, '', false);
613bbd7c 576}
577
2123b644 578
579########### FROM weblib.php ##########################################################################
580
aa68a7b0 581/**
582 * Creates a nicely formatted table and returns it.
583 *
584 * @param array $table is an object with several properties.
585 * <ul<li>$table->head - An array of heading names.
586 * <li>$table->align - An array of column alignments
587 * <li>$table->size - An array of column sizes
588 * <li>$table->wrap - An array of "nowrap"s or nothing
589 * <li>$table->data[] - An array of arrays containing the data.
590 * <li>$table->class - A css class name
591 * <li>$table->fontsize - Is the size of all the text
592 * <li>$table->tablealign - Align the whole table
593 * <li>$table->width - A percentage of the page
594 * <li>$table->cellpadding - Padding on each cell
595 * <li>$table->cellspacing - Spacing between cells
596 * </ul>
597 * @return string
598 * @todo Finish documenting this function
599 */
600function make_table($table) {
601 return print_table($table, true);
602}
603
2123b644 604
605/**
606 * Print a message in a standard themed box.
364fffda 607 * This old function used to implement boxes using tables. Now it uses a DIV, but the old
2123b644 608 * parameters remain. If possible, $align, $width and $color should not be defined at all.
609 * Preferably just use print_box() in weblib.php
610 *
611 * @param string $align, alignment of the box, not the text (default center, left, right).
612 * @param string $width, width of the box, including units %, for example '100%'.
613 * @param string $color, background colour of the box, for example '#eee'.
614 * @param int $padding, padding in pixels, specified without units.
615 * @param string $class, space-separated class names.
616 * @param string $id, space-separated id names.
617 * @param boolean $return, return as string or just print it
618 */
619function print_simple_box($message, $align='', $width='', $color='', $padding=5, $class='generalbox', $id='', $return=false) {
620 $output = '';
621 $output .= print_simple_box_start($align, $width, $color, $padding, $class, $id, true);
622 $output .= stripslashes_safe($message);
623 $output .= print_simple_box_end(true);
624
625 if ($return) {
626 return $output;
627 } else {
628 echo $output;
629 }
630}
631
632
633
634/**
364fffda 635 * This old function used to implement boxes using tables. Now it uses a DIV, but the old
2123b644 636 * parameters remain. If possible, $align, $width and $color should not be defined at all.
637 * Even better, please use print_box_start() in weblib.php
638 *
639 * @param string $align, alignment of the box, not the text (default center, left, right). DEPRECATED
640 * @param string $width, width of the box, including % units, for example '100%'. DEPRECATED
641 * @param string $color, background colour of the box, for example '#eee'. DEPRECATED
642 * @param int $padding, padding in pixels, specified without units. OBSOLETE
643 * @param string $class, space-separated class names.
644 * @param string $id, space-separated id names.
645 * @param boolean $return, return as string or just print it
646 */
647function print_simple_box_start($align='', $width='', $color='', $padding=5, $class='generalbox', $id='', $return=false) {
648
649 $output = '';
650
8f36e33e 651 $divclasses = 'box '.$class.' '.$class.'content';
2123b644 652 $divstyles = '';
653
654 if ($align) {
655 $divclasses .= ' boxalign'.$align; // Implement alignment using a class
656 }
657 if ($width) { // Hopefully we can eliminate these in calls to this function (inline styles are bad)
8f36e33e 658 if (substr($width, -1, 1) == '%') { // Width is a % value
659 $width = (int) substr($width, 0, -1); // Extract just the number
660 if ($width < 40) {
661 $divclasses .= ' boxwidthnarrow'; // Approx 30% depending on theme
662 } else if ($width > 60) {
663 $divclasses .= ' boxwidthwide'; // Approx 80% depending on theme
664 } else {
665 $divclasses .= ' boxwidthnormal'; // Approx 50% depending on theme
666 }
667 } else {
668 $divstyles .= ' width:'.$width.';'; // Last resort
669 }
2123b644 670 }
671 if ($color) { // Hopefully we can eliminate these in calls to this function (inline styles are bad)
672 $divstyles .= ' background:'.$color.';';
673 }
674 if ($divstyles) {
675 $divstyles = ' style="'.$divstyles.'"';
676 }
677
678 if ($id) {
679 $id = ' id="'.$id.'"';
680 }
681
682 $output .= '<div'.$id.$divstyles.' class="'.$divclasses.'">';
683
684 if ($return) {
685 return $output;
686 } else {
687 echo $output;
688 }
689}
690
691
692/**
693 * Print the end portion of a standard themed box.
694 * Preferably just use print_box_end() in weblib.php
695 */
696function print_simple_box_end($return=false) {
697 $output = '</div>';
698 if ($return) {
699 return $output;
700 } else {
701 echo $output;
702 }
703}
704
ed5dd29f 705/**
706 * deprecated - use clean_param($string, PARAM_FILE); instead
707 * Check for bad characters ?
708 *
709 * @param string $string ?
710 * @param int $allowdots ?
711 * @todo Finish documenting this function - more detail needed in description as well as details on arguments
712 */
713function detect_munged_arguments($string, $allowdots=1) {
714 if (substr_count($string, '..') > $allowdots) { // Sometimes we allow dots in references
715 return true;
716 }
717 if (ereg('[\|\`]', $string)) { // check for other bad characters
718 return true;
719 }
720 if (empty($string) or $string == '/') {
721 return true;
722 }
723
724 return false;
725}
726
9152fc99 727
ed5dd29f 728/////////////////////////////////////////////////////////////
729/// Old functions not used anymore - candidates for removal
730/////////////////////////////////////////////////////////////
731
ed5dd29f 732
1d684195 733/** various deprecated groups function **/
734
735
5bf243d1 736/**
737 * Get the IDs for the user's groups in the given course.
738 *
739 * @uses $USER
740 * @param int $courseid The course being examined - the 'course' table id field.
741 * @return array An _array_ of groupids.
742 * (Was return $groupids[0] - consequences!)
743 */
744function mygroupid($courseid) {
745 global $USER;
746 if ($groups = groups_get_all_groups($courseid, $USER->id)) {
747 return array_keys($groups);
748 } else {
749 return false;
750 }
751}
752
5bf243d1 753
754/**
755 * Returns an array of user objects
756 *
757 * @uses $CFG
758 * @param int $groupid The group in question.
759 * @param string $sort ?
760 * @param string $exceptions ?
761 * @return object
762 * @todo Finish documenting this function
763 */
364fffda 764function get_group_users($groupid, $sort='u.lastaccess DESC', $exceptions='',
5bf243d1 765 $fields='u.*') {
766 global $CFG;
767 if (!empty($exceptions)) {
768 $except = ' AND u.id NOT IN ('. $exceptions .') ';
769 } else {
770 $except = '';
771 }
772 // in postgres, you can't have things in sort that aren't in the select, so...
773 $extrafield = str_replace('ASC','',$sort);
774 $extrafield = str_replace('DESC','',$extrafield);
775 $extrafield = trim($extrafield);
776 if (!empty($extrafield)) {
777 $extrafield = ','.$extrafield;
778 }
779 return get_records_sql("SELECT DISTINCT $fields $extrafield
780 FROM {$CFG->prefix}user u,
781 {$CFG->prefix}groups_members m
782 WHERE m.groupid = '$groupid'
783 AND m.userid = u.id $except
784 ORDER BY $sort");
785}
786
787/**
788 * Returns the current group mode for a given course or activity module
364fffda 789 *
5bf243d1 790 * Could be false, SEPARATEGROUPS or VISIBLEGROUPS (<-- Martin)
791 */
792function groupmode($course, $cm=null) {
793
794 if (isset($cm->groupmode) && empty($course->groupmodeforce)) {
795 return $cm->groupmode;
796 }
797 return $course->groupmode;
798}
799
800
5bf243d1 801/**
364fffda 802 * Gets the current group - either from the session variable or from the database.
5bf243d1 803 *
804 * @uses $USER
805 * @uses $SESSION
364fffda 806 * @param int $courseid The course being examined - relates to id field in
5bf243d1 807 * 'course' table.
364fffda 808 * @param bool $full If true, the return value is a full record object.
5bf243d1 809 * If false, just the id of the record.
810 */
811function get_current_group($courseid, $full = false) {
812 global $SESSION;
813
814 if (isset($SESSION->currentgroup[$courseid])) {
815 if ($full) {
816 return groups_get_group($SESSION->currentgroup[$courseid]);
817 } else {
818 return $SESSION->currentgroup[$courseid];
819 }
820 }
821
822 $mygroupid = mygroupid($courseid);
823 if (is_array($mygroupid)) {
824 $mygroupid = array_shift($mygroupid);
825 set_current_group($courseid, $mygroupid);
826 if ($full) {
827 return groups_get_group($mygroupid);
828 } else {
829 return $mygroupid;
830 }
831 }
832
833 if ($full) {
834 return false;
835 } else {
836 return 0;
837 }
838}
839
840
841/**
842 * A combination function to make it easier for modules
843 * to set up groups.
844 *
845 * It will use a given "groupid" parameter and try to use
846 * that to reset the current group for the user.
847 *
848 * @uses VISIBLEGROUPS
849 * @param course $course A {@link $COURSE} object
850 * @param int $groupmode Either NOGROUPS, SEPARATEGROUPS or VISIBLEGROUPS
851 * @param int $groupid Will try to use this optional parameter to
852 * reset the current group for the user
853 * @return int|false Returns the current group id or false if error.
854 */
855function get_and_set_current_group($course, $groupmode, $groupid=-1) {
856
364fffda 857 // Sets to the specified group, provided the current user has view permission
5bf243d1 858 if (!$groupmode) { // Groups don't even apply
859 return false;
860 }
861
862 $currentgroupid = get_current_group($course->id);
863
864 if ($groupid < 0) { // No change was specified
865 return $currentgroupid;
866 }
867
868 $context = get_context_instance(CONTEXT_COURSE, $course->id);
869 if ($groupid and $group = get_record('groups', 'id', $groupid)) { // Try to change the current group to this groupid
870 if ($group->courseid == $course->id) {
871 if (has_capability('moodle/site:accessallgroups', $context)) { // Sets current default group
872 $currentgroupid = set_current_group($course->id, $groupid);
873
874 } elseif ($groupmode == VISIBLEGROUPS) {
875 // All groups are visible
876 //if (groups_is_member($group->id)){
877 $currentgroupid = set_current_group($course->id, $groupid); //set this since he might post
878 /*)}else {
879 $currentgroupid = $group->id;*/
880 } elseif ($groupmode == SEPARATEGROUPS) { // student in separate groups switching
881 if (groups_is_member($groupid)) { //check if is a member
882 $currentgroupid = set_current_group($course->id, $groupid); //might need to set_current_group?
883 }
884 else {
885 notify('You do not belong to this group! ('.$groupid.')', 'error');
886 }
887 }
888 }
889 } else { // When groupid = 0 it means show ALL groups
890 // this is changed, non editting teacher needs access to group 0 as well,
891 // for viewing work in visible groups (need to set current group for multiple pages)
892 if (has_capability('moodle/site:accessallgroups', $context)) { // Sets current default group
893 $currentgroupid = set_current_group($course->id, 0);
894
895 } else if ($groupmode == VISIBLEGROUPS) { // All groups are visible
896 $currentgroupid = set_current_group($course->id, 0);
897 }
898 }
899
900 return $currentgroupid;
901}
902
903
904/**
905 * A big combination function to make it easier for modules
906 * to set up groups.
907 *
908 * Terminates if the current user shouldn't be looking at this group
909 * Otherwise returns the current group if there is one
910 * Otherwise returns false if groups aren't relevant
911 *
912 * @uses SEPARATEGROUPS
913 * @uses VISIBLEGROUPS
914 * @param course $course A {@link $COURSE} object
915 * @param int $groupmode Either NOGROUPS, SEPARATEGROUPS or VISIBLEGROUPS
916 * @param string $urlroot ?
917 * @return int|false
918 */
919function setup_and_print_groups($course, $groupmode, $urlroot) {
920
921 global $USER, $SESSION; //needs his id, need to hack his groups in session
922
923 $changegroup = optional_param('group', -1, PARAM_INT);
924
925 $currentgroup = get_and_set_current_group($course, $groupmode, $changegroup);
926 if ($currentgroup === false) {
927 return false;
928 }
929
930 $context = get_context_instance(CONTEXT_COURSE, $course->id);
931
932 if ($groupmode == SEPARATEGROUPS and !$currentgroup and !has_capability('moodle/site:accessallgroups', $context)) {
933 //we are in separate groups and the current group is group 0, as last set.
934 //this can mean that either, this guy has no group
935 //or, this guy just came from a visible all forum, and he left when he set his current group to 0 (show all)
936
937 if ($usergroups = groups_get_all_groups($course->id, $USER->id)){
938 //for the second situation, we need to perform the trick and get him a group.
939 $first = reset($usergroups);
940 $currentgroup = get_and_set_current_group($course, $groupmode, $first->id);
941
942 } else {
943 //else he has no group in this course
944 print_heading(get_string('notingroup'));
945 print_footer($course);
946 exit;
947 }
948 }
949
950 if ($groupmode == VISIBLEGROUPS or ($groupmode and has_capability('moodle/site:accessallgroups', $context))) {
951
952 if ($groups = groups_get_all_groups($course->id)) {
953
954 echo '<div class="groupselector">';
955 print_group_menu($groups, $groupmode, $currentgroup, $urlroot, 1);
956 echo '</div>';
957 }
958
959 } else if ($groupmode == SEPARATEGROUPS and has_capability('moodle/course:view', $context)) {
960 //get all the groups this guy is in in this course
961 if ($usergroups = groups_get_all_groups($course->id, $USER->id)){
962 echo '<div class="groupselector">';
963 //print them in the menu
964 print_group_menu($usergroups, $groupmode, $currentgroup, $urlroot, 0);
965 echo '</div>';
966 }
967 }
968
969 return $currentgroup;
970}
971
13534ef7
ML
972/**
973 * Prints an appropriate group selection menu
974 *
975 * @uses VISIBLEGROUPS
976 * @param array $groups ?
977 * @param int $groupmode ?
978 * @param string $currentgroup ?
979 * @param string $urlroot ?
980 * @param boolean $showall: if set to 0, it is a student in separate groups, do not display all participants
981 * @todo Finish documenting this function
982 */
983function print_group_menu($groups, $groupmode, $currentgroup, $urlroot, $showall=1, $return=false) {
984
985 $output = '';
986 $groupsmenu = array();
987
988/// Add an "All groups" to the start of the menu
989 if ($showall){
990 $groupsmenu[0] = get_string('allparticipants');
991 }
992 foreach ($groups as $key => $group) {
993 $groupsmenu[$key] = format_string($group->name);
994 }
995
996 if ($groupmode == VISIBLEGROUPS) {
997 $grouplabel = get_string('groupsvisible');
998 } else {
999 $grouplabel = get_string('groupsseparate');
1000 }
1001
1002 if (count($groupsmenu) == 1) {
1003 $groupname = reset($groupsmenu);
1004 $output .= $grouplabel.': '.$groupname;
1005 } else {
1006 $output .= popup_form($urlroot.'&amp;group=', $groupsmenu, 'selectgroup', $currentgroup, '', '', '', true, 'self', $grouplabel);
1007 }
1008
1009 if ($return) {
1010 return $output;
1011 } else {
1012 echo $output;
1013 }
1014
1015}
1016
59bef728 1017/**
1018 * All users that we have not seen for a really long time (ie dead accounts)
1019 * TODO: Delete this for Moodle 2.0
1020 *
1021 * @uses $CFG
1022 * @deprecated The query is executed directly within admin/cron.php (MDL-11571)
1023 * @param string $cutofftime ?
1024 * @return object {@link $USER} records
1025 */
1026function get_users_longtimenosee($cutofftime) {
1027 global $CFG;
1028 return get_records_sql("SELECT id, userid, courseid
1029 FROM {$CFG->prefix}user_lastaccess
1030 WHERE courseid != ".SITEID."
1031 AND timeaccess < $cutofftime ");
1032}
1033
1034/**
1035 * Full list of users that have not yet confirmed their accounts.
1036 * TODO: Delete this for Moodle 2.0
1037 *
1038 * @uses $CFG
1039 * @deprecated The query is executed directly within admin/cron.php (MDL-11487)
1040 * @param string $cutofftime ?
1041 * @return object {@link $USER} records
1042 */
1043function get_users_unconfirmed($cutofftime=2000000000) {
1044 global $CFG;
1045 return get_records_sql("SELECT *
1046 FROM {$CFG->prefix}user
1047 WHERE confirmed = 0
1048 AND firstaccess > 0
1049 AND firstaccess < $cutofftime");
1050}
1051
1052/**
1053 * Full list of bogus accounts that are probably not ever going to be used
1054 * TODO: Delete this for Moodle 2.0
1055 *
1056 * @uses $CFG
1057 * @deprecated The query is executed directly within admin/cron.php (MDL-11487)
1058 * @param string $cutofftime ?
1059 * @return object {@link $USER} records
1060 */
1061function get_users_not_fully_set_up($cutofftime=2000000000) {
1062 global $CFG;
1063 return get_records_sql("SELECT *
1064 FROM {$CFG->prefix}user
1065 WHERE confirmed = 1
1066 AND lastaccess > 0
1067 AND lastaccess < $cutofftime
1068 AND deleted = 0
1069 AND (lastname = '' OR firstname = '' OR email = '')");
1070}
1071
9801a97a 1072/**
1073 * Returns SQL to be used as a subselect to find the primary role of users.
1074 * Geoff Cant <geoff@catalyst.net.nz> (the author) is very keen for this to
1075 * be implemented as a view in future versions.
1076 *
1077 * eg if this function returns a string called $primaryroles, then you could:
1078 * $sql = 'SELECT COUNT(DISTINCT prs.userid) FROM ('.$primary_roles.') prs
1079 * WHERE prs.primary_roleid='.$role->id.' AND prs.courseid='.$course->id.
1080 * ' AND prs.contextlevel = '.CONTEXT_COURSE;
1081 *
1082 * @return string the piece of SQL code to be used in your FROM( ) statement.
1083 */
1084function sql_primary_role_subselect() {
1085 global $CFG;
1086 return 'SELECT ra.userid,
1087 ra.roleid AS primary_roleid,
1088 ra.contextid,
1089 r.sortorder,
1090 r.name,
1091 r.description,
1092 r.shortname,
1093 c.instanceid AS courseid,
1094 c.contextlevel
1095 FROM '.$CFG->prefix.'role_assignments ra
1096 INNER JOIN '.$CFG->prefix.'role r ON ra.roleid = r.id
1097 INNER JOIN '.$CFG->prefix.'context c ON ra.contextid = c.id
1098 WHERE NOT EXISTS (
1099 SELECT 1
1100 FROM '.$CFG->prefix.'role_assignments i_ra
1101 INNER JOIN '.$CFG->prefix.'role i_r ON i_ra.roleid = i_r.id
1102 WHERE ra.userid = i_ra.userid AND
1103 ra.contextid = i_ra.contextid AND
1104 i_r.sortorder < r.sortorder
1105 ) ';
1106}
1107
42580031 1108/**
1109 * Can include a given document file (depends on second
1110 * parameter) or just return info about it.
1111 *
1112 * @uses $CFG
1113 * @param string $file ?
1114 * @param bool $include ?
1115 * @return ?
1116 * @todo Finish documenting this function
1117 */
1118function document_file($file, $include=true) {
1119 global $CFG;
1120
1121 debugging('The document_file() function is deprecated.', DEBUG_DEVELOPER);
1122
1123 $file = clean_filename($file);
1124
1125 if (empty($file)) {
1126 return false;
1127 }
1128
1129 $langs = array(current_language(), get_string('parentlanguage'), 'en');
1130
1131 foreach ($langs as $lang) {
1132 $info = new object();
1133 $info->filepath = $CFG->dirroot .'/lang/'. $lang .'/docs/'. $file;
1134 $info->urlpath = $CFG->wwwroot .'/lang/'. $lang .'/docs/'. $file;
1135
1136 if (file_exists($info->filepath)) {
1137 if ($include) {
1138 include($info->filepath);
1139 }
1140 return $info;
1141 }
1142 }
1143
1144 return false;
1145}
1146
8ec50604 1147/**
1148 * Print an error page displaying an error message.
1149 * Old method, don't call directly in new code - use print_error instead.
1150 *
1151 *
1152 * @uses $SESSION
1153 * @uses $CFG
1154 * @param string $message The message to display to the user about the error.
1155 * @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
1156 */
1157function error ($message, $link='') {
1158
1159 global $CFG, $SESSION, $THEME;
e3105d45 1160 debugging('error() is a deprecated function, please call print_error() instead of error()', DEBUG_DEVELOPER);
8ec50604 1161 $message = clean_text($message); // In case nasties are in here
1162
1163 if (defined('FULLME') && FULLME == 'cron') {
1164 // Errors in cron should be mtrace'd.
1165 mtrace($message);
1166 die;
1167 }
1168
1169 if (! defined('HEADER_PRINTED')) {
1170 //header not yet printed
1171 @header('HTTP/1.0 404 Not Found');
1172 print_header(get_string('error'));
1173 } else {
1174 print_container_end_all(false, $THEME->open_header_containers);
1175 }
1176
1177 echo '<br />';
1178 print_simple_box($message, '', '', '', '', 'errorbox');
1179
1180 debugging('Stack trace:', DEBUG_DEVELOPER);
1181
1182 // in case we are logging upgrade in admin/index.php stop it
1183 if (function_exists('upgrade_log_finish')) {
1184 upgrade_log_finish();
1185 }
1186
1187 if (empty($link) and !defined('ADMIN_EXT_HEADER_PRINTED')) {
1188 if ( !empty($SESSION->fromurl) ) {
1189 $link = $SESSION->fromurl;
1190 unset($SESSION->fromurl);
1191 } else {
1192 $link = $CFG->wwwroot .'/';
1193 }
1194 }
1195
1196 if (!empty($link)) {
1197 print_continue($link);
1198 }
1199
1200 print_footer();
1201
1202 for ($i=0;$i<512;$i++) { // Padding to help IE work with 404
1203 echo ' ';
1204 }
1205
1206 die;
1207}
c4d0753b 1208?>