MDL-20498 User pictures should not have 'generic' alt text
[moodle.git] / lib / grouplib.php
CommitLineData
e4f0a85e 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
21 * @package moodlecore
22 */
2c386f82 23
13534ef7 24/**
ffc536af 25 * Groups not used in course or activity
13534ef7
ML
26 */
27define('NOGROUPS', 0);
28
29/**
ffc536af 30 * Groups used, users do not see other groups
13534ef7
ML
31 */
32define('SEPARATEGROUPS', 1);
5bf243d1 33
5bf243d1 34/**
ffc536af 35 * Groups used, students see other groups
13534ef7
ML
36 */
37define('VISIBLEGROUPS', 2);
38
39
40/**
41 * Determines if a group with a given groupid exists.
e4f0a85e 42 *
43 * @global object
5bf243d1 44 * @param int $groupid The groupid to check for
13534ef7
ML
45 * @return boolean True if the group exists, false otherwise or if an error
46 * occurred.
5bf243d1 47 */
48function groups_group_exists($groupid) {
f33e1ed4 49 global $DB;
50 return $DB->record_exists('groups', array('id'=>$groupid));
5bf243d1 51}
52
53/**
54 * Gets the name of a group with a specified id
e4f0a85e 55 *
56 * @global object
5bf243d1 57 * @param int $groupid The id of the group
58 * @return string The name of the group
59 */
60function groups_get_group_name($groupid) {
f33e1ed4 61 global $DB;
62 return $DB->get_field('groups', 'name', array('id'=>$groupid));
5bf243d1 63}
2c386f82 64
4d8e3407 65/**
66 * Gets the name of a grouping with a specified id
e4f0a85e 67 *
68 * @global object
4d8e3407 69 * @param int $groupingid The id of the grouping
70 * @return string The name of the grouping
71 */
72function groups_get_grouping_name($groupingid) {
f33e1ed4 73 global $DB;
74 return $DB->get_field('groupings', 'name', array('id'=>$groupingid));
4d8e3407 75}
76
2c386f82 77/**
78 * Returns the groupid of a group with the name specified for the course.
79 * Group names should be unique in course
e4f0a85e 80 *
81 * @global object
2c386f82 82 * @param int $courseid The id of the course
83 * @param string $name name of group (without magic quotes)
84 * @return int $groupid
85 */
86function groups_get_group_by_name($courseid, $name) {
f33e1ed4 87 global $DB;
88 if ($groups = $DB->get_records('groups', array('courseid'=>$courseid, 'name'=>$name))) {
ddff2fa8 89 return key($groups);
2c386f82 90 }
ddff2fa8 91 return false;
92}
2c386f82 93
ddff2fa8 94/**
95 * Returns the groupingid of a grouping with the name specified for the course.
96 * Grouping names should be unique in course
e4f0a85e 97 *
98 * @global object
ddff2fa8 99 * @param int $courseid The id of the course
100 * @param string $name name of group (without magic quotes)
101 * @return int $groupid
102 */
103function groups_get_grouping_by_name($courseid, $name) {
f33e1ed4 104 global $DB;
c70552d8 105 if ($groupings = $DB->get_records('groupings', array('courseid'=>$courseid, 'name'=>$name))) {
ddff2fa8 106 return key($groupings);
107 }
108 return false;
2c386f82 109}
110
111/**
112 * Get the group object
e4f0a85e 113 *
e4f0a85e 114 * @param int $groupid ID of the group.
115 * @return object group object
2c386f82 116 */
9a0df45a 117function groups_get_group($groupid, $fields='*', $strictness=IGNORE_MISSING) {
f33e1ed4 118 global $DB;
9a0df45a 119 return $DB->get_record('groups', array('id'=>$groupid), $fields, $strictness);
2c386f82 120}
121
f16fa0a3 122/**
123 * Get the grouping object
e4f0a85e 124 *
e4f0a85e 125 * @param int $groupingid ID of the group.
9a0df45a 126 * @param string $fields
e4f0a85e 127 * @return object group object
f16fa0a3 128 */
9a0df45a 129function groups_get_grouping($groupingid, $fields='*', $strictness=IGNORE_MISSING) {
f33e1ed4 130 global $DB;
9a0df45a 131 return $DB->get_record('groupings', array('id'=>$groupingid), $fields, $strictness);
f16fa0a3 132}
133
2c386f82 134/**
135 * Gets array of all groups in a specified course.
e4f0a85e 136 *
2c386f82 137 * @param int $courseid The id of the course.
65bcf17b 138 * @param mixed $userid optional user id or array of ids, returns only groups of the user.
62d63838 139 * @param int $groupingid optional returns only groups in the specified grouping.
e4f0a85e 140 * @param string $fields
141 * @return array|bool Returns an array of the group objects or false if no records
65bcf17b 142 * or an error occurred. (userid field returned if array in $userid)
2c386f82 143 */
65bcf17b 144function groups_get_all_groups($courseid, $userid=0, $groupingid=0, $fields='g.*') {
f33e1ed4 145 global $CFG, $DB;
2c386f82 146
7e4fdf25 147 // groupings are ignored when not enabled
c0d4238d 148 if (empty($CFG->enablegroupings)) {
149 $groupingid = 0;
150 }
151
f33e1ed4 152
65bcf17b 153 if (empty($userid)) {
62d63838 154 $userfrom = "";
155 $userwhere = "";
f33e1ed4 156 $params = array();
65bcf17b 157
158 } else {
f33e1ed4 159 list($usql, $params) = $DB->get_in_or_equal($userid);
160 $userfrom = ", {groups_members} gm";
161 $userwhere = "AND g.id = gm.groupid AND gm.userid $usql";
62d63838 162 }
2c386f82 163
62d63838 164 if (!empty($groupingid)) {
f33e1ed4 165 $groupingfrom = ", {groupings_groups} gg";
166 $groupingwhere = "AND g.id = gg.groupid AND gg.groupingid = ?";
167 $params[] = $groupingid;
2c386f82 168 } else {
62d63838 169 $groupingfrom = "";
170 $groupingwhere = "";
2c386f82 171 }
62d63838 172
f33e1ed4 173 array_unshift($params, $courseid);
174
175 return $DB->get_records_sql("SELECT $fields
176 FROM {groups} g $userfrom $groupingfrom
177 WHERE g.courseid = ? $userwhere $groupingwhere
178 ORDER BY name ASC", $params);
2c386f82 179}
180
dd97c328 181/**
182 * Returns info about user's groups in course.
e4f0a85e 183 *
184 * @global object
185 * @global object
186 * @global object
dd97c328 187 * @param int $courseid
188 * @param int $userid $USER if not specified
e4f0a85e 189 * @return array Array[groupingid][groupid] including grouping id 0 which means all groups
dd97c328 190 */
191function groups_get_user_groups($courseid, $userid=0) {
f33e1ed4 192 global $CFG, $USER, $DB;
dd97c328 193
194 if (empty($userid)) {
195 $userid = $USER->id;
196 }
197
f33e1ed4 198 $sql = "SELECT g.id, gg.groupingid
199 FROM {groups} g
200 JOIN {groups_members} gm ON gm.groupid = g.id
201 LEFT JOIN {groupings_groups} gg ON gg.groupid = g.id
202 WHERE gm.userid = ? AND g.courseid = ?";
203 $params = array($userid, $courseid);
204
205 if (!$rs = $DB->get_recordset_sql($sql, $params)) {
dd97c328 206 return array('0' => array());
207 }
208
0b943ef1 209 $result = array();
210 $allgroups = array();
117bd748 211
f33e1ed4 212 foreach ($rs as $group) {
ca182d90 213 $allgroups[$group->id] = $group->id;
dd97c328 214 if (is_null($group->groupingid)) {
215 continue;
216 }
217 if (!array_key_exists($group->groupingid, $result)) {
218 $result[$group->groupingid] = array();
219 }
220 $result[$group->groupingid][$group->id] = $group->id;
221 }
f33e1ed4 222 $rs->close();
0b943ef1 223
224 $result['0'] = array_keys($allgroups); // all groups
dd97c328 225
226 return $result;
227}
228
acf000b0 229/**
230 * Gets array of all groupings in a specified course.
117bd748 231 *
e4f0a85e 232 * @global object
233 * @global object
18d43e96 234 * @param int $courseid return only groupings in this with this courseid
e4f0a85e 235 * @return array|bool Returns an array of the grouping objects or false if no records
acf000b0 236 * or an error occurred.
237 */
238function groups_get_all_groupings($courseid) {
f33e1ed4 239 global $CFG, $DB;
acf000b0 240
241 // groupings are ignored when not enabled
242 if (empty($CFG->enablegroupings)) {
243 return(false);
244 }
f33e1ed4 245 return $DB->get_records_sql("SELECT *
246 FROM {groupings}
247 WHERE courseid = ?
248 ORDER BY name ASC", array($courseid));
acf000b0 249}
250
251
252
2c386f82 253/**
254 * Determines if the user is a member of the given group.
255 *
aaeba371 256 * If $userid is null, use the global object.
257 *
258 * @global object
e4f0a85e 259 * @global object
2c386f82 260 * @param int $groupid The group to check for membership.
261 * @param int $userid The user to check against the group.
262 * @return boolean True if the user is a member, false otherwise.
263 */
264function groups_is_member($groupid, $userid=null) {
f33e1ed4 265 global $USER, $DB;
2c386f82 266
267 if (!$userid) {
268 $userid = $USER->id;
269 }
270
f33e1ed4 271 return $DB->record_exists('groups_members', array('groupid'=>$groupid, 'userid'=>$userid));
2c386f82 272}
273
f8e3d5f0 274/**
275 * Determines if current or specified is member of any active group in activity
e4f0a85e 276 *
277 * @global object
278 * @global object
279 * @global object
280 * @staticvar array $cache
f8e3d5f0 281 * @param object $cm coruse module object
282 * @param int $userid id of user, null menas $USER->id
283 * @return booelan true if user member of at least one group used in activity
284 */
285function groups_has_membership($cm, $userid=null) {
f33e1ed4 286 global $CFG, $USER, $DB;
f16fa0a3 287
e0bc99e4 288 static $cache = array();
f16fa0a3 289
7e4fdf25 290 // groupings are ignored when not enabled
c0d4238d 291 if (empty($CFG->enablegroupings)) {
292 $cm->groupingid = 0;
293 }
294
f8e3d5f0 295 if (empty($userid)) {
296 $userid = $USER->id;
297 }
298
e0bc99e4 299 $cachekey = $userid.'|'.$cm->course.'|'.$cm->groupingid;
300 if (isset($cache[$cachekey])) {
301 return($cache[$cachekey]);
302 }
303
f8e3d5f0 304 if ($cm->groupingid) {
305 // find out if member of any group in selected activity grouping
306 $sql = "SELECT 'x'
f33e1ed4 307 FROM {groups_members} gm, {groupings_groups} gg
308 WHERE gm.userid = ? AND gm.groupid = gg.groupid AND gg.groupingid = ?";
309 $params = array($userid, $cm->groupingid);
f8e3d5f0 310
311 } else {
312 // no grouping used - check all groups in course
313 $sql = "SELECT 'x'
f33e1ed4 314 FROM {groups_members} gm, {groups} g
315 WHERE gm.userid = ? AND gm.groupid = g.id AND g.courseid = ?";
316 $params = array($userid, $cm->course);
f8e3d5f0 317 }
f16fa0a3 318
f33e1ed4 319 $cache[$cachekey] = $DB->record_exists_sql($sql, $params);
f16fa0a3 320
e0bc99e4 321 return $cache[$cachekey];
f8e3d5f0 322}
323
62d63838 324/**
325 * Returns the users in the specified group.
e4f0a85e 326 *
327 * @global object
62d63838 328 * @param int $groupid The groupid to get the users for
e6839677 329 * @param int $fields The fields to return
62d63838 330 * @param int $sort optional sorting of returned users
e4f0a85e 331 * @return array|bool Returns an array of the users for the specified
62d63838 332 * group or false if no users or an error returned.
333 */
e6839677 334function groups_get_members($groupid, $fields='u.*', $sort='lastname ASC') {
f33e1ed4 335 global $DB;
62d63838 336
f33e1ed4 337 return $DB->get_records_sql("SELECT $fields
338 FROM {user} u, {groups_members} gm
339 WHERE u.id = gm.userid AND gm.groupid = ?
340 ORDER BY $sort", array($groupid));
62d63838 341}
342
e6839677 343
344/**
345 * Returns the users in the specified grouping.
e4f0a85e 346 *
347 * @global object
e6839677 348 * @param int $groupingid The groupingid to get the users for
349 * @param int $fields The fields to return
350 * @param int $sort optional sorting of returned users
e4f0a85e 351 * @return array|bool Returns an array of the users for the specified
e6839677 352 * group or false if no users or an error returned.
353 */
354function groups_get_grouping_members($groupingid, $fields='u.*', $sort='lastname ASC') {
f33e1ed4 355 global $DB;
356
357 return $DB->get_records_sql("SELECT $fields
358 FROM {user} u
359 INNER JOIN {groups_members} gm ON u.id = gm.userid
360 INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid
361 WHERE gg.groupingid = ?
362 ORDER BY $sort", array($groupingid));
e6839677 363}
364
b2bc96d1 365/**
366 * Returns effective groupmode used in course
117bd748 367 *
b2bc96d1 368 * @return integer group mode
369 */
370function groups_get_course_groupmode($course) {
371 return $course->groupmode;
372}
373
13534ef7
ML
374/**
375 * Returns effective groupmode used in activity, course setting
376 * overrides activity setting if groupmodeforce enabled.
e4f0a85e 377 *
378 * @global object
379 * @global object
380 * @param object $cm the course module object. Only the ->course and ->groupmode need to be set.
381 * @param object $course object optional course object to improve perf
13534ef7
ML
382 * @return integer group mode
383 */
dd97c328 384function groups_get_activity_groupmode($cm, $course=null) {
f33e1ed4 385 global $COURSE, $DB;
13534ef7
ML
386
387 // get course object (reuse COURSE if possible)
dd97c328 388 if (isset($course->id) and $course->id == $cm->course) {
389 //ok
390 } else if ($cm->course == $COURSE->id) {
13534ef7
ML
391 $course = $COURSE;
392 } else {
f33e1ed4 393 if (!$course = $DB->get_record('course', array('id'=>$cm->course))) {
06e84d52 394 print_error('invalidcourseid');
13534ef7
ML
395 }
396 }
397
398 return empty($course->groupmodeforce) ? $cm->groupmode : $course->groupmode;
399}
400
b2bc96d1 401/**
402 * Print group menu selector for course level.
e4f0a85e 403 *
404 * @global object
405 * @global object
b2bc96d1 406 * @param object $course course object
407 * @param string $urlroot return address
408 * @param boolean $return return as string instead of printing
409 * @return mixed void or string depending on $return param
410 */
411function groups_print_course_menu($course, $urlroot, $return=false) {
d81b05e7 412 global $CFG, $USER, $SESSION, $OUTPUT;
b2bc96d1 413
414 if (!$groupmode = $course->groupmode) {
415 if ($return) {
416 return '';
417 } else {
418 return;
419 }
420 }
421
422 $context = get_context_instance(CONTEXT_COURSE, $course->id);
423 if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context)) {
25bc3cd3 424 $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid);
89f39741 425 // detect changes related to groups and fix active group
426 if (!empty($SESSION->activegroup[$course->id][VISIBLEGROUPS][0])) {
427 if (!array_key_exists($SESSION->activegroup[$course->id][VISIBLEGROUPS][0], $allowedgroups)) {
428 // active does not exist anymore
429 unset($SESSION->activegroup[$course->id][VISIBLEGROUPS][0]);
dd97c328 430 }
89f39741 431 }
432 if (!empty($SESSION->activegroup[$course->id]['aag'][0])) {
433 if (!array_key_exists($SESSION->activegroup[$course->id]['aag'][0], $allowedgroups)) {
434 // active group does not exist anymore
435 unset($SESSION->activegroup[$course->id]['aag'][0]);
dd97c328 436 }
89f39741 437 }
438
b2bc96d1 439 } else {
25bc3cd3 440 $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
89f39741 441 // detect changes related to groups and fix active group
442 if (isset($SESSION->activegroup[$course->id][SEPARATEGROUPS][0])) {
443 if ($SESSION->activegroup[$course->id][SEPARATEGROUPS][0] == 0) {
444 if ($allowedgroups) {
445 // somebody must have assigned at least one group, we can select it now - yay!
446 unset($SESSION->activegroup[$course->id][SEPARATEGROUPS][0]);
447 }
448 } else {
449 if (!array_key_exists($SESSION->activegroup[$course->id][SEPARATEGROUPS][0], $allowedgroups)) {
450 // active group not allowed or does not exist anymore
451 unset($SESSION->activegroup[$course->id][SEPARATEGROUPS][0]);
dd97c328 452 }
89f39741 453 }
454 }
b2bc96d1 455 }
456
457 $activegroup = groups_get_course_group($course, true);
458
459 $groupsmenu = array();
460 if (!$allowedgroups or $groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context)) {
461 $groupsmenu[0] = get_string('allparticipants');
462 }
463
464 if ($allowedgroups) {
465 foreach ($allowedgroups as $group) {
466 $groupsmenu[$group->id] = format_string($group->name);
467 }
468 }
469
470 if ($groupmode == VISIBLEGROUPS) {
471 $grouplabel = get_string('groupsvisible');
472 } else {
473 $grouplabel = get_string('groupsseparate');
474 }
475
476 if (count($groupsmenu) == 1) {
477 $groupname = reset($groupsmenu);
478 $output = $grouplabel.': '.$groupname;
479 } else {
7b1f2c82 480 $select = html_select::make_popup_form($urlroot, 'group', $groupsmenu, 'selectgroup', $activegroup);
d81b05e7 481 $select->nothinglabel = false;
482 $select->set_label($grouplabel);
117bd748 483 $output = $OUTPUT->select($select);
b2bc96d1 484 }
485
486 $output = '<div class="groupselector">'.$output.'</div>';
487
488 if ($return) {
489 return $output;
490 } else {
491 echo $output;
492 }
493}
494
13534ef7
ML
495/**
496 * Print group menu selector for activity.
e4f0a85e 497 *
498 * @global object
499 * @global object
500 * @global object
13534ef7 501 * @param object $cm course module object
f16fa0a3 502 * @param string $urlroot return address that users get to if they choose an option;
18d43e96 503 * should include any parameters needed, e.g. 'view.php?id=34'
13534ef7 504 * @param boolean $return return as string instead of printing
f16fa0a3 505 * @param boolean $hideallparticipants If true, this prevents the 'All participants'
506 * option from appearing in cases where it normally would. This is intended for
507 * use only by activities that cannot display all groups together. (Note that
508 * selecting this option does not prevent groups_get_activity_group from
509 * returning 0; it will still do that if the user has chosen 'all participants'
510 * in another activity, or not chosen anything.)
13534ef7
ML
511 * @return mixed void or string depending on $return param
512 */
18d43e96 513function groups_print_activity_menu($cm, $urlroot, $return=false, $hideallparticipants=false) {
d81b05e7 514 global $CFG, $USER, $SESSION, $OUTPUT;
c0d4238d 515
7e4fdf25 516 // groupings are ignored when not enabled
c0d4238d 517 if (empty($CFG->enablegroupings)) {
518 $cm->groupingid = 0;
519 }
13534ef7
ML
520
521 if (!$groupmode = groups_get_activity_groupmode($cm)) {
522 if ($return) {
523 return '';
524 } else {
525 return;
526 }
527 }
528
529 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
530 if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context)) {
531 $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); // any group in grouping (all if groupings not used)
89f39741 532 // detect changes related to groups and fix active group
533 if (!empty($SESSION->activegroup[$cm->course][VISIBLEGROUPS][$cm->groupingid])) {
534 if (!array_key_exists($SESSION->activegroup[$cm->course][VISIBLEGROUPS][$cm->groupingid], $allowedgroups)) {
535 // active group does not exist anymore
536 unset($SESSION->activegroup[$cm->course][VISIBLEGROUPS][$cm->groupingid]);
dd97c328 537 }
89f39741 538 }
539 if (!empty($SESSION->activegroup[$cm->course]['aag'][$cm->groupingid])) {
540 if (!array_key_exists($SESSION->activegroup[$cm->course]['aag'][$cm->groupingid], $allowedgroups)) {
541 // active group does not exist anymore
542 unset($SESSION->activegroup[$cm->course]['aag'][$cm->groupingid]);
dd97c328 543 }
89f39741 544 }
545
13534ef7
ML
546 } else {
547 $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); // only assigned groups
89f39741 548 // detect changes related to groups and fix active group
549 if (isset($SESSION->activegroup[$cm->course][SEPARATEGROUPS][$cm->groupingid])) {
550 if ($SESSION->activegroup[$cm->course][SEPARATEGROUPS][$cm->groupingid] == 0) {
551 if ($allowedgroups) {
552 // somebody must have assigned at least one group, we can select it now - yay!
553 unset($SESSION->activegroup[$cm->course][SEPARATEGROUPS][$cm->groupingid]);
554 }
555 } else {
556 if (!array_key_exists($SESSION->activegroup[$cm->course][SEPARATEGROUPS][$cm->groupingid], $allowedgroups)) {
557 // active group not allowed or does not exist anymore
558 unset($SESSION->activegroup[$cm->course][SEPARATEGROUPS][$cm->groupingid]);
dd97c328 559 }
89f39741 560 }
561 }
13534ef7
ML
562 }
563
564 $activegroup = groups_get_activity_group($cm, true);
565
566 $groupsmenu = array();
f16fa0a3 567 if ((!$allowedgroups or $groupmode == VISIBLEGROUPS or
18d43e96 568 has_capability('moodle/site:accessallgroups', $context)) and !$hideallparticipants) {
13534ef7
ML
569 $groupsmenu[0] = get_string('allparticipants');
570 }
571
572 if ($allowedgroups) {
573 foreach ($allowedgroups as $group) {
574 $groupsmenu[$group->id] = format_string($group->name);
575 }
576 }
577
578 if ($groupmode == VISIBLEGROUPS) {
579 $grouplabel = get_string('groupsvisible');
580 } else {
581 $grouplabel = get_string('groupsseparate');
582 }
583
584 if (count($groupsmenu) == 1) {
585 $groupname = reset($groupsmenu);
586 $output = $grouplabel.': '.$groupname;
587 } else {
7b1f2c82 588 $select = html_select::make_popup_form($urlroot, 'group', $groupsmenu, 'selectgroup', $activegroup);
d81b05e7 589 $select->nothinglabel = false;
590 $select->set_label($grouplabel);
117bd748 591 $output = $OUTPUT->select($select);
13534ef7
ML
592 }
593
594 $output = '<div class="groupselector">'.$output.'</div>';
595
596 if ($return) {
597 return $output;
598 } else {
599 echo $output;
600 }
601}
602
b2bc96d1 603/**
604 * Returns group active in course, changes the group by default if 'group' page param present
605 *
e4f0a85e 606 * @global object
607 * @global object
608 * @global object
b2bc96d1 609 * @param object $course course bject
610 * @param boolean $update change active group if group param submitted
611 * @return mixed false if groups not used, int if groups used, 0 means all groups (access must be verified in SEPARATE mode)
612 */
613function groups_get_course_group($course, $update=false) {
614 global $CFG, $USER, $SESSION;
615
616 if (!$groupmode = $course->groupmode) {
617 // NOGROUPS used
618 return false;
619 }
620
621 // init activegroup array
177d5493 622 if (!isset($SESSION->activegroup)) {
b2bc96d1 623 $SESSION->activegroup = array();
624 }
625 if (!array_key_exists($course->id, $SESSION->activegroup)) {
b0dcd128 626 $SESSION->activegroup[$course->id] = array(SEPARATEGROUPS=>array(), VISIBLEGROUPS=>array(), 'aag'=>array());
627 }
628
e873679b 629 $context = get_context_instance(CONTEXT_COURSE, $course->id);
b0dcd128 630 if (has_capability('moodle/site:accessallgroups', $context)) {
631 $groupmode = 'aag';
b2bc96d1 632 }
633
634 // grouping used the first time - add first user group as default
635 if (!array_key_exists(0, $SESSION->activegroup[$course->id][$groupmode])) {
b0dcd128 636 if ($groupmode == 'aag') {
637 $SESSION->activegroup[$course->id][$groupmode][0] = 0; // all groups by default if user has accessallgroups
638
25bc3cd3 639 } else if ($usergroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid)) {
b2bc96d1 640 $fistgroup = reset($usergroups);
641 $SESSION->activegroup[$course->id][$groupmode][0] = $fistgroup->id;
b0dcd128 642
b2bc96d1 643 } else {
644 // this happen when user not assigned into group in SEPARATEGROUPS mode or groups do not exist yet
645 // mod authors must add extra checks for this when SEPARATEGROUPS mode used (such as when posting to forum)
646 $SESSION->activegroup[$course->id][$groupmode][0] = 0;
647 }
648 }
649
650 // set new active group if requested
651 $changegroup = optional_param('group', -1, PARAM_INT);
652 if ($update and $changegroup != -1) {
b2bc96d1 653
654 if ($changegroup == 0) {
655 // do not allow changing to all groups without accessallgroups capability
b0dcd128 656 if ($groupmode == VISIBLEGROUPS or $groupmode == 'aag') {
b2bc96d1 657 $SESSION->activegroup[$course->id][$groupmode][0] = 0;
658 }
659
660 } else {
661 // first make list of allowed groups
b0dcd128 662 if ($groupmode == VISIBLEGROUPS or $groupmode == 'aag') {
25bc3cd3 663 $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid);
b2bc96d1 664 } else {
25bc3cd3 665 $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
b2bc96d1 666 }
667
668 if ($allowedgroups and array_key_exists($changegroup, $allowedgroups)) {
669 $SESSION->activegroup[$course->id][$groupmode][0] = $changegroup;
670 }
671 }
672 }
673
674 return $SESSION->activegroup[$course->id][$groupmode][0];
675}
676
13534ef7
ML
677/**
678 * Returns group active in activity, changes the group by default if 'group' page param present
679 *
e4f0a85e 680 * @global object
681 * @global object
682 * @global object
13534ef7
ML
683 * @param object $cm course module object
684 * @param boolean $update change active group if group param submitted
685 * @return mixed false if groups not used, int if groups used, 0 means all groups (access must be verified in SEPARATE mode)
686 */
687function groups_get_activity_group($cm, $update=false) {
c0d4238d 688 global $CFG, $USER, $SESSION;
689
7e4fdf25 690 // groupings are ignored when not enabled
c0d4238d 691 if (empty($CFG->enablegroupings)) {
692 $cm->groupingid = 0;
693 }
13534ef7
ML
694
695 if (!$groupmode = groups_get_activity_groupmode($cm)) {
696 // NOGROUPS used
697 return false;
698 }
699
b2bc96d1 700 // init activegroup array
177d5493 701 if (!isset($SESSION->activegroup)) {
13534ef7
ML
702 $SESSION->activegroup = array();
703 }
704 if (!array_key_exists($cm->course, $SESSION->activegroup)) {
b0dcd128 705 $SESSION->activegroup[$cm->course] = array(SEPARATEGROUPS=>array(), VISIBLEGROUPS=>array(), 'aag'=>array());
706 }
707
708 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
709 if (has_capability('moodle/site:accessallgroups', $context)) {
710 $groupmode = 'aag';
13534ef7
ML
711 }
712
713 // grouping used the first time - add first user group as default
714 if (!array_key_exists($cm->groupingid, $SESSION->activegroup[$cm->course][$groupmode])) {
b0dcd128 715 if ($groupmode == 'aag') {
716 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = 0; // all groups by default if user has accessallgroups
717
718 } else if ($usergroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid)) {
13534ef7
ML
719 $fistgroup = reset($usergroups);
720 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = $fistgroup->id;
b0dcd128 721
13534ef7
ML
722 } else {
723 // this happen when user not assigned into group in SEPARATEGROUPS mode or groups do not exist yet
724 // mod authors must add extra checks for this when SEPARATEGROUPS mode used (such as when posting to forum)
725 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = 0;
726 }
727 }
728
729 // set new active group if requested
730 $changegroup = optional_param('group', -1, PARAM_INT);
731 if ($update and $changegroup != -1) {
13534ef7
ML
732
733 if ($changegroup == 0) {
b0dcd128 734 // allgroups visible only in VISIBLEGROUPS or when accessallgroups
735 if ($groupmode == VISIBLEGROUPS or $groupmode == 'aag') {
13534ef7
ML
736 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = 0;
737 }
738
739 } else {
740 // first make list of allowed groups
b0dcd128 741 if ($groupmode == VISIBLEGROUPS or $groupmode == 'aag') {
13534ef7
ML
742 $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); // any group in grouping (all if groupings not used)
743 } else {
744 $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); // only assigned groups
745 }
746
747 if ($allowedgroups and array_key_exists($changegroup, $allowedgroups)) {
748 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = $changegroup;
749 }
750 }
751 }
752
753 return $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid];
754}
62d63838 755
18d43e96 756/**
f16fa0a3 757 * Gets a list of groups that the user is allowed to access within the
18d43e96 758 * specified activity.
e4f0a85e 759 *
760 * @global object
18d43e96 761 * @param object $cm Course-module
762 * @param int $userid User ID (defaults to current user)
763 * @return array An array of group objects, or false if none
764 */
cdaa9410 765function groups_get_activity_allowed_groups($cm,$userid=0) {
18d43e96 766 // Use current user by default
767 global $USER;
768 if(!$userid) {
769 $userid=$USER->id;
770 }
f16fa0a3 771
18d43e96 772 // Get groupmode for activity, taking into account course settings
773 $groupmode=groups_get_activity_groupmode($cm);
774
775 // If visible groups mode, or user has the accessallgroups capability,
776 // then they can access all groups for the activity...
f16fa0a3 777 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
18d43e96 778 if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context)) {
f16fa0a3 779 return groups_get_all_groups($cm->course, 0, $cm->groupingid);
18d43e96 780 } else {
781 // ...otherwise they can only access groups they belong to
f16fa0a3 782 return groups_get_all_groups($cm->course, $userid, $cm->groupingid);
783 }
18d43e96 784}
785
dcd8db68 786/**
787 * Determine if a course module is currently visible to a user
aaeba371 788 *
789 * $USER If $userid is null, use the global object.
790 *
791 * @global object
e4f0a85e 792 * @global object
dcd8db68 793 * @param int $cm The course module
794 * @param int $userid The user to check against the group.
795 * @return boolean True if the user can view the course module, false otherwise.
796 */
797function groups_course_module_visible($cm, $userid=null) {
798 global $CFG, $USER;
f16fa0a3 799
dcd8db68 800 if (empty($userid)) {
801 $userid = $USER->id;
802 }
803 if (empty($CFG->enablegroupings)) {
dd97c328 804 return true;
dcd8db68 805 }
806 if (empty($cm->groupmembersonly)) {
dd97c328 807 return true;
dcd8db68 808 }
dd97c328 809 if (has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id), $userid) or groups_has_membership($cm, $userid)) {
810 return true;
dcd8db68 811 }
dd97c328 812 return false;
dcd8db68 813}