From 83360c8d524f8bb2b5d2db923bb8e3f7687ea030 Mon Sep 17 00:00:00 2001 From: Syxton Date: Mon, 14 Jul 2014 11:14:27 -0400 Subject: [PATCH] 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. --- mod/assign/db/access.php | 9 +++++ mod/assign/lang/en/assign.php | 1 + mod/assign/locallib.php | 59 ++++++++++++++++++++++++++++-- mod/assign/tests/base_test.php | 4 ++ mod/assign/tests/locallib_test.php | 52 ++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 3 deletions(-) diff --git a/mod/assign/db/access.php b/mod/assign/db/access.php index f61579cba37..e58da85cf57 100644 --- a/mod/assign/db/access.php +++ b/mod/assign/db/access.php @@ -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 + ) + ), ); diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index 3c0e43b1d42..0180565c162 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -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'; diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 53413e9701a..112c3e48f63 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -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); diff --git a/mod/assign/tests/base_test.php b/mod/assign/tests/base_test.php index 6e65b499dc0..fb3d213816e 100644 --- a/mod/assign/tests/base_test.php +++ b/mod/assign/tests/base_test.php @@ -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); diff --git a/mod/assign/tests/locallib_test.php b/mod/assign/tests/locallib_test.php index f43b0f6d7e4..bd7dccd3f86 100644 --- a/mod/assign/tests/locallib_test.php +++ b/mod/assign/tests/locallib_test.php @@ -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;