/**
  * Returns SQL to fetch all enrolled users with the given capability in the current workshop
  *
  * The returned array consists of string $sql and the $params array. Note that the $sql can be
  * empty if a grouping is selected and it has no groups.
  *
  * The list is automatically restricted according to any availability restrictions
  * that apply to user lists (e.g. group, grouping restrictions).
  *
  * @param string $capability the name of the capability
  * @param bool $musthavesubmission ff true, return only users who have already submitted
  * @param int $groupid 0 means ignore groups, any other value limits the result by group id
  * @return array of (string)sql, (array)params
  */
 protected function get_users_with_capability_sql($capability, $musthavesubmission, $groupid)
 {
     global $CFG;
     /** @var int static counter used to generate unique parameter holders */
     static $inc = 0;
     $inc++;
     // If the caller requests all groups and we are using a selected grouping,
     // recursively call this function for each group in the grouping (this is
     // needed because get_enrolled_sql only supports a single group).
     if (empty($groupid) and $this->cm->groupingid) {
         $groupingid = $this->cm->groupingid;
         $groupinggroupids = array_keys(groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid, 'g.id'));
         $sql = array();
         $params = array();
         foreach ($groupinggroupids as $groupinggroupid) {
             if ($groupinggroupid > 0) {
                 // just in case in order not to fall into the endless loop
                 list($gsql, $gparams) = $this->get_users_with_capability_sql($capability, $musthavesubmission, $groupinggroupid);
                 $sql[] = $gsql;
                 $params = array_merge($params, $gparams);
             }
         }
         $sql = implode(PHP_EOL . " UNION " . PHP_EOL, $sql);
         return array($sql, $params);
     }
     list($esql, $params) = get_enrolled_sql($this->context, $capability, $groupid, true);
     $userfields = user_picture::fields('u');
     $sql = "SELECT {$userfields}\n                  FROM {user} u\n                  JOIN ({$esql}) je ON (je.id = u.id AND u.deleted = 0) ";
     if ($musthavesubmission) {
         $sql .= " JOIN {workshop_submissions} ws ON (ws.authorid = u.id AND ws.example = 0 AND ws.workshopid = :workshopid{$inc}) ";
         $params['workshopid' . $inc] = $this->id;
     }
     // If the activity is restricted so that only certain users should appear
     // in user lists, integrate this into the same SQL.
     $info = new \core_availability\info_module($this->cm);
     list($listsql, $listparams) = $info->get_user_list_sql(false);
     if ($listsql) {
         $sql .= " JOIN ({$listsql}) restricted ON restricted.id = u.id ";
         $params = array_merge($params, $listparams);
     }
     return array($sql, $params);
 }
Exemple #2
0
 /**
  * Tests the filter_users (bulk checking) function. Also tests the SQL
  * variant get_user_list_sql.
  */
 public function test_filter_users()
 {
     global $DB, $CFG;
     $this->resetAfterTest();
     $CFG->enableavailability = true;
     // Erase static cache before test.
     condition::wipe_static_cache();
     // Make a test course and some users.
     $generator = $this->getDataGenerator();
     $course = $generator->create_course();
     $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
     $teacher = $generator->create_user();
     $generator->enrol_user($teacher->id, $course->id, $roleids['editingteacher']);
     $allusers = array($teacher->id => $teacher);
     $students = array();
     for ($i = 0; $i < 3; $i++) {
         $student = $generator->create_user();
         $students[$i] = $student;
         $generator->enrol_user($student->id, $course->id, $roleids['student']);
         $allusers[$student->id] = $student;
     }
     $info = new \core_availability\mock_info($course);
     $checker = new \core_availability\capability_checker($info->get_context());
     // Make test groups.
     $group1 = $generator->create_group(array('courseid' => $course->id));
     $group2 = $generator->create_group(array('courseid' => $course->id));
     $grouping1 = $generator->create_grouping(array('courseid' => $course->id));
     $grouping2 = $generator->create_grouping(array('courseid' => $course->id));
     groups_assign_grouping($grouping1->id, $group1->id);
     groups_assign_grouping($grouping2->id, $group2->id);
     // Make page in grouping 2.
     $pagegen = $generator->get_plugin_generator('mod_page');
     $page = $pagegen->create_instance(array('course' => $course->id, 'groupingid' => $grouping2->id, 'availability' => '{"op":"|","show":true,"c":[{"type":"grouping","activity":true}]}'));
     // Assign students to groups as follows (teacher is not in a group):
     // 0: no groups.
     // 1: in group 1/grouping 1.
     // 2: in group 2/grouping 2.
     groups_add_member($group1, $students[1]);
     groups_add_member($group2, $students[2]);
     // Test specific grouping.
     $cond = new condition((object) array('id' => (int) $grouping1->id));
     $result = array_keys($cond->filter_user_list($allusers, false, $info, $checker));
     ksort($result);
     $expected = array($teacher->id, $students[1]->id);
     $this->assertEquals($expected, $result);
     // Test it with get_user_list_sql.
     list($sql, $params) = $cond->get_user_list_sql(false, $info, true);
     $result = $DB->get_fieldset_sql($sql, $params);
     sort($result);
     $this->assertEquals($expected, $result);
     // NOT test.
     $result = array_keys($cond->filter_user_list($allusers, true, $info, $checker));
     ksort($result);
     $expected = array($teacher->id, $students[0]->id, $students[2]->id);
     $this->assertEquals($expected, $result);
     // NOT with get_user_list_sql.
     list($sql, $params) = $cond->get_user_list_sql(true, $info, true);
     $result = $DB->get_fieldset_sql($sql, $params);
     sort($result);
     $this->assertEquals($expected, $result);
     // Test course-module grouping.
     $modinfo = get_fast_modinfo($course);
     $cm = $modinfo->get_cm($page->cmid);
     $info = new \core_availability\info_module($cm);
     $result = array_keys($info->filter_user_list($allusers, $course));
     $expected = array($teacher->id, $students[2]->id);
     $this->assertEquals($expected, $result);
     // With get_user_list_sql.
     list($sql, $params) = $info->get_user_list_sql(true);
     $result = $DB->get_fieldset_sql($sql, $params);
     sort($result);
     $this->assertEquals($expected, $result);
 }