MDL-58768 mod_assign: Added userid param to calendar callbacks
authorShamim Rezaie <shamim@moodle.com>
Thu, 5 Apr 2018 08:17:36 +0000 (18:17 +1000)
committerShamim Rezaie <shamim@moodle.com>
Fri, 27 Jul 2018 21:51:33 +0000 (07:51 +1000)
The mod_assign_core_calendar_is_event_visible and mod_assign_core_calendar_provide_event_action
functions now accept a new parameter ($userid) so they are not always dependet to the logged in user.

mod/assign/lib.php
mod/assign/tests/lib_test.php

index 5eeccf3..002404d 100644 (file)
@@ -1826,20 +1826,25 @@ function assign_check_updates_since(cm_info $cm, $from, $filter = array()) {
  * the ASSIGN_EVENT_TYPE_GRADINGDUE event will not be shown to students on their calendar.
  *
  * @param calendar_event $event
+ * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default).
  * @return bool Returns true if the event is visible to the current user, false otherwise.
  */
-function mod_assign_core_calendar_is_event_visible(calendar_event $event) {
+function mod_assign_core_calendar_is_event_visible(calendar_event $event, $userid = 0) {
     global $CFG, $USER;
 
     require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
-    $cm = get_fast_modinfo($event->courseid)->instances['assign'][$event->instance];
+    if (empty($userid)) {
+        $userid = $USER->id;
+    }
+
+    $cm = get_fast_modinfo($event->courseid, $userid)->instances['assign'][$event->instance];
     $context = context_module::instance($cm->id);
 
     $assign = new assign($context, $cm, null);
 
     if ($event->eventtype == ASSIGN_EVENT_TYPE_GRADINGDUE) {
-        return $assign->can_grade();
+        return $assign->can_grade($userid);
     } else {
         return true;
     }
@@ -1853,22 +1858,28 @@ function mod_assign_core_calendar_is_event_visible(calendar_event $event) {
  *
  * @param calendar_event $event
  * @param \core_calendar\action_factory $factory
+ * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default).
  * @return \core_calendar\local\event\entities\action_interface|null
  */
 function mod_assign_core_calendar_provide_event_action(calendar_event $event,
-                                                       \core_calendar\action_factory $factory) {
+                                                       \core_calendar\action_factory $factory,
+                                                       $userid = 0) {
 
     global $CFG, $USER;
 
     require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
-    $cm = get_fast_modinfo($event->courseid)->instances['assign'][$event->instance];
+    if (empty($userid)) {
+        $userid = $USER->id;
+    }
+
+    $cm = get_fast_modinfo($event->courseid, $userid)->instances['assign'][$event->instance];
     $context = context_module::instance($cm->id);
 
     $assign = new assign($context, $cm, null);
 
     // Apply overrides.
-    $assign->update_effective_access($USER->id);
+    $assign->update_effective_access($userid);
 
     if ($event->eventtype == ASSIGN_EVENT_TYPE_GRADINGDUE) {
         $name = get_string('grade');
@@ -1877,16 +1888,16 @@ function mod_assign_core_calendar_provide_event_action(calendar_event $event,
             'action' => 'grader'
         ]);
         $itemcount = $assign->count_submissions_need_grading();
-        $actionable = $assign->can_grade() && (time() >= $assign->get_instance()->allowsubmissionsfromdate);
+        $actionable = $assign->can_grade($userid) && (time() >= $assign->get_instance()->allowsubmissionsfromdate);
     } else {
-        $usersubmission = $assign->get_user_submission($USER->id, false);
+        $usersubmission = $assign->get_user_submission($userid, false);
         if ($usersubmission && $usersubmission->status === ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
             // The user has already submitted.
             // We do not want to change the text to edit the submission, we want to remove the event from the Dashboard entirely.
             return null;
         }
 
-        $participant = $assign->get_participant($USER->id);
+        $participant = $assign->get_participant($userid);
 
         if (!$participant) {
             // If the user is not a participant in the assignment then they have
@@ -1901,7 +1912,7 @@ function mod_assign_core_calendar_provide_event_action(calendar_event $event,
             'action' => 'editsubmission'
         ]);
         $itemcount = 1;
-        $actionable = $assign->is_any_submission_plugin_enabled() && $assign->can_edit_submission($USER->id);
+        $actionable = $assign->is_any_submission_plugin_enabled() && $assign->can_edit_submission($userid, $userid);
     }
 
     return $factory->create_instance(
index 9c758c1..4d47f85 100644 (file)
@@ -426,6 +426,24 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertTrue(mod_assign_core_calendar_is_event_visible($event));
     }
 
+    public function test_assign_core_calendar_is_event_visible_duedate_event_for_teacher() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $assign = $this->create_instance($course);
+
+        $this->setAdminUser();
+
+        // Create a calendar event.
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_DUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // The teacher should see the due date event.
+        $this->assertTrue(mod_assign_core_calendar_is_event_visible($event, $teacher->id));
+    }
+
     public function test_assign_core_calendar_is_event_visible_duedate_event_as_student() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -443,6 +461,25 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertTrue(mod_assign_core_calendar_is_event_visible($event));
     }
 
+    public function test_assign_core_calendar_is_event_visible_duedate_event_for_student() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $assign = $this->create_instance($course, ['assignsubmission_onlinetext_enabled' => 1]);
+
+        $this->setAdminUser();
+
+        // Create a calendar event.
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_DUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // The student should care about the due date event.
+        $this->assertTrue(mod_assign_core_calendar_is_event_visible($event, $student->id));
+    }
+
     public function test_assign_core_calendar_is_event_visible_gradingduedate_event_as_teacher() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -458,6 +495,24 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertTrue(mod_assign_core_calendar_is_event_visible($event));
     }
 
+
+    public function test_assign_core_calendar_is_event_visible_gradingduedate_event_for_teacher() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $assign = $this->create_instance($course);
+
+        // Create a calendar event.
+        $this->setAdminUser();
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_GRADINGDUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // The teacher should see the due date event.
+        $this->assertTrue(mod_assign_core_calendar_is_event_visible($event, $teacher->id));
+    }
+
     public function test_assign_core_calendar_is_event_visible_gradingduedate_event_as_student() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -473,6 +528,24 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertFalse(mod_assign_core_calendar_is_event_visible($event));
     }
 
+
+    public function test_assign_core_calendar_is_event_visible_gradingduedate_event_for_student() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $assign = $this->create_instance($course);
+
+        // Create a calendar event.
+        $this->setAdminUser();
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_GRADINGDUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // The student should not see the due date event.
+        $this->assertFalse(mod_assign_core_calendar_is_event_visible($event, $student->id));
+    }
+
     public function test_assign_core_calendar_provide_event_action_duedate_as_teacher() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -492,6 +565,27 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertNull($actionevent);
     }
 
+    public function test_assign_core_calendar_provide_event_action_duedate_for_teacher() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $assign = $this->create_instance($course);
+
+        // Create a calendar event.
+        $this->setAdminUser();
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_DUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // Decorate action event for a teacher.
+        $factory = new \core_calendar\action_factory();
+        $actionevent = mod_assign_core_calendar_provide_event_action($event, $factory, $teacher->id);
+
+        // The teacher should not have an action for a due date event.
+        $this->assertNull($actionevent);
+    }
+
     public function test_assign_core_calendar_provide_event_action_duedate_as_student() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -515,6 +609,31 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertTrue($actionevent->is_actionable());
     }
 
+    public function test_assign_core_calendar_provide_event_action_duedate_for_student() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $assign = $this->create_instance($course, ['assignsubmission_onlinetext_enabled' => 1]);
+
+        // Create a calendar event.
+        $this->setAdminUser();
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_DUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // Decorate action event for a student.
+        $factory = new \core_calendar\action_factory();
+        $actionevent = mod_assign_core_calendar_provide_event_action($event, $factory, $student->id);
+
+        // Confirm the event was decorated.
+        $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
+        $this->assertEquals(get_string('addsubmission', 'assign'), $actionevent->get_name());
+        $this->assertInstanceOf('moodle_url', $actionevent->get_url());
+        $this->assertEquals(1, $actionevent->get_item_count());
+        $this->assertTrue($actionevent->is_actionable());
+    }
+
     public function test_assign_core_calendar_provide_event_action_gradingduedate_as_teacher() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -537,6 +656,31 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertTrue($actionevent->is_actionable());
     }
 
+    public function test_assign_core_calendar_provide_event_action_gradingduedate_for_teacher() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $assign = $this->create_instance($course);
+
+        // Create a calendar event.
+        $this->setAdminUser();
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_GRADINGDUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // Decorate action event for a teacher.
+        $factory = new \core_calendar\action_factory();
+        $actionevent = mod_assign_core_calendar_provide_event_action($event, $factory, $teacher->id);
+
+        // Confirm the event was decorated.
+        $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
+        $this->assertEquals(get_string('grade'), $actionevent->get_name());
+        $this->assertInstanceOf('moodle_url', $actionevent->get_url());
+        $this->assertEquals(0, $actionevent->get_item_count());
+        $this->assertTrue($actionevent->is_actionable());
+    }
+
     public function test_assign_core_calendar_provide_event_action_gradingduedate_as_student() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -559,6 +703,31 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertFalse($actionevent->is_actionable());
     }
 
+    public function test_assign_core_calendar_provide_event_action_gradingduedate_for_student() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $assign = $this->create_instance($course);
+
+        // Create a calendar event.
+        $this->setAdminUser();
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_GRADINGDUE);
+
+        // Now, log out.
+        $this->setUser();
+
+        // Decorate action event for a student.
+        $factory = new \core_calendar\action_factory();
+        $actionevent = mod_assign_core_calendar_provide_event_action($event, $factory, $student->id);
+
+        // Confirm the event was decorated.
+        $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
+        $this->assertEquals(get_string('grade'), $actionevent->get_name());
+        $this->assertInstanceOf('moodle_url', $actionevent->get_url());
+        $this->assertEquals(0, $actionevent->get_item_count());
+        $this->assertFalse($actionevent->is_actionable());
+    }
+
     public function test_assign_core_calendar_provide_event_action_duedate_as_student_submitted() {
         $this->resetAfterTest();
         $course = $this->getDataGenerator()->create_course();
@@ -584,6 +753,34 @@ class mod_assign_lib_testcase extends advanced_testcase {
         $this->assertNull($actionevent);
     }
 
+    public function test_assign_core_calendar_provide_event_action_duedate_for_student_submitted() {
+        $this->resetAfterTest();
+        $course = $this->getDataGenerator()->create_course();
+        $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+        $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+        $assign = $this->create_instance($course, ['assignsubmission_onlinetext_enabled' => 1]);
+
+        $this->setAdminUser();
+
+        // Create a calendar event.
+        $event = $this->create_action_event($course, $assign, ASSIGN_EVENT_TYPE_DUE);
+
+        // Create an action factory.
+        $factory = new \core_calendar\action_factory();
+
+        // Submit as the student.
+        $this->add_submission($student, $assign);
+        $this->submit_for_grading($student, $assign);
+
+        // Now, log out.
+        $this->setUser();
+
+        // Confirm there was no event to action.
+        $factory = new \core_calendar\action_factory();
+        $actionevent = mod_assign_core_calendar_provide_event_action($event, $factory, $student->id);
+        $this->assertNull($actionevent);
+    }
+
     /**
      * Creates an action event.
      *