diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php index d7c2a735dae5e..1574792c6f06f 100644 --- a/apps/dav/lib/CalDAV/Schedule/Plugin.php +++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php @@ -143,7 +143,7 @@ protected function getAddressesForPrincipal($principal) { if ($result === null) { $result = []; } - + // iterate through items and html decode values foreach ($result as $key => $value) { $result[$key] = urldecode($value); @@ -202,12 +202,12 @@ public function calendarObjectChange(RequestInterface $request, ResponseInterfac } // process request $this->processICalendarChange($currentObject, $vCal, $addresses, [], $modified); - + if ($currentObject) { // Destroy circular references so PHP will GC the object. $currentObject->destroy(); } - + } catch (SameOrganizerForAllComponentsException $e) { $this->handleSameOrganizerException($e, $vCal, $calendarPath); } @@ -435,12 +435,20 @@ public function propFindDefaultCalendarUrl(PropFind $propFind, INode $node) { } else { // Otherwise if we have really nothing, create a new calendar if ($currentCalendarDeleted) { - // If the calendar exists but is deleted, we need to purge it first - // This may cause some issues in a non synchronous database setup + // If the calendar exists but is in the trash bin, we try to rename its uri + // so that we can create the new one and still restore the previous one + // otherwise we just purge the calendar by removing it before recreating it $calendar = $this->getCalendar($calendarHome, $uri); if ($calendar instanceof Calendar) { - $calendar->disableTrashbin(); - $calendar->delete(); + $backend = $calendarHome->getCalDAVBackend(); + if ($backend instanceof CalDavBackend) { + // If the CalDAV backend supports moving calendars + $this->moveCalendar($backend, $principalUrl, $uri, $uri . '-back-' . time()); + } else { + // Otherwise just purge the calendar + $calendar->disableTrashbin(); + $calendar->delete(); + } } } $this->createCalendar($calendarHome, $principalUrl, $uri, $displayName); @@ -577,7 +585,7 @@ private function isAvailableAtTime(string $email, \DateTimeInterface $start, \Da $homePath = $result[0][200]['{' . self::NS_CALDAV . '}calendar-home-set']->getHref(); /** @var \OCA\DAV\CalDAV\Calendar $node */ foreach ($this->server->tree->getNodeForPath($homePath)->getChildren() as $node) { - + if (!$node instanceof ICalendar) { continue; } @@ -709,6 +717,10 @@ private function createCalendar(CalendarHome $calendarHome, string $principalUri ]); } + private function moveCalendar(CalDavBackend $calDavBackend, string $principalUri, string $oldUri, string $newUri): void { + $calDavBackend->moveCalendar($oldUri, $principalUri, $principalUri, $newUri); + } + /** * Try to handle the given exception gracefully or throw it if necessary. * diff --git a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php index 15e598389c142..7a1d61a083b25 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php @@ -353,7 +353,7 @@ public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $ca '{DAV:}displayname' => $displayName, ]); - $calendarHomeObject->expects($this->once()) + $calendarHomeObject->expects($this->exactly($deleted ? 2 : 1)) ->method('getCalDAVBackend') ->with() ->willReturn($calendarBackend);