MDL-56223 calendar: skip events updating if nothing has changed

This commit is contained in:
Simey Lameze 2019-08-14 09:02:08 +08:00
parent 310d6901f9
commit d5727ed3ba
3 changed files with 43 additions and 18 deletions

View File

@ -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
*/
@ -2865,11 +2870,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.
@ -3003,18 +3020,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;
@ -3022,8 +3034,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:
@ -3032,6 +3045,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 .= '<p>' . get_string('erroraddingevent', 'calendar') . ': ';
if (empty($event->properties['SUMMARY'])) {
@ -3044,18 +3060,26 @@ function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid
}
}
$return .= "<p>" . get_string('eventsimported', 'calendar', $eventcount) . "</p> ";
$return .= "<p>" . get_string('eventsupdated', 'calendar', $updatecount) . "</p>";
// 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 .= "<p> " . get_string('eventsdeleted', 'calendar') . ": {$deletecount} </p>\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 .= "<p>" . get_string('eventsimported', 'calendar', $eventcount) . "</p> ";
$return .= "<p>" . get_string('eventsskipped', 'calendar', $skippedcount) . "</p> ";
$return .= "<p>" . get_string('eventsupdated', 'calendar', $updatecount) . "</p>";
return $return;
}

View File

@ -112,6 +112,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';

View File

@ -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();
}