Merge branch 'MDL-57411-master' of git://github.com/jleyva/moodle

This commit is contained in:
Dan Poltawski 2017-04-03 17:59:34 +01:00
commit a29cd3138c
11 changed files with 393 additions and 9 deletions

View File

@ -426,10 +426,7 @@ function groups_has_membership($cm, $userid=null) {
function groups_get_members($groupid, $fields='u.*', $sort='lastname ASC') {
global $DB;
return $DB->get_records_sql("SELECT $fields
FROM {user} u, {groups_members} gm
WHERE u.id = gm.userid AND gm.groupid = ?
ORDER BY $sort", array($groupid));
return groups_get_groups_members([$groupid], $fields, $sort);
}
@ -1133,3 +1130,47 @@ function groups_user_groups_visible($course, $userid, $cm = null) {
}
return false;
}
/**
* Returns the users in the specified groups.
*
* @param array $groupsids The list of groups ids to check
* @param int $fields The fields to return
* @param int $sort optional sorting of returned users
* @return array|bool Returns an array of the users for the specified group or false if no users or an error returned.
* @since Moodle 3.3
*/
function groups_get_groups_members($groupsids, $fields='u.*', $sort='lastname ASC') {
global $DB;
list($insql, $params) = $DB->get_in_or_equal($groupsids);
return $DB->get_records_sql("SELECT $fields
FROM {user} u, {groups_members} gm
WHERE u.id = gm.userid AND gm.groupid $insql
GROUP BY u.id
ORDER BY $sort", $params);
}
/**
* Returns users who share group membership with the specified user in the given actiivty.
*
* @param stdClass|cm_info $cm course module
* @param int $userid user id (empty for current user)
* @return array a list of user
* @since Moodle 3.3
*/
function groups_get_activity_shared_group_members($cm, $userid = null) {
global $USER;
if (empty($userid)) {
$userid = $USER;
}
$groupsids = array_keys(groups_get_activity_allowed_groups($cm, $userid));
// No groups no users.
if (empty($groupsids)) {
return [];
}
return groups_get_groups_members($groupsids);
}

View File

@ -1388,4 +1388,138 @@ class core_grouplib_testcase extends advanced_testcase {
$result = groups_user_groups_visible($course, $user1->id, $cm);
$this->assertTrue($result); // Cm with visible groups.
}
/**
* Tests for groups_get_groups_members() method.
*/
public function test_groups_get_groups_members() {
$this->resetAfterTest(true);
$generator = $this->getDataGenerator();
// Create courses.
$course1 = $generator->create_course();
$course2 = $generator->create_course();
// Create users.
$user1 = $generator->create_user();
$user2 = $generator->create_user();
$user3 = $generator->create_user();
// Enrol users.
$generator->enrol_user($user1->id, $course1->id);
$generator->enrol_user($user1->id, $course2->id);
$generator->enrol_user($user2->id, $course2->id);
$generator->enrol_user($user3->id, $course2->id);
// Create groups.
$group1 = $generator->create_group(array('courseid' => $course1->id));
$group2 = $generator->create_group(array('courseid' => $course2->id));
$group3 = $generator->create_group(array('courseid' => $course2->id));
// Assign users to groups.
$this->assertTrue($generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)));
$this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id)));
$this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)));
// Test get_groups_members.
$members = groups_get_groups_members([$group1->id, $group2->id], 'u.*', 'id ASC');
$this->assertCount(2, $members);
$this->assertEquals([$user1->id, $user2->id], array_keys($members));
// Group with just one.
$members = groups_get_groups_members([$group1->id]);
$this->assertCount(1, $members);
$this->assertEquals($user1->id, $members[$user1->id]->id);
// Group with just one plus empty group.
$members = groups_get_groups_members([$group1->id, $group3->id]);
$this->assertCount(1, $members);
$this->assertEquals($user1->id, $members[$user1->id]->id);
// Empty group.
$members = groups_get_groups_members([$group3->id]);
$this->assertCount(0, $members);
// Test groups_get_members.
$members = groups_get_members($group2->id, 'u.*', 'id ASC');
$this->assertCount(2, $members);
$this->assertEquals([$user1->id, $user2->id], array_keys($members));
}
/**
* Tests for groups_get_activity_shared_group_members() method.
*/
public function test_groups_get_activity_shared_group_members() {
$this->resetAfterTest(true);
$generator = $this->getDataGenerator();
// Create courses.
$course = $generator->create_course();
// Create cm.
$assign = $generator->create_module("assign", array('course' => $course->id));
$cm = get_coursemodule_from_instance("assign", $assign->id);
// Create users.
$user1 = $generator->create_user();
$user2 = $generator->create_user();
$user3 = $generator->create_user();
$user4 = $generator->create_user();
// Enrol users.
$generator->enrol_user($user1->id, $course->id);
$generator->enrol_user($user2->id, $course->id);
$generator->enrol_user($user3->id, $course->id);
$generator->enrol_user($user4->id, $course->id);
// Create groups.
$group1 = $generator->create_group(array('courseid' => $course->id));
$group2 = $generator->create_group(array('courseid' => $course->id));
$group3 = $generator->create_group(array('courseid' => $course->id));
// Assign users to groups.
$generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
$generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
$generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
$generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user3->id));
// Retrieve users sharing groups with user1.
$members = groups_get_activity_shared_group_members($cm, $user1->id);
$this->assertCount(2, $members);
$this->assertEquals([$user1->id, $user2->id], array_keys($members), '', 0.0, 10, true);
// Retrieve users sharing groups with user2.
$members = groups_get_activity_shared_group_members($cm, $user2->id);
$this->assertCount(2, $members);
$this->assertEquals([$user1->id, $user2->id], array_keys($members), '', 0.0, 10, true);
// Retrieve users sharing groups with user3.
$members = groups_get_activity_shared_group_members($cm, $user3->id);
$this->assertCount(1, $members);
$this->assertEquals($user3->id, $members[$user3->id]->id);
// Retrieve users sharing groups with user without groups (user4).
$members = groups_get_activity_shared_group_members($cm, $user4->id);
$this->assertCount(0, $members);
// Now, create a different activity using groupings.
$grouping = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 1'));
// Skip group 2.
groups_assign_grouping($grouping->id, $group1->id);
groups_assign_grouping($grouping->id, $group3->id);
$assign = $generator->create_module("assign", array('course' => $course->id, 'groupingid' => $grouping->id));
$cm = get_coursemodule_from_instance("assign", $assign->id);
// Since the activity is forced to groupings (groups 1 and 3), I don't see members of group 2.
$members = groups_get_activity_shared_group_members($cm, $user1->id);
$this->assertCount(1, $members);
$this->assertEquals($user1->id, $members[$user1->id]->id);
// Add user1 to group 3 (in the grouping).
$generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user1->id));
$members = groups_get_activity_shared_group_members($cm, $user1->id);
$this->assertCount(2, $members); // Now I see members of group 3.
$this->assertEquals([$user1->id, $user3->id], array_keys($members), '', 0.0, 10, true);
}
}

View File

@ -1692,5 +1692,35 @@ function assign_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->grades->itemids = array_keys($grades);
}
// Now, teachers should see other students updates.
if (has_capability('mod/assign:viewgrades', $cm->context)) {
$params = array('id' => $cm->instance, 'since1' => $from, 'since2' => $from);
$select = 'assignment = :id AND (timecreated > :since1 OR timemodified > :since2)';
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers, SQL_PARAMS_NAMED);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->usersubmissions = (object) array('updated' => false);
$submissions = $DB->get_records_select('assign_submission', $select, $params, '', 'id');
if (!empty($submissions)) {
$updates->usersubmissions->updated = true;
$updates->usersubmissions->itemids = array_keys($submissions);
}
$updates->usergrades = (object) array('updated' => false);
$grades = $DB->get_records_select('assign_grades', $select, $params, '', 'id');
if (!empty($grades)) {
$updates->usergrades->updated = true;
$updates->usergrades->itemids = array_keys($grades);
}
}
return $updates;
}

View File

@ -5562,10 +5562,8 @@ class assign {
public function get_shared_group_members($cm, $userid) {
if (!isset($this->sharedgroupmembers[$userid])) {
$this->sharedgroupmembers[$userid] = array();
$groupsids = array_keys(groups_get_activity_allowed_groups($cm, $userid));
foreach ($groupsids as $groupid) {
$members = array_keys(groups_get_members($groupid, 'u.id'));
$this->sharedgroupmembers[$userid] = array_merge($this->sharedgroupmembers[$userid], $members);
if ($members = groups_get_activity_shared_group_members($cm, $userid)) {
$this->sharedgroupmembers[$userid] = array_keys($members);
}
}

View File

@ -4202,6 +4202,10 @@ function data_check_updates_since(cm_info $cm, $from, $filter = array()) {
$searcharray[DATA_TIMEMODIFIED]->data = $from;
$currentgroup = groups_get_activity_group($cm);
// Teachers should retrieve all entries when not in separate groups.
if (has_capability('mod/data:manageentries', $cm->context) && groups_get_activity_groupmode($cm) != SEPARATEGROUPS) {
$currentgroup = 0;
}
list($entries, $maxcount, $totalcount, $page, $nowperpage, $sort, $mode) =
data_search_entries($data, $cm, $cm->context, 'list', $currentgroup, '', null, null, 0, 0, true, $searcharray);

View File

@ -3357,5 +3357,35 @@ function feedback_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->attemptsunfinished->itemids = array_keys($attemptsunfinished);
}
// Now, teachers should see other students updates.
if (has_capability('mod/feedback:viewreports', $cm->context)) {
$select = 'feedback = ? AND timemodified > ?';
$params = array($cm->instance, $from);
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->userattemptsfinished = (object) array('updated' => false);
$attemptsfinished = $DB->get_records_select('feedback_completed', $select, $params, '', 'id');
if (!empty($attemptsfinished)) {
$updates->userattemptsfinished->updated = true;
$updates->userattemptsfinished->itemids = array_keys($attemptsfinished);
}
$updates->userattemptsunfinished = (object) array('updated' => false);
$attemptsunfinished = $DB->get_records_select('feedback_completedtmp', $select, $params, '', 'id');
if (!empty($attemptsunfinished)) {
$updates->userattemptsunfinished->updated = true;
$updates->userattemptsunfinished->itemids = array_keys($attemptsunfinished);
}
}
return $updates;
}

View File

@ -1508,7 +1508,7 @@ function lesson_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->pages = (object) array('updated' => false);
$updates->answers = (object) array('updated' => false);
$select = 'lessonid = ? AND (timecreated > ? OR timemodified > ?)';
$params = array($cm->instance, $USER->id, $from);
$params = array($cm->instance, $from, $from);
$pages = $DB->get_records_select('lesson_pages', $select, $params, '', 'id');
if (!empty($pages)) {
@ -1556,5 +1556,54 @@ function lesson_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->timers->itemids = array_keys($timers);
}
// Now, teachers should see other students updates.
if (has_capability('mod/lesson:viewreports', $cm->context)) {
$select = 'lessonid = ? AND timeseen > ?';
$params = array($cm->instance, $from);
$insql = '';
$inparams = [];
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->userquestionattempts = (object) array('updated' => false);
$updates->usergrades = (object) array('updated' => false);
$updates->userpagesviewed = (object) array('updated' => false);
$updates->usertimers = (object) array('updated' => false);
$questionattempts = $DB->get_records_select('lesson_attempts', $select, $params, '', 'id');
if (!empty($questionattempts)) {
$updates->userquestionattempts->updated = true;
$updates->userquestionattempts->itemids = array_keys($questionattempts);
}
$pagesviewed = $DB->get_records_select('lesson_branch', $select, $params, '', 'id');
if (!empty($pagesviewed)) {
$updates->userpagesviewed->updated = true;
$updates->userpagesviewed->itemids = array_keys($pagesviewed);
}
$select = 'lessonid = ? AND completed > ? ' . $insql;
$grades = $DB->get_records_select('lesson_grades', $select, $params, '', 'id');
if (!empty($grades)) {
$updates->usergrades->updated = true;
$updates->usergrades->itemids = array_keys($grades);
}
$select = 'lessonid = ? AND (starttime > ? OR lessontime > ? OR timemodifiedoffline > ?) ' . $insql;
$params = array($cm->instance, $from, $from, $from);
$params = array_merge($params, $inparams);
$timers = $DB->get_records_select('lesson_timer', $select, $params, '', 'id');
if (!empty($timers)) {
$updates->usertimers->updated = true;
$updates->usertimers->itemids = array_keys($timers);
}
}
return $updates;
}

View File

@ -604,6 +604,29 @@ function lti_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->submissions->itemids = array_keys($submissions);
}
// Now, teachers should see other students updates.
if (has_capability('mod/lti:manage', $cm->context)) {
$select = 'ltiid = :id AND (datesubmitted > :since1 OR dateupdated > :since2)';
$params = array('id' => $cm->instance, 'since1' => $from, 'since2' => $from);
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers, SQL_PARAMS_NAMED);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->usersubmissions = (object) array('updated' => false);
$submissions = $DB->get_records_select('lti_submission', $select, $params, '', 'id');
if (!empty($submissions)) {
$updates->usersubmissions->updated = true;
$updates->usersubmissions->itemids = array_keys($submissions);
}
}
return $updates;
}

View File

@ -2048,6 +2048,35 @@ function quiz_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->grades->itemids = array_keys($grades);
}
// Now, teachers should see other students updates.
if (has_capability('mod/quiz:viewreports', $cm->context)) {
$select = 'quiz = ? AND timemodified > ?';
$params = array($cm->instance, $from);
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->userattempts = (object) array('updated' => false);
$attempts = $DB->get_records_select('quiz_attempts', $select, $params, '', 'id');
if (!empty($attempts)) {
$updates->userattempts->updated = true;
$updates->userattempts->itemids = array_keys($attempts);
}
$updates->usergrades = (object) array('updated' => false);
$grades = $DB->get_records_select('quiz_grades', $select, $params, '', 'id');
if (!empty($grades)) {
$updates->usergrades->updated = true;
$updates->usergrades->itemids = array_keys($grades);
}
}
return $updates;
}

View File

@ -1525,6 +1525,29 @@ function scorm_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->tracks->updated = true;
$updates->tracks->itemids = array_keys($tracks);
}
// Now, teachers should see other students updates.
if (has_capability('mod/scorm:viewreport', $cm->context)) {
$select = 'scormid = ? AND timemodified > ?';
$params = array($scorm->id, $from);
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->usertracks = (object) array('updated' => false);
$tracks = $DB->get_records_select('scorm_scoes_track', $select, $params, '', 'id');
if (!empty($tracks)) {
$updates->usertracks->updated = true;
$updates->usertracks->itemids = array_keys($tracks);
}
}
return $updates;
}

View File

@ -1072,5 +1072,28 @@ function survey_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates->answers->updated = true;
$updates->answers->itemids = array_keys($answers);
}
// Now, teachers should see other students updates.
if (has_capability('mod/survey:readresponses', $cm->context)) {
$select = 'survey = ? AND time > ?';
$params = array($cm->instance, $from);
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
$groupusers = array_keys(groups_get_activity_shared_group_members($cm));
if (empty($groupusers)) {
return $updates;
}
list($insql, $inparams) = $DB->get_in_or_equal($groupusers);
$select .= ' AND userid ' . $insql;
$params = array_merge($params, $inparams);
}
$updates->useranswers = (object) array('updated' => false);
$answers = $DB->get_records_select('survey_answers', $select, $params, '', 'id');
if (!empty($answers)) {
$updates->useranswers->updated = true;
$updates->useranswers->itemids = array_keys($answers);
}
}
return $updates;
}