Merge branch 'MDL-62960-master' of git://github.com/rezaies/moodle
authorDamyon Wiese <damyon@moodle.com>
Tue, 16 Oct 2018 03:43:24 +0000 (11:43 +0800)
committerDamyon Wiese <damyon@moodle.com>
Tue, 16 Oct 2018 03:43:24 +0000 (11:43 +0800)
calendar/classes/external/calendar_event_exporter.php
calendar/classes/local/api.php
calendar/tests/calendar_event_exporter_test.php
calendar/upgrade.txt
course/lib.php
course/tests/courselib_test.php

index bd1d751..f4b629f 100644 (file)
@@ -176,6 +176,9 @@ class calendar_event_exporter extends event_exporter_base {
 
         if ($event->get_course_module()) {
             $values = array_merge($values, $this->get_module_timestamp_limits($event));
+        } else if ($hascourse && $course->id != SITEID && empty($event->get_group())) {
+            // This is a course event.
+            $values = array_merge($values, $this->get_course_timestamp_limits($event));
         }
 
         return $values;
@@ -210,6 +213,44 @@ class calendar_event_exporter extends event_exporter_base {
         return $this->event->get_type();
     }
 
+    /**
+     * Return the set of minimum and maximum date timestamp values
+     * for the given event.
+     *
+     * @param event_interface $event
+     * @return array
+     */
+    protected function get_course_timestamp_limits($event) {
+        $values = [];
+        $mapper = container::get_event_mapper();
+        $starttime = $event->get_times()->get_start_time();
+
+        list($min, $max) = component_callback(
+            'core_course',
+            'core_calendar_get_valid_event_timestart_range',
+            [$mapper->from_event_to_legacy_event($event), $event->get_course()->get_proxied_instance()],
+            [false, false]
+        );
+
+        // The callback will return false for either of the
+        // min or max cutoffs to indicate that there are no
+        // valid timestart values. In which case the event is
+        // not draggable.
+        if ($min === false || $max === false) {
+            return ['draggable' => false];
+        }
+
+        if ($min) {
+            $values = array_merge($values, $this->get_timestamp_min_limit($starttime, $min));
+        }
+
+        if ($max) {
+            $values = array_merge($values, $this->get_timestamp_max_limit($starttime, $max));
+        }
+
+        return $values;
+    }
+
     /**
      * Return the set of minimum and maximum date timestamp values
      * for the given event.
@@ -240,11 +281,11 @@ class calendar_event_exporter extends event_exporter_base {
         }
 
         if ($min) {
-            $values = array_merge($values, $this->get_module_timestamp_min_limit($starttime, $min));
+            $values = array_merge($values, $this->get_timestamp_min_limit($starttime, $min));
         }
 
         if ($max) {
-            $values = array_merge($values, $this->get_module_timestamp_max_limit($starttime, $max));
+            $values = array_merge($values, $this->get_timestamp_max_limit($starttime, $max));
         }
 
         return $values;
@@ -252,12 +293,13 @@ class calendar_event_exporter extends event_exporter_base {
 
     /**
      * Get the correct minimum midnight day limit based on the event start time
-     * and the module's minimum timestamp limit.
+     * and the minimum timestamp limit of what the event belongs to.
      *
      * @param DateTimeInterface $starttime The event start time
      * @param array $min The module's minimum limit for the event
+     * @return array Returns an array with mindaytimestamp and mindayerror keys.
      */
-    protected function get_module_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
+    protected function get_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
         // We need to check that the minimum valid time is earlier in the
         // day than the current event time so that if the user drags and drops
         // the event to this day (which changes the date but not the time) it
@@ -295,15 +337,16 @@ class calendar_event_exporter extends event_exporter_base {
 
     /**
      * Get the correct maximum midnight day limit based on the event start time
-     * and the module's maximum timestamp limit.
+     * and the maximum timestamp limit of what the event belongs to.
      *
      * @param DateTimeInterface $starttime The event start time
      * @param array $max The module's maximum limit for the event
+     * @return array Returns an array with maxdaytimestamp and maxdayerror keys.
      */
-    protected function get_module_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
+    protected function get_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
         // We're doing a similar calculation here as we are for the minimum
         // day timestamp. See the explanation above.
-        $values;
+        $values = [];
         $timestamp = $max[0];
         $errorstring = $max[1];
         $maxdate = (new \DateTimeImmutable())->setTimestamp($timestamp);
@@ -326,4 +369,36 @@ class calendar_event_exporter extends event_exporter_base {
         $values['maxdayerror'] = $errorstring;
         return $values;
     }
+
+    /**
+     * Get the correct minimum midnight day limit based on the event start time
+     * and the module's minimum timestamp limit.
+     *
+     * @deprecated since Moodle 3.6. Please use get_timestamp_min_limit().
+     * @todo final deprecation. To be removed in Moodle 4.0
+     * @param DateTimeInterface $starttime The event start time
+     * @param array $min The module's minimum limit for the event
+     * @return array Returns an array with mindaytimestamp and mindayerror keys.
+     */
+    protected function get_module_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
+        debugging('get_module_timestamp_min_limit() has been deprecated. Please call get_timestamp_min_limit() instead.',
+                DEBUG_DEVELOPER);
+        return $this->get_timestamp_min_limit($starttime, $min);
+    }
+
+    /**
+     * Get the correct maximum midnight day limit based on the event start time
+     * and the module's maximum timestamp limit.
+     *
+     * @deprecated since Moodle 3.6. Please use get_timestamp_max_limit().
+     * @todo final deprecation. To be removed in Moodle 4.0
+     * @param DateTimeInterface $starttime The event start time
+     * @param array $max The module's maximum limit for the event
+     * @return array Returns an array with maxdaytimestamp and maxdayerror keys.
+     */
+    protected function get_module_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
+        debugging('get_module_timestamp_max_limit() has been deprecated. Please call get_timestamp_max_limit() instead.',
+                DEBUG_DEVELOPER);
+        return $this->get_timestamp_max_limit($starttime, $max);
+    }
 }
index 6da620e..ac0f613 100644 (file)
@@ -242,6 +242,7 @@ class api {
             $startdate->format('n'),
             $startdate->format('j')
         );
+        $starttimestamp = $starttime->getTimestamp();
 
         if ($hascoursemodule) {
             $moduleinstance = $DB->get_record(
@@ -250,7 +251,6 @@ class api {
                 '*',
                 MUST_EXIST
             );
-            $legacyevent->timestart = $starttime->getTimestamp();
 
             // If there is a timestart range callback implemented then we can
             // use the values returned from the valid timestart range to apply
@@ -262,20 +262,30 @@ class api {
                 [$legacyevent, $moduleinstance],
                 [false, false]
             );
+        } else if ($legacyevent->courseid != 0 && $legacyevent->courseid != SITEID && $legacyevent->groupid == 0) {
+            // This is a course event.
+            list($min, $max) = component_callback(
+                'core_course',
+                'core_calendar_get_valid_event_timestart_range',
+                [$legacyevent, $event->get_course()->get_proxied_instance()],
+                [0, 0]
+            );
+        } else {
+            $min = $max = 0;
+        }
 
-            // If the callback returns false for either value it means that
-            // there is no valid time start range.
-            if ($min === false || $max === false) {
-                throw new \moodle_exception('The start day of this event can not be modified');
-            }
+        // If the callback returns false for either value it means that
+        // there is no valid time start range.
+        if ($min === false || $max === false) {
+            throw new \moodle_exception('The start day of this event can not be modified');
+        }
 
-            if ($min && $legacyevent->timestart < $min[0]) {
-                throw new \moodle_exception($min[1]);
-            }
+        if ($min && $starttimestamp < $min[0]) {
+            throw new \moodle_exception($min[1]);
+        }
 
-            if ($max && $legacyevent->timestart > $max[0]) {
-                throw new \moodle_exception($max[1]);
-            }
+        if ($max && $starttimestamp > $max[0]) {
+            throw new \moodle_exception($max[1]);
         }
 
         // This function does our capability checks.
index f5a7b9b..86c815d 100644 (file)
@@ -38,10 +38,10 @@ require_once(__DIR__ . '/helpers.php');
  */
 class core_calendar_event_exporter_testcase extends advanced_testcase {
     /**
-     * Data provider for the module timestamp min limit test case to confirm
+     * Data provider for the timestamp min limit test case to confirm
      * that the minimum time limit is set correctly on the boundary cases.
      */
-    public function get_module_timestamp_min_limit_test_cases() {
+    public function get_timestamp_min_limit_test_cases() {
         $now = time();
         $todaymidnight = usergetmidnight($now);
         $tomorrowmidnight = $todaymidnight + DAYSECS;
@@ -77,16 +77,16 @@ class core_calendar_event_exporter_testcase extends advanced_testcase {
     }
 
     /**
-     * @dataProvider get_module_timestamp_min_limit_test_cases()
+     * @dataProvider get_timestamp_min_limit_test_cases()
      */
-    public function test_get_module_timestamp_min_limit($starttime, $min, $expected) {
+    public function test_get_timestamp_min_limit($starttime, $min, $expected) {
         $class = \core_calendar\external\calendar_event_exporter::class;
         $mock = $this->getMockBuilder($class)
             ->disableOriginalConstructor()
             ->setMethods(null)
             ->getMock();
         $reflector = new ReflectionClass($class);
-        $method = $reflector->getMethod('get_module_timestamp_min_limit');
+        $method = $reflector->getMethod('get_timestamp_min_limit');
         $method->setAccessible(true);
 
         $result = $method->invoke($mock, $starttime, $min);
@@ -95,10 +95,10 @@ class core_calendar_event_exporter_testcase extends advanced_testcase {
     }
 
     /**
-     * Data provider for the module timestamp min limit test case to confirm
-     * that the minimum time limit is set correctly on the boundary cases.
+     * Data provider for the timestamp max limit test case to confirm
+     * that the maximum time limit is set correctly on the boundary cases.
      */
-    public function get_module_timestamp_max_limit_test_cases() {
+    public function get_timestamp_max_limit_test_cases() {
         $now = time();
         $todaymidnight = usergetmidnight($now);
         $yesterdaymidnight = $todaymidnight - DAYSECS;
@@ -134,16 +134,16 @@ class core_calendar_event_exporter_testcase extends advanced_testcase {
     }
 
     /**
-     * @dataProvider get_module_timestamp_max_limit_test_cases()
+     * @dataProvider get_timestamp_max_limit_test_cases()
      */
-    public function test_get_module_timestamp_max_limit($starttime, $max, $expected) {
+    public function test_get_timestamp_max_limit($starttime, $max, $expected) {
         $class = \core_calendar\external\calendar_event_exporter::class;
         $mock = $this->getMockBuilder($class)
             ->disableOriginalConstructor()
             ->setMethods(null)
             ->getMock();
         $reflector = new ReflectionClass($class);
-        $method = $reflector->getMethod('get_module_timestamp_max_limit');
+        $method = $reflector->getMethod('get_timestamp_max_limit');
         $method->setAccessible(true);
 
         $result = $method->invoke($mock, $starttime, $max);
index 342ad35..48b9ac2 100644 (file)
@@ -8,6 +8,8 @@ information provided here is intended especially for developers.
   set_requesting_user() and get_requesting_user().
 * The following functions have been finally deprecated and can not be used anymore:
   * calendar_preferences_button()
+* added core_calendar_get_valid_event_timestart_range callback for course events when the update_event_start_day function is used
+  in the local api.
 
 === 3.5 ===
 * core_calendar_external::get_calendar_events now returns the categoryid for category events.
index a1d9680..cba9402 100644 (file)
@@ -3711,6 +3711,41 @@ function core_course_inplace_editable($itemtype, $itemid, $newvalue) {
     }
 }
 
+/**
+ * This function calculates the minimum and maximum cutoff values for the timestart of
+ * the given event.
+ *
+ * It will return an array with two values, the first being the minimum cutoff value and
+ * the second being the maximum cutoff value. Either or both values can be null, which
+ * indicates there is no minimum or maximum, respectively.
+ *
+ * If a cutoff is required then the function must return an array containing the cutoff
+ * timestamp and error string to display to the user if the cutoff value is violated.
+ *
+ * A minimum and maximum cutoff return value will look like:
+ * [
+ *     [1505704373, 'The date must be after this date'],
+ *     [1506741172, 'The date must be before this date']
+ * ]
+ *
+ * @param calendar_event $event The calendar event to get the time range for
+ * @param stdClass $course The course object to get the range from
+ * @return array Returns an array with min and max date.
+ */
+function core_course_core_calendar_get_valid_event_timestart_range(\calendar_event $event, $course) {
+    $mindate = null;
+    $maxdate = null;
+
+    if ($course->startdate) {
+        $mindate = [
+            $course->startdate,
+            get_string('errorbeforecoursestart', 'calendar')
+        ];
+    }
+
+    return [$mindate, $maxdate];
+}
+
 /**
  * Returns course modules tagged with a specified tag ready for output on tag/index.php page
  *
index 297e54b..1bdf3b5 100644 (file)
@@ -4717,4 +4717,55 @@ class core_course_courselib_testcase extends advanced_testcase {
         $this->assertEquals($expectedcourses, $actual);
         $this->assertEquals($expectedprocessedcount, $processedcount);
     }
+
+
+    /**
+     * Testing core_course_core_calendar_get_valid_event_timestart_range when the course has no end date.
+     */
+    public function test_core_course_core_calendar_get_valid_event_timestart_range_no_enddate() {
+        global $CFG;
+        require_once($CFG->dirroot . "/calendar/lib.php");
+
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+        $generator = $this->getDataGenerator();
+        $now = time();
+        $course = $generator->create_course(['startdate' => $now - 86400]);
+
+        // Create a course event.
+        $event = new \calendar_event([
+            'name' => 'Test course event',
+            'eventtype' => 'course',
+            'courseid' => $course->id,
+        ]);
+
+        list ($min, $max) = core_course_core_calendar_get_valid_event_timestart_range($event, $course);
+        $this->assertEquals($course->startdate, $min[0]);
+        $this->assertNull($max);
+    }
+
+    /**
+     * Testing core_course_core_calendar_get_valid_event_timestart_range when the course has end date.
+     */
+    public function test_core_course_core_calendar_get_valid_event_timestart_range_with_enddate() {
+        global $CFG;
+        require_once($CFG->dirroot . "/calendar/lib.php");
+
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+        $generator = $this->getDataGenerator();
+        $now = time();
+        $course = $generator->create_course(['startdate' => $now - 86400, 'enddate' => $now + 86400]);
+
+        // Create a course event.
+        $event = new \calendar_event([
+            'name' => 'Test course event',
+            'eventtype' => 'course',
+            'courseid' => $course->id,
+        ]);
+
+        list ($min, $max) = core_course_core_calendar_get_valid_event_timestart_range($event, $course);
+        $this->assertEquals($course->startdate, $min[0]);
+        $this->assertNull($max);
+    }
 }