MDL-45965 assign: add notification capability

MDL-45965 assign: add notification capability

Adds a new capability that adds flexibility to what users receive grader
submission messages. Includes phpunit tests. Function is based off of
get_graders() but is separate because it is bad form to have a
capability that is dependent on another capabilities setting.
This commit is contained in:
Syxton 2014-07-14 11:14:27 -04:00
parent 5fd0df97c5
commit 83360c8d52
5 changed files with 122 additions and 3 deletions

View File

@ -169,5 +169,14 @@ $capabilities = array(
)
),
'mod/assign:receivegradernotifications' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
);

View File

@ -47,6 +47,7 @@ $string['assign:grade'] = 'Grade assignment';
$string['assign:grantextension'] = 'Grant extension';
$string['assign:manageallocations'] = 'Manage markers allocated to submissions';
$string['assign:managegrades'] = 'Review and release grades';
$string['assign:receivegradernotifications'] = 'Receive grader submission notifications';
$string['assign:releasegrades'] = 'Release grades';
$string['assign:revealidentities'] = 'Reveal student identities';
$string['assign:reviewgrades'] = 'Review grades';

View File

@ -4447,6 +4447,58 @@ class assign {
return $graders;
}
/**
* Returns a list of users that should receive notification about given submission.
*
* @param int $userid The submission to grade
* @return array
*/
protected function get_notifiable_users($userid) {
// Potential users should be active users only.
$potentialusers = get_enrolled_users($this->context, "mod/assign:receivegradernotifications",
null, 'u.*', null, null, null, true);
$notifiableusers = array();
if (groups_get_activity_groupmode($this->get_course_module()) == SEPARATEGROUPS) {
if ($groups = groups_get_all_groups($this->get_course()->id, $userid, $this->get_course_module()->groupingid)) {
foreach ($groups as $group) {
foreach ($potentialusers as $potentialuser) {
if ($potentialuser->id == $userid) {
// Do not send self.
continue;
}
if (groups_is_member($group->id, $potentialuser->id)) {
$notifiableusers[$potentialuser->id] = $potentialuser;
}
}
}
} else {
// User not in group, try to find graders without group.
foreach ($potentialusers as $potentialuser) {
if ($potentialuser->id == $userid) {
// Do not send self.
continue;
}
if (!groups_has_membership($this->get_course_module(), $potentialuser->id)) {
$notifiableusers[$potentialuser->id] = $potentialuser;
}
}
}
} else {
foreach ($potentialusers as $potentialuser) {
if ($potentialuser->id == $userid) {
// Do not send self.
continue;
}
// Must be enrolled.
if (is_enrolled($this->get_course_context(), $potentialuser->id)) {
$notifiableusers[$potentialuser->id] = $potentialuser;
}
}
}
return $notifiableusers;
}
/**
* Format a notification for plain text.
*
@ -4705,10 +4757,11 @@ class assign {
} else {
$user = $USER;
}
if ($teachers = $this->get_graders($user->id)) {
foreach ($teachers as $teacher) {
if ($notifyusers = $this->get_notifiable_users($user->id)) {
foreach ($notifyusers as $notifyuser) {
$this->send_notification($user,
$teacher,
$notifyuser,
'gradersubmissionupdated',
'assign_notification',
$submission->timemodified);

View File

@ -305,6 +305,10 @@ class testable_assign extends assign {
return parent::get_graders($userid);
}
public function testable_get_notifiable_users($userid) {
return parent::get_notifiable_users($userid);
}
public function testable_view_batch_set_workflow_state($selectedusers) {
$mform = $this->testable_grading_batch_operations_form('setmarkingworkflowstate', $selectedusers);
return parent::view_batch_set_workflow_state($mform);

View File

@ -845,6 +845,58 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
$this->assertCount(10, $assign->testable_get_graders($this->students[1]->id));
}
public function test_get_notified_users() {
global $CFG, $DB;
$capability = 'mod/assign:receivegradernotifications';
$coursecontext = context_course::instance($this->course->id);
$role = $DB->get_record('role', array('shortname' => 'teacher'));
$this->create_extra_users();
$this->setUser($this->editingteachers[0]);
// Create an assignment with no groups.
$assign = $this->create_instance();
$this->assertCount(self::DEFAULT_TEACHER_COUNT +
self::DEFAULT_EDITING_TEACHER_COUNT +
self::EXTRA_TEACHER_COUNT +
self::EXTRA_EDITING_TEACHER_COUNT,
$assign->testable_get_notifiable_users($this->students[0]->id));
// Change nonediting teachers role to not receive grader notifications.
assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext);
$this->assertCount(self::DEFAULT_EDITING_TEACHER_COUNT +
self::EXTRA_EDITING_TEACHER_COUNT,
$assign->testable_get_notifiable_users($this->students[0]->id));
// Reset nonediting teachers role to default.
unassign_capability($capability, $role->id, $coursecontext);
// Force create an assignment with SEPARATEGROUPS.
$data = new stdClass();
$data->courseid = $this->course->id;
$data->name = 'Grouping';
$groupingid = groups_create_grouping($data);
groups_assign_grouping($groupingid, $this->groups[0]->id);
$assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS));
$this->setUser($this->students[1]);
$this->assertCount(4, $assign->testable_get_notifiable_users($this->students[0]->id));
// Note the second student is in a group that is not in the grouping.
// This means that we get all graders that are not in a group in the grouping.
$this->assertCount(10, $assign->testable_get_notifiable_users($this->students[1]->id));
// Change nonediting teachers role to not receive grader notifications.
assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext);
$this->assertCount(2, $assign->testable_get_notifiable_users($this->students[0]->id));
// Note the second student is in a group that is not in the grouping.
// This means that we get all graders that are not in a group in the grouping.
$this->assertCount(5, $assign->testable_get_notifiable_users($this->students[1]->id));
}
public function test_group_members_only() {
global $CFG;