Delete old birthday calendar object when moving contact to another address book

When an contact is moved to another address book, the contact is copied to
the second address book.
During copying, the birthday event is created - but it gets the same UID
as the contact's birthday event in the first address book.

To prevent the "Calendar object with uid already exists" error that followed,
we need to delete the old entry before the new one is created.

Resolves: https://github.com/nextcloud/server/issues/20492
Signed-off-by: Christian Weiske <cweiske@cweiske.de>
This commit is contained in:
Christian Weiske 2020-08-11 22:13:55 +02:00 committed by John Molakvoæ (skjnldsv)
parent f97491eb8f
commit 8ee995f214
No known key found for this signature in database
GPG Key ID: 60C25B8C072916CF
1 changed files with 17 additions and 3 deletions

View File

@ -381,12 +381,26 @@ class BirthdayService {
$objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics'; $objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics';
$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']); $calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']);
$existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri); $existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri);
if (is_null($calendarData)) { if ($calendarData === null) {
if (!is_null($existing)) { if ($existing !== null) {
$this->calDavBackEnd->deleteCalendarObject($calendarId, $objectUri); $this->calDavBackEnd->deleteCalendarObject($calendarId, $objectUri);
} }
} else { } else {
if (is_null($existing)) { if ($existing === null) {
// not found by URI, but maybe by UID
// happens when a contact with birthday is moved to a different address book
$calendarInfo = $this->calDavBackEnd->getCalendarById($calendarId);
$extraData = $this->calDavBackEnd->getDenormalizedData($calendarData->serialize());
if ($calendarInfo && array_key_exists('principaluri', $calendarInfo)) {
$existing2path = $this->calDavBackEnd->getCalendarObjectByUID($calendarInfo['principaluri'], $extraData['uid']);
if ($existing2path !== null && array_key_exists('uri', $calendarInfo)) {
// delete the old birthday entry first so that we do not get duplicate UIDs
$existing2objectUri = substr($existing2path, strlen($calendarInfo['uri']) + 1);
$this->calDavBackEnd->deleteCalendarObject($calendarId, $existing2objectUri);
}
}
$this->calDavBackEnd->createCalendarObject($calendarId, $objectUri, $calendarData->serialize()); $this->calDavBackEnd->createCalendarObject($calendarId, $objectUri, $calendarData->serialize());
} else { } else {
if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) { if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) {