MDL-58810 calendar: Fix rrule_manager issues
authorJun Pataleta <jun@moodle.com>
Thu, 4 May 2017 01:57:51 +0000 (09:57 +0800)
committerJun Pataleta <jun@moodle.com>
Mon, 8 May 2017 01:49:13 +0000 (09:49 +0800)
* Set the correct repeat ID for the recurring event
* Unset UUID for 'child' events of recurring events

calendar/classes/rrule_manager.php
lib/db/upgrade.php
version.php

index ea8e184..c746671 100644 (file)
@@ -24,6 +24,7 @@
 
 namespace core_calendar;
 
+use calendar_event;
 use DateInterval;
 use DateTime;
 use moodle_exception;
@@ -223,7 +224,7 @@ class rrule_manager {
     /**
      * Create events for specified rrule.
      *
-     * @param \calendar_event $passedevent Properties of event to create.
+     * @param calendar_event $passedevent Properties of event to create.
      * @throws moodle_exception
      */
     public function create_events($passedevent) {
@@ -243,13 +244,16 @@ class rrule_manager {
         // Generate timestamps that obey the rrule.
         $eventtimes = $this->generate_recurring_event_times($eventrec);
 
-        // Adjust the parent event's timestart, if necessary.
+        // Update the parent event. Make sure that its repeat ID is the same as its ID.
+        $calevent = new calendar_event($eventrec);
+        $updatedata = new stdClass();
+        $updatedata->repeatid = $event->id;
+        // Also, adjust the parent event's timestart, if necessary.
         if (count($eventtimes) > 0 && !in_array($eventrec->timestart, $eventtimes)) {
-            $calevent = new \calendar_event($eventrec);
-            $updatedata = (object)['timestart' => $eventtimes[0], 'repeatid' => $eventrec->id];
-            $calevent->update($updatedata, false);
-            $eventrec->timestart = $calevent->timestart;
+            $updatedata->timestart = reset($eventtimes);
         }
+        $calevent->update($updatedata, false);
+        $eventrec->timestart = $calevent->timestart;
 
         // Create the recurring calendar events.
         $this->create_recurring_events($eventrec, $eventtimes);
@@ -719,7 +723,9 @@ class rrule_manager {
             $cloneevent->repeatid = $event->id;
             $cloneevent->timestart = $time;
             unset($cloneevent->id);
-            \calendar_event::create($cloneevent, false);
+            // UUID should only be set on the first instance of the recurring events.
+            unset($cloneevent->uuid);
+            calendar_event::create($cloneevent, false);
         }
 
         // If COUNT rule is defined and the number of the generated event times is less than the the COUNT rule,
index d70037f..6d1a188 100644 (file)
@@ -2872,5 +2872,27 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2017050300.01);
     }
 
+    if ($oldversion < 2017050500.01) {
+        // Get the list of parent event IDs.
+        $sql = "SELECT DISTINCT repeatid
+                           FROM {event}
+                          WHERE repeatid <> 0";
+        $parentids = array_keys($DB->get_records_sql($sql));
+        // Check if there are repeating events we need to process.
+        if (!empty($parentids)) {
+            // The repeat IDs of parent events should match their own ID.
+            // So we need to update parent events that have non-matching IDs and repeat IDs.
+            list($insql, $params) = $DB->get_in_or_equal($parentids);
+            $updatesql = "UPDATE {event}
+                             SET repeatid = id
+                           WHERE id <> repeatid
+                                 AND id $insql";
+            $DB->execute($updatesql, $params);
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2017050500.01);
+    }
+
     return true;
 }
index 9e8fc2c..0352d30 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2017050500.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2017050500.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.