mirror of
https://github.com/nextcloud/server.git
synced 2026-10-11 23:51:03 +02:00
PHP 8.3 allows class constants to declare a type. Adopt it where doing so cannot break third-party apps. Typing an inheritable constant is a hard BC break: a subclass that redeclares it untyped fails to load with "Type of C::FOO must be compatible with P::FOO of type string". Changes are therefore limited to constants that cannot be redeclared by a subclass: - private const (not inherited) - final public/protected const - constants declared in a final class or an enum Interface constants, trait constants, and public/protected constants in non-final (including abstract) classes are left untyped, as is all of lib/public (OCP) and lib/unstable (NCU). One review-requested exception: the public OBJECT_PREFIX/OBJECT_SUFFIX constants of the app-internal CalDAV import helpers (TextImporter, XmlImporter) are typed as well; these classes are not public API and have no subclasses. Only string, int and array are used. float is avoided because it would silently coerce an int literal and change === comparisons. No constant name or value is modified: every changed line adds only the type token, so runtime behaviour is unchanged. Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
101 lines
2.7 KiB
PHP
101 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\DAV\CalDAV;
|
|
|
|
use OCA\DAV\CalDAV\Schedule\IMipService;
|
|
use Sabre\VObject\Component\VCalendar;
|
|
use Sabre\VObject\Component\VEvent;
|
|
|
|
class EventComparisonService {
|
|
|
|
/** @var string[] */
|
|
private const array EVENT_DIFF = [
|
|
'RECURRENCE-ID',
|
|
'RRULE',
|
|
'SEQUENCE',
|
|
'LAST-MODIFIED'
|
|
];
|
|
|
|
/**
|
|
* If found, remove the event from $eventsToFilter that
|
|
* is identical to the passed $filterEvent
|
|
* and return whether an identical event was found
|
|
*
|
|
* This function takes into account the SEQUENCE,
|
|
* RRULE, RECURRENCE-ID and LAST-MODIFIED parameters
|
|
*
|
|
* @param VEvent $filterEvent
|
|
* @param array $eventsToFilter
|
|
* @return bool true if there was an identical event found and removed, false if there wasn't
|
|
*/
|
|
private function removeIfUnchanged(VEvent $filterEvent, array &$eventsToFilter): bool {
|
|
$filterEventData = [];
|
|
foreach (self::EVENT_DIFF as $eventDiff) {
|
|
$filterEventData[] = IMipService::readPropertyWithDefault($filterEvent, $eventDiff, '');
|
|
}
|
|
|
|
/** @var VEvent $component */
|
|
foreach ($eventsToFilter as $k => $eventToFilter) {
|
|
$eventToFilterData = [];
|
|
foreach (self::EVENT_DIFF as $eventDiff) {
|
|
$eventToFilterData[] = IMipService::readPropertyWithDefault($eventToFilter, $eventDiff, '');
|
|
}
|
|
// events are identical and can be removed
|
|
if ($filterEventData === $eventToFilterData) {
|
|
unset($eventsToFilter[$k]);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Compare two VCalendars with each other and find all changed elements
|
|
*
|
|
* Returns an array of old and new events
|
|
*
|
|
* Old events are only detected if they are also changed
|
|
* If there is no corresponding old event for a VEvent, it
|
|
* has been newly created
|
|
*
|
|
* @param VCalendar $new
|
|
* @param VCalendar|null $old
|
|
* @return array<string, VEvent[]|null>
|
|
*/
|
|
public function findModified(VCalendar $new, ?VCalendar $old): array {
|
|
$newEventComponents = $new->getComponents();
|
|
|
|
foreach ($newEventComponents as $k => $event) {
|
|
if (!$event instanceof VEvent) {
|
|
unset($newEventComponents[$k]);
|
|
}
|
|
}
|
|
|
|
if (empty($old)) {
|
|
return ['old' => null, 'new' => $newEventComponents];
|
|
}
|
|
|
|
$oldEventComponents = $old->getComponents();
|
|
if (is_array($oldEventComponents) && !empty($oldEventComponents)) {
|
|
foreach ($oldEventComponents as $k => $event) {
|
|
if (!$event instanceof VEvent) {
|
|
unset($oldEventComponents[$k]);
|
|
continue;
|
|
}
|
|
if ($this->removeIfUnchanged($event, $newEventComponents)) {
|
|
unset($oldEventComponents[$k]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ['old' => array_values($oldEventComponents), 'new' => array_values($newEventComponents)];
|
|
}
|
|
}
|