[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 core_group 22 */ 23 24 defined('MOODLE_INTERNAL') || die(); 25 26 /** 27 * Groups not used in course or activity 28 */ 29 define('NOGROUPS', 0); 30 31 /** 32 * Groups used, users do not see other groups 33 */ 34 define('SEPARATEGROUPS', 1); 35 36 /** 37 * Groups used, students see other groups 38 */ 39 define('VISIBLEGROUPS', 2); 40 41 42 /** 43 * Determines if a group with a given groupid exists. 44 * 45 * @category group 46 * @param int $groupid The groupid to check for 47 * @return bool True if the group exists, false otherwise or if an error 48 * occurred. 49 */ 50 function groups_group_exists($groupid) { 51 global $DB; 52 return $DB->record_exists('groups', array('id'=>$groupid)); 53 } 54 55 /** 56 * Gets the name of a group with a specified id 57 * 58 * @category group 59 * @param int $groupid The id of the group 60 * @return string The name of the group 61 */ 62 function groups_get_group_name($groupid) { 63 global $DB; 64 return $DB->get_field('groups', 'name', array('id'=>$groupid)); 65 } 66 67 /** 68 * Gets the name of a grouping with a specified id 69 * 70 * @category group 71 * @param int $groupingid The id of the grouping 72 * @return string The name of the grouping 73 */ 74 function groups_get_grouping_name($groupingid) { 75 global $DB; 76 return $DB->get_field('groupings', 'name', array('id'=>$groupingid)); 77 } 78 79 /** 80 * Returns the groupid of a group with the name specified for the course. 81 * Group names should be unique in course 82 * 83 * @category group 84 * @param int $courseid The id of the course 85 * @param string $name name of group (without magic quotes) 86 * @return int $groupid 87 */ 88 function groups_get_group_by_name($courseid, $name) { 89 $data = groups_get_course_data($courseid); 90 foreach ($data->groups as $group) { 91 if ($group->name == $name) { 92 return $group->id; 93 } 94 } 95 return false; 96 } 97 98 /** 99 * Returns the groupid of a group with the idnumber specified for the course. 100 * Group idnumbers should be unique within course 101 * 102 * @category group 103 * @param int $courseid The id of the course 104 * @param string $idnumber idnumber of group 105 * @return group object 106 */ 107 function groups_get_group_by_idnumber($courseid, $idnumber) { 108 if (empty($idnumber)) { 109 return false; 110 } 111 $data = groups_get_course_data($courseid); 112 foreach ($data->groups as $group) { 113 if ($group->idnumber == $idnumber) { 114 return $group; 115 } 116 } 117 return false; 118 } 119 120 /** 121 * Returns the groupingid of a grouping with the name specified for the course. 122 * Grouping names should be unique in course 123 * 124 * @category group 125 * @param int $courseid The id of the course 126 * @param string $name name of group (without magic quotes) 127 * @return int $groupid 128 */ 129 function groups_get_grouping_by_name($courseid, $name) { 130 $data = groups_get_course_data($courseid); 131 foreach ($data->groupings as $grouping) { 132 if ($grouping->name == $name) { 133 return $grouping->id; 134 } 135 } 136 return false; 137 } 138 139 /** 140 * Returns the groupingid of a grouping with the idnumber specified for the course. 141 * Grouping names should be unique within course 142 * 143 * @category group 144 * @param int $courseid The id of the course 145 * @param string $idnumber idnumber of the group 146 * @return grouping object 147 */ 148 function groups_get_grouping_by_idnumber($courseid, $idnumber) { 149 if (empty($idnumber)) { 150 return false; 151 } 152 $data = groups_get_course_data($courseid); 153 foreach ($data->groupings as $grouping) { 154 if ($grouping->idnumber == $idnumber) { 155 return $grouping; 156 } 157 } 158 return false; 159 } 160 161 /** 162 * Get the group object 163 * 164 * @category group 165 * @param int $groupid ID of the group. 166 * @param string $fields (default is all fields) 167 * @param int $strictness (IGNORE_MISSING - default) 168 * @return stdGlass group object 169 */ 170 function groups_get_group($groupid, $fields='*', $strictness=IGNORE_MISSING) { 171 global $DB; 172 return $DB->get_record('groups', array('id'=>$groupid), $fields, $strictness); 173 } 174 175 /** 176 * Get the grouping object 177 * 178 * @category group 179 * @param int $groupingid ID of the group. 180 * @param string $fields 181 * @param int $strictness (IGNORE_MISSING - default) 182 * @return stdClass group object 183 */ 184 function groups_get_grouping($groupingid, $fields='*', $strictness=IGNORE_MISSING) { 185 global $DB; 186 return $DB->get_record('groupings', array('id'=>$groupingid), $fields, $strictness); 187 } 188 189 /** 190 * Gets array of all groups in a specified course. 191 * 192 * @category group 193 * @param int $courseid The id of the course. 194 * @param mixed $userid optional user id or array of ids, returns only groups of the user. 195 * @param int $groupingid optional returns only groups in the specified grouping. 196 * @param string $fields 197 * @return array Returns an array of the group objects (userid field returned if array in $userid) 198 */ 199 function groups_get_all_groups($courseid, $userid=0, $groupingid=0, $fields='g.*') { 200 global $DB; 201 202 // We need to check that we each field in the fields list belongs to the group table and that it has not being 203 // aliased. If its something else we need to avoid the cache and run the query as who knows whats going on. 204 $knownfields = true; 205 if ($fields !== 'g.*') { 206 // Quickly check if the first field is no longer g.id as using the 207 // cache will return an array indexed differently than when expect 208 if (strpos($fields, 'g.*') !== 0 && strpos($fields, 'g.id') !== 0) { 209 $knownfields = false; 210 } else { 211 $fieldbits = explode(',', $fields); 212 foreach ($fieldbits as $bit) { 213 $bit = trim($bit); 214 if (strpos($bit, 'g.') !== 0 or stripos($bit, ' AS ') !== false) { 215 $knownfields = false; 216 break; 217 } 218 } 219 } 220 } 221 222 if (empty($userid) && $knownfields) { 223 // We can use the cache. 224 $data = groups_get_course_data($courseid); 225 if (empty($groupingid)) { 226 // All groups.. Easy! 227 $groups = $data->groups; 228 } else { 229 $groups = array(); 230 foreach ($data->mappings as $mapping) { 231 if ($mapping->groupingid != $groupingid) { 232 continue; 233 } 234 if (isset($data->groups[$mapping->groupid])) { 235 $groups[$mapping->groupid] = $data->groups[$mapping->groupid]; 236 } 237 } 238 } 239 // Yay! We could use the cache. One more query saved. 240 return $groups; 241 } 242 243 244 if (empty($userid)) { 245 $userfrom = ""; 246 $userwhere = ""; 247 $params = array(); 248 249 } else { 250 list($usql, $params) = $DB->get_in_or_equal($userid); 251 $userfrom = ", {groups_members} gm"; 252 $userwhere = "AND g.id = gm.groupid AND gm.userid $usql"; 253 } 254 255 if (!empty($groupingid)) { 256 $groupingfrom = ", {groupings_groups} gg"; 257 $groupingwhere = "AND g.id = gg.groupid AND gg.groupingid = ?"; 258 $params[] = $groupingid; 259 } else { 260 $groupingfrom = ""; 261 $groupingwhere = ""; 262 } 263 264 array_unshift($params, $courseid); 265 266 return $DB->get_records_sql("SELECT $fields 267 FROM {groups} g $userfrom $groupingfrom 268 WHERE g.courseid = ? $userwhere $groupingwhere 269 ORDER BY name ASC", $params); 270 } 271 272 273 /** 274 * Gets array of all groups in current user. 275 * 276 * @since Moodle 2.5 277 * @category group 278 * @return array Returns an array of the group objects. 279 */ 280 function groups_get_my_groups() { 281 global $DB, $USER; 282 return $DB->get_records_sql("SELECT * 283 FROM {groups_members} gm 284 JOIN {groups} g 285 ON g.id = gm.groupid 286 WHERE gm.userid = ? 287 ORDER BY name ASC", array($USER->id)); 288 } 289 290 /** 291 * Returns info about user's groups in course. 292 * 293 * @category group 294 * @param int $courseid 295 * @param int $userid $USER if not specified 296 * @return array Array[groupingid][groupid] including grouping id 0 which means all groups 297 */ 298 function groups_get_user_groups($courseid, $userid=0) { 299 global $USER, $DB; 300 301 if (empty($userid)) { 302 $userid = $USER->id; 303 } 304 305 $sql = "SELECT g.id, gg.groupingid 306 FROM {groups} g 307 JOIN {groups_members} gm ON gm.groupid = g.id 308 LEFT JOIN {groupings_groups} gg ON gg.groupid = g.id 309 WHERE gm.userid = ? AND g.courseid = ?"; 310 $params = array($userid, $courseid); 311 312 $rs = $DB->get_recordset_sql($sql, $params); 313 314 if (!$rs->valid()) { 315 $rs->close(); // Not going to iterate (but exit), close rs 316 return array('0' => array()); 317 } 318 319 $result = array(); 320 $allgroups = array(); 321 322 foreach ($rs as $group) { 323 $allgroups[$group->id] = $group->id; 324 if (is_null($group->groupingid)) { 325 continue; 326 } 327 if (!array_key_exists($group->groupingid, $result)) { 328 $result[$group->groupingid] = array(); 329 } 330 $result[$group->groupingid][$group->id] = $group->id; 331 } 332 $rs->close(); 333 334 $result['0'] = array_keys($allgroups); // all groups 335 336 return $result; 337 } 338 339 /** 340 * Gets an array of all groupings in a specified course. This value is cached 341 * for a single course (so you can call it repeatedly for the same course 342 * without a performance penalty). 343 * 344 * @category group 345 * @param int $courseid return all groupings from course with this courseid 346 * @return array Returns an array of the grouping objects (empty if none) 347 */ 348 function groups_get_all_groupings($courseid) { 349 $data = groups_get_course_data($courseid); 350 return $data->groupings; 351 } 352 353 /** 354 * Determines if the user is a member of the given group. 355 * 356 * If $userid is null, use the global object. 357 * 358 * @category group 359 * @param int $groupid The group to check for membership. 360 * @param int $userid The user to check against the group. 361 * @return bool True if the user is a member, false otherwise. 362 */ 363 function groups_is_member($groupid, $userid=null) { 364 global $USER, $DB; 365 366 if (!$userid) { 367 $userid = $USER->id; 368 } 369 370 return $DB->record_exists('groups_members', array('groupid'=>$groupid, 'userid'=>$userid)); 371 } 372 373 /** 374 * Determines if current or specified is member of any active group in activity 375 * 376 * @category group 377 * @staticvar array $cache 378 * @param stdClass|cm_info $cm course module object 379 * @param int $userid id of user, null means $USER->id 380 * @return bool true if user member of at least one group used in activity 381 */ 382 function groups_has_membership($cm, $userid=null) { 383 global $CFG, $USER, $DB; 384 385 static $cache = array(); 386 387 if (empty($userid)) { 388 $userid = $USER->id; 389 } 390 391 $cachekey = $userid.'|'.$cm->course.'|'.$cm->groupingid; 392 if (isset($cache[$cachekey])) { 393 return($cache[$cachekey]); 394 } 395 396 if ($cm->groupingid) { 397 // find out if member of any group in selected activity grouping 398 $sql = "SELECT 'x' 399 FROM {groups_members} gm, {groupings_groups} gg 400 WHERE gm.userid = ? AND gm.groupid = gg.groupid AND gg.groupingid = ?"; 401 $params = array($userid, $cm->groupingid); 402 403 } else { 404 // no grouping used - check all groups in course 405 $sql = "SELECT 'x' 406 FROM {groups_members} gm, {groups} g 407 WHERE gm.userid = ? AND gm.groupid = g.id AND g.courseid = ?"; 408 $params = array($userid, $cm->course); 409 } 410 411 $cache[$cachekey] = $DB->record_exists_sql($sql, $params); 412 413 return $cache[$cachekey]; 414 } 415 416 /** 417 * Returns the users in the specified group. 418 * 419 * @category group 420 * @param int $groupid The groupid to get the users for 421 * @param int $fields The fields to return 422 * @param int $sort optional sorting of returned users 423 * @return array|bool Returns an array of the users for the specified 424 * group or false if no users or an error returned. 425 */ 426 function groups_get_members($groupid, $fields='u.*', $sort='lastname ASC') { 427 global $DB; 428 429 return $DB->get_records_sql("SELECT $fields 430 FROM {user} u, {groups_members} gm 431 WHERE u.id = gm.userid AND gm.groupid = ? 432 ORDER BY $sort", array($groupid)); 433 } 434 435 436 /** 437 * Returns the users in the specified grouping. 438 * 439 * @category group 440 * @param int $groupingid The groupingid to get the users for 441 * @param string $fields The fields to return 442 * @param string $sort optional sorting of returned users 443 * @return array|bool Returns an array of the users for the specified 444 * group or false if no users or an error returned. 445 */ 446 function groups_get_grouping_members($groupingid, $fields='u.*', $sort='lastname ASC') { 447 global $DB; 448 449 return $DB->get_records_sql("SELECT $fields 450 FROM {user} u 451 INNER JOIN {groups_members} gm ON u.id = gm.userid 452 INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid 453 WHERE gg.groupingid = ? 454 ORDER BY $sort", array($groupingid)); 455 } 456 457 /** 458 * Returns effective groupmode used in course 459 * 460 * @category group 461 * @param stdClass $course course object. 462 * @return int group mode 463 */ 464 function groups_get_course_groupmode($course) { 465 return $course->groupmode; 466 } 467 468 /** 469 * Returns effective groupmode used in activity, course setting 470 * overrides activity setting if groupmodeforce enabled. 471 * 472 * If $cm is an instance of cm_info it is easier to use $cm->effectivegroupmode 473 * 474 * @category group 475 * @param cm_info|stdClass $cm the course module object. Only the ->course and ->groupmode need to be set. 476 * @param stdClass $course object optional course object to improve perf 477 * @return int group mode 478 */ 479 function groups_get_activity_groupmode($cm, $course=null) { 480 if ($cm instanceof cm_info) { 481 return $cm->effectivegroupmode; 482 } 483 if (isset($course->id) and $course->id == $cm->course) { 484 //ok 485 } else { 486 // Get course object (reuse $COURSE if possible). 487 $course = get_course($cm->course, false); 488 } 489 490 return empty($course->groupmodeforce) ? $cm->groupmode : $course->groupmode; 491 } 492 493 /** 494 * Print group menu selector for course level. 495 * 496 * @category group 497 * @param stdClass $course course object 498 * @param mixed $urlroot return address. Accepts either a string or a moodle_url 499 * @param bool $return return as string instead of printing 500 * @return mixed void or string depending on $return param 501 */ 502 function groups_print_course_menu($course, $urlroot, $return=false) { 503 global $USER, $OUTPUT; 504 505 if (!$groupmode = $course->groupmode) { 506 if ($return) { 507 return ''; 508 } else { 509 return; 510 } 511 } 512 513 $context = context_course::instance($course->id); 514 $aag = has_capability('moodle/site:accessallgroups', $context); 515 516 $usergroups = array(); 517 if ($groupmode == VISIBLEGROUPS or $aag) { 518 $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid); 519 // Get user's own groups and put to the top. 520 $usergroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid); 521 } else { 522 $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid); 523 } 524 525 $activegroup = groups_get_course_group($course, true, $allowedgroups); 526 527 $groupsmenu = array(); 528 if (!$allowedgroups or $groupmode == VISIBLEGROUPS or $aag) { 529 $groupsmenu[0] = get_string('allparticipants'); 530 } 531 532 $groupsmenu += groups_sort_menu_options($allowedgroups, $usergroups); 533 534 if ($groupmode == VISIBLEGROUPS) { 535 $grouplabel = get_string('groupsvisible'); 536 } else { 537 $grouplabel = get_string('groupsseparate'); 538 } 539 540 if ($aag and $course->defaultgroupingid) { 541 if ($grouping = groups_get_grouping($course->defaultgroupingid)) { 542 $grouplabel = $grouplabel . ' (' . format_string($grouping->name) . ')'; 543 } 544 } 545 546 if (count($groupsmenu) == 1) { 547 $groupname = reset($groupsmenu); 548 $output = $grouplabel.': '.$groupname; 549 } else { 550 $select = new single_select(new moodle_url($urlroot), 'group', $groupsmenu, $activegroup, null, 'selectgroup'); 551 $select->label = $grouplabel; 552 $output = $OUTPUT->render($select); 553 } 554 555 $output = '<div class="groupselector">'.$output.'</div>'; 556 557 if ($return) { 558 return $output; 559 } else { 560 echo $output; 561 } 562 } 563 564 /** 565 * Turn an array of groups into an array of menu options. 566 * @param array $groups of group objects. 567 * @return array groupid => formatted group name. 568 */ 569 function groups_list_to_menu($groups) { 570 $groupsmenu = array(); 571 foreach ($groups as $group) { 572 $groupsmenu[$group->id] = format_string($group->name); 573 } 574 return $groupsmenu; 575 } 576 577 /** 578 * Takes user's allowed groups and own groups and formats for use in group selector menu 579 * If user has allowed groups + own groups will add to an optgroup 580 * Own groups are removed from allowed groups 581 * @param array $allowedgroups All groups user is allowed to see 582 * @param array $usergroups Groups user belongs to 583 * @return array 584 */ 585 function groups_sort_menu_options($allowedgroups, $usergroups) { 586 $useroptions = array(); 587 if ($usergroups) { 588 $useroptions = groups_list_to_menu($usergroups); 589 590 // Remove user groups from other groups list. 591 foreach ($usergroups as $group) { 592 unset($allowedgroups[$group->id]); 593 } 594 } 595 596 $allowedoptions = array(); 597 if ($allowedgroups) { 598 $allowedoptions = groups_list_to_menu($allowedgroups); 599 } 600 601 if ($useroptions && $allowedoptions) { 602 return array( 603 1 => array(get_string('mygroups', 'group') => $useroptions), 604 2 => array(get_string('othergroups', 'group') => $allowedoptions) 605 ); 606 } else if ($useroptions) { 607 return $useroptions; 608 } else { 609 return $allowedoptions; 610 } 611 } 612 613 /** 614 * Generates html to print menu selector for course level, listing all groups. 615 * Note: This api does not do any group mode check use groups_print_course_menu() instead if you want proper checks. 616 * 617 * @param stdclass $course course object. 618 * @param string|moodle_url $urlroot return address. Accepts either a string or a moodle_url. 619 * @param bool $update set this to true to update current active group based on the group param. 620 * @param int $activegroup Change group active to this group if $update set to true. 621 * 622 * @return string html or void 623 */ 624 function groups_allgroups_course_menu($course, $urlroot, $update = false, $activegroup = 0) { 625 global $SESSION, $OUTPUT, $USER; 626 627 $groupmode = groups_get_course_groupmode($course); 628 $context = context_course::instance($course->id); 629 $groupsmenu = array(); 630 631 if (has_capability('moodle/site:accessallgroups', $context)) { 632 $groupsmenu[0] = get_string('allparticipants'); 633 $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid); 634 } else { 635 $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid); 636 } 637 638 $groupsmenu += groups_list_to_menu($allowedgroups); 639 640 if ($update) { 641 // Init activegroup array if necessary. 642 if (!isset($SESSION->activegroup)) { 643 $SESSION->activegroup = array(); 644 } 645 if (!isset($SESSION->activegroup[$course->id])) { 646 $SESSION->activegroup[$course->id] = array(SEPARATEGROUPS => array(), VISIBLEGROUPS => array(), 'aag' => array()); 647 } 648 if (empty($groupsmenu[$activegroup])) { 649 $activegroup = key($groupsmenu); // Force set to one of accessible groups. 650 } 651 $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid] = $activegroup; 652 } 653 654 $grouplabel = get_string('groups'); 655 if (count($groupsmenu) == 0) { 656 return ''; 657 } else if (count($groupsmenu) == 1) { 658 $groupname = reset($groupsmenu); 659 $output = $grouplabel.': '.$groupname; 660 } else { 661 $select = new single_select(new moodle_url($urlroot), 'group', $groupsmenu, $activegroup, null, 'selectgroup'); 662 $select->label = $grouplabel; 663 $output = $OUTPUT->render($select); 664 } 665 666 return $output; 667 668 } 669 670 /** 671 * Print group menu selector for activity. 672 * 673 * @category group 674 * @param stdClass|cm_info $cm course module object 675 * @param string|moodle_url $urlroot return address that users get to if they choose an option; 676 * should include any parameters needed, e.g. "$CFG->wwwroot/mod/forum/view.php?id=34" 677 * @param bool $return return as string instead of printing 678 * @param bool $hideallparticipants If true, this prevents the 'All participants' 679 * option from appearing in cases where it normally would. This is intended for 680 * use only by activities that cannot display all groups together. (Note that 681 * selecting this option does not prevent groups_get_activity_group from 682 * returning 0; it will still do that if the user has chosen 'all participants' 683 * in another activity, or not chosen anything.) 684 * @return mixed void or string depending on $return param 685 */ 686 function groups_print_activity_menu($cm, $urlroot, $return=false, $hideallparticipants=false) { 687 global $USER, $OUTPUT; 688 689 if ($urlroot instanceof moodle_url) { 690 // no changes necessary 691 692 } else { 693 if (strpos($urlroot, 'http') !== 0) { // Will also work for https 694 // Display error if urlroot is not absolute (this causes the non-JS version to break) 695 debugging('groups_print_activity_menu requires absolute URL for ' . 696 '$urlroot, not <tt>' . s($urlroot) . '</tt>. Example: ' . 697 'groups_print_activity_menu($cm, $CFG->wwwroot . \'/mod/mymodule/view.php?id=13\');', 698 DEBUG_DEVELOPER); 699 } 700 $urlroot = new moodle_url($urlroot); 701 } 702 703 if (!$groupmode = groups_get_activity_groupmode($cm)) { 704 if ($return) { 705 return ''; 706 } else { 707 return; 708 } 709 } 710 711 $context = context_module::instance($cm->id); 712 $aag = has_capability('moodle/site:accessallgroups', $context); 713 714 $usergroups = array(); 715 if ($groupmode == VISIBLEGROUPS or $aag) { 716 $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); // any group in grouping 717 // Get user's own groups and put to the top. 718 $usergroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); 719 } else { 720 $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); // only assigned groups 721 } 722 723 $activegroup = groups_get_activity_group($cm, true, $allowedgroups); 724 725 $groupsmenu = array(); 726 if ((!$allowedgroups or $groupmode == VISIBLEGROUPS or $aag) and !$hideallparticipants) { 727 $groupsmenu[0] = get_string('allparticipants'); 728 } 729 730 $groupsmenu += groups_sort_menu_options($allowedgroups, $usergroups); 731 732 if ($groupmode == VISIBLEGROUPS) { 733 $grouplabel = get_string('groupsvisible'); 734 } else { 735 $grouplabel = get_string('groupsseparate'); 736 } 737 738 if ($aag and $cm->groupingid) { 739 if ($grouping = groups_get_grouping($cm->groupingid)) { 740 $grouplabel = $grouplabel . ' (' . format_string($grouping->name) . ')'; 741 } 742 } 743 744 if (count($groupsmenu) == 1) { 745 $groupname = reset($groupsmenu); 746 $output = $grouplabel.': '.$groupname; 747 } else { 748 $select = new single_select($urlroot, 'group', $groupsmenu, $activegroup, null, 'selectgroup'); 749 $select->label = $grouplabel; 750 $output = $OUTPUT->render($select); 751 } 752 753 $output = '<div class="groupselector">'.$output.'</div>'; 754 755 if ($return) { 756 return $output; 757 } else { 758 echo $output; 759 } 760 } 761 762 /** 763 * Returns group active in course, changes the group by default if 'group' page param present 764 * 765 * @category group 766 * @param stdClass $course course bject 767 * @param bool $update change active group if group param submitted 768 * @param array $allowedgroups list of groups user may access (INTERNAL, to be used only from groups_print_course_menu()) 769 * @return mixed false if groups not used, int if groups used, 0 means all groups (access must be verified in SEPARATE mode) 770 */ 771 function groups_get_course_group($course, $update=false, $allowedgroups=null) { 772 global $USER, $SESSION; 773 774 if (!$groupmode = $course->groupmode) { 775 // NOGROUPS used 776 return false; 777 } 778 779 $context = context_course::instance($course->id); 780 if (has_capability('moodle/site:accessallgroups', $context)) { 781 $groupmode = 'aag'; 782 } 783 784 if (!is_array($allowedgroups)) { 785 if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') { 786 $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid); 787 } else { 788 $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid); 789 } 790 } 791 792 _group_verify_activegroup($course->id, $groupmode, $course->defaultgroupingid, $allowedgroups); 793 794 // set new active group if requested 795 $changegroup = optional_param('group', -1, PARAM_INT); 796 if ($update and $changegroup != -1) { 797 798 if ($changegroup == 0) { 799 // do not allow changing to all groups without accessallgroups capability 800 if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') { 801 $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid] = 0; 802 } 803 804 } else { 805 if ($allowedgroups and array_key_exists($changegroup, $allowedgroups)) { 806 $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid] = $changegroup; 807 } 808 } 809 } 810 811 return $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid]; 812 } 813 814 /** 815 * Returns group active in activity, changes the group by default if 'group' page param present 816 * 817 * @category group 818 * @param stdClass|cm_info $cm course module object 819 * @param bool $update change active group if group param submitted 820 * @param array $allowedgroups list of groups user may access (INTERNAL, to be used only from groups_print_activity_menu()) 821 * @return mixed false if groups not used, int if groups used, 0 means all groups (access must be verified in SEPARATE mode) 822 */ 823 function groups_get_activity_group($cm, $update=false, $allowedgroups=null) { 824 global $USER, $SESSION; 825 826 if (!$groupmode = groups_get_activity_groupmode($cm)) { 827 // NOGROUPS used 828 return false; 829 } 830 831 $context = context_module::instance($cm->id); 832 if (has_capability('moodle/site:accessallgroups', $context)) { 833 $groupmode = 'aag'; 834 } 835 836 if (!is_array($allowedgroups)) { 837 if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') { 838 $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); 839 } else { 840 $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); 841 } 842 } 843 844 _group_verify_activegroup($cm->course, $groupmode, $cm->groupingid, $allowedgroups); 845 846 // set new active group if requested 847 $changegroup = optional_param('group', -1, PARAM_INT); 848 if ($update and $changegroup != -1) { 849 850 if ($changegroup == 0) { 851 // allgroups visible only in VISIBLEGROUPS or when accessallgroups 852 if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') { 853 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = 0; 854 } 855 856 } else { 857 if ($allowedgroups and array_key_exists($changegroup, $allowedgroups)) { 858 $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = $changegroup; 859 } 860 } 861 } 862 863 return $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid]; 864 } 865 866 /** 867 * Gets a list of groups that the user is allowed to access within the 868 * specified activity. 869 * 870 * @category group 871 * @param stdClass|cm_info $cm Course-module 872 * @param int $userid User ID (defaults to current user) 873 * @return array An array of group objects, or false if none 874 */ 875 function groups_get_activity_allowed_groups($cm,$userid=0) { 876 // Use current user by default 877 global $USER; 878 if(!$userid) { 879 $userid=$USER->id; 880 } 881 882 // Get groupmode for activity, taking into account course settings 883 $groupmode=groups_get_activity_groupmode($cm); 884 885 // If visible groups mode, or user has the accessallgroups capability, 886 // then they can access all groups for the activity... 887 $context = context_module::instance($cm->id); 888 if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context, $userid)) { 889 return groups_get_all_groups($cm->course, 0, $cm->groupingid); 890 } else { 891 // ...otherwise they can only access groups they belong to 892 return groups_get_all_groups($cm->course, $userid, $cm->groupingid); 893 } 894 } 895 896 /** 897 * Determine if a given group is visible to user or not in a given context. 898 * 899 * @since Moodle 2.6 900 * @param int $groupid Group id to test. 0 for all groups. 901 * @param stdClass $course Course object. 902 * @param stdClass $cm Course module object. 903 * @param int $userid user id to test against. Defaults to $USER. 904 * @return boolean true if visible, false otherwise 905 */ 906 function groups_group_visible($groupid, $course, $cm = null, $userid = null) { 907 global $USER; 908 909 if (empty($userid)) { 910 $userid = $USER->id; 911 } 912 913 $groupmode = empty($cm) ? groups_get_course_groupmode($course) : groups_get_activity_groupmode($cm, $course); 914 if ($groupmode == NOGROUPS || $groupmode == VISIBLEGROUPS) { 915 // Groups are not used, or everything is visible, no need to go any further. 916 return true; 917 } 918 919 $context = empty($cm) ? context_course::instance($course->id) : context_module::instance($cm->id); 920 if (has_capability('moodle/site:accessallgroups', $context, $userid)) { 921 // User can see everything. Groupid = 0 is handled here as well. 922 return true; 923 } else if ($groupid != 0) { 924 // Group mode is separate, and user doesn't have access all groups capability. Check if user can see requested group. 925 $groups = empty($cm) ? groups_get_all_groups($course->id, $userid) : groups_get_activity_allowed_groups($cm, $userid); 926 if (array_key_exists($groupid, $groups)) { 927 // User can see the group. 928 return true; 929 } 930 } 931 return false; 932 } 933 934 /** 935 * Internal method, sets up $SESSION->activegroup and verifies previous value 936 * 937 * @param int $courseid 938 * @param int|string $groupmode SEPARATEGROUPS, VISIBLEGROUPS or 'aag' (access all groups) 939 * @param int $groupingid 0 means all groups 940 * @param array $allowedgroups list of groups user can see 941 */ 942 function _group_verify_activegroup($courseid, $groupmode, $groupingid, array $allowedgroups) { 943 global $SESSION, $USER; 944 945 // init activegroup array if necessary 946 if (!isset($SESSION->activegroup)) { 947 $SESSION->activegroup = array(); 948 } 949 if (!array_key_exists($courseid, $SESSION->activegroup)) { 950 $SESSION->activegroup[$courseid] = array(SEPARATEGROUPS=>array(), VISIBLEGROUPS=>array(), 'aag'=>array()); 951 } 952 953 // make sure that the current group info is ok 954 if (array_key_exists($groupingid, $SESSION->activegroup[$courseid][$groupmode]) and !array_key_exists($SESSION->activegroup[$courseid][$groupmode][$groupingid], $allowedgroups)) { 955 // active group does not exist anymore or is 0 956 if ($SESSION->activegroup[$courseid][$groupmode][$groupingid] > 0 or $groupmode == SEPARATEGROUPS) { 957 // do not do this if all groups selected and groupmode is not separate 958 unset($SESSION->activegroup[$courseid][$groupmode][$groupingid]); 959 } 960 } 961 962 // set up defaults if necessary 963 if (!array_key_exists($groupingid, $SESSION->activegroup[$courseid][$groupmode])) { 964 if ($groupmode == 'aag') { 965 $SESSION->activegroup[$courseid][$groupmode][$groupingid] = 0; // all groups by default if user has accessallgroups 966 967 } else if ($allowedgroups) { 968 if ($groupmode != SEPARATEGROUPS and $mygroups = groups_get_all_groups($courseid, $USER->id, $groupingid)) { 969 $firstgroup = reset($mygroups); 970 } else { 971 $firstgroup = reset($allowedgroups); 972 } 973 $SESSION->activegroup[$courseid][$groupmode][$groupingid] = $firstgroup->id; 974 975 } else { 976 // this happen when user not assigned into group in SEPARATEGROUPS mode or groups do not exist yet 977 // mod authors must add extra checks for this when SEPARATEGROUPS mode used (such as when posting to forum) 978 $SESSION->activegroup[$courseid][$groupmode][$groupingid] = 0; 979 } 980 } 981 } 982 983 /** 984 * Caches group data for a particular course to speed up subsequent requests. 985 * 986 * @param int $courseid The course id to cache data for. 987 * @param cache $cache The cache if it has already been initialised. If not a new one will be created. 988 * @return stdClass A data object containing groups, groupings, and mappings. 989 */ 990 function groups_cache_groupdata($courseid, cache $cache = null) { 991 global $DB; 992 993 if ($cache === null) { 994 // Initialise a cache if we wern't given one. 995 $cache = cache::make('core', 'groupdata'); 996 } 997 998 // Get the groups that belong to the course. 999 $groups = $DB->get_records('groups', array('courseid' => $courseid), 'name ASC'); 1000 // Get the groupings that belong to the course. 1001 $groupings = $DB->get_records('groupings', array('courseid' => $courseid), 'name ASC'); 1002 1003 if (!is_array($groups)) { 1004 $groups = array(); 1005 } 1006 1007 if (!is_array($groupings)) { 1008 $groupings = array(); 1009 } 1010 1011 if (!empty($groupings)) { 1012 // Finally get the mappings between the two. 1013 list($insql, $params) = $DB->get_in_or_equal(array_keys($groupings)); 1014 $mappings = $DB->get_records_sql(" 1015 SELECT gg.id, gg.groupingid, gg.groupid 1016 FROM {groupings_groups} gg 1017 JOIN {groups} g ON g.id = gg.groupid 1018 WHERE gg.groupingid $insql 1019 ORDER BY g.name ASC", $params); 1020 } else { 1021 $mappings = array(); 1022 } 1023 1024 // Prepare the data array. 1025 $data = new stdClass; 1026 $data->groups = $groups; 1027 $data->groupings = $groupings; 1028 $data->mappings = $mappings; 1029 // Cache the data. 1030 $cache->set($courseid, $data); 1031 // Finally return it so it can be used if desired. 1032 return $data; 1033 } 1034 1035 /** 1036 * Gets group data for a course. 1037 * 1038 * This returns an object with the following properties: 1039 * - groups : An array of all the groups in the course. 1040 * - groupings : An array of all the groupings within the course. 1041 * - mappings : An array of group to grouping mappings. 1042 * 1043 * @param int $courseid The course id to get data for. 1044 * @param cache $cache The cache if it has already been initialised. If not a new one will be created. 1045 * @return stdClass 1046 */ 1047 function groups_get_course_data($courseid, cache $cache = null) { 1048 if ($cache === null) { 1049 // Initialise a cache if we wern't given one. 1050 $cache = cache::make('core', 'groupdata'); 1051 } 1052 // Try to retrieve it from the cache. 1053 $data = $cache->get($courseid); 1054 if ($data === false) { 1055 $data = groups_cache_groupdata($courseid, $cache); 1056 } 1057 return $data; 1058 } 1059 1060 /** 1061 * Determine if the current user can see at least one of the groups of the specified user. 1062 * 1063 * @param stdClass $course Course object. 1064 * @param int $userid user id to check against. 1065 * @param stdClass $cm Course module object. Optional, just for checking at activity level instead course one. 1066 * @return boolean true if visible, false otherwise 1067 * @since Moodle 2.9 1068 */ 1069 function groups_user_groups_visible($course, $userid, $cm = null) { 1070 global $USER; 1071 1072 $groupmode = empty($cm) ? groups_get_course_groupmode($course) : groups_get_activity_groupmode($cm, $course); 1073 if ($groupmode == NOGROUPS || $groupmode == VISIBLEGROUPS) { 1074 // Groups are not used, or everything is visible, no need to go any further. 1075 return true; 1076 } 1077 1078 $context = empty($cm) ? context_course::instance($course->id) : context_module::instance($cm->id); 1079 if (has_capability('moodle/site:accessallgroups', $context)) { 1080 // User can see everything. 1081 return true; 1082 } else { 1083 // Group mode is separate, and user doesn't have access all groups capability. 1084 if (empty($cm)) { 1085 $usergroups = groups_get_all_groups($course->id, $userid); 1086 $currentusergroups = groups_get_all_groups($course->id, $USER->id); 1087 } else { 1088 $usergroups = groups_get_activity_allowed_groups($cm, $userid); 1089 $currentusergroups = groups_get_activity_allowed_groups($cm, $USER->id); 1090 } 1091 1092 $samegroups = array_intersect_key($currentusergroups, $usergroups); 1093 if (!empty($samegroups)) { 1094 // We share groups! 1095 return true; 1096 } 1097 } 1098 return false; 1099 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |