aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Citharel <tcit@tcit.fr>2022-05-12 09:23:26 +0200
committerThomas Citharel <tcit@tcit.fr>2022-06-14 14:40:24 +0200
commit39ef0500d1d9b2d16540c7548100181e535f2a31 (patch)
tree0eb154048c90c8d9294da9aff4ec9a623c041d38
parentad10cd5f65fc145889bade0a57a910502cd02750 (diff)
downloadnextcloud-server-39ef0500d1d9b2d16540c7548100181e535f2a31.tar.gz
nextcloud-server-39ef0500d1d9b2d16540c7548100181e535f2a31.zip
Handle the move operation properly between shared calendars
- Introduce a new CalendarObjectMovedEvent typed event dedicated for this operation - Handle the event in the activity backend and add new appropriate activity subjects Signed-off-by: Thomas Citharel <tcit@tcit.fr>
-rw-r--r--apps/dav/composer/composer/autoload_classmap.php1
-rw-r--r--apps/dav/composer/composer/autoload_static.php1
-rw-r--r--apps/dav/lib/AppInfo/Application.php3
-rw-r--r--apps/dav/lib/CalDAV/Activity/Backend.php102
-rw-r--r--apps/dav/lib/CalDAV/Activity/Provider/Event.php23
-rw-r--r--apps/dav/lib/CalDAV/Activity/Provider/Todo.php22
-rw-r--r--apps/dav/lib/CalDAV/CalDavBackend.php20
-rw-r--r--apps/dav/lib/CalDAV/Calendar.php2
-rw-r--r--apps/dav/lib/CalDAV/CalendarObject.php7
-rw-r--r--apps/dav/lib/Events/CalendarObjectMovedEvent.php120
-rw-r--r--apps/dav/lib/Listener/ActivityUpdaterListener.php22
11 files changed, 312 insertions, 11 deletions
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 6f02140df40..c620de3fe4a 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -209,6 +209,7 @@ return array(
'OCA\\DAV\\Events\\CalendarMovedToTrashEvent' => $baseDir . '/../lib/Events/CalendarMovedToTrashEvent.php',
'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CalendarObjectCreatedEvent.php',
'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CalendarObjectDeletedEvent.php',
+ 'OCA\\DAV\\Events\\CalendarObjectMovedEvent' => $baseDir . '/../lib/Events/CalendarObjectMovedEvent.php',
'OCA\\DAV\\Events\\CalendarObjectMovedToTrashEvent' => $baseDir . '/../lib/Events/CalendarObjectMovedToTrashEvent.php',
'OCA\\DAV\\Events\\CalendarObjectRestoredEvent' => $baseDir . '/../lib/Events/CalendarObjectRestoredEvent.php',
'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CalendarObjectUpdatedEvent.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 296b8a497c9..21f94cf71ce 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -224,6 +224,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Events\\CalendarMovedToTrashEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarMovedToTrashEvent.php',
'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectCreatedEvent.php',
'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectDeletedEvent.php',
+ 'OCA\\DAV\\Events\\CalendarObjectMovedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectMovedEvent.php',
'OCA\\DAV\\Events\\CalendarObjectMovedToTrashEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectMovedToTrashEvent.php',
'OCA\\DAV\\Events\\CalendarObjectRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectRestoredEvent.php',
'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectUpdatedEvent.php',
diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php
index e4eeed61dbe..10f0c52c79c 100644
--- a/apps/dav/lib/AppInfo/Application.php
+++ b/apps/dav/lib/AppInfo/Application.php
@@ -57,6 +57,7 @@ use OCA\DAV\Events\CalendarDeletedEvent;
use OCA\DAV\Events\CalendarMovedToTrashEvent;
use OCA\DAV\Events\CalendarObjectCreatedEvent;
use OCA\DAV\Events\CalendarObjectDeletedEvent;
+use OCA\DAV\Events\CalendarObjectMovedEvent;
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
use OCA\DAV\Events\CalendarObjectRestoredEvent;
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
@@ -154,6 +155,8 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarObjectReminderUpdaterListener::class);
$context->registerEventListener(CalendarObjectDeletedEvent::class, ActivityUpdaterListener::class);
$context->registerEventListener(CalendarObjectDeletedEvent::class, CalendarObjectReminderUpdaterListener::class);
+ $context->registerEventListener(CalendarObjectMovedEvent::class, ActivityUpdaterListener::class);
+ $context->registerEventListener(CalendarObjectMovedEvent::class, CalendarObjectReminderUpdaterListener::class);
$context->registerEventListener(CalendarObjectMovedToTrashEvent::class, ActivityUpdaterListener::class);
$context->registerEventListener(CalendarObjectMovedToTrashEvent::class, CalendarObjectReminderUpdaterListener::class);
$context->registerEventListener(CalendarObjectRestoredEvent::class, ActivityUpdaterListener::class);
diff --git a/apps/dav/lib/CalDAV/Activity/Backend.php b/apps/dav/lib/CalDAV/Activity/Backend.php
index af2d790e10d..23256054b26 100644
--- a/apps/dav/lib/CalDAV/Activity/Backend.php
+++ b/apps/dav/lib/CalDAV/Activity/Backend.php
@@ -438,6 +438,11 @@ class Backend {
$classification = $objectData['classification'] ?? CalDavBackend::CLASSIFICATION_PUBLIC;
$object = $this->getObjectNameAndType($objectData);
+
+ if (!$object) {
+ return;
+ }
+
$action = $action . '_' . $object['type'];
if ($object['type'] === 'todo' && strpos($action, Event::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'COMPLETED') {
@@ -494,8 +499,103 @@ class Backend {
}
/**
+ * Creates activities when a calendar object was moved
+ */
+ public function onMovedCalendarObject(array $sourceCalendarData, array $targetCalendarData, array $sourceShares, array $targetShares, array $objectData): void {
+ if (!isset($targetCalendarData['principaluri'])) {
+ return;
+ }
+
+ $sourcePrincipal = explode('/', $sourceCalendarData['principaluri']);
+ $sourceOwner = array_pop($sourcePrincipal);
+
+ $targetPrincipal = explode('/', $targetCalendarData['principaluri']);
+ $targetOwner = array_pop($targetPrincipal);
+
+ if ($sourceOwner !== $targetOwner) {
+ $this->onTouchCalendarObject(
+ Event::SUBJECT_OBJECT_DELETE,
+ $sourceCalendarData,
+ $sourceShares,
+ $objectData
+ );
+ $this->onTouchCalendarObject(
+ Event::SUBJECT_OBJECT_ADD,
+ $targetCalendarData,
+ $targetShares,
+ $objectData
+ );
+ return;
+ }
+
+ $currentUser = $this->userSession->getUser();
+ if ($currentUser instanceof IUser) {
+ $currentUser = $currentUser->getUID();
+ } else {
+ $currentUser = $targetOwner;
+ }
+
+ $classification = $objectData['classification'] ?? CalDavBackend::CLASSIFICATION_PUBLIC;
+ $object = $this->getObjectNameAndType($objectData);
+
+ if (!$object) {
+ return;
+ }
+
+ $event = $this->activityManager->generateEvent();
+ $event->setApp('dav')
+ ->setObject('calendar', (int) $targetCalendarData['id'])
+ ->setType($object['type'] === 'event' ? 'calendar_event' : 'calendar_todo')
+ ->setAuthor($currentUser);
+
+ $users = $this->getUsersForShares(array_intersect($sourceShares, $targetShares));
+ $users[] = $targetOwner;
+
+ // Users for share can return the owner itself if the calendar is published
+ foreach (array_unique($users) as $user) {
+ if ($classification === CalDavBackend::CLASSIFICATION_PRIVATE && $user !== $targetOwner) {
+ // Private events are only shown to the owner
+ continue;
+ }
+
+ $params = [
+ 'actor' => $event->getAuthor(),
+ 'sourceCalendar' => [
+ 'id' => (int) $sourceCalendarData['id'],
+ 'uri' => $sourceCalendarData['uri'],
+ 'name' => $sourceCalendarData['{DAV:}displayname'],
+ ],
+ 'targetCalendar' => [
+ 'id' => (int) $targetCalendarData['id'],
+ 'uri' => $targetCalendarData['uri'],
+ 'name' => $targetCalendarData['{DAV:}displayname'],
+ ],
+ 'object' => [
+ 'id' => $object['id'],
+ 'name' => $classification === CalDavBackend::CLASSIFICATION_CONFIDENTIAL && $user !== $targetOwner ? 'Busy' : $object['name'],
+ 'classified' => $classification === CalDavBackend::CLASSIFICATION_CONFIDENTIAL && $user !== $targetOwner,
+ ],
+ ];
+
+ if ($object['type'] === 'event' && $this->appManager->isEnabledForUser('calendar')) {
+ $params['object']['link']['object_uri'] = $objectData['uri'];
+ $params['object']['link']['calendar_uri'] = $targetCalendarData['uri'];
+ $params['object']['link']['owner'] = $targetOwner;
+ }
+
+ $event->setAffectedUser($user)
+ ->setSubject(
+ $user === $currentUser ? Event::SUBJECT_OBJECT_MOVE . '_' . $object['type'] . '_self' : Event::SUBJECT_OBJECT_MOVE . '_' . $object['type'],
+ $params
+ );
+
+ $this->activityManager->publish($event);
+ }
+ }
+
+ /**
* @param array $objectData
- * @return string[]|bool
+ * @return string[]|false
*/
protected function getObjectNameAndType(array $objectData) {
$vObject = Reader::read($objectData['calendardata']);
diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Event.php b/apps/dav/lib/CalDAV/Activity/Provider/Event.php
index 3ed591219af..9ae04aadbba 100644
--- a/apps/dav/lib/CalDAV/Activity/Provider/Event.php
+++ b/apps/dav/lib/CalDAV/Activity/Provider/Event.php
@@ -40,6 +40,7 @@ use OCP\L10N\IFactory;
class Event extends Base {
public const SUBJECT_OBJECT_ADD = 'object_add';
public const SUBJECT_OBJECT_UPDATE = 'object_update';
+ public const SUBJECT_OBJECT_MOVE = 'object_move';
public const SUBJECT_OBJECT_MOVE_TO_TRASH = 'object_move_to_trash';
public const SUBJECT_OBJECT_RESTORE = 'object_restore';
public const SUBJECT_OBJECT_DELETE = 'object_delete';
@@ -145,6 +146,10 @@ class Event extends Base {
$subject = $this->l->t('{actor} updated event {event} in calendar {calendar}');
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_event_self') {
$subject = $this->l->t('You updated event {event} in calendar {calendar}');
+ } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_event') {
+ $subject = $this->l->t('{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}');
+ } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_event_self') {
+ $subject = $this->l->t('You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}');
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE_TO_TRASH . '_event') {
$subject = $this->l->t('{actor} deleted event {event} from calendar {calendar}');
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE_TO_TRASH . '_event_self') {
@@ -198,6 +203,24 @@ class Event extends Base {
}
}
+ if (isset($parameters['sourceCalendar']) && isset($parameters['targetCalendar'])) {
+ switch ($subject) {
+ case self::SUBJECT_OBJECT_MOVE . '_event':
+ return [
+ 'actor' => $this->generateUserParameter($parameters['actor']),
+ 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
+ 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
+ 'event' => $this->generateClassifiedObjectParameter($parameters['object']),
+ ];
+ case self::SUBJECT_OBJECT_MOVE . '_event_self':
+ return [
+ 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
+ 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
+ 'event' => $this->generateClassifiedObjectParameter($parameters['object']),
+ ];
+ }
+ }
+
// Legacy - Do NOT Remove unless necessary
// Removing this will break parsing of activities that were created on
// Nextcloud 12, so we should keep this as long as it's acceptable.
diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php
index a3ab81e38ae..4b2796aca53 100644
--- a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php
+++ b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php
@@ -69,6 +69,10 @@ class Todo extends Event {
$subject = $this->l->t('{actor} reopened todo {todo} in list {calendar}');
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self') {
$subject = $this->l->t('You reopened todo {todo} in list {calendar}');
+ } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_todo') {
+ $subject = $this->l->t('{actor} moved todo {todo} from list {sourceCalendar} to list {targetCalendar}');
+ } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_todo_self') {
+ $subject = $this->l->t('You moved todo {todo} from list {sourceCalendar} to list {targetCalendar}');
} else {
throw new \InvalidArgumentException();
}
@@ -114,6 +118,24 @@ class Todo extends Event {
}
}
+ if (isset($parameters['sourceCalendar']) && isset($parameters['targetCalendar'])) {
+ switch ($subject) {
+ case self::SUBJECT_OBJECT_MOVE . '_todo':
+ return [
+ 'actor' => $this->generateUserParameter($parameters['actor']),
+ 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
+ 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
+ 'todo' => $this->generateObjectParameter($parameters['object']),
+ ];
+ case self::SUBJECT_OBJECT_MOVE . '_todo_self':
+ return [
+ 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
+ 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
+ 'todo' => $this->generateObjectParameter($parameters['object']),
+ ];
+ }
+ }
+
// Legacy - Do NOT Remove unless necessary
// Removing this will break parsing of activities that were created on
// Nextcloud 12, so we should keep this as long as it's acceptable.
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php
index f445382ce8c..3ab047d5183 100644
--- a/apps/dav/lib/CalDAV/CalDavBackend.php
+++ b/apps/dav/lib/CalDAV/CalDavBackend.php
@@ -52,6 +52,7 @@ use OCA\DAV\Events\CalendarDeletedEvent;
use OCA\DAV\Events\CalendarMovedToTrashEvent;
use OCA\DAV\Events\CalendarObjectCreatedEvent;
use OCA\DAV\Events\CalendarObjectDeletedEvent;
+use OCA\DAV\Events\CalendarObjectMovedEvent;
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
use OCA\DAV\Events\CalendarObjectRestoredEvent;
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
@@ -1341,13 +1342,14 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* @param int $sourceCalendarId
* @param int $targetCalendarId
* @param int $objectId
- * @param string $principalUri
+ * @param string $oldPrincipalUri
+ * @param string $newPrincipalUri
* @param int $calendarType
* @return bool
* @throws Exception
*/
- public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $principalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool {
- $object = $this->getCalendarObjectById($principalUri, $objectId);
+ public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $oldPrincipalUri, string $newPrincipalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool {
+ $object = $this->getCalendarObjectById($oldPrincipalUri, $objectId);
if (empty($object)) {
return false;
}
@@ -1365,21 +1367,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$this->addChange($sourceCalendarId, $object['uri'], 1, $calendarType);
$this->addChange($targetCalendarId, $object['uri'], 3, $calendarType);
- $object = $this->getCalendarObjectById($principalUri, $objectId);
+ $object = $this->getCalendarObjectById($newPrincipalUri, $objectId);
// Calendar Object wasn't found - possibly because it was deleted in the meantime by a different client
if (empty($object)) {
return false;
}
- $calendarRow = $this->getCalendarById($targetCalendarId);
+ $targetCalendarRow = $this->getCalendarById($targetCalendarId);
// the calendar this event is being moved to does not exist any longer
- if (empty($calendarRow)) {
+ if (empty($targetCalendarRow)) {
return false;
}
if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
- $shares = $this->getShares($targetCalendarId);
- $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent($targetCalendarId, $calendarRow, $shares, $object));
+ $sourceShares = $this->getShares($sourceCalendarId);
+ $targetShares = $this->getShares($targetCalendarId);
+ $sourceCalendarRow = $this->getCalendarById($sourceCalendarId);
+ $this->dispatcher->dispatchTyped(new CalendarObjectMovedEvent($sourceCalendarId, $sourceCalendarRow, $targetCalendarId, $targetCalendarRow, $sourceShares, $targetShares, $object));
}
return true;
}
diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php
index 79d2244b42c..806e99d8a05 100644
--- a/apps/dav/lib/CalDAV/Calendar.php
+++ b/apps/dav/lib/CalDAV/Calendar.php
@@ -450,7 +450,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
}
try {
- return $this->caldavBackend->moveCalendarObject($sourceNode->getCalendarId(), (int)$this->calendarInfo['id'], $sourceNode->getId(), $sourceNode->getPrincipalUri());
+ return $this->caldavBackend->moveCalendarObject($sourceNode->getCalendarId(), (int)$this->calendarInfo['id'], $sourceNode->getId(), $sourceNode->getOwner(), $this->getOwner());
} catch (Exception $e) {
$this->logger->error('Could not move calendar object: ' . $e->getMessage(), ['exception' => $e]);
return false;
diff --git a/apps/dav/lib/CalDAV/CalendarObject.php b/apps/dav/lib/CalDAV/CalendarObject.php
index c927254fba3..32bcff900c2 100644
--- a/apps/dav/lib/CalDAV/CalendarObject.php
+++ b/apps/dav/lib/CalDAV/CalendarObject.php
@@ -162,4 +162,11 @@ class CalendarObject extends \Sabre\CalDAV\CalendarObject {
public function getPrincipalUri(): string {
return $this->calendarInfo['principaluri'];
}
+
+ public function getOwner(): ?string {
+ if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
+ return $this->calendarInfo['{http://owncloud.org/ns}owner-principal'];
+ }
+ return parent::getOwner();
+ }
}
diff --git a/apps/dav/lib/Events/CalendarObjectMovedEvent.php b/apps/dav/lib/Events/CalendarObjectMovedEvent.php
new file mode 100644
index 00000000000..0143dad9a96
--- /dev/null
+++ b/apps/dav/lib/Events/CalendarObjectMovedEvent.php
@@ -0,0 +1,120 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2020, Georg Ehrke
+ *
+ * @author Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCA\DAV\Events;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * Class CalendarObjectMovedEvent
+ *
+ * @package OCA\DAV\Events
+ * @since 25.0.0
+ */
+class CalendarObjectMovedEvent extends Event {
+ private int $sourceCalendarId;
+ private array $sourceCalendarData;
+ private int $targetCalendarId;
+ private array $targetCalendarData;
+ private array $sourceShares;
+ private array $targetShares;
+ private array $objectData;
+
+ /**
+ * @since 25.0.0
+ */
+ public function __construct(int $sourceCalendarId,
+ array $sourceCalendarData,
+ int $targetCalendarId,
+ array $targetCalendarData,
+ array $sourceShares,
+ array $targetShares,
+ array $objectData) {
+ parent::__construct();
+ $this->sourceCalendarId = $sourceCalendarId;
+ $this->sourceCalendarData = $sourceCalendarData;
+ $this->targetCalendarId = $targetCalendarId;
+ $this->targetCalendarData = $targetCalendarData;
+ $this->sourceShares = $sourceShares;
+ $this->targetShares = $targetShares;
+ $this->objectData = $objectData;
+ }
+
+ /**
+ * @return int
+ * @since 25.0.0
+ */
+ public function getSourceCalendarId(): int {
+ return $this->sourceCalendarId;
+ }
+
+ /**
+ * @return array
+ * @since 25.0.0
+ */
+ public function getSourceCalendarData(): array {
+ return $this->sourceCalendarData;
+ }
+
+ /**
+ * @return int
+ * @since 25.0.0
+ */
+ public function getTargetCalendarId(): int {
+ return $this->targetCalendarId;
+ }
+
+ /**
+ * @return array
+ * @since 25.0.0
+ */
+ public function getTargetCalendarData(): array {
+ return $this->targetCalendarData;
+ }
+
+ /**
+ * @return array
+ * @since 25.0.0
+ */
+ public function getSourceShares(): array {
+ return $this->sourceShares;
+ }
+
+ /**
+ * @return array
+ * @since 25.0.0
+ */
+ public function getTargetShares(): array {
+ return $this->targetShares;
+ }
+
+ /**
+ * @return array
+ * @since 25.0.0
+ */
+ public function getObjectData(): array {
+ return $this->objectData;
+ }
+}
diff --git a/apps/dav/lib/Listener/ActivityUpdaterListener.php b/apps/dav/lib/Listener/ActivityUpdaterListener.php
index 371912ff035..ea3ec49c14d 100644
--- a/apps/dav/lib/Listener/ActivityUpdaterListener.php
+++ b/apps/dav/lib/Listener/ActivityUpdaterListener.php
@@ -32,6 +32,7 @@ use OCA\DAV\Events\CalendarDeletedEvent;
use OCA\DAV\Events\CalendarMovedToTrashEvent;
use OCA\DAV\Events\CalendarObjectCreatedEvent;
use OCA\DAV\Events\CalendarObjectDeletedEvent;
+use OCA\DAV\Events\CalendarObjectMovedEvent;
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
use OCA\DAV\Events\CalendarObjectRestoredEvent;
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
@@ -173,7 +174,26 @@ class ActivityUpdaterListener implements IEventListener {
);
$this->logger->debug(
- sprintf('Activity generated for deleted calendar object %d', $event->getCalendarId())
+ sprintf('Activity generated for updated calendar object in calendar %d', $event->getCalendarId())
+ );
+ } catch (Throwable $e) {
+ // Any error with activities shouldn't abort the calendar deletion, so we just log it
+ $this->logger->error('Error generating activity for a deleted calendar object: ' . $e->getMessage(), [
+ 'exception' => $e,
+ ]);
+ }
+ } elseif ($event instanceof CalendarObjectMovedEvent) {
+ try {
+ $this->activityBackend->onMovedCalendarObject(
+ $event->getSourceCalendarData(),
+ $event->getTargetCalendarData(),
+ $event->getSourceShares(),
+ $event->getTargetShares(),
+ $event->getObjectData()
+ );
+
+ $this->logger->debug(
+ sprintf('Activity generated for moved calendar object from calendar %d to calendar %d', $event->getSourceCalendarId(), $event->getTargetCalendarId())
);
} catch (Throwable $e) {
// Any error with activities shouldn't abort the calendar deletion, so we just log it