Skip to content

Commit

Permalink
Move calendar objects between calendars instead of deleting and recre…
Browse files Browse the repository at this point in the history
…ating them

Signed-off-by: Anna Larch <[email protected]>
  • Loading branch information
miaulalala committed Feb 7, 2022
1 parent bb55b79 commit 747a4bc
Show file tree
Hide file tree
Showing 19 changed files with 245 additions and 71 deletions.
3 changes: 2 additions & 1 deletion apps/dav/appinfo/v1/caldav.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
use OCA\DAV\Connector\Sabre\Principal;
use Psr\Log\LoggerInterface;

$authBackend = new Auth(
\OC::$server->getSession(),
Expand Down Expand Up @@ -83,7 +84,7 @@
$principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend);
$principalCollection->disableListing = !$debugging; // Disable listing

$addressBookRoot = new CalendarRoot($principalBackend, $calDavBackend);
$addressBookRoot = new CalendarRoot($principalBackend, $calDavBackend, 'principals', \OC::$server->get(LoggerInterface::class));
$addressBookRoot->disableListing = !$debugging; // Disable listing

$nodes = [
Expand Down
52 changes: 51 additions & 1 deletion apps/dav/lib/CalDAV/CalDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
use OCA\DAV\Events\SubscriptionCreatedEvent;
use OCA\DAV\Events\SubscriptionDeletedEvent;
use OCA\DAV\Events\SubscriptionUpdatedEvent;
use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
Expand Down Expand Up @@ -1122,7 +1123,7 @@ public function getDeletedCalendarObjects(int $deletedBefore): array {
*
* @param string $principalUri
* @return array
* @throws \OCP\DB\Exception
* @throws Exception
*/
public function getDeletedCalendarObjectsByPrincipal(string $principalUri): array {
$query = $this->db->getQueryBuilder();
Expand Down Expand Up @@ -1415,6 +1416,55 @@ public function updateCalendarObject($calendarId, $objectUri, $calendarData, $ca
return '"' . $extraData['etag'] . '"';
}

/**
* Moves a calendar object from calendar to calendar.
*
* @param int $sourceCalendarId
* @param int $targetCalendarId
* @param int $objectId
* @param string $principalUri
* @param int $calendarType
* @throws Exception
*/
public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $principalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool {
$object = $this->getCalendarObjectById($principalUri, $objectId);
if (empty($object)) {
return false;
}

$query = $this->db->getQueryBuilder();
$query->update('calendarobjects')
->set('calendarid', $query->createNamedParameter($targetCalendarId))
->where($query->expr()->eq('id', $query->createNamedParameter($objectId)))
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
->executeStatement();

$this->purgeProperties($sourceCalendarId, $objectId);
$this->updateProperties($targetCalendarId, $object['uri'], $object['calendardata'], $calendarType);

$this->addChange($sourceCalendarId, $object['uri'], 1, $calendarType);
$this->addChange($targetCalendarId, $object['uri'], 3, $calendarType);

$object = $this->getCalendarObjectById($principalUri, $objectId);
// Calendar Object wasn't found - possibly because it was deleted in the meantime by a different client
if (empty($object)) {
return false;
}

$calendarRow = $this->getCalendarById($targetCalendarId);
// the calendar this event is being moved to does not exist any longer
if (empty($calendarRow)) {
return false;
}

if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
$shares = $this->getShares($targetCalendarId);
$this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent($targetCalendarId, $calendarRow, $shares, $object));
}
return true;
}


/**
* @param int $calendarObjectId
* @param int $classification
Expand Down
26 changes: 24 additions & 2 deletions apps/dav/lib/CalDAV/Calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@
use OCA\DAV\CalDAV\Trashbin\Plugin as TrashbinPlugin;
use OCA\DAV\DAV\Sharing\IShareable;
use OCA\DAV\Exception\UnsupportedLimitOnInitialSyncException;
use OCP\DB\Exception;
use OCP\IConfig;
use OCP\IL10N;
use Psr\Log\LoggerInterface;
use Sabre\CalDAV\Backend\BackendInterface;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\IMoveTarget;
use Sabre\DAV\INode;
use Sabre\DAV\PropPatch;

/**
Expand All @@ -46,7 +50,7 @@
* @package OCA\DAV\CalDAV
* @property CalDavBackend $caldavBackend
*/
class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable {
class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable, IMoveTarget {

/** @var IConfig */
private $config;
Expand All @@ -57,6 +61,9 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
/** @var bool */
private $useTrashbin = true;

/** @var LoggerInterface */
private $logger;

/**
* Calendar constructor.
*
Expand All @@ -65,7 +72,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
* @param IL10N $l10n
* @param IConfig $config
*/
public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n, IConfig $config) {
public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n, IConfig $config, LoggerInterface $logger) {
// Convert deletion date to ISO8601 string
if (isset($calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT])) {
$calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT] = (new DateTimeImmutable())
Expand All @@ -85,6 +92,7 @@ public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10

$this->config = $config;
$this->l10n = $l10n;
$this->logger = $logger;
}

/**
Expand Down Expand Up @@ -422,4 +430,18 @@ public function restore(): void {
public function disableTrashbin(): void {
$this->useTrashbin = false;
}

public function moveInto($targetName, $sourcePath, INode $sourceNode) {
if (!($sourceNode instanceof CalendarObject)) {
return false;
}

try {
$result = $this->caldavBackend->moveCalendarObject($sourceNode->getCalendarId(), (int)$this->calendarInfo['id'], $sourceNode->getId(), $sourceNode->getPrincipalUri());
} catch (Exception $e) {
$this->logger->error('Could not move calendar object: ' . $e->getMessage(), ['exception' => $e]);
return false;
}
return $result;
}
}
11 changes: 8 additions & 3 deletions apps/dav/lib/CalDAV/CalendarHome.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
use OCA\DAV\CalDAV\Integration\ICalendarProvider;
use OCA\DAV\CalDAV\Trashbin\TrashbinHome;
use Psr\Log\LoggerInterface;
use Sabre\CalDAV\Backend\BackendInterface;
use Sabre\CalDAV\Backend\NotificationSupport;
use Sabre\CalDAV\Backend\SchedulingSupport;
Expand All @@ -55,14 +56,18 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
/** @var bool */
private $returnCachedSubscriptions = false;

public function __construct(BackendInterface $caldavBackend, $principalInfo) {
/** @var LoggerInterface */
private $logger;

public function __construct(BackendInterface $caldavBackend, $principalInfo, LoggerInterface $logger) {
parent::__construct($caldavBackend, $principalInfo);
$this->l10n = \OC::$server->getL10N('dav');
$this->config = \OC::$server->getConfig();
$this->pluginManager = new PluginManager(
\OC::$server,
\OC::$server->getAppManager()
);
$this->logger = $logger;
}

/**
Expand Down Expand Up @@ -95,7 +100,7 @@ public function getChildren() {
$calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']);
$objects = [];
foreach ($calendars as $calendar) {
$objects[] = new Calendar($this->caldavBackend, $calendar, $this->l10n, $this->config);
$objects[] = new Calendar($this->caldavBackend, $calendar, $this->l10n, $this->config, $this->logger);
}

if ($this->caldavBackend instanceof SchedulingSupport) {
Expand Down Expand Up @@ -157,7 +162,7 @@ public function getChild($name) {
// Calendars
foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) {
if ($calendar['uri'] === $name) {
return new Calendar($this->caldavBackend, $calendar, $this->l10n, $this->config);
return new Calendar($this->caldavBackend, $calendar, $this->l10n, $this->config, $this->logger);
}
}

Expand Down
9 changes: 7 additions & 2 deletions apps/dav/lib/CalDAV/CalendarManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use OCP\Calendar\IManager;
use OCP\IConfig;
use OCP\IL10N;
use Psr\Log\LoggerInterface;

class CalendarManager {

Expand All @@ -39,17 +40,21 @@ class CalendarManager {
/** @var IConfig */
private $config;

/** @var LoggerInterface */
private $logger;

/**
* CalendarManager constructor.
*
* @param CalDavBackend $backend
* @param IL10N $l10n
* @param IConfig $config
*/
public function __construct(CalDavBackend $backend, IL10N $l10n, IConfig $config) {
public function __construct(CalDavBackend $backend, IL10N $l10n, IConfig $config, LoggerInterface $logger) {
$this->backend = $backend;
$this->l10n = $l10n;
$this->config = $config;
$this->logger = $logger;
}

/**
Expand All @@ -67,7 +72,7 @@ public function setupCalendarProvider(IManager $cm, $userId) {
*/
private function register(IManager $cm, array $calendars) {
foreach ($calendars as $calendarInfo) {
$calendar = new Calendar($this->backend, $calendarInfo, $this->l10n, $this->config);
$calendar = new Calendar($this->backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
$cm->registerCalendar(new CalendarImpl(
$calendar,
$calendarInfo,
Expand Down
8 changes: 8 additions & 0 deletions apps/dav/lib/CalDAV/CalendarObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,12 @@ private function canWrite() {
}
return true;
}

public function getCalendarId(): int {
return (int)$this->objectData['calendarId'];
}

public function getPrincipalUri(): string {
return $this->objectData['principaluri'];
}
}
9 changes: 7 additions & 2 deletions apps/dav/lib/CalDAV/CalendarProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use OCP\Calendar\ICalendarProvider;
use OCP\IConfig;
use OCP\IL10N;
use Psr\Log\LoggerInterface;

class CalendarProvider implements ICalendarProvider {

Expand All @@ -40,10 +41,14 @@ class CalendarProvider implements ICalendarProvider {
/** @var IConfig */
private $config;

public function __construct(CalDavBackend $calDavBackend, IL10N $l10n, IConfig $config) {
/** @var LoggerInterface */
private $logger;

public function __construct(CalDavBackend $calDavBackend, IL10N $l10n, IConfig $config, LoggerInterface $logger) {
$this->calDavBackend = $calDavBackend;
$this->l10n = $l10n;
$this->config = $config;
$this->logger = $logger;
}

public function getCalendars(string $principalUri, array $calendarUris = []): array {
Expand All @@ -60,7 +65,7 @@ public function getCalendars(string $principalUri, array $calendarUris = []): ar

$iCalendars = [];
foreach ($calendarInfos as $calendarInfo) {
$calendar = new Calendar($this->calDavBackend, $calendarInfo, $this->l10n, $this->config);
$calendar = new Calendar($this->calDavBackend, $calendarInfo, $this->l10n, $this->config, $this->logger);
$iCalendars[] = new CalendarImpl(
$calendar,
$calendarInfo,
Expand Down
15 changes: 14 additions & 1 deletion apps/dav/lib/CalDAV/CalendarRoot.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,22 @@
*/
namespace OCA\DAV\CalDAV;

use Psr\Log\LoggerInterface;
use Sabre\CalDAV\Backend;
use Sabre\DAVACL\PrincipalBackend;

class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {

/** @var LoggerInterface */
private $logger;

public function __construct(PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals', LoggerInterface $logger) {
parent::__construct($principalBackend, $caldavBackend, $principalPrefix);
$this->logger = $logger;
}

public function getChildForPrincipal(array $principal) {
return new CalendarHome($this->caldavBackend, $principal);
return new CalendarHome($this->caldavBackend, $principal, $this->logger);
}

public function getName() {
Expand Down
9 changes: 7 additions & 2 deletions apps/dav/lib/CalDAV/PublicCalendarRoot.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

use OCP\IConfig;
use OCP\IL10N;
use Psr\Log\LoggerInterface;
use Sabre\DAV\Collection;

class PublicCalendarRoot extends Collection {
Expand All @@ -40,6 +41,9 @@ class PublicCalendarRoot extends Collection {
/** @var \OCP\IConfig */
protected $config;

/** @var LoggerInterface */
private $logger;

/**
* PublicCalendarRoot constructor.
*
Expand All @@ -48,10 +52,11 @@ class PublicCalendarRoot extends Collection {
* @param IConfig $config
*/
public function __construct(CalDavBackend $caldavBackend, IL10N $l10n,
IConfig $config) {
IConfig $config, LoggerInterface $logger) {
$this->caldavBackend = $caldavBackend;
$this->l10n = $l10n;
$this->config = $config;
$this->logger = $logger;
}

/**
Expand All @@ -66,7 +71,7 @@ public function getName() {
*/
public function getChild($name) {
$calendar = $this->caldavBackend->getPublicCalendar($name);
return new PublicCalendar($this->caldavBackend, $calendar, $this->l10n, $this->config);
return new PublicCalendar($this->caldavBackend, $calendar, $this->l10n, $this->config, $this->logger);
}

/**
Expand Down
Loading

0 comments on commit 747a4bc

Please sign in to comment.