Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move calendar objects between calendars #30120

Merged
merged 1 commit into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
53 changes: 52 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,56 @@ 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
* @return bool
* @throws Exception
*/
public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $principalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool {
$object = $this->getCalendarObjectById($principalUri, $objectId);
if (empty($object)) {
return false;
}

$query = $this->db->getQueryBuilder();
$query->update('calendarobjects')
->set('calendarid', $query->createNamedParameter($targetCalendarId, IQueryBuilder::PARAM_INT))
->where($query->expr()->eq('id', $query->createNamedParameter($objectId, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT))
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT))
->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
31 changes: 29 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 @@ -415,11 +423,30 @@ public function getChanges($syncToken, $syncLevel, $limit = null) {
return parent::getChanges($syncToken, $syncLevel, $limit);
}

/**
* @inheritDoc
*/
public function restore(): void {
$this->caldavBackend->restoreCalendar((int) $this->calendarInfo['id']);
}

public function disableTrashbin(): void {
$this->useTrashbin = false;
}

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

try {
return $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;
}
}
}
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