From a2a489d1f8b0c40ae7d72870feceefc19c7bb234 Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Wed, 14 Aug 2019 09:02:08 +0800 Subject: [PATCH] MDL-56223 calendar: skip events updating if nothing has changed --- calendar/lib.php | 58 +++++++++++++++++++-------- lang/en/calendar.php | 1 + lib/tests/calendar_cron_task_test.php | 2 +- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/calendar/lib.php b/calendar/lib.php index 0747773010c..f716b6c069d 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -104,6 +104,11 @@ define('CALENDAR_IMPORT_FROM_FILE', 0); */ define('CALENDAR_IMPORT_FROM_URL', 1); +/** + * CALENDAR_IMPORT_EVENT_UPDATED_SKIPPED - imported event was skipped + */ +define('CALENDAR_IMPORT_EVENT_SKIPPED', -1); + /** * CALENDAR_IMPORT_EVENT_UPDATED - imported event was updated */ @@ -2862,11 +2867,23 @@ function calendar_add_icalendar_event($event, $unused = null, $subscriptionid, $ if ($updaterecord = $DB->get_record('event', array('uuid' => $eventrecord->uuid, 'subscriptionid' => $eventrecord->subscriptionid))) { - $eventrecord->id = $updaterecord->id; - $return = CALENDAR_IMPORT_EVENT_UPDATED; // Update. + + // Compare iCal event data against the moodle event to see if something has changed. + $result = array_diff((array) $eventrecord, (array) $updaterecord); + + // Unset timemodified field because it's always going to be different. + unset($result['timemodified']); + + if (count($result)) { + $eventrecord->id = $updaterecord->id; + $return = CALENDAR_IMPORT_EVENT_UPDATED; // Update. + } else { + return CALENDAR_IMPORT_EVENT_SKIPPED; + } } else { $return = CALENDAR_IMPORT_EVENT_INSERTED; // Insert. } + if ($createdevent = \calendar_event::create($eventrecord, false)) { if (!empty($event->properties['RRULE'])) { // Repeating events. @@ -3000,18 +3017,13 @@ function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid $return = ''; $eventcount = 0; $updatecount = 0; + $skippedcount = 0; // Large calendars take a while... if (!CLI_SCRIPT) { \core_php_time_limit::raise(300); } - // Mark all events in a subscription with a zero timestamp. - if (!empty($subscriptionid)) { - $sql = "UPDATE {event} SET timemodified = :time WHERE subscriptionid = :id"; - $DB->execute($sql, array('time' => 0, 'id' => $subscriptionid)); - } - // Grab the timezone from the iCalendar file to be used later. if (isset($ical->properties['X-WR-TIMEZONE'][0]->value)) { $timezone = $ical->properties['X-WR-TIMEZONE'][0]->value; @@ -3019,8 +3031,9 @@ function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid $timezone = 'UTC'; } - $return = ''; + $icaluuids = []; foreach ($ical->components['VEVENT'] as $event) { + $icaluuids[] = $event->properties['UID'][0]->value; $res = calendar_add_icalendar_event($event, null, $subscriptionid, $timezone); switch ($res) { case CALENDAR_IMPORT_EVENT_UPDATED: @@ -3029,6 +3042,9 @@ function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid case CALENDAR_IMPORT_EVENT_INSERTED: $eventcount++; break; + case CALENDAR_IMPORT_EVENT_SKIPPED: + $skippedcount++; + break; case 0: $return .= '

' . get_string('erroraddingevent', 'calendar') . ': '; if (empty($event->properties['SUMMARY'])) { @@ -3041,18 +3057,26 @@ function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid } } - $return .= "

" . get_string('eventsimported', 'calendar', $eventcount) . "

"; - $return .= "

" . get_string('eventsupdated', 'calendar', $updatecount) . "

"; - - // Delete remaining zero-marked events since they're not in remote calendar. if (!empty($subscriptionid)) { - $deletecount = $DB->count_records('event', array('timemodified' => 0, 'subscriptionid' => $subscriptionid)); - if (!empty($deletecount)) { - $DB->delete_records('event', array('timemodified' => 0, 'subscriptionid' => $subscriptionid)); - $return .= "

" . get_string('eventsdeleted', 'calendar') . ": {$deletecount}

\n"; + $eventsuuids = $DB->get_records_menu('event', ['subscriptionid' => $subscriptionid], '', 'id, uuid'); + + $icaleventscount = count($icaluuids); + $tobedeleted = []; + if (count($eventsuuids) > $icaleventscount) { + foreach ($eventsuuids as $eventid => $eventuuid) { + if (!in_array($eventuuid, $icaluuids)) { + $tobedeleted[] = $eventid; + } + } + if (!empty($tobedeleted)) { + $DB->delete_records_list('event', 'id', $tobedeleted); + } } } + $return .= "

" . get_string('eventsimported', 'calendar', $eventcount) . "

"; + $return .= "

" . get_string('eventsskipped', 'calendar', $skippedcount) . "

"; + $return .= "

" . get_string('eventsupdated', 'calendar', $updatecount) . "

"; return $return; } diff --git a/lang/en/calendar.php b/lang/en/calendar.php index 8a0f70350e5..a573276d398 100644 --- a/lang/en/calendar.php +++ b/lang/en/calendar.php @@ -110,6 +110,7 @@ $string['eventsall'] = 'All events'; $string['eventsdeleted'] = 'Events deleted'; $string['eventsimported'] = 'Events imported: {$a}'; $string['eventsource'] = 'Event source'; +$string['eventsskipped'] = 'Events skipped: {$a}'; $string['eventsupdated'] = 'Events updated: {$a}'; $string['eventsfor'] = '{$a} events'; $string['eventskey'] = 'Events key'; diff --git a/lib/tests/calendar_cron_task_test.php b/lib/tests/calendar_cron_task_test.php index f17ab150ece..6b099876807 100644 --- a/lib/tests/calendar_cron_task_test.php +++ b/lib/tests/calendar_cron_task_test.php @@ -58,7 +58,7 @@ class core_calendar_cron_task_testcase extends advanced_testcase { $subscription->lastupdated = 0; calendar_add_subscription($subscription); - $this->expectOutputRegex('/Events imported: .* Events updated:/'); + $this->expectOutputRegex('/Events imported: .* Events skipped: .* Events updated:/'); $task = new \core\task\calendar_cron_task(); $task->execute(); }