[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/ -> grouplib.php (source)

   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      if ($groupmode == VISIBLEGROUPS or $aag) {
 517          $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid);
 518      } else {
 519          $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
 520      }
 521  
 522      $activegroup = groups_get_course_group($course, true, $allowedgroups);
 523  
 524      $groupsmenu = array();
 525      if (!$allowedgroups or $groupmode == VISIBLEGROUPS or $aag) {
 526          $groupsmenu[0] = get_string('allparticipants');
 527      }
 528  
 529      if ($allowedgroups) {
 530          foreach ($allowedgroups as $group) {
 531              $groupsmenu[$group->id] = format_string($group->name);
 532          }
 533      }
 534  
 535      if ($groupmode == VISIBLEGROUPS) {
 536          $grouplabel = get_string('groupsvisible');
 537      } else {
 538          $grouplabel = get_string('groupsseparate');
 539      }
 540  
 541      if ($aag and $course->defaultgroupingid) {
 542          if ($grouping = groups_get_grouping($course->defaultgroupingid)) {
 543              $grouplabel = $grouplabel . ' (' . format_string($grouping->name) . ')';
 544          }
 545      }
 546  
 547      if (count($groupsmenu) == 1) {
 548          $groupname = reset($groupsmenu);
 549          $output = $grouplabel.': '.$groupname;
 550      } else {
 551          $select = new single_select(new moodle_url($urlroot), 'group', $groupsmenu, $activegroup, null, 'selectgroup');
 552          $select->label = $grouplabel;
 553          $output = $OUTPUT->render($select);
 554      }
 555  
 556      $output = '<div class="groupselector">'.$output.'</div>';
 557  
 558      if ($return) {
 559          return $output;
 560      } else {
 561          echo $output;
 562      }
 563  }
 564  
 565  /**
 566   * Generates html to print menu selector for course level, listing all groups.
 567   * Note: This api does not do any group mode check use groups_print_course_menu() instead if you want proper checks.
 568   *
 569   * @param stdclass          $course  course object.
 570   * @param string|moodle_url $urlroot return address. Accepts either a string or a moodle_url.
 571   * @param bool              $update  set this to true to update current active group based on the group param.
 572   * @param int               $activegroup Change group active to this group if $update set to true.
 573   *
 574   * @return string html or void
 575   */
 576  function groups_allgroups_course_menu($course, $urlroot, $update = false, $activegroup = 0) {
 577      global $SESSION, $OUTPUT, $USER;
 578  
 579      $groupmode = groups_get_course_groupmode($course);
 580      $context = context_course::instance($course->id);
 581      $groupsmenu = array();
 582  
 583      if (has_capability('moodle/site:accessallgroups', $context)) {
 584          $groupsmenu[0] = get_string('allparticipants');
 585          $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid);
 586      } else {
 587          $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
 588      }
 589  
 590      foreach ($allowedgroups as $group) {
 591          $groupsmenu[$group->id] = format_string($group->name);
 592      }
 593  
 594      if ($update) {
 595          // Init activegroup array if necessary.
 596          if (!isset($SESSION->activegroup)) {
 597              $SESSION->activegroup = array();
 598          }
 599          if (!isset($SESSION->activegroup[$course->id])) {
 600              $SESSION->activegroup[$course->id] = array(SEPARATEGROUPS => array(), VISIBLEGROUPS => array(), 'aag' => array());
 601          }
 602          if (empty($groupsmenu[$activegroup])) {
 603              $activegroup = key($groupsmenu); // Force set to one of accessible groups.
 604          }
 605          $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid] = $activegroup;
 606      }
 607  
 608      $grouplabel = get_string('groups');
 609      if (count($groupsmenu) == 0) {
 610          return '';
 611      } else if (count($groupsmenu) == 1) {
 612          $groupname = reset($groupsmenu);
 613          $output = $grouplabel.': '.$groupname;
 614      } else {
 615          $select = new single_select(new moodle_url($urlroot), 'group', $groupsmenu, $activegroup, null, 'selectgroup');
 616          $select->label = $grouplabel;
 617          $output = $OUTPUT->render($select);
 618      }
 619  
 620      return $output;
 621  
 622  }
 623  
 624  /**
 625   * Print group menu selector for activity.
 626   *
 627   * @category group
 628   * @param stdClass|cm_info $cm course module object
 629   * @param string|moodle_url $urlroot return address that users get to if they choose an option;
 630   *   should include any parameters needed, e.g. "$CFG->wwwroot/mod/forum/view.php?id=34"
 631   * @param bool $return return as string instead of printing
 632   * @param bool $hideallparticipants If true, this prevents the 'All participants'
 633   *   option from appearing in cases where it normally would. This is intended for
 634   *   use only by activities that cannot display all groups together. (Note that
 635   *   selecting this option does not prevent groups_get_activity_group from
 636   *   returning 0; it will still do that if the user has chosen 'all participants'
 637   *   in another activity, or not chosen anything.)
 638   * @return mixed void or string depending on $return param
 639   */
 640  function groups_print_activity_menu($cm, $urlroot, $return=false, $hideallparticipants=false) {
 641      global $USER, $OUTPUT;
 642  
 643      if ($urlroot instanceof moodle_url) {
 644          // no changes necessary
 645  
 646      } else {
 647          if (strpos($urlroot, 'http') !== 0) { // Will also work for https
 648              // Display error if urlroot is not absolute (this causes the non-JS version to break)
 649              debugging('groups_print_activity_menu requires absolute URL for ' .
 650                        '$urlroot, not <tt>' . s($urlroot) . '</tt>. Example: ' .
 651                        'groups_print_activity_menu($cm, $CFG->wwwroot . \'/mod/mymodule/view.php?id=13\');',
 652                        DEBUG_DEVELOPER);
 653          }
 654          $urlroot = new moodle_url($urlroot);
 655      }
 656  
 657      if (!$groupmode = groups_get_activity_groupmode($cm)) {
 658          if ($return) {
 659              return '';
 660          } else {
 661              return;
 662          }
 663      }
 664  
 665      $context = context_module::instance($cm->id);
 666      $aag = has_capability('moodle/site:accessallgroups', $context);
 667  
 668      if ($groupmode == VISIBLEGROUPS or $aag) {
 669          $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); // any group in grouping
 670      } else {
 671          $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); // only assigned groups
 672      }
 673  
 674      $activegroup = groups_get_activity_group($cm, true, $allowedgroups);
 675  
 676      $groupsmenu = array();
 677      if ((!$allowedgroups or $groupmode == VISIBLEGROUPS or $aag) and !$hideallparticipants) {
 678          $groupsmenu[0] = get_string('allparticipants');
 679      }
 680  
 681      if ($allowedgroups) {
 682          foreach ($allowedgroups as $group) {
 683              $groupsmenu[$group->id] = format_string($group->name);
 684          }
 685      }
 686  
 687      if ($groupmode == VISIBLEGROUPS) {
 688          $grouplabel = get_string('groupsvisible');
 689      } else {
 690          $grouplabel = get_string('groupsseparate');
 691      }
 692  
 693      if ($aag and $cm->groupingid) {
 694          if ($grouping = groups_get_grouping($cm->groupingid)) {
 695              $grouplabel = $grouplabel . ' (' . format_string($grouping->name) . ')';
 696          }
 697      }
 698  
 699      if (count($groupsmenu) == 1) {
 700          $groupname = reset($groupsmenu);
 701          $output = $grouplabel.': '.$groupname;
 702      } else {
 703          $select = new single_select($urlroot, 'group', $groupsmenu, $activegroup, null, 'selectgroup');
 704          $select->label = $grouplabel;
 705          $output = $OUTPUT->render($select);
 706      }
 707  
 708      $output = '<div class="groupselector">'.$output.'</div>';
 709  
 710      if ($return) {
 711          return $output;
 712      } else {
 713          echo $output;
 714      }
 715  }
 716  
 717  /**
 718   * Returns group active in course, changes the group by default if 'group' page param present
 719   *
 720   * @category group
 721   * @param stdClass $course course bject
 722   * @param bool $update change active group if group param submitted
 723   * @param array $allowedgroups list of groups user may access (INTERNAL, to be used only from groups_print_course_menu())
 724   * @return mixed false if groups not used, int if groups used, 0 means all groups (access must be verified in SEPARATE mode)
 725   */
 726  function groups_get_course_group($course, $update=false, $allowedgroups=null) {
 727      global $USER, $SESSION;
 728  
 729      if (!$groupmode = $course->groupmode) {
 730          // NOGROUPS used
 731          return false;
 732      }
 733  
 734      $context = context_course::instance($course->id);
 735      if (has_capability('moodle/site:accessallgroups', $context)) {
 736          $groupmode = 'aag';
 737      }
 738  
 739      if (!is_array($allowedgroups)) {
 740          if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') {
 741              $allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid);
 742          } else {
 743              $allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
 744          }
 745      }
 746  
 747      _group_verify_activegroup($course->id, $groupmode, $course->defaultgroupingid, $allowedgroups);
 748  
 749      // set new active group if requested
 750      $changegroup = optional_param('group', -1, PARAM_INT);
 751      if ($update and $changegroup != -1) {
 752  
 753          if ($changegroup == 0) {
 754              // do not allow changing to all groups without accessallgroups capability
 755              if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') {
 756                  $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid] = 0;
 757              }
 758  
 759          } else {
 760              if ($allowedgroups and array_key_exists($changegroup, $allowedgroups)) {
 761                  $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid] = $changegroup;
 762              }
 763          }
 764      }
 765  
 766      return $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid];
 767  }
 768  
 769  /**
 770   * Returns group active in activity, changes the group by default if 'group' page param present
 771   *
 772   * @category group
 773   * @param stdClass|cm_info $cm course module object
 774   * @param bool $update change active group if group param submitted
 775   * @param array $allowedgroups list of groups user may access (INTERNAL, to be used only from groups_print_activity_menu())
 776   * @return mixed false if groups not used, int if groups used, 0 means all groups (access must be verified in SEPARATE mode)
 777   */
 778  function groups_get_activity_group($cm, $update=false, $allowedgroups=null) {
 779      global $USER, $SESSION;
 780  
 781      if (!$groupmode = groups_get_activity_groupmode($cm)) {
 782          // NOGROUPS used
 783          return false;
 784      }
 785  
 786      $context = context_module::instance($cm->id);
 787      if (has_capability('moodle/site:accessallgroups', $context)) {
 788          $groupmode = 'aag';
 789      }
 790  
 791      if (!is_array($allowedgroups)) {
 792          if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') {
 793              $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid);
 794          } else {
 795              $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid);
 796          }
 797      }
 798  
 799      _group_verify_activegroup($cm->course, $groupmode, $cm->groupingid, $allowedgroups);
 800  
 801      // set new active group if requested
 802      $changegroup = optional_param('group', -1, PARAM_INT);
 803      if ($update and $changegroup != -1) {
 804  
 805          if ($changegroup == 0) {
 806              // allgroups visible only in VISIBLEGROUPS or when accessallgroups
 807              if ($groupmode == VISIBLEGROUPS or $groupmode === 'aag') {
 808                  $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = 0;
 809              }
 810  
 811          } else {
 812              if ($allowedgroups and array_key_exists($changegroup, $allowedgroups)) {
 813                  $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid] = $changegroup;
 814              }
 815          }
 816      }
 817  
 818      return $SESSION->activegroup[$cm->course][$groupmode][$cm->groupingid];
 819  }
 820  
 821  /**
 822   * Gets a list of groups that the user is allowed to access within the
 823   * specified activity.
 824   *
 825   * @category group
 826   * @param stdClass|cm_info $cm Course-module
 827   * @param int $userid User ID (defaults to current user)
 828   * @return array An array of group objects, or false if none
 829   */
 830  function groups_get_activity_allowed_groups($cm,$userid=0) {
 831      // Use current user by default
 832      global $USER;
 833      if(!$userid) {
 834          $userid=$USER->id;
 835      }
 836  
 837      // Get groupmode for activity, taking into account course settings
 838      $groupmode=groups_get_activity_groupmode($cm);
 839  
 840      // If visible groups mode, or user has the accessallgroups capability,
 841      // then they can access all groups for the activity...
 842      $context = context_module::instance($cm->id);
 843      if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context, $userid)) {
 844          return groups_get_all_groups($cm->course, 0, $cm->groupingid);
 845      } else {
 846          // ...otherwise they can only access groups they belong to
 847          return groups_get_all_groups($cm->course, $userid, $cm->groupingid);
 848      }
 849  }
 850  
 851  /**
 852   * Determine if a given group is visible to user or not in a given context.
 853   *
 854   * @since Moodle 2.6
 855   * @param int      $groupid Group id to test. 0 for all groups.
 856   * @param stdClass $course  Course object.
 857   * @param stdClass $cm      Course module object.
 858   * @param int      $userid  user id to test against. Defaults to $USER.
 859   * @return boolean true if visible, false otherwise
 860   */
 861  function groups_group_visible($groupid, $course, $cm = null, $userid = null) {
 862      global $USER;
 863  
 864      if (empty($userid)) {
 865          $userid = $USER->id;
 866      }
 867  
 868      $groupmode = empty($cm) ? groups_get_course_groupmode($course) : groups_get_activity_groupmode($cm, $course);
 869      if ($groupmode == NOGROUPS || $groupmode == VISIBLEGROUPS) {
 870          // Groups are not used, or everything is visible, no need to go any further.
 871          return true;
 872      }
 873  
 874      $context = empty($cm) ? context_course::instance($course->id) : context_module::instance($cm->id);
 875      if (has_capability('moodle/site:accessallgroups', $context, $userid)) {
 876          // User can see everything. Groupid = 0 is handled here as well.
 877          return true;
 878      } else if ($groupid != 0) {
 879          // Group mode is separate, and user doesn't have access all groups capability. Check if user can see requested group.
 880          $groups = empty($cm) ? groups_get_all_groups($course->id, $userid) : groups_get_activity_allowed_groups($cm, $userid);
 881          if (array_key_exists($groupid, $groups)) {
 882              // User can see the group.
 883              return true;
 884          }
 885      }
 886      return false;
 887  }
 888  
 889  /**
 890   * Internal method, sets up $SESSION->activegroup and verifies previous value
 891   *
 892   * @param int $courseid
 893   * @param int|string $groupmode SEPARATEGROUPS, VISIBLEGROUPS or 'aag' (access all groups)
 894   * @param int $groupingid 0 means all groups
 895   * @param array $allowedgroups list of groups user can see
 896   */
 897  function _group_verify_activegroup($courseid, $groupmode, $groupingid, array $allowedgroups) {
 898      global $SESSION, $USER;
 899  
 900      // init activegroup array if necessary
 901      if (!isset($SESSION->activegroup)) {
 902          $SESSION->activegroup = array();
 903      }
 904      if (!array_key_exists($courseid, $SESSION->activegroup)) {
 905          $SESSION->activegroup[$courseid] = array(SEPARATEGROUPS=>array(), VISIBLEGROUPS=>array(), 'aag'=>array());
 906      }
 907  
 908      // make sure that the current group info is ok
 909      if (array_key_exists($groupingid, $SESSION->activegroup[$courseid][$groupmode]) and !array_key_exists($SESSION->activegroup[$courseid][$groupmode][$groupingid], $allowedgroups)) {
 910          // active group does not exist anymore or is 0
 911          if ($SESSION->activegroup[$courseid][$groupmode][$groupingid] > 0 or $groupmode == SEPARATEGROUPS) {
 912              // do not do this if all groups selected and groupmode is not separate
 913              unset($SESSION->activegroup[$courseid][$groupmode][$groupingid]);
 914          }
 915      }
 916  
 917      // set up defaults if necessary
 918      if (!array_key_exists($groupingid, $SESSION->activegroup[$courseid][$groupmode])) {
 919          if ($groupmode == 'aag') {
 920              $SESSION->activegroup[$courseid][$groupmode][$groupingid] = 0; // all groups by default if user has accessallgroups
 921  
 922          } else if ($allowedgroups) {
 923              if ($groupmode != SEPARATEGROUPS and $mygroups = groups_get_all_groups($courseid, $USER->id, $groupingid)) {
 924                  $firstgroup = reset($mygroups);
 925              } else {
 926                  $firstgroup = reset($allowedgroups);
 927              }
 928              $SESSION->activegroup[$courseid][$groupmode][$groupingid] = $firstgroup->id;
 929  
 930          } else {
 931              // this happen when user not assigned into group in SEPARATEGROUPS mode or groups do not exist yet
 932              // mod authors must add extra checks for this when SEPARATEGROUPS mode used (such as when posting to forum)
 933              $SESSION->activegroup[$courseid][$groupmode][$groupingid] = 0;
 934          }
 935      }
 936  }
 937  
 938  /**
 939   * Caches group data for a particular course to speed up subsequent requests.
 940   *
 941   * @param int $courseid The course id to cache data for.
 942   * @param cache $cache The cache if it has already been initialised. If not a new one will be created.
 943   * @return stdClass A data object containing groups, groupings, and mappings.
 944   */
 945  function groups_cache_groupdata($courseid, cache $cache = null) {
 946      global $DB;
 947  
 948      if ($cache === null) {
 949          // Initialise a cache if we wern't given one.
 950          $cache = cache::make('core', 'groupdata');
 951      }
 952  
 953      // Get the groups that belong to the course.
 954      $groups = $DB->get_records('groups', array('courseid' => $courseid), 'name ASC');
 955      // Get the groupings that belong to the course.
 956      $groupings = $DB->get_records('groupings', array('courseid' => $courseid), 'name ASC');
 957  
 958      if (!is_array($groups)) {
 959          $groups = array();
 960      }
 961  
 962      if (!is_array($groupings)) {
 963          $groupings = array();
 964      }
 965  
 966      if (!empty($groupings)) {
 967          // Finally get the mappings between the two.
 968          list($insql, $params) = $DB->get_in_or_equal(array_keys($groupings));
 969          $mappings = $DB->get_records_sql("
 970                  SELECT gg.id, gg.groupingid, gg.groupid
 971                    FROM {groupings_groups} gg
 972                    JOIN {groups} g ON g.id = gg.groupid
 973                   WHERE gg.groupingid $insql
 974                ORDER BY g.name ASC", $params);
 975      } else {
 976          $mappings = array();
 977      }
 978  
 979      // Prepare the data array.
 980      $data = new stdClass;
 981      $data->groups = $groups;
 982      $data->groupings = $groupings;
 983      $data->mappings = $mappings;
 984      // Cache the data.
 985      $cache->set($courseid, $data);
 986      // Finally return it so it can be used if desired.
 987      return $data;
 988  }
 989  
 990  /**
 991   * Gets group data for a course.
 992   *
 993   * This returns an object with the following properties:
 994   *   - groups : An array of all the groups in the course.
 995   *   - groupings : An array of all the groupings within the course.
 996   *   - mappings : An array of group to grouping mappings.
 997   *
 998   * @param int $courseid The course id to get data for.
 999   * @param cache $cache The cache if it has already been initialised. If not a new one will be created.
1000   * @return stdClass
1001   */
1002  function groups_get_course_data($courseid, cache $cache = null) {
1003      if ($cache === null) {
1004          // Initialise a cache if we wern't given one.
1005          $cache = cache::make('core', 'groupdata');
1006      }
1007      // Try to retrieve it from the cache.
1008      $data = $cache->get($courseid);
1009      if ($data === false) {
1010          $data = groups_cache_groupdata($courseid, $cache);
1011      }
1012      return $data;
1013  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1