Add a trashbin for calendars and calendar objects
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
parent
9e596dd0cf
commit
d6d8e9215c
|
@ -5,7 +5,7 @@
|
||||||
<name>WebDAV</name>
|
<name>WebDAV</name>
|
||||||
<summary>WebDAV endpoint</summary>
|
<summary>WebDAV endpoint</summary>
|
||||||
<description>WebDAV endpoint</description>
|
<description>WebDAV endpoint</description>
|
||||||
<version>1.17.2</version>
|
<version>1.18.0</version>
|
||||||
<licence>agpl</licence>
|
<licence>agpl</licence>
|
||||||
<author>owncloud.org</author>
|
<author>owncloud.org</author>
|
||||||
<namespace>DAV</namespace>
|
<namespace>DAV</namespace>
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
<job>OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob</job>
|
<job>OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob</job>
|
||||||
<job>OCA\DAV\BackgroundJob\CleanupInvitationTokenJob</job>
|
<job>OCA\DAV\BackgroundJob\CleanupInvitationTokenJob</job>
|
||||||
<job>OCA\DAV\BackgroundJob\EventReminderJob</job>
|
<job>OCA\DAV\BackgroundJob\EventReminderJob</job>
|
||||||
|
<job>OCA\DAV\BackgroundJob\CalendarRetentionJob</job>
|
||||||
</background-jobs>
|
</background-jobs>
|
||||||
|
|
||||||
<repair-steps>
|
<repair-steps>
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
<command>OCA\DAV\Command\CreateCalendar</command>
|
<command>OCA\DAV\Command\CreateCalendar</command>
|
||||||
<command>OCA\DAV\Command\MoveCalendar</command>
|
<command>OCA\DAV\Command\MoveCalendar</command>
|
||||||
<command>OCA\DAV\Command\ListCalendars</command>
|
<command>OCA\DAV\Command\ListCalendars</command>
|
||||||
|
<command>OCA\DAV\Command\RetentionCleanupCommand</command>
|
||||||
<command>OCA\DAV\Command\SendEventReminders</command>
|
<command>OCA\DAV\Command\SendEventReminders</command>
|
||||||
<command>OCA\DAV\Command\SyncBirthdayCalendar</command>
|
<command>OCA\DAV\Command\SyncBirthdayCalendar</command>
|
||||||
<command>OCA\DAV\Command\SyncSystemAddressBook</command>
|
<command>OCA\DAV\Command\SyncSystemAddressBook</command>
|
||||||
|
|
|
@ -61,8 +61,20 @@ $random = \OC::$server->getSecureRandom();
|
||||||
$logger = \OC::$server->getLogger();
|
$logger = \OC::$server->getLogger();
|
||||||
$dispatcher = \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class);
|
$dispatcher = \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class);
|
||||||
$legacyDispatcher = \OC::$server->getEventDispatcher();
|
$legacyDispatcher = \OC::$server->getEventDispatcher();
|
||||||
|
$config = \OC::$server->get(\OCP\IConfig::class);
|
||||||
|
|
||||||
$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, \OC::$server->getGroupManager(), $random, $logger, $dispatcher, $legacyDispatcher, true);
|
$calDavBackend = new CalDavBackend(
|
||||||
|
$db,
|
||||||
|
$principalBackend,
|
||||||
|
$userManager,
|
||||||
|
\OC::$server->getGroupManager(),
|
||||||
|
$random,
|
||||||
|
$logger,
|
||||||
|
$dispatcher,
|
||||||
|
$legacyDispatcher,
|
||||||
|
$config,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false);
|
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false);
|
||||||
$sendInvitations = \OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes';
|
$sendInvitations = \OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes';
|
||||||
|
|
|
@ -13,6 +13,7 @@ return array(
|
||||||
'OCA\\DAV\\Avatars\\AvatarNode' => $baseDir . '/../lib/Avatars/AvatarNode.php',
|
'OCA\\DAV\\Avatars\\AvatarNode' => $baseDir . '/../lib/Avatars/AvatarNode.php',
|
||||||
'OCA\\DAV\\Avatars\\RootCollection' => $baseDir . '/../lib/Avatars/RootCollection.php',
|
'OCA\\DAV\\Avatars\\RootCollection' => $baseDir . '/../lib/Avatars/RootCollection.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => $baseDir . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
|
'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => $baseDir . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
|
||||||
|
'OCA\\DAV\\BackgroundJob\\CalendarRetentionJob' => $baseDir . '/../lib/BackgroundJob/CalendarRetentionJob.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
|
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => $baseDir . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
|
'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => $baseDir . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir . '/../lib/BackgroundJob/EventReminderJob.php',
|
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir . '/../lib/BackgroundJob/EventReminderJob.php',
|
||||||
|
@ -44,6 +45,7 @@ return array(
|
||||||
'OCA\\DAV\\CalDAV\\CalendarObject' => $baseDir . '/../lib/CalDAV/CalendarObject.php',
|
'OCA\\DAV\\CalDAV\\CalendarObject' => $baseDir . '/../lib/CalDAV/CalendarObject.php',
|
||||||
'OCA\\DAV\\CalDAV\\CalendarRoot' => $baseDir . '/../lib/CalDAV/CalendarRoot.php',
|
'OCA\\DAV\\CalDAV\\CalendarRoot' => $baseDir . '/../lib/CalDAV/CalendarRoot.php',
|
||||||
'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => $baseDir . '/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
|
'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => $baseDir . '/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\IRestorable' => $baseDir . '/../lib/CalDAV/IRestorable.php',
|
||||||
'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => $baseDir . '/../lib/CalDAV/Integration/ExternalCalendar.php',
|
'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => $baseDir . '/../lib/CalDAV/Integration/ExternalCalendar.php',
|
||||||
'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => $baseDir . '/../lib/CalDAV/Integration/ICalendarProvider.php',
|
'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => $baseDir . '/../lib/CalDAV/Integration/ICalendarProvider.php',
|
||||||
'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => $baseDir . '/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
|
'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => $baseDir . '/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
|
||||||
|
@ -72,6 +74,7 @@ return array(
|
||||||
'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
|
'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
|
||||||
'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
|
'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
|
||||||
'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
|
'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\RetentionService' => $baseDir . '/../lib/CalDAV/RetentionService.php',
|
||||||
'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => $baseDir . '/../lib/CalDAV/Schedule/IMipPlugin.php',
|
'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => $baseDir . '/../lib/CalDAV/Schedule/IMipPlugin.php',
|
||||||
'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => $baseDir . '/../lib/CalDAV/Schedule/Plugin.php',
|
'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => $baseDir . '/../lib/CalDAV/Schedule/Plugin.php',
|
||||||
'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => $baseDir . '/../lib/CalDAV/Search/SearchPlugin.php',
|
'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => $baseDir . '/../lib/CalDAV/Search/SearchPlugin.php',
|
||||||
|
@ -82,6 +85,11 @@ return array(
|
||||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
|
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
|
||||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
|
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
|
||||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => $baseDir . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
|
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => $baseDir . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\DeletedCalendarObject' => $baseDir . '/../lib/CalDAV/Trashbin/DeletedCalendarObject.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\DeletedCalendarObjectsCollection' => $baseDir . '/../lib/CalDAV/Trashbin/DeletedCalendarObjectsCollection.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\Plugin' => $baseDir . '/../lib/CalDAV/Trashbin/Plugin.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\RestoreTarget' => $baseDir . '/../lib/CalDAV/Trashbin/RestoreTarget.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\TrashbinHome' => $baseDir . '/../lib/CalDAV/Trashbin/TrashbinHome.php',
|
||||||
'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => $baseDir . '/../lib/CalDAV/WebcalCaching/Plugin.php',
|
'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => $baseDir . '/../lib/CalDAV/WebcalCaching/Plugin.php',
|
||||||
'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => $baseDir . '/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
|
'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => $baseDir . '/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
|
||||||
'OCA\\DAV\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
|
'OCA\\DAV\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
|
||||||
|
@ -113,6 +121,7 @@ return array(
|
||||||
'OCA\\DAV\\Command\\ListCalendars' => $baseDir . '/../lib/Command/ListCalendars.php',
|
'OCA\\DAV\\Command\\ListCalendars' => $baseDir . '/../lib/Command/ListCalendars.php',
|
||||||
'OCA\\DAV\\Command\\MoveCalendar' => $baseDir . '/../lib/Command/MoveCalendar.php',
|
'OCA\\DAV\\Command\\MoveCalendar' => $baseDir . '/../lib/Command/MoveCalendar.php',
|
||||||
'OCA\\DAV\\Command\\RemoveInvalidShares' => $baseDir . '/../lib/Command/RemoveInvalidShares.php',
|
'OCA\\DAV\\Command\\RemoveInvalidShares' => $baseDir . '/../lib/Command/RemoveInvalidShares.php',
|
||||||
|
'OCA\\DAV\\Command\\RetentionCleanupCommand' => $baseDir . '/../lib/Command/RetentionCleanupCommand.php',
|
||||||
'OCA\\DAV\\Command\\SendEventReminders' => $baseDir . '/../lib/Command/SendEventReminders.php',
|
'OCA\\DAV\\Command\\SendEventReminders' => $baseDir . '/../lib/Command/SendEventReminders.php',
|
||||||
'OCA\\DAV\\Command\\SyncBirthdayCalendar' => $baseDir . '/../lib/Command/SyncBirthdayCalendar.php',
|
'OCA\\DAV\\Command\\SyncBirthdayCalendar' => $baseDir . '/../lib/Command/SyncBirthdayCalendar.php',
|
||||||
'OCA\\DAV\\Command\\SyncSystemAddressBook' => $baseDir . '/../lib/Command/SyncSystemAddressBook.php',
|
'OCA\\DAV\\Command\\SyncSystemAddressBook' => $baseDir . '/../lib/Command/SyncSystemAddressBook.php',
|
||||||
|
@ -188,10 +197,14 @@ return array(
|
||||||
'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
|
'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarCreatedEvent' => $baseDir . '/../lib/Events/CalendarCreatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarCreatedEvent' => $baseDir . '/../lib/Events/CalendarCreatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarDeletedEvent' => $baseDir . '/../lib/Events/CalendarDeletedEvent.php',
|
'OCA\\DAV\\Events\\CalendarDeletedEvent' => $baseDir . '/../lib/Events/CalendarDeletedEvent.php',
|
||||||
|
'OCA\\DAV\\Events\\CalendarMovedToTrashEvent' => $baseDir . '/../lib/Events/CalendarMovedToTrashEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CalendarObjectCreatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CalendarObjectCreatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CalendarObjectDeletedEvent.php',
|
'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CalendarObjectDeletedEvent.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',
|
'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CalendarObjectUpdatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarPublishedEvent' => $baseDir . '/../lib/Events/CalendarPublishedEvent.php',
|
'OCA\\DAV\\Events\\CalendarPublishedEvent' => $baseDir . '/../lib/Events/CalendarPublishedEvent.php',
|
||||||
|
'OCA\\DAV\\Events\\CalendarRestoredEvent' => $baseDir . '/../lib/Events/CalendarRestoredEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => $baseDir . '/../lib/Events/CalendarShareUpdatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => $baseDir . '/../lib/Events/CalendarShareUpdatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => $baseDir . '/../lib/Events/CalendarUnpublishedEvent.php',
|
'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => $baseDir . '/../lib/Events/CalendarUnpublishedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarUpdatedEvent' => $baseDir . '/../lib/Events/CalendarUpdatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarUpdatedEvent' => $baseDir . '/../lib/Events/CalendarUpdatedEvent.php',
|
||||||
|
@ -248,6 +261,7 @@ return array(
|
||||||
'OCA\\DAV\\Migration\\Version1012Date20190808122342' => $baseDir . '/../lib/Migration/Version1012Date20190808122342.php',
|
'OCA\\DAV\\Migration\\Version1012Date20190808122342' => $baseDir . '/../lib/Migration/Version1012Date20190808122342.php',
|
||||||
'OCA\\DAV\\Migration\\Version1016Date20201109085907' => $baseDir . '/../lib/Migration/Version1016Date20201109085907.php',
|
'OCA\\DAV\\Migration\\Version1016Date20201109085907' => $baseDir . '/../lib/Migration/Version1016Date20201109085907.php',
|
||||||
'OCA\\DAV\\Migration\\Version1017Date20210216083742' => $baseDir . '/../lib/Migration/Version1017Date20210216083742.php',
|
'OCA\\DAV\\Migration\\Version1017Date20210216083742' => $baseDir . '/../lib/Migration/Version1017Date20210216083742.php',
|
||||||
|
'OCA\\DAV\\Migration\\Version1018Date20210312100735' => $baseDir . '/../lib/Migration/Version1018Date20210312100735.php',
|
||||||
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
|
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
|
||||||
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
|
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
|
||||||
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
|
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
|
||||||
|
|
|
@ -28,6 +28,7 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\Avatars\\AvatarNode' => __DIR__ . '/..' . '/../lib/Avatars/AvatarNode.php',
|
'OCA\\DAV\\Avatars\\AvatarNode' => __DIR__ . '/..' . '/../lib/Avatars/AvatarNode.php',
|
||||||
'OCA\\DAV\\Avatars\\RootCollection' => __DIR__ . '/..' . '/../lib/Avatars/RootCollection.php',
|
'OCA\\DAV\\Avatars\\RootCollection' => __DIR__ . '/..' . '/../lib/Avatars/RootCollection.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
|
'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
|
||||||
|
'OCA\\DAV\\BackgroundJob\\CalendarRetentionJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CalendarRetentionJob.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
|
'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
|
'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
|
||||||
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/EventReminderJob.php',
|
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/EventReminderJob.php',
|
||||||
|
@ -59,6 +60,7 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\CalDAV\\CalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarObject.php',
|
'OCA\\DAV\\CalDAV\\CalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarObject.php',
|
||||||
'OCA\\DAV\\CalDAV\\CalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarRoot.php',
|
'OCA\\DAV\\CalDAV\\CalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarRoot.php',
|
||||||
'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
|
'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\IRestorable' => __DIR__ . '/..' . '/../lib/CalDAV/IRestorable.php',
|
||||||
'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => __DIR__ . '/..' . '/../lib/CalDAV/Integration/ExternalCalendar.php',
|
'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => __DIR__ . '/..' . '/../lib/CalDAV/Integration/ExternalCalendar.php',
|
||||||
'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Integration/ICalendarProvider.php',
|
'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Integration/ICalendarProvider.php',
|
||||||
'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => __DIR__ . '/..' . '/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
|
'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => __DIR__ . '/..' . '/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
|
||||||
|
@ -87,6 +89,7 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
|
'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
|
||||||
'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
|
'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
|
||||||
'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
|
'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\RetentionService' => __DIR__ . '/..' . '/../lib/CalDAV/RetentionService.php',
|
||||||
'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/IMipPlugin.php',
|
'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/IMipPlugin.php',
|
||||||
'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/Plugin.php',
|
'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/Plugin.php',
|
||||||
'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Search/SearchPlugin.php',
|
'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Search/SearchPlugin.php',
|
||||||
|
@ -97,6 +100,11 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
|
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
|
||||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
|
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
|
||||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
|
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\DeletedCalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/Trashbin/DeletedCalendarObject.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\DeletedCalendarObjectsCollection' => __DIR__ . '/..' . '/../lib/CalDAV/Trashbin/DeletedCalendarObjectsCollection.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Trashbin/Plugin.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\RestoreTarget' => __DIR__ . '/..' . '/../lib/CalDAV/Trashbin/RestoreTarget.php',
|
||||||
|
'OCA\\DAV\\CalDAV\\Trashbin\\TrashbinHome' => __DIR__ . '/..' . '/../lib/CalDAV/Trashbin/TrashbinHome.php',
|
||||||
'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/Plugin.php',
|
'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/Plugin.php',
|
||||||
'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
|
'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
|
||||||
'OCA\\DAV\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
|
'OCA\\DAV\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
|
||||||
|
@ -128,6 +136,7 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\Command\\ListCalendars' => __DIR__ . '/..' . '/../lib/Command/ListCalendars.php',
|
'OCA\\DAV\\Command\\ListCalendars' => __DIR__ . '/..' . '/../lib/Command/ListCalendars.php',
|
||||||
'OCA\\DAV\\Command\\MoveCalendar' => __DIR__ . '/..' . '/../lib/Command/MoveCalendar.php',
|
'OCA\\DAV\\Command\\MoveCalendar' => __DIR__ . '/..' . '/../lib/Command/MoveCalendar.php',
|
||||||
'OCA\\DAV\\Command\\RemoveInvalidShares' => __DIR__ . '/..' . '/../lib/Command/RemoveInvalidShares.php',
|
'OCA\\DAV\\Command\\RemoveInvalidShares' => __DIR__ . '/..' . '/../lib/Command/RemoveInvalidShares.php',
|
||||||
|
'OCA\\DAV\\Command\\RetentionCleanupCommand' => __DIR__ . '/..' . '/../lib/Command/RetentionCleanupCommand.php',
|
||||||
'OCA\\DAV\\Command\\SendEventReminders' => __DIR__ . '/..' . '/../lib/Command/SendEventReminders.php',
|
'OCA\\DAV\\Command\\SendEventReminders' => __DIR__ . '/..' . '/../lib/Command/SendEventReminders.php',
|
||||||
'OCA\\DAV\\Command\\SyncBirthdayCalendar' => __DIR__ . '/..' . '/../lib/Command/SyncBirthdayCalendar.php',
|
'OCA\\DAV\\Command\\SyncBirthdayCalendar' => __DIR__ . '/..' . '/../lib/Command/SyncBirthdayCalendar.php',
|
||||||
'OCA\\DAV\\Command\\SyncSystemAddressBook' => __DIR__ . '/..' . '/../lib/Command/SyncSystemAddressBook.php',
|
'OCA\\DAV\\Command\\SyncSystemAddressBook' => __DIR__ . '/..' . '/../lib/Command/SyncSystemAddressBook.php',
|
||||||
|
@ -203,10 +212,14 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
|
'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarCreatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarCreatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarDeletedEvent.php',
|
'OCA\\DAV\\Events\\CalendarDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarDeletedEvent.php',
|
||||||
|
'OCA\\DAV\\Events\\CalendarMovedToTrashEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarMovedToTrashEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectCreatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectCreatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectDeletedEvent.php',
|
'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectDeletedEvent.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',
|
'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectUpdatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarPublishedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarPublishedEvent.php',
|
'OCA\\DAV\\Events\\CalendarPublishedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarPublishedEvent.php',
|
||||||
|
'OCA\\DAV\\Events\\CalendarRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarRestoredEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarShareUpdatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarShareUpdatedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarUnpublishedEvent.php',
|
'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarUnpublishedEvent.php',
|
||||||
'OCA\\DAV\\Events\\CalendarUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarUpdatedEvent.php',
|
'OCA\\DAV\\Events\\CalendarUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarUpdatedEvent.php',
|
||||||
|
@ -263,6 +276,7 @@ class ComposerStaticInitDAV
|
||||||
'OCA\\DAV\\Migration\\Version1012Date20190808122342' => __DIR__ . '/..' . '/../lib/Migration/Version1012Date20190808122342.php',
|
'OCA\\DAV\\Migration\\Version1012Date20190808122342' => __DIR__ . '/..' . '/../lib/Migration/Version1012Date20190808122342.php',
|
||||||
'OCA\\DAV\\Migration\\Version1016Date20201109085907' => __DIR__ . '/..' . '/../lib/Migration/Version1016Date20201109085907.php',
|
'OCA\\DAV\\Migration\\Version1016Date20201109085907' => __DIR__ . '/..' . '/../lib/Migration/Version1016Date20201109085907.php',
|
||||||
'OCA\\DAV\\Migration\\Version1017Date20210216083742' => __DIR__ . '/..' . '/../lib/Migration/Version1017Date20210216083742.php',
|
'OCA\\DAV\\Migration\\Version1017Date20210216083742' => __DIR__ . '/..' . '/../lib/Migration/Version1017Date20210216083742.php',
|
||||||
|
'OCA\\DAV\\Migration\\Version1018Date20210312100735' => __DIR__ . '/..' . '/../lib/Migration/Version1018Date20210312100735.php',
|
||||||
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
|
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
|
||||||
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
|
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
|
||||||
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
|
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
|
||||||
|
|
|
@ -57,9 +57,13 @@ use OCA\DAV\Events\AddressBookShareUpdatedEvent;
|
||||||
use OCA\DAV\Events\AddressBookUpdatedEvent;
|
use OCA\DAV\Events\AddressBookUpdatedEvent;
|
||||||
use OCA\DAV\Events\CalendarCreatedEvent;
|
use OCA\DAV\Events\CalendarCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarDeletedEvent;
|
use OCA\DAV\Events\CalendarDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarMovedToTrashEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarShareUpdatedEvent;
|
use OCA\DAV\Events\CalendarShareUpdatedEvent;
|
||||||
use OCA\DAV\Events\CalendarUpdatedEvent;
|
use OCA\DAV\Events\CalendarUpdatedEvent;
|
||||||
use OCA\DAV\Events\CardCreatedEvent;
|
use OCA\DAV\Events\CardCreatedEvent;
|
||||||
|
@ -129,7 +133,11 @@ class Application extends App implements IBootstrap {
|
||||||
$context->registerEventListener(CalendarDeletedEvent::class, ActivityUpdaterListener::class);
|
$context->registerEventListener(CalendarDeletedEvent::class, ActivityUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarDeletedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
$context->registerEventListener(CalendarDeletedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarDeletedEvent::class, CalendarDeletionDefaultUpdaterListener::class);
|
$context->registerEventListener(CalendarDeletedEvent::class, CalendarDeletionDefaultUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarMovedToTrashEvent::class, ActivityUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarMovedToTrashEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarUpdatedEvent::class, ActivityUpdaterListener::class);
|
$context->registerEventListener(CalendarUpdatedEvent::class, ActivityUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarRestoredEvent::class, ActivityUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarRestoredEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarObjectCreatedEvent::class, ActivityUpdaterListener::class);
|
$context->registerEventListener(CalendarObjectCreatedEvent::class, ActivityUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarContactInteractionListener::class);
|
$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarContactInteractionListener::class);
|
||||||
$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
|
@ -138,6 +146,10 @@ class Application extends App implements IBootstrap {
|
||||||
$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarObjectDeletedEvent::class, ActivityUpdaterListener::class);
|
$context->registerEventListener(CalendarObjectDeletedEvent::class, ActivityUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarObjectDeletedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
$context->registerEventListener(CalendarObjectDeletedEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarObjectMovedToTrashEvent::class, ActivityUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarObjectMovedToTrashEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarObjectRestoredEvent::class, ActivityUpdaterListener::class);
|
||||||
|
$context->registerEventListener(CalendarObjectRestoredEvent::class, CalendarObjectReminderUpdaterListener::class);
|
||||||
$context->registerEventListener(CalendarShareUpdatedEvent::class, CalendarContactInteractionListener::class);
|
$context->registerEventListener(CalendarShareUpdatedEvent::class, CalendarContactInteractionListener::class);
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,6 +232,7 @@ class Application extends App implements IBootstrap {
|
||||||
$syncService->updateUser($user);
|
$syncService->updateUser($user);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateShares', function (GenericEvent $event) use ($container) {
|
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateShares', function (GenericEvent $event) use ($container) {
|
||||||
/** @var Backend $backend */
|
/** @var Backend $backend */
|
||||||
$backend = $container->query(Backend::class);
|
$backend = $container->query(Backend::class);
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\BackgroundJob;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\RetentionService;
|
||||||
|
use OCP\AppFramework\Utility\ITimeFactory;
|
||||||
|
use OCP\BackgroundJob\TimedJob;
|
||||||
|
|
||||||
|
class CalendarRetentionJob extends TimedJob {
|
||||||
|
/** @var RetentionService */
|
||||||
|
private $service;
|
||||||
|
|
||||||
|
public function __construct(ITimeFactory $time,
|
||||||
|
RetentionService $service) {
|
||||||
|
parent::__construct($time);
|
||||||
|
$this->service = $service;
|
||||||
|
|
||||||
|
// Run four times a day
|
||||||
|
$this->setInterval(6 * 60 * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function run($argument): void {
|
||||||
|
$this->service->cleanUp();
|
||||||
|
}
|
||||||
|
}
|
|
@ -415,7 +415,10 @@ class UpdateCalendarResourcesRoomsBackgroundJob extends TimedJob {
|
||||||
CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI);
|
CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI);
|
||||||
|
|
||||||
if ($calendar !== null) {
|
if ($calendar !== null) {
|
||||||
$this->calDavBackend->deleteCalendar($calendar['id']);
|
$this->calDavBackend->deleteCalendar(
|
||||||
|
$calendar['id'],
|
||||||
|
true // Because this wasn't deleted by a user
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,13 +84,33 @@ class Backend {
|
||||||
$this->triggerCalendarActivity(Calendar::SUBJECT_UPDATE, $calendarData, $shares, $properties);
|
$this->triggerCalendarActivity(Calendar::SUBJECT_UPDATE, $calendarData, $shares, $properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates activities when a calendar was moved to trash
|
||||||
|
*
|
||||||
|
* @param array $calendarData
|
||||||
|
* @param array $shares
|
||||||
|
*/
|
||||||
|
public function onCalendarMovedToTrash(array $calendarData, array $shares): void {
|
||||||
|
$this->triggerCalendarActivity(Calendar::SUBJECT_MOVE_TO_TRASH, $calendarData, $shares);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates activities when a calendar was restored
|
||||||
|
*
|
||||||
|
* @param array $calendarData
|
||||||
|
* @param array $shares
|
||||||
|
*/
|
||||||
|
public function onCalendarRestored(array $calendarData, array $shares): void {
|
||||||
|
$this->triggerCalendarActivity(Calendar::SUBJECT_RESTORE, $calendarData, $shares);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates activities when a calendar was deleted
|
* Creates activities when a calendar was deleted
|
||||||
*
|
*
|
||||||
* @param array $calendarData
|
* @param array $calendarData
|
||||||
* @param array $shares
|
* @param array $shares
|
||||||
*/
|
*/
|
||||||
public function onCalendarDelete(array $calendarData, array $shares) {
|
public function onCalendarDelete(array $calendarData, array $shares): void {
|
||||||
$this->triggerCalendarActivity(Calendar::SUBJECT_DELETE, $calendarData, $shares);
|
$this->triggerCalendarActivity(Calendar::SUBJECT_DELETE, $calendarData, $shares);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ use OCP\L10N\IFactory;
|
||||||
class Calendar extends Base {
|
class Calendar extends Base {
|
||||||
public const SUBJECT_ADD = 'calendar_add';
|
public const SUBJECT_ADD = 'calendar_add';
|
||||||
public const SUBJECT_UPDATE = 'calendar_update';
|
public const SUBJECT_UPDATE = 'calendar_update';
|
||||||
|
public const SUBJECT_MOVE_TO_TRASH = 'calendar_move_to_trash';
|
||||||
|
public const SUBJECT_RESTORE = 'calendar_restore';
|
||||||
public const SUBJECT_DELETE = 'calendar_delete';
|
public const SUBJECT_DELETE = 'calendar_delete';
|
||||||
public const SUBJECT_PUBLISH = 'calendar_publish';
|
public const SUBJECT_PUBLISH = 'calendar_publish';
|
||||||
public const SUBJECT_UNPUBLISH = 'calendar_unpublish';
|
public const SUBJECT_UNPUBLISH = 'calendar_unpublish';
|
||||||
|
@ -107,6 +109,14 @@ class Calendar extends Base {
|
||||||
$subject = $this->l->t('{actor} updated calendar {calendar}');
|
$subject = $this->l->t('{actor} updated calendar {calendar}');
|
||||||
} elseif ($event->getSubject() === self::SUBJECT_UPDATE . '_self') {
|
} elseif ($event->getSubject() === self::SUBJECT_UPDATE . '_self') {
|
||||||
$subject = $this->l->t('You updated calendar {calendar}');
|
$subject = $this->l->t('You updated calendar {calendar}');
|
||||||
|
} elseif ($event->getSubject() === self::SUBJECT_MOVE_TO_TRASH) {
|
||||||
|
$subject = $this->l->t('{actor} deleted calendar {calendar}');
|
||||||
|
} elseif ($event->getSubject() === self::SUBJECT_MOVE_TO_TRASH . '_self') {
|
||||||
|
$subject = $this->l->t('You deleted calendar {calendar}');
|
||||||
|
} elseif ($event->getSubject() === self::SUBJECT_RESTORE) {
|
||||||
|
$subject = $this->l->t('{actor} restored calendar {calendar}');
|
||||||
|
} elseif ($event->getSubject() === self::SUBJECT_RESTORE . '_self') {
|
||||||
|
$subject = $this->l->t('You restored calendar {calendar}');
|
||||||
} elseif ($event->getSubject() === self::SUBJECT_PUBLISH . '_self') {
|
} elseif ($event->getSubject() === self::SUBJECT_PUBLISH . '_self') {
|
||||||
$subject = $this->l->t('You shared calendar {calendar} as public link');
|
$subject = $this->l->t('You shared calendar {calendar} as public link');
|
||||||
} elseif ($event->getSubject() === self::SUBJECT_UNPUBLISH . '_self') {
|
} elseif ($event->getSubject() === self::SUBJECT_UNPUBLISH . '_self') {
|
||||||
|
@ -172,6 +182,10 @@ class Calendar extends Base {
|
||||||
case self::SUBJECT_DELETE . '_self':
|
case self::SUBJECT_DELETE . '_self':
|
||||||
case self::SUBJECT_UPDATE:
|
case self::SUBJECT_UPDATE:
|
||||||
case self::SUBJECT_UPDATE . '_self':
|
case self::SUBJECT_UPDATE . '_self':
|
||||||
|
case self::SUBJECT_MOVE_TO_TRASH:
|
||||||
|
case self::SUBJECT_MOVE_TO_TRASH . '_self':
|
||||||
|
case self::SUBJECT_RESTORE:
|
||||||
|
case self::SUBJECT_RESTORE . '_self':
|
||||||
case self::SUBJECT_PUBLISH . '_self':
|
case self::SUBJECT_PUBLISH . '_self':
|
||||||
case self::SUBJECT_UNPUBLISH . '_self':
|
case self::SUBJECT_UNPUBLISH . '_self':
|
||||||
case self::SUBJECT_SHARE_USER:
|
case self::SUBJECT_SHARE_USER:
|
||||||
|
|
|
@ -40,6 +40,8 @@ use OCP\L10N\IFactory;
|
||||||
class Event extends Base {
|
class Event extends Base {
|
||||||
public const SUBJECT_OBJECT_ADD = 'object_add';
|
public const SUBJECT_OBJECT_ADD = 'object_add';
|
||||||
public const SUBJECT_OBJECT_UPDATE = 'object_update';
|
public const SUBJECT_OBJECT_UPDATE = 'object_update';
|
||||||
|
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';
|
public const SUBJECT_OBJECT_DELETE = 'object_delete';
|
||||||
|
|
||||||
/** @var IFactory */
|
/** @var IFactory */
|
||||||
|
@ -143,6 +145,14 @@ class Event extends Base {
|
||||||
$subject = $this->l->t('{actor} updated event {event} in calendar {calendar}');
|
$subject = $this->l->t('{actor} updated event {event} in calendar {calendar}');
|
||||||
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_event_self') {
|
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_event_self') {
|
||||||
$subject = $this->l->t('You updated event {event} in calendar {calendar}');
|
$subject = $this->l->t('You updated event {event} in calendar {calendar}');
|
||||||
|
} 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') {
|
||||||
|
$subject = $this->l->t('You deleted event {event} from calendar {calendar}');
|
||||||
|
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_RESTORE . '_event') {
|
||||||
|
$subject = $this->l->t('{actor} restored event {event} of calendar {calendar}');
|
||||||
|
} elseif ($event->getSubject() === self::SUBJECT_OBJECT_RESTORE . '_event_self') {
|
||||||
|
$subject = $this->l->t('You restored event {event} of calendar {calendar}');
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException();
|
throw new \InvalidArgumentException();
|
||||||
}
|
}
|
||||||
|
@ -169,6 +179,8 @@ class Event extends Base {
|
||||||
case self::SUBJECT_OBJECT_ADD . '_event':
|
case self::SUBJECT_OBJECT_ADD . '_event':
|
||||||
case self::SUBJECT_OBJECT_DELETE . '_event':
|
case self::SUBJECT_OBJECT_DELETE . '_event':
|
||||||
case self::SUBJECT_OBJECT_UPDATE . '_event':
|
case self::SUBJECT_OBJECT_UPDATE . '_event':
|
||||||
|
case self::SUBJECT_OBJECT_MOVE_TO_TRASH . '_event':
|
||||||
|
case self::SUBJECT_OBJECT_RESTORE . '_event':
|
||||||
return [
|
return [
|
||||||
'actor' => $this->generateUserParameter($parameters['actor']),
|
'actor' => $this->generateUserParameter($parameters['actor']),
|
||||||
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
||||||
|
@ -177,6 +189,8 @@ class Event extends Base {
|
||||||
case self::SUBJECT_OBJECT_ADD . '_event_self':
|
case self::SUBJECT_OBJECT_ADD . '_event_self':
|
||||||
case self::SUBJECT_OBJECT_DELETE . '_event_self':
|
case self::SUBJECT_OBJECT_DELETE . '_event_self':
|
||||||
case self::SUBJECT_OBJECT_UPDATE . '_event_self':
|
case self::SUBJECT_OBJECT_UPDATE . '_event_self':
|
||||||
|
case self::SUBJECT_OBJECT_MOVE_TO_TRASH . '_event_self':
|
||||||
|
case self::SUBJECT_OBJECT_RESTORE . '_event_self':
|
||||||
return [
|
return [
|
||||||
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
||||||
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
|
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
namespace OCA\DAV\CalDAV;
|
namespace OCA\DAV\CalDAV;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use OCA\DAV\AppInfo\Application;
|
||||||
use OCA\DAV\Connector\Sabre\Principal;
|
use OCA\DAV\Connector\Sabre\Principal;
|
||||||
use OCA\DAV\DAV\Sharing\Backend;
|
use OCA\DAV\DAV\Sharing\Backend;
|
||||||
use OCA\DAV\DAV\Sharing\IShareable;
|
use OCA\DAV\DAV\Sharing\IShareable;
|
||||||
|
@ -47,10 +48,14 @@ use OCA\DAV\Events\CachedCalendarObjectDeletedEvent;
|
||||||
use OCA\DAV\Events\CachedCalendarObjectUpdatedEvent;
|
use OCA\DAV\Events\CachedCalendarObjectUpdatedEvent;
|
||||||
use OCA\DAV\Events\CalendarCreatedEvent;
|
use OCA\DAV\Events\CalendarCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarDeletedEvent;
|
use OCA\DAV\Events\CalendarDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarMovedToTrashEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
||||||
use OCA\DAV\Events\CalendarPublishedEvent;
|
use OCA\DAV\Events\CalendarPublishedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarShareUpdatedEvent;
|
use OCA\DAV\Events\CalendarShareUpdatedEvent;
|
||||||
use OCA\DAV\Events\CalendarUnpublishedEvent;
|
use OCA\DAV\Events\CalendarUnpublishedEvent;
|
||||||
use OCA\DAV\Events\CalendarUpdatedEvent;
|
use OCA\DAV\Events\CalendarUpdatedEvent;
|
||||||
|
@ -59,12 +64,14 @@ use OCA\DAV\Events\SubscriptionDeletedEvent;
|
||||||
use OCA\DAV\Events\SubscriptionUpdatedEvent;
|
use OCA\DAV\Events\SubscriptionUpdatedEvent;
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
use OCP\EventDispatcher\IEventDispatcher;
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
|
use OCP\IConfig;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
use OCP\IGroupManager;
|
use OCP\IGroupManager;
|
||||||
use OCP\ILogger;
|
use OCP\ILogger;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
use OCP\Security\ISecureRandom;
|
use OCP\Security\ISecureRandom;
|
||||||
|
use RuntimeException;
|
||||||
use Sabre\CalDAV\Backend\AbstractBackend;
|
use Sabre\CalDAV\Backend\AbstractBackend;
|
||||||
use Sabre\CalDAV\Backend\SchedulingSupport;
|
use Sabre\CalDAV\Backend\SchedulingSupport;
|
||||||
use Sabre\CalDAV\Backend\SubscriptionSupport;
|
use Sabre\CalDAV\Backend\SubscriptionSupport;
|
||||||
|
@ -72,6 +79,7 @@ use Sabre\CalDAV\Backend\SyncSupport;
|
||||||
use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
|
use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
|
||||||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
|
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
|
||||||
use Sabre\DAV;
|
use Sabre\DAV;
|
||||||
|
use Sabre\DAV\Exception\BadRequest;
|
||||||
use Sabre\DAV\Exception\Forbidden;
|
use Sabre\DAV\Exception\Forbidden;
|
||||||
use Sabre\DAV\Exception\NotFound;
|
use Sabre\DAV\Exception\NotFound;
|
||||||
use Sabre\DAV\PropPatch;
|
use Sabre\DAV\PropPatch;
|
||||||
|
@ -87,6 +95,15 @@ use Sabre\VObject\Reader;
|
||||||
use Sabre\VObject\Recur\EventIterator;
|
use Sabre\VObject\Recur\EventIterator;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||||
|
use function array_merge;
|
||||||
|
use function array_values;
|
||||||
|
use function explode;
|
||||||
|
use function is_array;
|
||||||
|
use function pathinfo;
|
||||||
|
use function sprintf;
|
||||||
|
use function str_replace;
|
||||||
|
use function strtolower;
|
||||||
|
use function time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CalDavBackend
|
* Class CalDavBackend
|
||||||
|
@ -134,6 +151,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone',
|
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone',
|
||||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
|
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
|
||||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
|
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
|
||||||
|
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => 'deleted_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,6 +209,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
/** @var EventDispatcherInterface */
|
/** @var EventDispatcherInterface */
|
||||||
private $legacyDispatcher;
|
private $legacyDispatcher;
|
||||||
|
|
||||||
|
/** @var IConfig */
|
||||||
|
private $config;
|
||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $legacyEndpoint;
|
private $legacyEndpoint;
|
||||||
|
|
||||||
|
@ -218,6 +239,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
ILogger $logger,
|
ILogger $logger,
|
||||||
IEventDispatcher $dispatcher,
|
IEventDispatcher $dispatcher,
|
||||||
EventDispatcherInterface $legacyDispatcher,
|
EventDispatcherInterface $legacyDispatcher,
|
||||||
|
IConfig $config,
|
||||||
bool $legacyEndpoint = false) {
|
bool $legacyEndpoint = false) {
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
$this->principalBackend = $principalBackend;
|
$this->principalBackend = $principalBackend;
|
||||||
|
@ -227,6 +249,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
$this->legacyDispatcher = $legacyDispatcher;
|
$this->legacyDispatcher = $legacyDispatcher;
|
||||||
|
$this->config = $config;
|
||||||
$this->legacyEndpoint = $legacyEndpoint;
|
$this->legacyEndpoint = $legacyEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,6 +284,26 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{id: int, deleted_at: int}[]
|
||||||
|
*/
|
||||||
|
public function getDeletedCalendars(int $deletedBefore): array {
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
$qb->select(['id', 'deleted_at'])
|
||||||
|
->from('calendars')
|
||||||
|
->where($qb->expr()->isNotNull('deleted_at'))
|
||||||
|
->andWhere($qb->expr()->lt('deleted_at', $qb->createNamedParameter($deletedBefore)));
|
||||||
|
$result = $qb->executeQuery();
|
||||||
|
$raw = $result->fetchAll();
|
||||||
|
$result->closeCursor();
|
||||||
|
return array_map(function ($row) {
|
||||||
|
return [
|
||||||
|
'id' => (int) $row['id'],
|
||||||
|
'deleted_at' => (int) $row['deleted_at'],
|
||||||
|
];
|
||||||
|
}, $raw);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of calendars for a principal.
|
* Returns a list of calendars for a principal.
|
||||||
*
|
*
|
||||||
|
@ -334,7 +377,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
if (!isset($calendars[$calendar['id']])) {
|
if (!isset($calendars[$calendar['id']])) {
|
||||||
$calendars[$calendar['id']] = $calendar;
|
$calendars[$calendar['id']] = $calendar;
|
||||||
|
@ -410,7 +454,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
$calendars[$calendar['id']] = $calendar;
|
$calendars[$calendar['id']] = $calendar;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +503,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
if (!isset($calendars[$calendar['id']])) {
|
if (!isset($calendars[$calendar['id']])) {
|
||||||
$calendars[$calendar['id']] = $calendar;
|
$calendars[$calendar['id']] = $calendar;
|
||||||
|
@ -534,7 +580,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
if (!isset($calendars[$calendar['id']])) {
|
if (!isset($calendars[$calendar['id']])) {
|
||||||
$calendars[$calendar['id']] = $calendar;
|
$calendars[$calendar['id']] = $calendar;
|
||||||
|
@ -601,7 +648,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
return $calendar;
|
return $calendar;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +702,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
return $calendar;
|
return $calendar;
|
||||||
}
|
}
|
||||||
|
@ -705,7 +754,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$calendar[$xmlName] = $row[$dbName];
|
$calendar[$xmlName] = $row[$dbName];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addOwnerPrincipal($calendar);
|
$calendar = $this->addOwnerPrincipalToCalendar($calendar);
|
||||||
|
$calendar = $this->addResourceTypeToCalendar($row, $calendar);
|
||||||
|
|
||||||
return $calendar;
|
return $calendar;
|
||||||
}
|
}
|
||||||
|
@ -872,33 +922,84 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
* @param mixed $calendarId
|
* @param mixed $calendarId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function deleteCalendar($calendarId) {
|
public function deleteCalendar($calendarId, bool $forceDeletePermanently = false) {
|
||||||
|
// The calendar is deleted right away if this is either enforced by the caller
|
||||||
|
// or the special contacts birthday calendar or when the preference of an empty
|
||||||
|
// retention (0 seconds) is set, which signals a disabled trashbin.
|
||||||
$calendarData = $this->getCalendarById($calendarId);
|
$calendarData = $this->getCalendarById($calendarId);
|
||||||
$shares = $this->getShares($calendarId);
|
$isBirthdayCalendar = isset($calendarData['uri']) && $calendarData['uri'] === BirthdayService::BIRTHDAY_CALENDAR_URI;
|
||||||
|
$trashbinDisabled = $this->config->getAppValue(Application::APP_ID, RetentionService::RETENTION_CONFIG_KEY) === '0';
|
||||||
|
if ($forceDeletePermanently || $isBirthdayCalendar || $trashbinDisabled) {
|
||||||
|
$calendarData = $this->getCalendarById($calendarId);
|
||||||
|
$shares = $this->getShares($calendarId);
|
||||||
|
|
||||||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `calendartype` = ?');
|
$qbDeleteCalendarObjectProps = $this->db->getQueryBuilder();
|
||||||
$stmt->execute([$calendarId, self::CALENDAR_TYPE_CALENDAR]);
|
$qbDeleteCalendarObjectProps->delete($this->dbObjectPropertiesTable)
|
||||||
|
->where($qbDeleteCalendarObjectProps->expr()->eq('calendarid', $qbDeleteCalendarObjectProps->createNamedParameter($calendarId)))
|
||||||
|
->andWhere($qbDeleteCalendarObjectProps->expr()->eq('calendartype', $qbDeleteCalendarObjectProps->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)))
|
||||||
|
->executeStatement();
|
||||||
|
|
||||||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendars` WHERE `id` = ?');
|
$qbDeleteCalendarObjects = $this->db->getQueryBuilder();
|
||||||
$stmt->execute([$calendarId]);
|
$qbDeleteCalendarObjects->delete('calendarobjects')
|
||||||
|
->where($qbDeleteCalendarObjects->expr()->eq('calendarid', $qbDeleteCalendarObjects->createNamedParameter($calendarId)))
|
||||||
|
->andWhere($qbDeleteCalendarObjects->expr()->eq('calendartype', $qbDeleteCalendarObjects->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)))
|
||||||
|
->executeStatement();
|
||||||
|
|
||||||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarchanges` WHERE `calendarid` = ? AND `calendartype` = ?');
|
$qbDeleteCalendarChanges = $this->db->getQueryBuilder();
|
||||||
$stmt->execute([$calendarId, self::CALENDAR_TYPE_CALENDAR]);
|
$qbDeleteCalendarObjects->delete('calendarchanges')
|
||||||
|
->where($qbDeleteCalendarChanges->expr()->eq('calendarid', $qbDeleteCalendarChanges->createNamedParameter($calendarId)))
|
||||||
|
->andWhere($qbDeleteCalendarChanges->expr()->eq('calendartype', $qbDeleteCalendarChanges->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)))
|
||||||
|
->executeStatement();
|
||||||
|
|
||||||
$this->calendarSharingBackend->deleteAllShares($calendarId);
|
$this->calendarSharingBackend->deleteAllShares($calendarId);
|
||||||
|
|
||||||
$query = $this->db->getQueryBuilder();
|
$qbDeleteCalendar = $this->db->getQueryBuilder();
|
||||||
$query->delete($this->dbObjectPropertiesTable)
|
$qbDeleteCalendarObjects->delete('calendars')
|
||||||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
->where($qbDeleteCalendar->expr()->eq('id', $qbDeleteCalendar->createNamedParameter($calendarId)))
|
||||||
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)))
|
->executeStatement();
|
||||||
->executeStatement();
|
|
||||||
|
|
||||||
// Only dispatch if we actually deleted anything
|
// Only dispatch if we actually deleted anything
|
||||||
if ($calendarData) {
|
if ($calendarData) {
|
||||||
$this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares));
|
$this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$qbMarkCalendarDeleted = $this->db->getQueryBuilder();
|
||||||
|
$qbMarkCalendarDeleted->update('calendars')
|
||||||
|
->set('deleted_at', $qbMarkCalendarDeleted->createNamedParameter(time()))
|
||||||
|
->where($qbMarkCalendarDeleted->expr()->eq('id', $qbMarkCalendarDeleted->createNamedParameter($calendarId)))
|
||||||
|
->executeStatement();
|
||||||
|
|
||||||
|
$calendarData = $this->getCalendarById($calendarId);
|
||||||
|
$shares = $this->getShares($calendarId);
|
||||||
|
if ($calendarData) {
|
||||||
|
$this->dispatcher->dispatchTyped(new CalendarMovedToTrashEvent(
|
||||||
|
(int)$calendarId,
|
||||||
|
$calendarData,
|
||||||
|
$shares
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function restoreCalendar(int $id): void {
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
$update = $qb->update('calendars')
|
||||||
|
->set('deleted_at', $qb->createNamedParameter(null))
|
||||||
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
|
||||||
|
$update->executeStatement();
|
||||||
|
|
||||||
|
$calendarData = $this->getCalendarById($id);
|
||||||
|
$shares = $this->getShares($id);
|
||||||
|
if ($calendarData === null) {
|
||||||
|
throw new RuntimeException('Calendar data that was just written can\'t be read back. Check your database configuration.');
|
||||||
|
}
|
||||||
|
$this->dispatcher->dispatchTyped(new CalendarRestoredEvent(
|
||||||
|
$id,
|
||||||
|
$calendarData,
|
||||||
|
$shares
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all of an user's shares
|
* Delete all of an user's shares
|
||||||
*
|
*
|
||||||
|
@ -946,7 +1047,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification'])
|
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification'])
|
||||||
->from('calendarobjects')
|
->from('calendarobjects')
|
||||||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
||||||
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
|
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
|
||||||
|
->andWhere($query->expr()->isNull('deleted_at'));
|
||||||
$stmt = $query->executeQuery();
|
$stmt = $query->executeQuery();
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
|
@ -967,6 +1069,63 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDeletedCalendarObjects(int $deletedBefore): array {
|
||||||
|
$query = $this->db->getQueryBuilder();
|
||||||
|
$query->select(['co.id', 'co.uri', 'co.lastmodified', 'co.etag', 'co.calendarid', 'co.calendartype', 'co.size', 'co.componenttype', 'co.classification', 'co.deleted_at'])
|
||||||
|
->from('calendarobjects', 'co')
|
||||||
|
->join('co', 'calendars', 'c', $query->expr()->eq('c.id', 'co.calendarid', IQueryBuilder::PARAM_INT))
|
||||||
|
->where($query->expr()->isNotNull('co.deleted_at'))
|
||||||
|
->andWhere($query->expr()->lt('co.deleted_at', $query->createNamedParameter($deletedBefore)));
|
||||||
|
$stmt = $query->executeQuery();
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
foreach ($stmt->fetchAll() as $row) {
|
||||||
|
$result[] = [
|
||||||
|
'id' => $row['id'],
|
||||||
|
'uri' => $row['uri'],
|
||||||
|
'lastmodified' => $row['lastmodified'],
|
||||||
|
'etag' => '"' . $row['etag'] . '"',
|
||||||
|
'calendarid' => (int) $row['calendarid'],
|
||||||
|
'calendartype' => (int) $row['calendartype'],
|
||||||
|
'size' => (int) $row['size'],
|
||||||
|
'component' => strtolower($row['componenttype']),
|
||||||
|
'classification' => (int) $row['classification'],
|
||||||
|
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDeletedCalendarObjectsByPrincipal(string $principalUri): array {
|
||||||
|
$query = $this->db->getQueryBuilder();
|
||||||
|
$query->select(['co.id', 'co.uri', 'co.lastmodified', 'co.etag', 'co.calendarid', 'co.size', 'co.componenttype', 'co.classification', 'co.deleted_at'])
|
||||||
|
->from('calendarobjects', 'co')
|
||||||
|
->join('co', 'calendars', 'c', $query->expr()->eq('c.id', 'co.calendarid', IQueryBuilder::PARAM_INT))
|
||||||
|
->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
|
||||||
|
->andWhere($query->expr()->isNotNull('co.deleted_at'));
|
||||||
|
$stmt = $query->executeQuery();
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
while ($row = $stmt->fetch()) {
|
||||||
|
$result[] = [
|
||||||
|
'id' => $row['id'],
|
||||||
|
'uri' => $row['uri'],
|
||||||
|
'lastmodified' => $row['lastmodified'],
|
||||||
|
'etag' => '"' . $row['etag'] . '"',
|
||||||
|
'calendarid' => $row['calendarid'],
|
||||||
|
'size' => (int)$row['size'],
|
||||||
|
'component' => strtolower($row['componenttype']),
|
||||||
|
'classification' => (int)$row['classification'],
|
||||||
|
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns information from a single calendar object, based on it's object
|
* Returns information from a single calendar object, based on it's object
|
||||||
* uri.
|
* uri.
|
||||||
|
@ -984,7 +1143,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
* @param int $calendarType
|
* @param int $calendarType
|
||||||
* @return array|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
public function getCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
|
public function getCalendarObject($calendarId, $objectUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR) {
|
||||||
$query = $this->db->getQueryBuilder();
|
$query = $this->db->getQueryBuilder();
|
||||||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
|
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
|
||||||
->from('calendarobjects')
|
->from('calendarobjects')
|
||||||
|
@ -1038,7 +1197,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
->from('calendarobjects')
|
->from('calendarobjects')
|
||||||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
||||||
->andWhere($query->expr()->in('uri', $query->createParameter('uri')))
|
->andWhere($query->expr()->in('uri', $query->createParameter('uri')))
|
||||||
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
|
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
|
||||||
|
->andWhere($query->expr()->isNull('deleted_at'));
|
||||||
|
|
||||||
foreach ($chunks as $uris) {
|
foreach ($chunks as $uris) {
|
||||||
$query->setParameter('uri', $uris, IQueryBuilder::PARAM_STR_ARRAY);
|
$query->setParameter('uri', $uris, IQueryBuilder::PARAM_STR_ARRAY);
|
||||||
|
@ -1085,19 +1245,34 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
|
public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
|
||||||
$extraData = $this->getDenormalizedData($calendarData);
|
$extraData = $this->getDenormalizedData($calendarData);
|
||||||
|
|
||||||
$q = $this->db->getQueryBuilder();
|
// Try to detect duplicates
|
||||||
$q->select($q->func()->count('*'))
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
$qb->select($qb->func()->count('*'))
|
||||||
->from('calendarobjects')
|
->from('calendarobjects')
|
||||||
->where($q->expr()->eq('calendarid', $q->createNamedParameter($calendarId)))
|
->where($qb->expr()->eq('calendarid', $qb->createNamedParameter($calendarId)))
|
||||||
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($extraData['uid'])))
|
->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($extraData['uid'])))
|
||||||
->andWhere($q->expr()->eq('calendartype', $q->createNamedParameter($calendarType)));
|
->andWhere($qb->expr()->eq('calendartype', $qb->createNamedParameter($calendarType)))
|
||||||
|
->andWhere($qb->expr()->isNull('deleted_at'));
|
||||||
$result = $q->executeQuery();
|
$result = $qb->executeQuery();
|
||||||
$count = (int) $result->fetchOne();
|
$count = (int) $result->fetchOne();
|
||||||
$result->closeCursor();
|
$result->closeCursor();
|
||||||
|
|
||||||
if ($count !== 0) {
|
if ($count !== 0) {
|
||||||
throw new \Sabre\DAV\Exception\BadRequest('Calendar object with uid already exists in this calendar collection.');
|
throw new BadRequest('Calendar object with uid already exists in this calendar collection.');
|
||||||
|
}
|
||||||
|
// For a more specific error message we also try to explicitly look up the UID but as a deleted entry
|
||||||
|
$qbDel = $this->db->getQueryBuilder();
|
||||||
|
$qbDel->select($qb->func()->count('*'))
|
||||||
|
->from('calendarobjects')
|
||||||
|
->where($qbDel->expr()->eq('calendarid', $qbDel->createNamedParameter($calendarId)))
|
||||||
|
->andWhere($qbDel->expr()->eq('uid', $qbDel->createNamedParameter($extraData['uid'])))
|
||||||
|
->andWhere($qbDel->expr()->eq('calendartype', $qbDel->createNamedParameter($calendarType)))
|
||||||
|
->andWhere($qbDel->expr()->isNotNull('deleted_at'));
|
||||||
|
$result = $qbDel->executeQuery();
|
||||||
|
$count = (int) $result->fetchOne();
|
||||||
|
$result->closeCursor();
|
||||||
|
if ($count !== 0) {
|
||||||
|
throw new BadRequest('Deleted calendar object with uid already exists in this calendar collection.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $this->db->getQueryBuilder();
|
$query = $this->db->getQueryBuilder();
|
||||||
|
@ -1236,11 +1411,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
* @param mixed $calendarId
|
* @param mixed $calendarId
|
||||||
* @param string $objectUri
|
* @param string $objectUri
|
||||||
* @param int $calendarType
|
* @param int $calendarType
|
||||||
|
* @param bool $forceDeletePermanently
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function deleteCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
|
public function deleteCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR, bool $forceDeletePermanently = false) {
|
||||||
$data = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
|
$data = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
|
||||||
if (is_array($data)) {
|
|
||||||
|
if ($data === null) {
|
||||||
|
// Nothing to delete
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($forceDeletePermanently || $this->config->getAppValue(Application::APP_ID, RetentionService::RETENTION_CONFIG_KEY) === '0') {
|
||||||
|
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `uri` = ? AND `calendartype` = ?');
|
||||||
|
$stmt->execute([$calendarId, $objectUri, $calendarType]);
|
||||||
|
|
||||||
|
$this->purgeProperties($calendarId, $data['id']);
|
||||||
|
|
||||||
if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
|
if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
|
||||||
$calendarRow = $this->getCalendarById($calendarId);
|
$calendarRow = $this->getCalendarById($calendarId);
|
||||||
$shares = $this->getShares($calendarId);
|
$shares = $this->getShares($calendarId);
|
||||||
|
@ -1260,18 +1447,107 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
$pathInfo = pathinfo($data['uri']);
|
||||||
|
if (!empty($pathInfo['extension'])) {
|
||||||
|
// Append a suffix to "free" the old URI for recreation
|
||||||
|
$newUri = sprintf(
|
||||||
|
"%s-deleted.%s",
|
||||||
|
$pathInfo['filename'],
|
||||||
|
$pathInfo['extension']
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$newUri = sprintf(
|
||||||
|
"%s-deleted",
|
||||||
|
$pathInfo['filename']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `uri` = ? AND `calendartype` = ?');
|
// Try to detect conflicts before the DB does
|
||||||
$stmt->execute([$calendarId, $objectUri, $calendarType]);
|
// As unlikely as it seems, this can happen when the user imports, then deletes, imports and deletes again
|
||||||
|
$newObject = $this->getCalendarObject($calendarId, $newUri, $calendarType);
|
||||||
|
if ($newObject !== null) {
|
||||||
|
throw new Forbidden("A calendar object with URI $newUri already exists in calendar $calendarId, therefore this object can't be moved into the trashbin");
|
||||||
|
}
|
||||||
|
|
||||||
if (is_array($data)) {
|
$qb = $this->db->getQueryBuilder();
|
||||||
$this->purgeProperties($calendarId, $data['id'], $calendarType);
|
$markObjectDeletedQuery = $qb->update('calendarobjects')
|
||||||
|
->set('deleted_at', $qb->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
|
||||||
|
->set('uri', $qb->createNamedParameter($newUri))
|
||||||
|
->where(
|
||||||
|
$qb->expr()->eq('calendarid', $qb->createNamedParameter($calendarId)),
|
||||||
|
$qb->expr()->eq('calendartype', $qb->createNamedParameter($calendarType, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT),
|
||||||
|
$qb->expr()->eq('uri', $qb->createNamedParameter($objectUri))
|
||||||
|
);
|
||||||
|
$markObjectDeletedQuery->executeStatement();
|
||||||
|
|
||||||
|
$calendarData = $this->getCalendarById($calendarId);
|
||||||
|
if ($calendarData !== null) {
|
||||||
|
$this->dispatcher->dispatchTyped(
|
||||||
|
new CalendarObjectMovedToTrashEvent(
|
||||||
|
(int)$calendarId,
|
||||||
|
$calendarData,
|
||||||
|
$this->getShares($calendarId),
|
||||||
|
$data
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addChange($calendarId, $objectUri, 3, $calendarType);
|
$this->addChange($calendarId, $objectUri, 3, $calendarType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $objectData
|
||||||
|
*
|
||||||
|
* @throws Forbidden
|
||||||
|
*/
|
||||||
|
public function restoreCalendarObject(array $objectData): void {
|
||||||
|
$id = (int) $objectData['id'];
|
||||||
|
$restoreUri = str_replace("-deleted.ics", ".ics", $objectData['uri']);
|
||||||
|
$targetObject = $this->getCalendarObject(
|
||||||
|
$objectData['calendarid'],
|
||||||
|
$restoreUri
|
||||||
|
);
|
||||||
|
if ($targetObject !== null) {
|
||||||
|
throw new Forbidden("Can not restore calendar $id because a calendar object with the URI $restoreUri already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
$update = $qb->update('calendarobjects')
|
||||||
|
->set('uri', $qb->createNamedParameter($restoreUri))
|
||||||
|
->set('deleted_at', $qb->createNamedParameter(null))
|
||||||
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
|
||||||
|
$update->executeStatement();
|
||||||
|
|
||||||
|
// Make sure this change is tracked in the changes table
|
||||||
|
$qb2 = $this->db->getQueryBuilder();
|
||||||
|
$selectObject = $qb2->select('calendardata', 'uri', 'calendarid', 'calendartype')
|
||||||
|
->from('calendarobjects')
|
||||||
|
->where($qb2->expr()->eq('id', $qb2->createNamedParameter($id, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
|
||||||
|
$result = $selectObject->executeQuery();
|
||||||
|
$row = $result->fetch();
|
||||||
|
$result->closeCursor();
|
||||||
|
if ($row === false) {
|
||||||
|
// Welp, this should possibly not have happened, but let's ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->addChange($row['calendarid'], $row['uri'], 1, (int) $row['calendartype']);
|
||||||
|
|
||||||
|
$calendarRow = $this->getCalendarById((int) $row['calendarid']);
|
||||||
|
if ($calendarRow === null) {
|
||||||
|
throw new RuntimeException('Calendar object data that was just written can\'t be read back. Check your database configuration.');
|
||||||
|
}
|
||||||
|
$this->dispatcher->dispatchTyped(
|
||||||
|
new CalendarObjectRestoredEvent(
|
||||||
|
(int) $objectData['calendarid'],
|
||||||
|
$calendarRow,
|
||||||
|
$this->getShares((int) $row['calendarid']),
|
||||||
|
$row
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a calendar-query on the contents of this calendar.
|
* Performs a calendar-query on the contents of this calendar.
|
||||||
*
|
*
|
||||||
|
@ -1359,7 +1635,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
$query->select($columns)
|
$query->select($columns)
|
||||||
->from('calendarobjects')
|
->from('calendarobjects')
|
||||||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
||||||
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
|
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
|
||||||
|
->andWhere($query->expr()->isNull('deleted_at'));
|
||||||
|
|
||||||
if ($componentType) {
|
if ($componentType) {
|
||||||
$query->andWhere($query->expr()->eq('componenttype', $query->createNamedParameter($componentType)));
|
$query->andWhere($query->expr()->eq('componenttype', $query->createNamedParameter($componentType)));
|
||||||
|
@ -1508,7 +1785,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
->andWhere($compExpr)
|
->andWhere($compExpr)
|
||||||
->andWhere($propParamExpr)
|
->andWhere($propParamExpr)
|
||||||
->andWhere($query->expr()->iLike('i.value',
|
->andWhere($query->expr()->iLike('i.value',
|
||||||
$query->createNamedParameter('%'.$this->db->escapeLikeParameter($filters['search-term']).'%')));
|
$query->createNamedParameter('%'.$this->db->escapeLikeParameter($filters['search-term']).'%')))
|
||||||
|
->andWhere($query->expr()->isNull('deleted_at'));
|
||||||
|
|
||||||
if ($offset) {
|
if ($offset) {
|
||||||
$query->setFirstResult($offset);
|
$query->setFirstResult($offset);
|
||||||
|
@ -1574,7 +1852,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
|
$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
|
||||||
->from('calendarobjects', 'c');
|
->from('calendarobjects', 'c')
|
||||||
|
->where($outerQuery->expr()->isNull('deleted_at'));
|
||||||
|
|
||||||
if (isset($options['timerange'])) {
|
if (isset($options['timerange'])) {
|
||||||
if (isset($options['timerange']['start']) && $options['timerange']['start'] instanceof DateTime) {
|
if (isset($options['timerange']['start']) && $options['timerange']['start'] instanceof DateTime) {
|
||||||
|
@ -1776,7 +2055,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
->leftJoin('cob', 'calendarobjects', 'co', $calendarObjectIdQuery->expr()->eq('co.id', 'cob.objectid'))
|
->leftJoin('cob', 'calendarobjects', 'co', $calendarObjectIdQuery->expr()->eq('co.id', 'cob.objectid'))
|
||||||
->andWhere($calendarObjectIdQuery->expr()->in('co.componenttype', $calendarObjectIdQuery->createNamedParameter($componentTypes, IQueryBuilder::PARAM_STR_ARRAY)))
|
->andWhere($calendarObjectIdQuery->expr()->in('co.componenttype', $calendarObjectIdQuery->createNamedParameter($componentTypes, IQueryBuilder::PARAM_STR_ARRAY)))
|
||||||
->andWhere($calendarOr)
|
->andWhere($calendarOr)
|
||||||
->andWhere($searchOr);
|
->andWhere($searchOr)
|
||||||
|
->andWhere($calendarObjectIdQuery->expr()->isNull('deleted_at'));
|
||||||
|
|
||||||
if ('' !== $pattern) {
|
if ('' !== $pattern) {
|
||||||
if (!$escapePattern) {
|
if (!$escapePattern) {
|
||||||
|
@ -1843,8 +2123,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
->from('calendarobjects', 'co')
|
->from('calendarobjects', 'co')
|
||||||
->leftJoin('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id'))
|
->leftJoin('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id'))
|
||||||
->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
|
->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
|
||||||
->andWhere($query->expr()->eq('co.uid', $query->createNamedParameter($uid)));
|
->andWhere($query->expr()->eq('co.uid', $query->createNamedParameter($uid)))
|
||||||
|
->andWhere($query->expr()->isNull('co.deleted_at'));
|
||||||
$stmt = $query->executeQuery();
|
$stmt = $query->executeQuery();
|
||||||
$row = $stmt->fetch();
|
$row = $stmt->fetch();
|
||||||
$stmt->closeCursor();
|
$stmt->closeCursor();
|
||||||
|
@ -1855,6 +2135,35 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCalendarObjectById(string $principalUri, int $id): ?array {
|
||||||
|
$query = $this->db->getQueryBuilder();
|
||||||
|
$query->select(['co.id', 'co.uri', 'co.lastmodified', 'co.etag', 'co.calendarid', 'co.size', 'co.calendardata', 'co.componenttype', 'co.classification', 'co.deleted_at'])
|
||||||
|
->from('calendarobjects', 'co')
|
||||||
|
->join('co', 'calendars', 'c', $query->expr()->eq('c.id', 'co.calendarid', IQueryBuilder::PARAM_INT))
|
||||||
|
->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
|
||||||
|
->andWhere($query->expr()->eq('co.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
|
||||||
|
$stmt = $query->executeQuery();
|
||||||
|
$row = $stmt->fetch();
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
if (!$row) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $row['id'],
|
||||||
|
'uri' => $row['uri'],
|
||||||
|
'lastmodified' => $row['lastmodified'],
|
||||||
|
'etag' => '"' . $row['etag'] . '"',
|
||||||
|
'calendarid' => $row['calendarid'],
|
||||||
|
'size' => (int)$row['size'],
|
||||||
|
'calendardata' => $this->readBlob($row['calendardata']),
|
||||||
|
'component' => strtolower($row['componenttype']),
|
||||||
|
'classification' => (int)$row['classification'],
|
||||||
|
'deleted_at' => isset($row['deleted_at']) ? ((int) $row['deleted_at']) : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The getChanges method returns all the changes that have happened, since
|
* The getChanges method returns all the changes that have happened, since
|
||||||
* the specified syncToken in the specified calendar.
|
* the specified syncToken in the specified calendar.
|
||||||
|
@ -2410,7 +2719,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$componentType) {
|
if (!$componentType) {
|
||||||
throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
|
throw new BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasDTSTART) {
|
if ($hasDTSTART) {
|
||||||
|
@ -2670,7 +2979,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
|
|
||||||
$ids = $result->fetchAll();
|
$ids = $result->fetchAll();
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$this->deleteCalendar($id['id']);
|
$this->deleteCalendar(
|
||||||
|
$id['id'],
|
||||||
|
true // No data to keep in the trashbin, if the user re-enables then we regenerate
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2802,9 +3114,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
/**
|
/**
|
||||||
* adds information about an owner to the calendar data
|
* adds information about an owner to the calendar data
|
||||||
*
|
*
|
||||||
* @param $calendarInfo
|
|
||||||
*/
|
*/
|
||||||
private function addOwnerPrincipal(&$calendarInfo) {
|
private function addOwnerPrincipalToCalendar(array $calendarInfo): array {
|
||||||
$ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal';
|
$ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal';
|
||||||
$displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname';
|
$displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname';
|
||||||
if (isset($calendarInfo[$ownerPrincipalKey])) {
|
if (isset($calendarInfo[$ownerPrincipalKey])) {
|
||||||
|
@ -2817,5 +3128,20 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
||||||
if (isset($principalInformation['{DAV:}displayname'])) {
|
if (isset($principalInformation['{DAV:}displayname'])) {
|
||||||
$calendarInfo[$displaynameKey] = $principalInformation['{DAV:}displayname'];
|
$calendarInfo[$displaynameKey] = $principalInformation['{DAV:}displayname'];
|
||||||
}
|
}
|
||||||
|
return $calendarInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addResourceTypeToCalendar(array $row, array $calendar): array {
|
||||||
|
if (isset($row['deleted_at'])) {
|
||||||
|
// Columns is set and not null -> this is a deleted calendar
|
||||||
|
// we send a custom resourcetype to hide the deleted calendar
|
||||||
|
// from ordinary DAV clients, but the Calendar app will know
|
||||||
|
// how to handle this special resource.
|
||||||
|
$calendar['{DAV:}resourcetype'] = new DAV\Xml\Property\ResourceType([
|
||||||
|
'{DAV:}collection',
|
||||||
|
sprintf('{%s}deleted-calendar', \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $calendar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,9 @@ use Sabre\DAV\PropPatch;
|
||||||
* Class Calendar
|
* Class Calendar
|
||||||
*
|
*
|
||||||
* @package OCA\DAV\CalDAV
|
* @package OCA\DAV\CalDAV
|
||||||
* @property BackendInterface|CalDavBackend $caldavBackend
|
* @property CalDavBackend $caldavBackend
|
||||||
*/
|
*/
|
||||||
class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable {
|
||||||
|
|
||||||
/** @var IConfig */
|
/** @var IConfig */
|
||||||
private $config;
|
private $config;
|
||||||
|
@ -52,6 +52,9 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
||||||
/** @var IL10N */
|
/** @var IL10N */
|
||||||
protected $l10n;
|
protected $l10n;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $useTrashbin = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calendar constructor.
|
* Calendar constructor.
|
||||||
*
|
*
|
||||||
|
@ -269,7 +272,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
||||||
$this->config->setUserValue($userId, 'dav', 'generateBirthdayCalendar', 'no');
|
$this->config->setUserValue($userId, 'dav', 'generateBirthdayCalendar', 'no');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::delete();
|
$this->caldavBackend->deleteCalendar(
|
||||||
|
$this->calendarInfo['id'],
|
||||||
|
!$this->useTrashbin
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function propPatch(PropPatch $propPatch) {
|
public function propPatch(PropPatch $propPatch) {
|
||||||
|
@ -399,4 +405,12 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
||||||
|
|
||||||
return parent::getChanges($syncToken, $syncLevel, $limit);
|
return parent::getChanges($syncToken, $syncLevel, $limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function restore(): void {
|
||||||
|
$this->caldavBackend->restoreCalendar((int) $this->calendarInfo['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableTrashbin(): void {
|
||||||
|
$this->useTrashbin = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace OCA\DAV\CalDAV;
|
||||||
use OCA\DAV\AppInfo\PluginManager;
|
use OCA\DAV\AppInfo\PluginManager;
|
||||||
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
|
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
|
||||||
use OCA\DAV\CalDAV\Integration\ICalendarProvider;
|
use OCA\DAV\CalDAV\Integration\ICalendarProvider;
|
||||||
|
use OCA\DAV\CalDAV\Trashbin\TrashbinHome;
|
||||||
use Sabre\CalDAV\Backend\BackendInterface;
|
use Sabre\CalDAV\Backend\BackendInterface;
|
||||||
use Sabre\CalDAV\Backend\NotificationSupport;
|
use Sabre\CalDAV\Backend\NotificationSupport;
|
||||||
use Sabre\CalDAV\Backend\SchedulingSupport;
|
use Sabre\CalDAV\Backend\SchedulingSupport;
|
||||||
|
@ -38,6 +39,7 @@ use Sabre\CalDAV\Schedule\Inbox;
|
||||||
use Sabre\CalDAV\Subscriptions\Subscription;
|
use Sabre\CalDAV\Subscriptions\Subscription;
|
||||||
use Sabre\DAV\Exception\MethodNotAllowed;
|
use Sabre\DAV\Exception\MethodNotAllowed;
|
||||||
use Sabre\DAV\Exception\NotFound;
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
use Sabre\DAV\INode;
|
||||||
use Sabre\DAV\MkCol;
|
use Sabre\DAV\MkCol;
|
||||||
|
|
||||||
class CalendarHome extends \Sabre\CalDAV\CalendarHome {
|
class CalendarHome extends \Sabre\CalDAV\CalendarHome {
|
||||||
|
@ -74,8 +76,11 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function createExtendedCollection($name, MkCol $mkCol) {
|
public function createExtendedCollection($name, MkCol $mkCol): void {
|
||||||
$reservedNames = [BirthdayService::BIRTHDAY_CALENDAR_URI];
|
$reservedNames = [
|
||||||
|
BirthdayService::BIRTHDAY_CALENDAR_URI,
|
||||||
|
TrashbinHome::NAME,
|
||||||
|
];
|
||||||
|
|
||||||
if (\in_array($name, $reservedNames, true) || ExternalCalendar::doesViolateReservedName($name)) {
|
if (\in_array($name, $reservedNames, true) || ExternalCalendar::doesViolateReservedName($name)) {
|
||||||
throw new MethodNotAllowed('The resource you tried to create has a reserved name');
|
throw new MethodNotAllowed('The resource you tried to create has a reserved name');
|
||||||
|
@ -104,6 +109,10 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
|
||||||
$objects[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
$objects[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->caldavBackend instanceof CalDavBackend) {
|
||||||
|
$objects[] = new TrashbinHome($this->caldavBackend, $this->principalInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// If the backend supports subscriptions, we'll add those as well,
|
// If the backend supports subscriptions, we'll add those as well,
|
||||||
if ($this->caldavBackend instanceof SubscriptionSupport) {
|
if ($this->caldavBackend instanceof SubscriptionSupport) {
|
||||||
foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) {
|
foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) {
|
||||||
|
@ -127,7 +136,9 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return INode
|
||||||
*/
|
*/
|
||||||
public function getChild($name) {
|
public function getChild($name) {
|
||||||
// Special nodes
|
// Special nodes
|
||||||
|
@ -140,6 +151,9 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
|
||||||
if ($name === 'notifications' && $this->caldavBackend instanceof NotificationSupport) {
|
if ($name === 'notifications' && $this->caldavBackend instanceof NotificationSupport) {
|
||||||
return new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
return new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
||||||
}
|
}
|
||||||
|
if ($name === TrashbinHome::NAME && $this->caldavBackend instanceof CalDavBackend) {
|
||||||
|
return new TrashbinHome($this->caldavBackend, $this->principalInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// Calendars
|
// Calendars
|
||||||
foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) {
|
foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) {
|
||||||
|
|
|
@ -82,6 +82,10 @@ class CalendarObject extends \Sabre\CalDAV\CalendarObject {
|
||||||
return $vObject->serialize();
|
return $vObject->serialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getId(): int {
|
||||||
|
return (int) $this->objectData['id'];
|
||||||
|
}
|
||||||
|
|
||||||
protected function isShared() {
|
protected function isShared() {
|
||||||
if (!isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
|
if (!isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV;
|
||||||
|
|
||||||
|
use Sabre\DAV\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for nodes that can be restored from the trashbin
|
||||||
|
*/
|
||||||
|
interface IRestorable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore this node
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function restore(): void;
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV;
|
||||||
|
|
||||||
|
use OCA\DAV\AppInfo\Application;
|
||||||
|
use OCP\AppFramework\Utility\ITimeFactory;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use function max;
|
||||||
|
|
||||||
|
class RetentionService {
|
||||||
|
public const RETENTION_CONFIG_KEY = 'calendarRetentionObligation';
|
||||||
|
private const DEFAULT_RETENTION_SECONDS = 30 * 24 * 60 * 60;
|
||||||
|
|
||||||
|
/** @var IConfig */
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/** @var ITimeFactory */
|
||||||
|
private $time;
|
||||||
|
|
||||||
|
/** @var CalDavBackend */
|
||||||
|
private $calDavBackend;
|
||||||
|
|
||||||
|
public function __construct(IConfig $config,
|
||||||
|
ITimeFactory $time,
|
||||||
|
CalDavBackend $calDavBackend) {
|
||||||
|
$this->config = $config;
|
||||||
|
$this->time = $time;
|
||||||
|
$this->calDavBackend = $calDavBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cleanUp(): void {
|
||||||
|
$retentionTime = max(
|
||||||
|
(int) $this->config->getAppValue(
|
||||||
|
Application::APP_ID,
|
||||||
|
self::RETENTION_CONFIG_KEY,
|
||||||
|
(string) self::DEFAULT_RETENTION_SECONDS
|
||||||
|
),
|
||||||
|
0 // Just making sure we don't delete things in the future when a negative number is passed
|
||||||
|
);
|
||||||
|
$now = $this->time->getTime();
|
||||||
|
|
||||||
|
$calendars = $this->calDavBackend->getDeletedCalendars($now - $retentionTime);
|
||||||
|
foreach ($calendars as $calendar) {
|
||||||
|
$this->calDavBackend->deleteCalendar($calendar['id'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$objects = $this->calDavBackend->getDeletedCalendarObjects($now - $retentionTime);
|
||||||
|
foreach ($objects as $object) {
|
||||||
|
$this->calDavBackend->deleteCalendarObject(
|
||||||
|
$object['calendarid'],
|
||||||
|
$object['uri'],
|
||||||
|
$object['calendartype'],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV\Trashbin;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\CalDavBackend;
|
||||||
|
use OCA\DAV\CalDAV\IRestorable;
|
||||||
|
use Sabre\CalDAV\ICalendarObject;
|
||||||
|
use Sabre\DAV\Exception\Forbidden;
|
||||||
|
|
||||||
|
class DeletedCalendarObject implements ICalendarObject, IRestorable {
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/** @var mixed[] */
|
||||||
|
private $objectData;
|
||||||
|
|
||||||
|
/** @var CalDavBackend */
|
||||||
|
private $calDavBackend;
|
||||||
|
|
||||||
|
public function __construct(string $name,
|
||||||
|
array $objectData,
|
||||||
|
CalDavBackend $calDavBackend) {
|
||||||
|
$this->name = $name;
|
||||||
|
$this->objectData = $objectData;
|
||||||
|
$this->calDavBackend = $calDavBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete() {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName($name) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastModified() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function put($data) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get() {
|
||||||
|
return $this->objectData['calendardata'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContentType() {
|
||||||
|
$mime = 'text/calendar; charset=utf-8';
|
||||||
|
if (isset($this->objectData['component']) && $this->objectData['component']) {
|
||||||
|
$mime .= '; component='.$this->objectData['component'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $mime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getETag() {
|
||||||
|
return $this->objectData['etag'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSize() {
|
||||||
|
return (int) $this->objectData['size'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function restore(): void {
|
||||||
|
$this->calDavBackend->restoreCalendarObject($this->objectData);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV\Trashbin;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\CalDavBackend;
|
||||||
|
use Sabre\CalDAV\ICalendarObjectContainer;
|
||||||
|
use Sabre\DAV\Exception\BadRequest;
|
||||||
|
use Sabre\DAV\Exception\Forbidden;
|
||||||
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
use Sabre\DAV\Exception\NotImplemented;
|
||||||
|
use function array_map;
|
||||||
|
use function implode;
|
||||||
|
use function preg_match;
|
||||||
|
|
||||||
|
class DeletedCalendarObjectsCollection implements ICalendarObjectContainer {
|
||||||
|
public const NAME = 'objects';
|
||||||
|
|
||||||
|
/** @var CalDavBackend */
|
||||||
|
protected $caldavBackend;
|
||||||
|
|
||||||
|
/** @var mixed[] */
|
||||||
|
private $principalInfo;
|
||||||
|
|
||||||
|
public function __construct(CalDavBackend $caldavBackend,
|
||||||
|
array $principalInfo) {
|
||||||
|
$this->caldavBackend = $caldavBackend;
|
||||||
|
$this->principalInfo = $principalInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \OCA\DAV\CalDAV\Trashbin\DeletedCalendarObjectsCollection::calendarQuery
|
||||||
|
*/
|
||||||
|
public function getChildren() {
|
||||||
|
throw new NotImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChild($name) {
|
||||||
|
if (!preg_match("/(\d+)\\.ics/", $name, $matches)) {
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->caldavBackend->getCalendarObjectById(
|
||||||
|
$this->principalInfo['uri'],
|
||||||
|
(int) $matches[1],
|
||||||
|
);
|
||||||
|
|
||||||
|
// If the object hasn't been deleted yet then we don't want to find it here
|
||||||
|
if ($data === null) {
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
|
if (!isset($data['deleted_at'])) {
|
||||||
|
throw new BadRequest('The calendar object you\'re trying to restore is not marked as deleted');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DeletedCalendarObject(
|
||||||
|
$this->getRelativeObjectPath($data),
|
||||||
|
$data,
|
||||||
|
$this->caldavBackend
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFile($name, $data = null) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createDirectory($name) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function childExists($name) {
|
||||||
|
try {
|
||||||
|
$this->getChild($name);
|
||||||
|
} catch (NotFound $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete() {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string {
|
||||||
|
return self::NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName($name) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastModified(): int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calendarQuery(array $filters) {
|
||||||
|
return array_map(function (array $calendarInfo) {
|
||||||
|
return $this->getRelativeObjectPath($calendarInfo);
|
||||||
|
}, $this->caldavBackend->getDeletedCalendarObjectsByPrincipal($this->principalInfo['uri']));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRelativeObjectPath(array $calendarInfo): string {
|
||||||
|
return implode(
|
||||||
|
'.',
|
||||||
|
[$calendarInfo['id'], 'ics'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV\Trashbin;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\Calendar;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
use Sabre\DAV\Server;
|
||||||
|
use Sabre\DAV\ServerPlugin;
|
||||||
|
use Sabre\HTTP\RequestInterface;
|
||||||
|
use Sabre\HTTP\ResponseInterface;
|
||||||
|
use function array_slice;
|
||||||
|
use function implode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditional logic to bypass the calendar trashbin
|
||||||
|
*/
|
||||||
|
class Plugin extends ServerPlugin {
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $disableTrashbin;
|
||||||
|
|
||||||
|
/** @var Server */
|
||||||
|
private $server;
|
||||||
|
|
||||||
|
public function __construct(IRequest $request) {
|
||||||
|
$this->disableTrashbin = $request->getHeader('X-NC-CalDAV-No-Trashbin') === '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initialize(Server $server): void {
|
||||||
|
$this->server = $server;
|
||||||
|
$server->on('beforeMethod:*', [$this, 'beforeMethod']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function beforeMethod(RequestInterface $request, ResponseInterface $response): void {
|
||||||
|
if (!$this->disableTrashbin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $request->getPath();
|
||||||
|
$pathParts = explode('/', ltrim($path, '/'));
|
||||||
|
if (\count($pathParts) < 3) {
|
||||||
|
// We are looking for a path like calendars/username/calendarname
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// $calendarPath will look like calendars/username/calendarname
|
||||||
|
$calendarPath = implode(
|
||||||
|
'/',
|
||||||
|
array_slice($pathParts, 0, 3)
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
$calendar = $this->server->tree->getNodeForPath($calendarPath);
|
||||||
|
if (!($calendar instanceof Calendar)) {
|
||||||
|
// This is odd
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Calendar $calendar */
|
||||||
|
$calendar->disableTrashbin();
|
||||||
|
} catch (NotFound $ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFeatures(): array {
|
||||||
|
return ['nc-calendar-trashbin'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPluginName(): string {
|
||||||
|
return 'nc-calendar-trashbin';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV\Trashbin;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\IRestorable;
|
||||||
|
use Sabre\DAV\Exception\Forbidden;
|
||||||
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
use Sabre\DAV\ICollection;
|
||||||
|
use Sabre\DAV\IMoveTarget;
|
||||||
|
use Sabre\DAV\INode;
|
||||||
|
|
||||||
|
class RestoreTarget implements ICollection, IMoveTarget {
|
||||||
|
public const NAME = 'restore';
|
||||||
|
|
||||||
|
public function createFile($name, $data = null) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createDirectory($name) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChild($name) {
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChildren(): array {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function childExists($name): bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function moveInto($targetName, $sourcePath, INode $sourceNode): bool {
|
||||||
|
if ($sourceNode instanceof IRestorable) {
|
||||||
|
$sourceNode->restore();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete() {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string {
|
||||||
|
return 'restore';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName($name) {
|
||||||
|
throw new Forbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastModified() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\CalDAV\Trashbin;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\CalDavBackend;
|
||||||
|
use Sabre\DAV\Exception\Forbidden;
|
||||||
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
use Sabre\DAV\ICollection;
|
||||||
|
use Sabre\DAV\INode;
|
||||||
|
use Sabre\DAV\IProperties;
|
||||||
|
use Sabre\DAV\PropPatch;
|
||||||
|
use Sabre\DAV\Xml\Property\ResourceType;
|
||||||
|
use Sabre\DAVACL\ACLTrait;
|
||||||
|
use Sabre\DAVACL\IACL;
|
||||||
|
use function in_array;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
class TrashbinHome implements IACL, ICollection, IProperties {
|
||||||
|
use ACLTrait;
|
||||||
|
|
||||||
|
public const NAME = 'trashbin';
|
||||||
|
|
||||||
|
/** @var CalDavBackend */
|
||||||
|
private $caldavBackend;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $principalInfo;
|
||||||
|
|
||||||
|
public function __construct(CalDavBackend $caldavBackend,
|
||||||
|
array $principalInfo) {
|
||||||
|
$this->caldavBackend = $caldavBackend;
|
||||||
|
$this->principalInfo = $principalInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOwner(): string {
|
||||||
|
return $this->principalInfo['uri'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFile($name, $data = null) {
|
||||||
|
throw new Forbidden('Permission denied to create files in the trashbin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createDirectory($name) {
|
||||||
|
throw new Forbidden('Permission denied to create a directory in the trashbin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChild($name): INode {
|
||||||
|
switch ($name) {
|
||||||
|
case RestoreTarget::NAME:
|
||||||
|
return new RestoreTarget();
|
||||||
|
case DeletedCalendarObjectsCollection::NAME:
|
||||||
|
return new DeletedCalendarObjectsCollection(
|
||||||
|
$this->caldavBackend,
|
||||||
|
$this->principalInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChildren(): array {
|
||||||
|
return [
|
||||||
|
new RestoreTarget(),
|
||||||
|
new DeletedCalendarObjectsCollection(
|
||||||
|
$this->caldavBackend,
|
||||||
|
$this->principalInfo
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function childExists($name): bool {
|
||||||
|
return in_array($name, [
|
||||||
|
RestoreTarget::NAME,
|
||||||
|
DeletedCalendarObjectsCollection::NAME,
|
||||||
|
], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete() {
|
||||||
|
throw new Forbidden('Permission denied to delete the trashbin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string {
|
||||||
|
return self::NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName($name) {
|
||||||
|
throw new Forbidden('Permission denied to rename the trashbin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastModified(): int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function propPatch(PropPatch $propPatch): void {
|
||||||
|
throw new Forbidden('not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProperties($properties): array {
|
||||||
|
return [
|
||||||
|
'{DAV:}resourcetype' => new ResourceType([
|
||||||
|
'{DAV:}collection',
|
||||||
|
sprintf('{%s}trash-bin', \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD),
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
||||||
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
|
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
|
||||||
use OCA\DAV\Connector\Sabre\Principal;
|
use OCA\DAV\Connector\Sabre\Principal;
|
||||||
use OCP\EventDispatcher\IEventDispatcher;
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
|
use OCP\IConfig;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
use OCP\IGroupManager;
|
use OCP\IGroupManager;
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
|
@ -94,9 +95,20 @@ class CreateCalendar extends Command {
|
||||||
$logger = \OC::$server->getLogger();
|
$logger = \OC::$server->getLogger();
|
||||||
$dispatcher = \OC::$server->get(IEventDispatcher::class);
|
$dispatcher = \OC::$server->get(IEventDispatcher::class);
|
||||||
$legacyDispatcher = \OC::$server->getEventDispatcher();
|
$legacyDispatcher = \OC::$server->getEventDispatcher();
|
||||||
|
$config = \OC::$server->get(IConfig::class);
|
||||||
|
|
||||||
$name = $input->getArgument('name');
|
$name = $input->getArgument('name');
|
||||||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $this->groupManager, $random, $logger, $dispatcher, $legacyDispatcher);
|
$caldav = new CalDavBackend(
|
||||||
|
$this->dbConnection,
|
||||||
|
$principalBackend,
|
||||||
|
$this->userManager,
|
||||||
|
$this->groupManager,
|
||||||
|
$random,
|
||||||
|
$logger,
|
||||||
|
$dispatcher,
|
||||||
|
$legacyDispatcher,
|
||||||
|
$config
|
||||||
|
);
|
||||||
$caldav->createCalendar("principals/users/$user", $name, []);
|
$caldav->createCalendar("principals/users/$user", $name, []);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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\Command;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\RetentionService;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class RetentionCleanupCommand extends Command {
|
||||||
|
/** @var RetentionService */
|
||||||
|
private $service;
|
||||||
|
|
||||||
|
public function __construct(RetentionService $service) {
|
||||||
|
parent::__construct('dav:retention:clean-up');
|
||||||
|
|
||||||
|
$this->service = $service;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||||
|
$this->service->cleanUp();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
class CalendarMovedToTrashEvent extends Event {
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $calendarId;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $calendarData;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $shares;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $calendarId
|
||||||
|
* @param array $calendarData
|
||||||
|
* @param array $shares
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function __construct(int $calendarId,
|
||||||
|
array $calendarData,
|
||||||
|
array $shares) {
|
||||||
|
parent::__construct();
|
||||||
|
$this->calendarId = $calendarId;
|
||||||
|
$this->calendarData = $calendarData;
|
||||||
|
$this->shares = $shares;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarId(): int {
|
||||||
|
return $this->calendarId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarData(): array {
|
||||||
|
return $this->calendarData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getShares(): array {
|
||||||
|
return $this->shares;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
class CalendarObjectMovedToTrashEvent extends Event {
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $calendarId;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $calendarData;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $shares;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $objectData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $calendarId
|
||||||
|
* @param array $calendarData
|
||||||
|
* @param array $shares
|
||||||
|
* @param array $objectData
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function __construct(int $calendarId,
|
||||||
|
array $calendarData,
|
||||||
|
array $shares,
|
||||||
|
array $objectData) {
|
||||||
|
parent::__construct();
|
||||||
|
$this->calendarId = $calendarId;
|
||||||
|
$this->calendarData = $calendarData;
|
||||||
|
$this->shares = $shares;
|
||||||
|
$this->objectData = $objectData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarId(): int {
|
||||||
|
return $this->calendarId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarData(): array {
|
||||||
|
return $this->calendarData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getShares(): array {
|
||||||
|
return $this->shares;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getObjectData(): array {
|
||||||
|
return $this->objectData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
class CalendarObjectRestoredEvent extends Event {
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $calendarId;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $calendarData;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $shares;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $objectData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $calendarId
|
||||||
|
* @param array $calendarData
|
||||||
|
* @param array $shares
|
||||||
|
* @param array $objectData
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function __construct(int $calendarId,
|
||||||
|
array $calendarData,
|
||||||
|
array $shares,
|
||||||
|
array $objectData) {
|
||||||
|
parent::__construct();
|
||||||
|
$this->calendarId = $calendarId;
|
||||||
|
$this->calendarData = $calendarData;
|
||||||
|
$this->shares = $shares;
|
||||||
|
$this->objectData = $objectData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarId(): int {
|
||||||
|
return $this->calendarId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarData(): array {
|
||||||
|
return $this->calendarData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getShares(): array {
|
||||||
|
return $this->shares;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getObjectData(): array {
|
||||||
|
return $this->objectData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
class CalendarRestoredEvent extends Event {
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $calendarId;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $calendarData;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $shares;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $calendarId
|
||||||
|
* @param array $calendarData
|
||||||
|
* @param array $shares
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function __construct(int $calendarId,
|
||||||
|
array $calendarData,
|
||||||
|
array $shares) {
|
||||||
|
parent::__construct();
|
||||||
|
$this->calendarId = $calendarId;
|
||||||
|
$this->calendarData = $calendarData;
|
||||||
|
$this->shares = $shares;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarId(): int {
|
||||||
|
return $this->calendarId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getCalendarData(): array {
|
||||||
|
return $this->calendarData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @since 22.0.0
|
||||||
|
*/
|
||||||
|
public function getShares(): array {
|
||||||
|
return $this->shares;
|
||||||
|
}
|
||||||
|
}
|
|
@ -128,7 +128,10 @@ class HookManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->calendarsToDelete as $calendar) {
|
foreach ($this->calendarsToDelete as $calendar) {
|
||||||
$this->calDav->deleteCalendar($calendar['id']);
|
$this->calDav->deleteCalendar(
|
||||||
|
$calendar['id'],
|
||||||
|
true // Make sure the data doesn't go into the trashbin, a new user with the same UID would later see it otherwise
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$this->calDav->deleteAllSharesByUser('principals/users/' . $uid);
|
$this->calDav->deleteAllSharesByUser('principals/users/' . $uid);
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,16 @@ declare(strict_types=1);
|
||||||
namespace OCA\DAV\Listener;
|
namespace OCA\DAV\Listener;
|
||||||
|
|
||||||
use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend;
|
use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend;
|
||||||
|
use OCA\DAV\DAV\Sharing\Plugin;
|
||||||
use OCA\DAV\Events\CalendarCreatedEvent;
|
use OCA\DAV\Events\CalendarCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarDeletedEvent;
|
use OCA\DAV\Events\CalendarDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarMovedToTrashEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarUpdatedEvent;
|
use OCA\DAV\Events\CalendarUpdatedEvent;
|
||||||
use OCP\EventDispatcher\Event;
|
use OCP\EventDispatcher\Event;
|
||||||
use OCP\EventDispatcher\IEventListener;
|
use OCP\EventDispatcher\IEventListener;
|
||||||
|
@ -85,16 +90,55 @@ class ActivityUpdaterListener implements IEventListener {
|
||||||
'exception' => $e,
|
'exception' => $e,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} elseif ($event instanceof CalendarDeletedEvent) {
|
} elseif ($event instanceof CalendarMovedToTrashEvent) {
|
||||||
try {
|
try {
|
||||||
$this->activityBackend->onCalendarDelete(
|
$this->activityBackend->onCalendarMovedToTrash(
|
||||||
$event->getCalendarData(),
|
$event->getCalendarData(),
|
||||||
$event->getShares()
|
$event->getShares()
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
sprintf('Activity generated for deleted calendar %d', $event->getCalendarId())
|
sprintf('Activity generated for changed calendar %d', $event->getCalendarId())
|
||||||
);
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with activities shouldn't abort the calendar update, so we just log it
|
||||||
|
$this->logger->error('Error generating activities for changed calendar: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} elseif ($event instanceof CalendarRestoredEvent) {
|
||||||
|
try {
|
||||||
|
$this->activityBackend->onCalendarRestored(
|
||||||
|
$event->getCalendarData(),
|
||||||
|
$event->getShares()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Activity generated for changed calendar %d', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with activities shouldn't abort the calendar update, so we just log it
|
||||||
|
$this->logger->error('Error generating activities for changed calendar: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} elseif ($event instanceof CalendarDeletedEvent) {
|
||||||
|
try {
|
||||||
|
$deletedProp = '{' . Plugin::NS_NEXTCLOUD . '}deleted-at';
|
||||||
|
if (isset($event->getCalendarData()[$deletedProp])) {
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Calendar %d was already in trashbin, skipping deletion activity', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->activityBackend->onCalendarDelete(
|
||||||
|
$event->getCalendarData(),
|
||||||
|
$event->getShares()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Activity generated for deleted calendar %d', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// Any error with activities shouldn't abort the calendar deletion, so we just log it
|
// Any error with activities shouldn't abort the calendar deletion, so we just log it
|
||||||
$this->logger->error('Error generating activities for a deleted calendar: ' . $e->getMessage(), [
|
$this->logger->error('Error generating activities for a deleted calendar: ' . $e->getMessage(), [
|
||||||
|
@ -137,18 +181,61 @@ class ActivityUpdaterListener implements IEventListener {
|
||||||
'exception' => $e,
|
'exception' => $e,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} elseif ($event instanceof CalendarObjectDeletedEvent) {
|
} elseif ($event instanceof CalendarObjectMovedToTrashEvent) {
|
||||||
try {
|
try {
|
||||||
$this->activityBackend->onTouchCalendarObject(
|
$this->activityBackend->onTouchCalendarObject(
|
||||||
\OCA\DAV\CalDAV\Activity\Provider\Event::SUBJECT_OBJECT_DELETE,
|
\OCA\DAV\CalDAV\Activity\Provider\Event::SUBJECT_OBJECT_MOVE_TO_TRASH,
|
||||||
$event->getCalendarData(),
|
$event->getCalendarData(),
|
||||||
$event->getShares(),
|
$event->getShares(),
|
||||||
$event->getObjectData()
|
$event->getObjectData()
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
sprintf('Activity generated for deleted calendar object %d', $event->getCalendarId())
|
sprintf('Activity generated for a calendar object of calendar %d that is moved to trash', $event->getCalendarId())
|
||||||
);
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with activities shouldn't abort the calendar object creation, so we just log it
|
||||||
|
$this->logger->error('Error generating activity for a new calendar object: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} elseif ($event instanceof CalendarObjectRestoredEvent) {
|
||||||
|
try {
|
||||||
|
$this->activityBackend->onTouchCalendarObject(
|
||||||
|
\OCA\DAV\CalDAV\Activity\Provider\Event::SUBJECT_OBJECT_RESTORE,
|
||||||
|
$event->getCalendarData(),
|
||||||
|
$event->getShares(),
|
||||||
|
$event->getObjectData()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Activity generated for a restore calendar object of calendar %d', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with activities shouldn't abort the calendar object restoration, so we just log it
|
||||||
|
$this->logger->error('Error generating activity for a restored calendar object: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} elseif ($event instanceof CalendarObjectDeletedEvent) {
|
||||||
|
try {
|
||||||
|
$deletedProp = '{' . Plugin::NS_NEXTCLOUD . '}deleted-at';
|
||||||
|
if (isset($event->getObjectData()[$deletedProp])) {
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Calendar object in calendar %d was already in trashbin, skipping deletion activity', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->activityBackend->onTouchCalendarObject(
|
||||||
|
\OCA\DAV\CalDAV\Activity\Provider\Event::SUBJECT_OBJECT_DELETE,
|
||||||
|
$event->getCalendarData(),
|
||||||
|
$event->getShares(),
|
||||||
|
$event->getObjectData()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Activity generated for deleted calendar object in calendar %d', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// Any error with activities shouldn't abort the calendar deletion, so we just log it
|
// 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(), [
|
$this->logger->error('Error generating activity for a deleted calendar object: ' . $e->getMessage(), [
|
||||||
|
|
|
@ -25,12 +25,17 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\DAV\Listener;
|
namespace OCA\DAV\Listener;
|
||||||
|
|
||||||
|
use OCA\DAV\CalDAV\CalDavBackend;
|
||||||
use OCA\DAV\CalDAV\Reminder\Backend as ReminderBackend;
|
use OCA\DAV\CalDAV\Reminder\Backend as ReminderBackend;
|
||||||
use OCA\DAV\CalDAV\Reminder\ReminderService;
|
use OCA\DAV\CalDAV\Reminder\ReminderService;
|
||||||
use OCA\DAV\Events\CalendarDeletedEvent;
|
use OCA\DAV\Events\CalendarDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarMovedToTrashEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
use OCA\DAV\Events\CalendarObjectDeletedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectMovedToTrashEvent;
|
||||||
|
use OCA\DAV\Events\CalendarObjectRestoredEvent;
|
||||||
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
||||||
|
use OCA\DAV\Events\CalendarRestoredEvent;
|
||||||
use OCP\EventDispatcher\Event;
|
use OCP\EventDispatcher\Event;
|
||||||
use OCP\EventDispatcher\IEventListener;
|
use OCP\EventDispatcher\IEventListener;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
@ -45,19 +50,39 @@ class CalendarObjectReminderUpdaterListener implements IEventListener {
|
||||||
/** @var ReminderService */
|
/** @var ReminderService */
|
||||||
private $reminderService;
|
private $reminderService;
|
||||||
|
|
||||||
|
/** @var CalDavBackend */
|
||||||
|
private $calDavBackend;
|
||||||
|
|
||||||
/** @var LoggerInterface */
|
/** @var LoggerInterface */
|
||||||
private $logger;
|
private $logger;
|
||||||
|
|
||||||
public function __construct(ReminderBackend $reminderBackend,
|
public function __construct(ReminderBackend $reminderBackend,
|
||||||
ReminderService $reminderService,
|
ReminderService $reminderService,
|
||||||
|
CalDavBackend $calDavBackend,
|
||||||
LoggerInterface $logger) {
|
LoggerInterface $logger) {
|
||||||
$this->reminderBackend = $reminderBackend;
|
$this->reminderBackend = $reminderBackend;
|
||||||
$this->reminderService = $reminderService;
|
$this->reminderService = $reminderService;
|
||||||
|
$this->calDavBackend = $calDavBackend;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(Event $event): void {
|
public function handle(Event $event): void {
|
||||||
if ($event instanceof CalendarDeletedEvent) {
|
if ($event instanceof CalendarMovedToTrashEvent) {
|
||||||
|
try {
|
||||||
|
$this->reminderBackend->cleanRemindersForCalendar(
|
||||||
|
$event->getCalendarId()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Reminders of calendar %d cleaned up after move into trashbin', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with reminders shouldn't abort the calendar move, so we just log it
|
||||||
|
$this->logger->error('Error cleaning up reminders of a calendar moved into trashbin: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} elseif ($event instanceof CalendarDeletedEvent) {
|
||||||
try {
|
try {
|
||||||
$this->reminderBackend->cleanRemindersForCalendar(
|
$this->reminderBackend->cleanRemindersForCalendar(
|
||||||
$event->getCalendarId()
|
$event->getCalendarId()
|
||||||
|
@ -72,6 +97,27 @@ class CalendarObjectReminderUpdaterListener implements IEventListener {
|
||||||
'exception' => $e,
|
'exception' => $e,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
} elseif ($event instanceof CalendarRestoredEvent) {
|
||||||
|
try {
|
||||||
|
$objects = $this->calDavBackend->getCalendarObjects($event->getCalendarId());
|
||||||
|
$this->logger->debug(sprintf('Restoring calendar reminder objects for %d items', count($objects)));
|
||||||
|
foreach ($objects as $object) {
|
||||||
|
$fullObject = $this->calDavBackend->getCalendarObject(
|
||||||
|
$event->getCalendarId(),
|
||||||
|
$object['uri']
|
||||||
|
);
|
||||||
|
$this->reminderService->onCalendarObjectCreate($fullObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Reminders of calendar %d restored', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with reminders shouldn't abort the calendar deletion, so we just log it
|
||||||
|
$this->logger->error('Error restoring reminders of a calendar: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
} elseif ($event instanceof CalendarObjectCreatedEvent) {
|
} elseif ($event instanceof CalendarObjectCreatedEvent) {
|
||||||
try {
|
try {
|
||||||
$this->reminderService->onCalendarObjectCreate(
|
$this->reminderService->onCalendarObjectCreate(
|
||||||
|
@ -102,6 +148,36 @@ class CalendarObjectReminderUpdaterListener implements IEventListener {
|
||||||
'exception' => $e,
|
'exception' => $e,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
} elseif ($event instanceof CalendarObjectMovedToTrashEvent) {
|
||||||
|
try {
|
||||||
|
$this->reminderService->onCalendarObjectDelete(
|
||||||
|
$event->getObjectData()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Reminders of restored calendar object of calendar %d deleted', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with reminders shouldn't abort the calendar object deletion, so we just log it
|
||||||
|
$this->logger->error('Error deleting reminders of a calendar object: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} elseif ($event instanceof CalendarObjectRestoredEvent) {
|
||||||
|
try {
|
||||||
|
$this->reminderService->onCalendarObjectCreate(
|
||||||
|
$event->getObjectData()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger->debug(
|
||||||
|
sprintf('Reminders of restored calendar object of calendar %d restored', $event->getCalendarId())
|
||||||
|
);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Any error with reminders shouldn't abort the calendar object deletion, so we just log it
|
||||||
|
$this->logger->error('Error restoring reminders of a calendar object: ' . $e->getMessage(), [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
} elseif ($event instanceof CalendarObjectDeletedEvent) {
|
} elseif ($event instanceof CalendarObjectDeletedEvent) {
|
||||||
try {
|
try {
|
||||||
$this->reminderService->onCalendarObjectDelete(
|
$this->reminderService->onCalendarObjectDelete(
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\DAV\Migration;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\DB\Types;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
|
class Version1018Date20210312100735 extends SimpleMigrationStep {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
* @return ISchemaWrapper
|
||||||
|
*/
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||||
|
/** @var ISchemaWrapper $schema */
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
$calendarsTable = $schema->getTable('calendars');
|
||||||
|
$calendarsTable->addColumn('deleted_at', Types::INTEGER, [
|
||||||
|
'notnull' => false,
|
||||||
|
'length' => 4,
|
||||||
|
'unsigned' => true,
|
||||||
|
]);
|
||||||
|
$calendarsTable->addIndex([
|
||||||
|
'principaluri',
|
||||||
|
'deleted_at',
|
||||||
|
], 'cals_princ_del_idx');
|
||||||
|
|
||||||
|
$calendarObjectsTable = $schema->getTable('calendarobjects');
|
||||||
|
$calendarObjectsTable->addColumn('deleted_at', Types::INTEGER, [
|
||||||
|
'notnull' => false,
|
||||||
|
'length' => 4,
|
||||||
|
'unsigned' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,6 +47,7 @@ use OCA\DAV\Upload\CleanupService;
|
||||||
use OCP\App\IAppManager;
|
use OCP\App\IAppManager;
|
||||||
use OCP\AppFramework\Utility\ITimeFactory;
|
use OCP\AppFramework\Utility\ITimeFactory;
|
||||||
use OCP\EventDispatcher\IEventDispatcher;
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
|
use OCP\IConfig;
|
||||||
use Sabre\DAV\SimpleCollection;
|
use Sabre\DAV\SimpleCollection;
|
||||||
|
|
||||||
class RootCollection extends SimpleCollection {
|
class RootCollection extends SimpleCollection {
|
||||||
|
@ -62,6 +63,7 @@ class RootCollection extends SimpleCollection {
|
||||||
$db = \OC::$server->getDatabaseConnection();
|
$db = \OC::$server->getDatabaseConnection();
|
||||||
$dispatcher = \OC::$server->get(IEventDispatcher::class);
|
$dispatcher = \OC::$server->get(IEventDispatcher::class);
|
||||||
$legacyDispatcher = \OC::$server->getEventDispatcher();
|
$legacyDispatcher = \OC::$server->getEventDispatcher();
|
||||||
|
$config = \OC::$server->get(IConfig::class);
|
||||||
$proxyMapper = \OC::$server->query(ProxyMapper::class);
|
$proxyMapper = \OC::$server->query(ProxyMapper::class);
|
||||||
|
|
||||||
$userPrincipalBackend = new Principal(
|
$userPrincipalBackend = new Principal(
|
||||||
|
@ -95,15 +97,23 @@ class RootCollection extends SimpleCollection {
|
||||||
|
|
||||||
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users');
|
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users');
|
||||||
$filesCollection->disableListing = $disableListing;
|
$filesCollection->disableListing = $disableListing;
|
||||||
$caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $random, $logger, $dispatcher, $legacyDispatcher);
|
$caldavBackend = new CalDavBackend(
|
||||||
|
$db,
|
||||||
|
$userPrincipalBackend,
|
||||||
|
$userManager,
|
||||||
|
$groupManager,
|
||||||
|
$random,
|
||||||
|
$logger,
|
||||||
|
$dispatcher,
|
||||||
|
$legacyDispatcher,
|
||||||
|
$config
|
||||||
|
);
|
||||||
$userCalendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users');
|
$userCalendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users');
|
||||||
$userCalendarRoot->disableListing = $disableListing;
|
$userCalendarRoot->disableListing = $disableListing;
|
||||||
|
|
||||||
$resourceCalendarCaldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $random, $logger, $dispatcher, $legacyDispatcher);
|
|
||||||
$resourceCalendarRoot = new CalendarRoot($calendarResourcePrincipalBackend, $caldavBackend, 'principals/calendar-resources');
|
$resourceCalendarRoot = new CalendarRoot($calendarResourcePrincipalBackend, $caldavBackend, 'principals/calendar-resources');
|
||||||
$resourceCalendarRoot->disableListing = $disableListing;
|
$resourceCalendarRoot->disableListing = $disableListing;
|
||||||
$roomCalendarCaldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $random, $logger, $dispatcher, $legacyDispatcher);
|
$roomCalendarRoot = new CalendarRoot($calendarRoomPrincipalBackend, $caldavBackend, 'principals/calendar-rooms');
|
||||||
$roomCalendarRoot = new CalendarRoot($calendarRoomPrincipalBackend, $roomCalendarCaldavBackend, 'principals/calendar-rooms');
|
|
||||||
$roomCalendarRoot->disableListing = $disableListing;
|
$roomCalendarRoot->disableListing = $disableListing;
|
||||||
|
|
||||||
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend, $l10n, $config);
|
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend, $l10n, $config);
|
||||||
|
|
|
@ -165,7 +165,8 @@ class Server {
|
||||||
$this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
|
$this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->server->addPlugin(new CalDAV\WebcalCaching\Plugin($request));
|
$this->server->addPlugin(new \OCA\DAV\CalDAV\Trashbin\Plugin($request));
|
||||||
|
$this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($request));
|
||||||
$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
|
$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
|
||||||
|
|
||||||
$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
|
$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
|
||||||
|
|
|
@ -115,20 +115,20 @@ class SystemTagsObjectMappingCollection implements ICollection {
|
||||||
throw new Forbidden('Permission denied to create collections');
|
throw new Forbidden('Permission denied to create collections');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChild($tagId) {
|
public function getChild($tagName) {
|
||||||
try {
|
try {
|
||||||
if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)) {
|
if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagName, true)) {
|
||||||
$tag = $this->tagManager->getTagsByIds([$tagId]);
|
$tag = $this->tagManager->getTagsByIds([$tagName]);
|
||||||
$tag = current($tag);
|
$tag = current($tag);
|
||||||
if ($this->tagManager->canUserSeeTag($tag, $this->user)) {
|
if ($this->tagManager->canUserSeeTag($tag, $this->user)) {
|
||||||
return $this->makeNode($tag);
|
return $this->makeNode($tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NotFound('Tag with id ' . $tagId . ' not present for object ' . $this->objectId);
|
throw new NotFound('Tag with id ' . $tagName . ' not present for object ' . $this->objectId);
|
||||||
} catch (\InvalidArgumentException $e) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
throw new BadRequest('Invalid tag id', 0, $e);
|
throw new BadRequest('Invalid tag id', 0, $e);
|
||||||
} catch (TagNotFoundException $e) {
|
} catch (TagNotFoundException $e) {
|
||||||
throw new NotFound('Tag with id ' . $tagId . ' not found', 0, $e);
|
throw new NotFound('Tag with id ' . $tagName . ' not found', 0, $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,17 +115,18 @@ class SystemTagsObjectTypeCollection implements ICollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $objectId
|
* @param string $objectName
|
||||||
|
*
|
||||||
* @return SystemTagsObjectMappingCollection
|
* @return SystemTagsObjectMappingCollection
|
||||||
* @throws NotFound
|
* @throws NotFound
|
||||||
*/
|
*/
|
||||||
public function getChild($objectId) {
|
public function getChild($objectName) {
|
||||||
// make sure the object exists and is reachable
|
// make sure the object exists and is reachable
|
||||||
if (!$this->childExists($objectId)) {
|
if (!$this->childExists($objectName)) {
|
||||||
throw new NotFound('Entity does not exist or is not available');
|
throw new NotFound('Entity does not exist or is not available');
|
||||||
}
|
}
|
||||||
return new SystemTagsObjectMappingCollection(
|
return new SystemTagsObjectMappingCollection(
|
||||||
$objectId,
|
$objectName,
|
||||||
$this->objectType,
|
$this->objectType,
|
||||||
$this->userSession->getUser(),
|
$this->userSession->getUser(),
|
||||||
$this->tagManager,
|
$this->tagManager,
|
||||||
|
|
|
@ -11,8 +11,12 @@ if [ ! -f pycalendar/setup.py ]; then
|
||||||
git clone https://github.com/apple/ccs-pycalendar.git pycalendar
|
git clone https://github.com/apple/ccs-pycalendar.git pycalendar
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# create test user
|
|
||||||
cd "$SCRIPTPATH/../../../../../"
|
cd "$SCRIPTPATH/../../../../../"
|
||||||
|
|
||||||
|
# disable the trashbin, so recurrent deletion of the same object works
|
||||||
|
php occ config:app:set dav calendarRetentionObligation --value=0
|
||||||
|
|
||||||
|
# create test user
|
||||||
OC_PASS=user01 php occ user:add --password-from-env user01
|
OC_PASS=user01 php occ user:add --password-from-env user01
|
||||||
php occ dav:create-calendar user01 calendar
|
php occ dav:create-calendar user01 calendar
|
||||||
php occ dav:create-calendar user01 shared
|
php occ dav:create-calendar user01 shared
|
||||||
|
|
|
@ -113,7 +113,18 @@ abstract class AbstractCalDavBackend extends TestCase {
|
||||||
$db = \OC::$server->getDatabaseConnection();
|
$db = \OC::$server->getDatabaseConnection();
|
||||||
$this->random = \OC::$server->getSecureRandom();
|
$this->random = \OC::$server->getSecureRandom();
|
||||||
$this->logger = $this->createMock(ILogger::class);
|
$this->logger = $this->createMock(ILogger::class);
|
||||||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->groupManager, $this->random, $this->logger, $this->dispatcher, $this->legacyDispatcher);
|
$this->config = $this->createMock(IConfig::class);
|
||||||
|
$this->backend = new CalDavBackend(
|
||||||
|
$db,
|
||||||
|
$this->principal,
|
||||||
|
$this->userManager,
|
||||||
|
$this->groupManager,
|
||||||
|
$this->random,
|
||||||
|
$this->logger,
|
||||||
|
$this->dispatcher,
|
||||||
|
$this->legacyDispatcher,
|
||||||
|
$this->config
|
||||||
|
);
|
||||||
|
|
||||||
$this->cleanUpBackend();
|
$this->cleanUpBackend();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +153,7 @@ abstract class AbstractCalDavBackend extends TestCase {
|
||||||
return $event instanceof CalendarDeletedEvent;
|
return $event instanceof CalendarDeletedEvent;
|
||||||
}));
|
}));
|
||||||
foreach ($calendars as $calendar) {
|
foreach ($calendars as $calendar) {
|
||||||
$this->backend->deleteCalendar($calendar['id']);
|
$this->backend->deleteCalendar($calendar['id'], true);
|
||||||
}
|
}
|
||||||
$subscriptions = $this->backend->getSubscriptionsForUser($principal);
|
$subscriptions = $this->backend->getSubscriptionsForUser($principal);
|
||||||
foreach ($subscriptions as $subscription) {
|
foreach ($subscriptions as $subscription) {
|
||||||
|
|
|
@ -83,7 +83,7 @@ class CalDavBackendTest extends AbstractCalDavBackend {
|
||||||
->with(self::callback(function ($event) {
|
->with(self::callback(function ($event) {
|
||||||
return $event instanceof CalendarDeletedEvent;
|
return $event instanceof CalendarDeletedEvent;
|
||||||
}));
|
}));
|
||||||
$this->backend->deleteCalendar($calendars[0]['id']);
|
$this->backend->deleteCalendar($calendars[0]['id'], true);
|
||||||
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||||
self::assertEmpty($calendars);
|
self::assertEmpty($calendars);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ EOD;
|
||||||
->with(self::callback(function ($event) {
|
->with(self::callback(function ($event) {
|
||||||
return $event instanceof CalendarDeletedEvent;
|
return $event instanceof CalendarDeletedEvent;
|
||||||
}));
|
}));
|
||||||
$this->backend->deleteCalendar($calendars[0]['id']);
|
$this->backend->deleteCalendar($calendars[0]['id'], true);
|
||||||
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||||
self::assertEmpty($calendars);
|
self::assertEmpty($calendars);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ use OCA\DAV\CalDAV\CalendarHome;
|
||||||
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
|
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
|
||||||
use OCA\DAV\CalDAV\Integration\ICalendarProvider;
|
use OCA\DAV\CalDAV\Integration\ICalendarProvider;
|
||||||
use OCA\DAV\CalDAV\Outbox;
|
use OCA\DAV\CalDAV\Outbox;
|
||||||
|
use OCA\DAV\CalDAV\Trashbin\TrashbinHome;
|
||||||
use Sabre\CalDAV\Schedule\Inbox;
|
use Sabre\CalDAV\Schedule\Inbox;
|
||||||
use Sabre\DAV\MkCol;
|
use Sabre\DAV\MkCol;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
|
@ -141,13 +142,14 @@ class CalendarHomeTest extends TestCase {
|
||||||
|
|
||||||
$actual = $this->calendarHome->getChildren();
|
$actual = $this->calendarHome->getChildren();
|
||||||
|
|
||||||
$this->assertCount(6, $actual);
|
$this->assertCount(7, $actual);
|
||||||
$this->assertInstanceOf(Inbox::class, $actual[0]);
|
$this->assertInstanceOf(Inbox::class, $actual[0]);
|
||||||
$this->assertInstanceOf(Outbox::class, $actual[1]);
|
$this->assertInstanceOf(Outbox::class, $actual[1]);
|
||||||
$this->assertEquals('plugin1calendar1', $actual[2]);
|
$this->assertInstanceOf(TrashbinHome::class, $actual[2]);
|
||||||
$this->assertEquals('plugin1calendar2', $actual[3]);
|
$this->assertEquals('plugin1calendar1', $actual[3]);
|
||||||
$this->assertEquals('plugin2calendar1', $actual[4]);
|
$this->assertEquals('plugin1calendar2', $actual[4]);
|
||||||
$this->assertEquals('plugin2calendar2', $actual[5]);
|
$this->assertEquals('plugin2calendar1', $actual[5]);
|
||||||
|
$this->assertEquals('plugin2calendar2', $actual[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetChildNonAppGenerated():void {
|
public function testGetChildNonAppGenerated():void {
|
||||||
|
|
|
@ -86,6 +86,7 @@ class PublicCalendarRootTest extends TestCase {
|
||||||
$this->logger = $this->createMock(ILogger::class);
|
$this->logger = $this->createMock(ILogger::class);
|
||||||
$dispatcher = $this->createMock(IEventDispatcher::class);
|
$dispatcher = $this->createMock(IEventDispatcher::class);
|
||||||
$legacyDispatcher = $this->createMock(EventDispatcherInterface::class);
|
$legacyDispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||||
|
$config = $this->createMock(IConfig::class);
|
||||||
|
|
||||||
$this->principal->expects($this->any())->method('getGroupMembership')
|
$this->principal->expects($this->any())->method('getGroupMembership')
|
||||||
->withAnyParameters()
|
->withAnyParameters()
|
||||||
|
@ -103,7 +104,8 @@ class PublicCalendarRootTest extends TestCase {
|
||||||
$this->random,
|
$this->random,
|
||||||
$this->logger,
|
$this->logger,
|
||||||
$dispatcher,
|
$dispatcher,
|
||||||
$legacyDispatcher
|
$legacyDispatcher,
|
||||||
|
$config
|
||||||
);
|
);
|
||||||
$this->l10n = $this->getMockBuilder(IL10N::class)
|
$this->l10n = $this->getMockBuilder(IL10N::class)
|
||||||
->disableOriginalConstructor()->getMock();
|
->disableOriginalConstructor()->getMock();
|
||||||
|
@ -129,7 +131,7 @@ class PublicCalendarRootTest extends TestCase {
|
||||||
|
|
||||||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||||
foreach ($books as $book) {
|
foreach ($books as $book) {
|
||||||
$this->backend->deleteCalendar($book['id']);
|
$this->backend->deleteCalendar($book['id'], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,9 @@ class CalDavContext implements \Behat\Behat\Context\Context {
|
||||||
'admin',
|
'admin',
|
||||||
'admin',
|
'admin',
|
||||||
],
|
],
|
||||||
|
'headers' => [
|
||||||
|
'X-NC-CalDAV-No-Trashbin' => '1',
|
||||||
|
]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||||
|
|
|
@ -163,11 +163,14 @@
|
||||||
<file src="apps/dav/lib/CalDAV/CalDavBackend.php">
|
<file src="apps/dav/lib/CalDAV/CalDavBackend.php">
|
||||||
<InvalidArgument occurrences="8">
|
<InvalidArgument occurrences="8">
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject'</code>
|
||||||
|
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::createSubscription'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::createSubscription'</code>
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject'</code>
|
||||||
|
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription'</code>
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::publishCalendar'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::publishCalendar'</code>
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject'</code>
|
||||||
|
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::updateShares'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::updateShares'</code>
|
||||||
<code>'\OCA\DAV\CalDAV\CalDavBackend::updateSubscription'</code>
|
<code>'\OCA\DAV\CalDAV\CalDavBackend::updateSubscription'</code>
|
||||||
</InvalidArgument>
|
</InvalidArgument>
|
||||||
|
@ -186,7 +189,7 @@
|
||||||
<RedundantCast occurrences="1">
|
<RedundantCast occurrences="1">
|
||||||
<code>(int)$calendarId</code>
|
<code>(int)$calendarId</code>
|
||||||
</RedundantCast>
|
</RedundantCast>
|
||||||
<TooManyArguments occurrences="9">
|
<TooManyArguments occurrences="13">
|
||||||
<code>dispatch</code>
|
<code>dispatch</code>
|
||||||
<code>dispatch</code>
|
<code>dispatch</code>
|
||||||
<code>dispatch</code>
|
<code>dispatch</code>
|
||||||
|
@ -200,7 +203,7 @@
|
||||||
<code>dispatch</code>
|
<code>dispatch</code>
|
||||||
<code>dispatch</code>
|
<code>dispatch</code>
|
||||||
<code>dispatch</code>
|
<code>dispatch</code>
|
||||||
<code>purgeProperties</code>
|
|
||||||
</TooManyArguments>
|
</TooManyArguments>
|
||||||
<UndefinedFunction occurrences="4">
|
<UndefinedFunction occurrences="4">
|
||||||
<code>Uri\split($principalUri)</code>
|
<code>Uri\split($principalUri)</code>
|
||||||
|
@ -210,16 +213,13 @@
|
||||||
</UndefinedFunction>
|
</UndefinedFunction>
|
||||||
</file>
|
</file>
|
||||||
<file src="apps/dav/lib/CalDAV/CalendarHome.php">
|
<file src="apps/dav/lib/CalDAV/CalendarHome.php">
|
||||||
<InvalidReturnStatement occurrences="5">
|
<InvalidNullableReturnType occurrences="1">
|
||||||
<code>$calendarPlugin->getCalendarInCalendarHome($this->principalInfo['uri'], $calendarUri)</code>
|
<code>INode</code>
|
||||||
<code>new Inbox($this->caldavBackend, $this->principalInfo['uri'])</code>
|
</InvalidNullableReturnType>
|
||||||
<code>new Outbox($this->config, $this->principalInfo['uri'])</code>
|
<LessSpecificImplementedReturnType occurrences="1">
|
||||||
<code>new Subscription($this->caldavBackend, $subscription)</code>
|
<code>INode</code>
|
||||||
<code>new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri'])</code>
|
</LessSpecificImplementedReturnType>
|
||||||
</InvalidReturnStatement>
|
|
||||||
<InvalidReturnType occurrences="1">
|
|
||||||
<code>getChild</code>
|
|
||||||
</InvalidReturnType>
|
|
||||||
<NullableReturnStatement occurrences="1">
|
<NullableReturnStatement occurrences="1">
|
||||||
<code>$calendarPlugin->getCalendarInCalendarHome($this->principalInfo['uri'], $calendarUri)</code>
|
<code>$calendarPlugin->getCalendarInCalendarHome($this->principalInfo['uri'], $calendarUri)</code>
|
||||||
</NullableReturnStatement>
|
</NullableReturnStatement>
|
||||||
|
|
Loading…
Reference in New Issue