Merge pull request #1733 from nextcloud/dav-events
Activities for calendars, events and todos
This commit is contained in:
commit
f6ff624e3d
|
@ -46,10 +46,10 @@ $principalBackend = new Principal(
|
|||
'principals/'
|
||||
);
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$config = \OC::$server->getConfig();
|
||||
$userManager = \OC::$server->getUserManager();
|
||||
$random = \OC::$server->getSecureRandom();
|
||||
$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, $config, $random);
|
||||
$dispatcher = \OC::$server->getEventDispatcher();
|
||||
$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, $random, $dispatcher);
|
||||
|
||||
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false);
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
namespace OCA\DAV\AppInfo;
|
||||
|
||||
use OCA\DAV\CalDAV\Activity\Backend;
|
||||
use OCA\DAV\CalDAV\Activity\Extension;
|
||||
use OCA\DAV\CalDAV\BirthdayService;
|
||||
use OCA\DAV\Capabilities;
|
||||
use OCA\DAV\CardDAV\ContactsManager;
|
||||
|
@ -88,6 +90,67 @@ class Application extends App {
|
|||
);
|
||||
}
|
||||
});
|
||||
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', function(GenericEvent $event) {
|
||||
/** @var Backend $backend */
|
||||
$backend = $this->getContainer()->query(Backend::class);
|
||||
$backend->onCalendarAdd(
|
||||
$event->getArgument('calendarData')
|
||||
);
|
||||
});
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', function(GenericEvent $event) {
|
||||
/** @var Backend $backend */
|
||||
$backend = $this->getContainer()->query(Backend::class);
|
||||
$backend->onCalendarUpdate(
|
||||
$event->getArgument('calendarData'),
|
||||
$event->getArgument('shares'),
|
||||
$event->getArgument('propertyMutations')
|
||||
);
|
||||
});
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', function(GenericEvent $event) {
|
||||
/** @var Backend $backend */
|
||||
$backend = $this->getContainer()->query(Backend::class);
|
||||
$backend->onCalendarDelete(
|
||||
$event->getArgument('calendarData'),
|
||||
$event->getArgument('shares')
|
||||
);
|
||||
});
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateShares', function(GenericEvent $event) {
|
||||
/** @var Backend $backend */
|
||||
$backend = $this->getContainer()->query(Backend::class);
|
||||
$backend->onCalendarUpdateShares(
|
||||
$event->getArgument('calendarData'),
|
||||
$event->getArgument('shares'),
|
||||
$event->getArgument('add'),
|
||||
$event->getArgument('remove')
|
||||
);
|
||||
});
|
||||
|
||||
$listener = function(GenericEvent $event, $eventName) {
|
||||
/** @var Backend $backend */
|
||||
$backend = $this->getContainer()->query(Backend::class);
|
||||
|
||||
$subject = Extension::SUBJECT_OBJECT_ADD;
|
||||
if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject') {
|
||||
$subject = Extension::SUBJECT_OBJECT_UPDATE;
|
||||
} else if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject') {
|
||||
$subject = Extension::SUBJECT_OBJECT_DELETE;
|
||||
}
|
||||
$backend->onTouchCalendarObject(
|
||||
$subject,
|
||||
$event->getArgument('calendarData'),
|
||||
$event->getArgument('shares'),
|
||||
$event->getArgument('objectData')
|
||||
);
|
||||
};
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $listener);
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', $listener);
|
||||
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', $listener);
|
||||
|
||||
$aM = $this->getContainer()->getServer()->getActivityManager();
|
||||
$aM->registerExtension(function() {
|
||||
return $this->getContainer()->query(Extension::class);
|
||||
});
|
||||
}
|
||||
|
||||
public function getSyncService() {
|
||||
|
|
|
@ -0,0 +1,466 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\CalDAV\Activity;
|
||||
|
||||
|
||||
use OCP\Activity\IEvent;
|
||||
use OCP\Activity\IManager as IActivityManager;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use Sabre\VObject\Reader;
|
||||
|
||||
/**
|
||||
* Class Backend
|
||||
*
|
||||
* @package OCA\DAV\CalDAV\Activity
|
||||
*/
|
||||
class Backend {
|
||||
|
||||
/** @var IActivityManager */
|
||||
protected $activityManager;
|
||||
|
||||
/** @var IGroupManager */
|
||||
protected $groupManager;
|
||||
|
||||
/** @var IUserSession */
|
||||
protected $userSession;
|
||||
|
||||
/**
|
||||
* @param IActivityManager $activityManager
|
||||
* @param IGroupManager $groupManager
|
||||
* @param IUserSession $userSession
|
||||
*/
|
||||
public function __construct(IActivityManager $activityManager, IGroupManager $groupManager, IUserSession $userSession) {
|
||||
$this->activityManager = $activityManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates activities when a calendar was creates
|
||||
*
|
||||
* @param array $calendarData
|
||||
*/
|
||||
public function onCalendarAdd(array $calendarData) {
|
||||
$this->triggerCalendarActivity(Extension::SUBJECT_ADD, $calendarData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates activities when a calendar was updated
|
||||
*
|
||||
* @param array $calendarData
|
||||
* @param array $shares
|
||||
* @param array $properties
|
||||
*/
|
||||
public function onCalendarUpdate(array $calendarData, array $shares, array $properties) {
|
||||
$this->triggerCalendarActivity(Extension::SUBJECT_UPDATE, $calendarData, $shares, $properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates activities when a calendar was deleted
|
||||
*
|
||||
* @param array $calendarData
|
||||
* @param array $shares
|
||||
*/
|
||||
public function onCalendarDelete(array $calendarData, array $shares) {
|
||||
$this->triggerCalendarActivity(Extension::SUBJECT_DELETE, $calendarData, $shares);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates activities for all related users when a calendar was touched
|
||||
*
|
||||
* @param string $action
|
||||
* @param array $calendarData
|
||||
* @param array $shares
|
||||
* @param array $changedProperties
|
||||
*/
|
||||
protected function triggerCalendarActivity($action, array $calendarData, array $shares = [], array $changedProperties = []) {
|
||||
if (!isset($calendarData['principaluri'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$principal = explode('/', $calendarData['principaluri']);
|
||||
$owner = $principal[2];
|
||||
|
||||
$currentUser = $this->userSession->getUser();
|
||||
if ($currentUser instanceof IUser) {
|
||||
$currentUser = $currentUser->getUID();
|
||||
} else {
|
||||
$currentUser = $owner;
|
||||
}
|
||||
|
||||
$event = $this->activityManager->generateEvent();
|
||||
$event->setApp('dav')
|
||||
->setObject(Extension::CALENDAR, $calendarData['id'])
|
||||
->setType(Extension::CALENDAR)
|
||||
->setAuthor($currentUser);
|
||||
|
||||
$changedVisibleInformation = array_intersect([
|
||||
'{DAV:}displayname',
|
||||
'{http://apple.com/ns/ical/}calendar-color'
|
||||
], array_keys($changedProperties));
|
||||
|
||||
if (empty($shares) || ($action === Extension::SUBJECT_UPDATE && empty($changedVisibleInformation))) {
|
||||
$users = [$owner];
|
||||
} else {
|
||||
$users = $this->getUsersForShares($shares);
|
||||
$users[] = $owner;
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$event->setAffectedUser($user)
|
||||
->setSubject(
|
||||
$user === $currentUser ? $action . '_self' : $action,
|
||||
[
|
||||
$currentUser,
|
||||
$calendarData['{DAV:}displayname'],
|
||||
]
|
||||
);
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates activities for all related users when a calendar was (un-)shared
|
||||
*
|
||||
* @param array $calendarData
|
||||
* @param array $shares
|
||||
* @param array $add
|
||||
* @param array $remove
|
||||
*/
|
||||
public function onCalendarUpdateShares(array $calendarData, array $shares, array $add, array $remove) {
|
||||
$principal = explode('/', $calendarData['principaluri']);
|
||||
$owner = $principal[2];
|
||||
|
||||
$currentUser = $this->userSession->getUser();
|
||||
if ($currentUser instanceof IUser) {
|
||||
$currentUser = $currentUser->getUID();
|
||||
} else {
|
||||
$currentUser = $owner;
|
||||
}
|
||||
|
||||
$event = $this->activityManager->generateEvent();
|
||||
$event->setApp('dav')
|
||||
->setObject(Extension::CALENDAR, $calendarData['id'])
|
||||
->setType(Extension::CALENDAR)
|
||||
->setAuthor($currentUser);
|
||||
|
||||
foreach ($remove as $principal) {
|
||||
// principal:principals/users/test
|
||||
$parts = explode(':', $principal, 2);
|
||||
if ($parts[0] !== 'principal') {
|
||||
continue;
|
||||
}
|
||||
$principal = explode('/', $parts[1]);
|
||||
|
||||
if ($principal[1] === 'users') {
|
||||
$this->triggerActivityUser(
|
||||
$principal[2],
|
||||
$event,
|
||||
$calendarData,
|
||||
Extension::SUBJECT_UNSHARE_USER,
|
||||
Extension::SUBJECT_DELETE . '_self'
|
||||
);
|
||||
|
||||
if ($owner !== $principal[2]) {
|
||||
$parameters = [
|
||||
$principal[2],
|
||||
$calendarData['{DAV:}displayname'],
|
||||
];
|
||||
|
||||
if ($owner === $event->getAuthor()) {
|
||||
$subject = Extension::SUBJECT_UNSHARE_USER . '_you';
|
||||
} else if ($principal[2] === $event->getAuthor()) {
|
||||
$subject = Extension::SUBJECT_UNSHARE_USER . '_self';
|
||||
} else {
|
||||
$event->setAffectedUser($event->getAuthor())
|
||||
->setSubject(Extension::SUBJECT_UNSHARE_USER . '_you', $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
|
||||
$subject = Extension::SUBJECT_UNSHARE_USER . '_by';
|
||||
$parameters[] = $event->getAuthor();
|
||||
}
|
||||
|
||||
$event->setAffectedUser($owner)
|
||||
->setSubject($subject, $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
} else if ($principal[1] === 'groups') {
|
||||
$this->triggerActivityGroup($principal[2], $event, $calendarData, Extension::SUBJECT_UNSHARE_USER);
|
||||
|
||||
$parameters = [
|
||||
$principal[2],
|
||||
$calendarData['{DAV:}displayname'],
|
||||
];
|
||||
|
||||
if ($owner === $event->getAuthor()) {
|
||||
$subject = Extension::SUBJECT_UNSHARE_GROUP . '_you';
|
||||
} else {
|
||||
$event->setAffectedUser($event->getAuthor())
|
||||
->setSubject(Extension::SUBJECT_UNSHARE_GROUP . '_you', $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
|
||||
$subject = Extension::SUBJECT_UNSHARE_GROUP . '_by';
|
||||
$parameters[] = $event->getAuthor();
|
||||
}
|
||||
|
||||
$event->setAffectedUser($owner)
|
||||
->setSubject($subject, $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($add as $share) {
|
||||
if ($this->isAlreadyShared($share['href'], $shares)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// principal:principals/users/test
|
||||
$parts = explode(':', $share['href'], 2);
|
||||
if ($parts[0] !== 'principal') {
|
||||
continue;
|
||||
}
|
||||
$principal = explode('/', $parts[1]);
|
||||
|
||||
if ($principal[1] === 'users') {
|
||||
$this->triggerActivityUser($principal[2], $event, $calendarData, Extension::SUBJECT_SHARE_USER);
|
||||
|
||||
if ($owner !== $principal[2]) {
|
||||
$parameters = [
|
||||
$principal[2],
|
||||
$calendarData['{DAV:}displayname'],
|
||||
];
|
||||
|
||||
if ($owner === $event->getAuthor()) {
|
||||
$subject = Extension::SUBJECT_SHARE_USER . '_you';
|
||||
} else {
|
||||
$event->setAffectedUser($event->getAuthor())
|
||||
->setSubject(Extension::SUBJECT_SHARE_USER . '_you', $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
|
||||
$subject = Extension::SUBJECT_SHARE_USER . '_by';
|
||||
$parameters[] = $event->getAuthor();
|
||||
}
|
||||
|
||||
$event->setAffectedUser($owner)
|
||||
->setSubject($subject, $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
} else if ($principal[1] === 'groups') {
|
||||
$this->triggerActivityGroup($principal[2], $event, $calendarData, Extension::SUBJECT_SHARE_USER);
|
||||
|
||||
$parameters = [
|
||||
$principal[2],
|
||||
$calendarData['{DAV:}displayname'],
|
||||
];
|
||||
|
||||
if ($owner === $event->getAuthor()) {
|
||||
$subject = Extension::SUBJECT_SHARE_GROUP . '_you';
|
||||
} else {
|
||||
$event->setAffectedUser($event->getAuthor())
|
||||
->setSubject(Extension::SUBJECT_SHARE_GROUP . '_you', $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
|
||||
$subject = Extension::SUBJECT_SHARE_GROUP . '_by';
|
||||
$parameters[] = $event->getAuthor();
|
||||
}
|
||||
|
||||
$event->setAffectedUser($owner)
|
||||
->setSubject($subject, $parameters);
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a calendar is already shared with a principal
|
||||
*
|
||||
* @param string $principal
|
||||
* @param array[] $shares
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAlreadyShared($principal, $shares) {
|
||||
foreach ($shares as $share) {
|
||||
if ($principal === $share['href']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given activity for all members of the given group
|
||||
*
|
||||
* @param string $gid
|
||||
* @param IEvent $event
|
||||
* @param array $properties
|
||||
* @param string $subject
|
||||
*/
|
||||
protected function triggerActivityGroup($gid, IEvent $event, array $properties, $subject) {
|
||||
$group = $this->groupManager->get($gid);
|
||||
|
||||
if ($group instanceof IGroup) {
|
||||
foreach ($group->getUsers() as $user) {
|
||||
// Exclude current user
|
||||
if ($user->getUID() !== $event->getAuthor()) {
|
||||
$this->triggerActivityUser($user->getUID(), $event, $properties, $subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given activity for the given user
|
||||
*
|
||||
* @param string $user
|
||||
* @param IEvent $event
|
||||
* @param array $properties
|
||||
* @param string $subject
|
||||
* @param string $subjectSelf
|
||||
*/
|
||||
protected function triggerActivityUser($user, IEvent $event, array $properties, $subject, $subjectSelf = '') {
|
||||
$event->setAffectedUser($user)
|
||||
->setSubject(
|
||||
$user === $event->getAuthor() && $subjectSelf ? $subjectSelf : $subject,
|
||||
[
|
||||
$event->getAuthor(),
|
||||
$properties['{DAV:}displayname'],
|
||||
]
|
||||
);
|
||||
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates activities when a calendar object was created/updated/deleted
|
||||
*
|
||||
* @param string $action
|
||||
* @param array $calendarData
|
||||
* @param array $shares
|
||||
* @param array $objectData
|
||||
*/
|
||||
public function onTouchCalendarObject($action, array $calendarData, array $shares, array $objectData) {
|
||||
if (!isset($calendarData['principaluri'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$principal = explode('/', $calendarData['principaluri']);
|
||||
$owner = $principal[2];
|
||||
|
||||
$currentUser = $this->userSession->getUser();
|
||||
if ($currentUser instanceof IUser) {
|
||||
$currentUser = $currentUser->getUID();
|
||||
} else {
|
||||
$currentUser = $owner;
|
||||
}
|
||||
|
||||
$object = $this->getObjectNameAndType($objectData);
|
||||
$action = $action . '_' . $object['type'];
|
||||
|
||||
if ($object['type'] === 'todo' && strpos($action, Extension::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'COMPLETED') {
|
||||
$action .= '_completed';
|
||||
} else if ($object['type'] === 'todo' && strpos($action, Extension::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'NEEDS-ACTION') {
|
||||
$action .= '_needs_action';
|
||||
}
|
||||
|
||||
$event = $this->activityManager->generateEvent();
|
||||
$event->setApp('dav')
|
||||
->setObject(Extension::CALENDAR, $calendarData['id'])
|
||||
->setType($object['type'] === 'event' ? Extension::CALENDAR_EVENT : Extension::CALENDAR_TODO)
|
||||
->setAuthor($currentUser);
|
||||
|
||||
$users = $this->getUsersForShares($shares);
|
||||
$users[] = $owner;
|
||||
|
||||
foreach ($users as $user) {
|
||||
$event->setAffectedUser($user)
|
||||
->setSubject(
|
||||
$user === $currentUser ? $action . '_self' : $action,
|
||||
[
|
||||
$currentUser,
|
||||
$calendarData['{DAV:}displayname'],
|
||||
$object['name'],
|
||||
]
|
||||
);
|
||||
$this->activityManager->publish($event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $objectData
|
||||
* @return string[]|bool
|
||||
*/
|
||||
protected function getObjectNameAndType(array $objectData) {
|
||||
$vObject = Reader::read($objectData['calendardata']);
|
||||
$component = $componentType = null;
|
||||
foreach($vObject->getComponents() as $component) {
|
||||
if (in_array($component->name, ['VEVENT', 'VTODO'])) {
|
||||
$componentType = $component->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$componentType) {
|
||||
// Calendar objects must have a VEVENT or VTODO component
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($componentType === 'VEVENT') {
|
||||
return ['name' => (string) $component->SUMMARY, 'type' => 'event'];
|
||||
}
|
||||
return ['name' => (string) $component->SUMMARY, 'type' => 'todo', 'status' => (string) $component->STATUS];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all users that have access to a given calendar
|
||||
*
|
||||
* @param array $shares
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getUsersForShares(array $shares) {
|
||||
$users = $groups = [];
|
||||
foreach ($shares as $share) {
|
||||
$prinical = explode('/', $share['{http://owncloud.org/ns}principal']);
|
||||
if ($prinical[1] === 'users') {
|
||||
$users[] = $prinical[2];
|
||||
} else if ($prinical[1] === 'groups') {
|
||||
$groups[] = $prinical[2];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($groups)) {
|
||||
foreach ($groups as $gid) {
|
||||
$group = $this->groupManager->get($gid);
|
||||
if ($group instanceof IGroup) {
|
||||
foreach ($group->getUsers() as $user) {
|
||||
$users[] = $user->getUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($users);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\CalDAV\Activity;
|
||||
|
||||
use OCP\Activity\IExtension;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\L10N\IFactory;
|
||||
|
||||
class Extension implements IExtension {
|
||||
const APP = 'dav';
|
||||
/**
|
||||
* Filter with all sharing related activities
|
||||
*/
|
||||
const CALENDAR = 'calendar';
|
||||
const CALENDAR_EVENT = 'calendar_event';
|
||||
const CALENDAR_TODO = 'calendar_todo';
|
||||
|
||||
const SUBJECT_ADD = 'calendar_add';
|
||||
const SUBJECT_UPDATE = 'calendar_update';
|
||||
const SUBJECT_DELETE = 'calendar_delete';
|
||||
const SUBJECT_SHARE_USER = 'calendar_user_share';
|
||||
const SUBJECT_SHARE_GROUP = 'calendar_group_share';
|
||||
const SUBJECT_UNSHARE_USER = 'calendar_user_unshare';
|
||||
const SUBJECT_UNSHARE_GROUP = 'calendar_group_unshare';
|
||||
|
||||
const SUBJECT_OBJECT_ADD = 'object_add';
|
||||
const SUBJECT_OBJECT_UPDATE = 'object_update';
|
||||
const SUBJECT_OBJECT_DELETE = 'object_delete';
|
||||
|
||||
/** @var IFactory */
|
||||
protected $languageFactory;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
protected $URLGenerator;
|
||||
|
||||
/**
|
||||
* @param IFactory $languageFactory
|
||||
* @param IURLGenerator $URLGenerator
|
||||
*/
|
||||
public function __construct(IFactory $languageFactory, IURLGenerator $URLGenerator) {
|
||||
$this->languageFactory = $languageFactory;
|
||||
$this->URLGenerator = $URLGenerator;
|
||||
}
|
||||
|
||||
protected function getL10N($languageCode = null) {
|
||||
return $this->languageFactory->get(self::APP, $languageCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can return an array of additional notification types.
|
||||
* If no additional types are to be added false is to be returned
|
||||
*
|
||||
* @param string $languageCode
|
||||
* @return array|false
|
||||
*/
|
||||
public function getNotificationTypes($languageCode) {
|
||||
$l = $this->getL10N($languageCode);
|
||||
|
||||
return array(
|
||||
self::CALENDAR => (string) $l->t('A <strong>calendar</strong> was modified'),
|
||||
self::CALENDAR_EVENT => (string) $l->t('A calendar <strong>event</strong> was modified'),
|
||||
self::CALENDAR_TODO => (string) $l->t('A calendar <strong>todo</strong> was modified'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given method additional types to be displayed in the settings can be returned.
|
||||
* In case no additional types are to be added false is to be returned.
|
||||
*
|
||||
* @param string $method
|
||||
* @return array|false
|
||||
*/
|
||||
public function getDefaultTypes($method) {
|
||||
$defaultTypes = [];
|
||||
if ($method === self::METHOD_STREAM) {
|
||||
$defaultTypes[] = self::CALENDAR;
|
||||
$defaultTypes[] = self::CALENDAR_EVENT;
|
||||
$defaultTypes[] = self::CALENDAR_TODO;
|
||||
}
|
||||
|
||||
return $defaultTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* A string naming the css class for the icon to be used can be returned.
|
||||
* If no icon is known for the given type false is to be returned.
|
||||
*
|
||||
* @param string $type
|
||||
* @return string|false
|
||||
*/
|
||||
public function getTypeIcon($type) {
|
||||
switch ($type) {
|
||||
case self::CALENDAR:
|
||||
case self::CALENDAR_EVENT:
|
||||
return 'icon-calendar-dark';
|
||||
case self::CALENDAR_TODO:
|
||||
return 'icon-checkmark';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can translate a given message to the requested languages.
|
||||
* If no translation is available false is to be returned.
|
||||
*
|
||||
* @param string $app
|
||||
* @param string $text
|
||||
* @param array $params
|
||||
* @param boolean $stripPath
|
||||
* @param boolean $highlightParams
|
||||
* @param string $languageCode
|
||||
* @return string|false
|
||||
*/
|
||||
public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
|
||||
if ($app !== self::APP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$l = $this->getL10N($languageCode);
|
||||
|
||||
switch ($text) {
|
||||
case self::SUBJECT_ADD:
|
||||
return (string) $l->t('%1$s created calendar %2$s', $params);
|
||||
case self::SUBJECT_ADD . '_self':
|
||||
return (string) $l->t('You created calendar %2$s', $params);
|
||||
case self::SUBJECT_DELETE:
|
||||
return (string) $l->t('%1$s deleted calendar %2$s', $params);
|
||||
case self::SUBJECT_DELETE . '_self':
|
||||
return (string) $l->t('You deleted calendar %2$s', $params);
|
||||
case self::SUBJECT_UPDATE:
|
||||
return (string) $l->t('%1$s updated calendar %2$s', $params);
|
||||
case self::SUBJECT_UPDATE . '_self':
|
||||
return (string) $l->t('You updated calendar %2$s', $params);
|
||||
|
||||
case self::SUBJECT_SHARE_USER:
|
||||
return (string) $l->t('%1$s shared calendar %2$s with you', $params);
|
||||
case self::SUBJECT_SHARE_USER . '_you':
|
||||
return (string) $l->t('You shared calendar %2$s with %1$s', $params);
|
||||
case self::SUBJECT_SHARE_USER . '_by':
|
||||
return (string) $l->t('%3$s shared calendar %2$s with %1$s', $params);
|
||||
case self::SUBJECT_UNSHARE_USER:
|
||||
return (string) $l->t('%1$s unshared calendar %2$s from you', $params);
|
||||
case self::SUBJECT_UNSHARE_USER . '_you':
|
||||
return (string) $l->t('You unshared calendar %2$s from %1$s', $params);
|
||||
case self::SUBJECT_UNSHARE_USER . '_by':
|
||||
return (string) $l->t('%3$s unshared calendar %2$s from %1$s', $params);
|
||||
case self::SUBJECT_UNSHARE_USER . '_self':
|
||||
return (string) $l->t('%1$s unshared calendar %2$s from themselves', $params);
|
||||
|
||||
case self::SUBJECT_SHARE_GROUP . '_you':
|
||||
return (string) $l->t('You shared calendar %2$s with group %1$s', $params);
|
||||
case self::SUBJECT_SHARE_GROUP . '_by':
|
||||
return (string) $l->t('%3$s shared calendar %2$s with group %1$s', $params);
|
||||
case self::SUBJECT_UNSHARE_GROUP . '_you':
|
||||
return (string) $l->t('You unshared calendar %2$s from group %1$s', $params);
|
||||
case self::SUBJECT_UNSHARE_GROUP . '_by':
|
||||
return (string) $l->t('%3$s unshared calendar %2$s from group %1$s', $params);
|
||||
|
||||
case self::SUBJECT_OBJECT_ADD . '_event':
|
||||
return (string) $l->t('%1$s created event %3$s in calendar %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_ADD . '_event_self':
|
||||
return (string) $l->t('You created event %3$s in calendar %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_DELETE . '_event':
|
||||
return (string) $l->t('%1$s deleted event %3$s from calendar %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_DELETE . '_event_self':
|
||||
return (string) $l->t('You deleted event %3$s from calendar %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_event':
|
||||
return (string) $l->t('%1$s updated event %3$s in calendar %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_event_self':
|
||||
return (string) $l->t('You updated event %3$s in calendar %2$s', $params);
|
||||
|
||||
case self::SUBJECT_OBJECT_ADD . '_todo':
|
||||
return (string) $l->t('%1$s created todo %3$s in list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_ADD . '_todo_self':
|
||||
return (string) $l->t('You created todo %3$s in list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_DELETE . '_todo':
|
||||
return (string) $l->t('%1$s deleted todo %3$s from list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_DELETE . '_todo_self':
|
||||
return (string) $l->t('You deleted todo %3$s from list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo':
|
||||
return (string) $l->t('%1$s updated todo %3$s in list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_self':
|
||||
return (string) $l->t('You updated todo %3$s in list %2$s', $params);
|
||||
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_completed':
|
||||
return (string) $l->t('%1$s solved todo %3$s in list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self':
|
||||
return (string) $l->t('You solved todo %3$s in list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action':
|
||||
return (string) $l->t('%1$s reopened todo %3$s in list %2$s', $params);
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self':
|
||||
return (string) $l->t('You reopened todo %3$s in list %2$s', $params);
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can define the type of parameters for translation
|
||||
*
|
||||
* Currently known types are:
|
||||
* * file => will strip away the path of the file and add a tooltip with it
|
||||
* * username => will add the avatar of the user
|
||||
*
|
||||
* @param string $app
|
||||
* @param string $text
|
||||
* @return array|false
|
||||
*/
|
||||
public function getSpecialParameterList($app, $text) {
|
||||
if ($app === self::APP) {
|
||||
switch ($text) {
|
||||
case self::SUBJECT_ADD:
|
||||
case self::SUBJECT_ADD . '_self':
|
||||
case self::SUBJECT_DELETE:
|
||||
case self::SUBJECT_DELETE . '_self':
|
||||
case self::SUBJECT_UPDATE:
|
||||
case self::SUBJECT_UPDATE . '_self':
|
||||
case self::SUBJECT_SHARE_USER:
|
||||
case self::SUBJECT_SHARE_USER . '_you':
|
||||
case self::SUBJECT_UNSHARE_USER:
|
||||
case self::SUBJECT_UNSHARE_USER . '_you':
|
||||
case self::SUBJECT_UNSHARE_USER . '_self':
|
||||
return [
|
||||
0 => 'username',
|
||||
//1 => 'calendar',
|
||||
];
|
||||
case self::SUBJECT_SHARE_USER . '_by':
|
||||
case self::SUBJECT_UNSHARE_USER . '_by':
|
||||
return [
|
||||
0 => 'username',
|
||||
//1 => 'calendar',
|
||||
2 => 'username',
|
||||
];
|
||||
case self::SUBJECT_SHARE_GROUP . '_you':
|
||||
case self::SUBJECT_UNSHARE_GROUP . '_you':
|
||||
return [
|
||||
//0 => 'group',
|
||||
//1 => 'calendar',
|
||||
];
|
||||
case self::SUBJECT_SHARE_GROUP . '_by':
|
||||
case self::SUBJECT_UNSHARE_GROUP . '_by':
|
||||
return [
|
||||
//0 => 'group',
|
||||
//1 => 'calendar',
|
||||
2 => 'username',
|
||||
];
|
||||
|
||||
case self::SUBJECT_OBJECT_ADD . '_event':
|
||||
case self::SUBJECT_OBJECT_ADD . '_event_self':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_event':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_event_self':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_event':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_event_self':
|
||||
|
||||
case self::SUBJECT_OBJECT_ADD . '_todo':
|
||||
case self::SUBJECT_OBJECT_ADD . '_todo_self':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_todo':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_todo_self':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_self':
|
||||
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_completed':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self':
|
||||
return [
|
||||
0 => 'username',
|
||||
//1 => 'calendar',
|
||||
//2 => 'object',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can define the parameter grouping by returning the index as integer.
|
||||
* In case no grouping is required false is to be returned.
|
||||
*
|
||||
* @param array $activity
|
||||
* @return integer|false
|
||||
*/
|
||||
public function getGroupParameter($activity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can define additional navigation entries. The array returned has to contain two keys 'top'
|
||||
* and 'apps' which hold arrays with the relevant entries.
|
||||
* If no further entries are to be added false is no be returned.
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function getNavigation() {
|
||||
$l = $this->getL10N();
|
||||
return [
|
||||
'apps' => [
|
||||
self::CALENDAR => [
|
||||
'id' => self::CALENDAR,
|
||||
'icon' => 'icon-calendar-dark',
|
||||
'name' => (string) $l->t('Calendar'),
|
||||
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::CALENDAR]),
|
||||
],
|
||||
self::CALENDAR_TODO => [
|
||||
'id' => self::CALENDAR_TODO,
|
||||
'icon' => 'icon-checkmark',
|
||||
'name' => (string) $l->t('Todos'),
|
||||
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::CALENDAR_TODO]),
|
||||
],
|
||||
],
|
||||
'top' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can check if a custom filter (given by a query string like filter=abc) is valid or not.
|
||||
*
|
||||
* @param string $filterValue
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFilterValid($filterValue) {
|
||||
return in_array($filterValue, [self::CALENDAR, self::CALENDAR_TODO]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can filter the types based on the filter if required.
|
||||
* In case no filter is to be applied false is to be returned unchanged.
|
||||
*
|
||||
* @param array $types
|
||||
* @param string $filter
|
||||
* @return array|false
|
||||
*/
|
||||
public function filterNotificationTypes($types, $filter) {
|
||||
switch ($filter) {
|
||||
case self::CALENDAR:
|
||||
return array_intersect([self::CALENDAR, self::CALENDAR_EVENT], $types);
|
||||
case self::CALENDAR_TODO:
|
||||
return array_intersect([self::CALENDAR_TODO], $types);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given filter the extension can specify the sql query conditions including parameters for that query.
|
||||
* In case the extension does not know the filter false is to be returned.
|
||||
* The query condition and the parameters are to be returned as array with two elements.
|
||||
* E.g. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%'));
|
||||
*
|
||||
* @param string $filter
|
||||
* @return array|false
|
||||
*/
|
||||
public function getQueryForFilter($filter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -29,7 +29,6 @@ use OCA\DAV\DAV\Sharing\IShareable;
|
|||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCA\DAV\DAV\Sharing\Backend;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
|
@ -49,6 +48,8 @@ use Sabre\HTTP\URLUtil;
|
|||
use Sabre\VObject\DateTimeParser;
|
||||
use Sabre\VObject\Reader;
|
||||
use Sabre\VObject\Recur\EventIterator;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
/**
|
||||
* Class CalDavBackend
|
||||
|
@ -125,32 +126,32 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
/** @var ISecureRandom */
|
||||
private $random;
|
||||
|
||||
/** @var EventDispatcherInterface */
|
||||
private $dispatcher;
|
||||
|
||||
/**
|
||||
* CalDavBackend constructor.
|
||||
*
|
||||
* @param IDBConnection $db
|
||||
* @param Principal $principalBackend
|
||||
* @param IUserManager $userManager
|
||||
* @param IConfig $config
|
||||
* @param ISecureRandom $random
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(IDBConnection $db,
|
||||
Principal $principalBackend,
|
||||
IUserManager $userManager,
|
||||
IConfig $config,
|
||||
ISecureRandom $random) {
|
||||
ISecureRandom $random,
|
||||
EventDispatcherInterface $dispatcher) {
|
||||
$this->db = $db;
|
||||
$this->principalBackend = $principalBackend;
|
||||
$this->userManager = $userManager;
|
||||
$this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar');
|
||||
$this->config = $config;
|
||||
$this->random = $random;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -613,7 +614,16 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
$query->setValue($column, $query->createNamedParameter($value));
|
||||
}
|
||||
$query->execute();
|
||||
return $query->getLastInsertId();
|
||||
$calendarId = $query->getLastInsertId();
|
||||
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::createCalendar',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
]));
|
||||
|
||||
return $calendarId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -661,6 +671,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
|
||||
$this->addChange($calendarId, "", 2);
|
||||
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::updateCalendar',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
'shares' => $this->getShares($calendarId),
|
||||
'propertyMutations' => $mutations,
|
||||
]));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -672,6 +691,14 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
* @return void
|
||||
*/
|
||||
function deleteCalendar($calendarId) {
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
'shares' => $this->getShares($calendarId),
|
||||
]));
|
||||
|
||||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ?');
|
||||
$stmt->execute([$calendarId]);
|
||||
|
||||
|
@ -876,6 +903,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
])
|
||||
->execute();
|
||||
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
'shares' => $this->getShares($calendarId),
|
||||
'objectData' => $this->getCalendarObject($calendarId, $objectUri),
|
||||
]
|
||||
));
|
||||
$this->addChange($calendarId, $objectUri, 1);
|
||||
|
||||
return '"' . $extraData['etag'] . '"';
|
||||
|
@ -917,6 +953,18 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
|
||||
->execute();
|
||||
|
||||
$data = $this->getCalendarObject($calendarId, $objectUri);
|
||||
if (is_array($data)) {
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
'shares' => $this->getShares($calendarId),
|
||||
'objectData' => $data,
|
||||
]
|
||||
));
|
||||
}
|
||||
$this->addChange($calendarId, $objectUri, 2);
|
||||
|
||||
return '"' . $extraData['etag'] . '"';
|
||||
|
@ -949,6 +997,19 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
* @return void
|
||||
*/
|
||||
function deleteCalendarObject($calendarId, $objectUri) {
|
||||
$data = $this->getCalendarObject($calendarId, $objectUri);
|
||||
if (is_array($data)) {
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
'shares' => $this->getShares($calendarId),
|
||||
'objectData' => $data,
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `uri` = ?');
|
||||
$stmt->execute([$calendarId, $objectUri]);
|
||||
|
||||
|
@ -1648,6 +1709,16 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
* @param array $remove
|
||||
*/
|
||||
public function updateShares($shareable, $add, $remove) {
|
||||
$calendarId = $shareable->getResourceId();
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateShares', new GenericEvent(
|
||||
'\OCA\DAV\CalDAV\CalDavBackend::updateShares',
|
||||
[
|
||||
'calendarId' => $calendarId,
|
||||
'calendarData' => $this->getCalendarById($calendarId),
|
||||
'shares' => $this->getShares($calendarId),
|
||||
'add' => $add,
|
||||
'remove' => $remove,
|
||||
]));
|
||||
$this->sharingBackend->updateShares($shareable, $add, $remove);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,11 +75,11 @@ class CreateCalendar extends Command {
|
|||
$this->userManager,
|
||||
$this->groupManager
|
||||
);
|
||||
$config = \OC::$server->getConfig();
|
||||
$random = \OC::$server->getSecureRandom();
|
||||
$dispatcher = \OC::$server->getEventDispatcher();
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config, $random);
|
||||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $random, $dispatcher);
|
||||
$caldav->createCalendar("principals/users/$user", $name, []);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ class RootCollection extends SimpleCollection {
|
|||
$systemPrincipals->disableListing = $disableListing;
|
||||
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users');
|
||||
$filesCollection->disableListing = $disableListing;
|
||||
$caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $config, $random);
|
||||
$caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $random, $dispatcher);
|
||||
$calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users');
|
||||
$calendarRoot->disableListing = $disableListing;
|
||||
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend);
|
||||
|
|
|
@ -22,18 +22,12 @@
|
|||
|
||||
namespace OCA\DAV\Tests\unit\CalDAV;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\CalDAV\Calendar;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCP\IL10N;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
|
||||
use Sabre\DAV\PropPatch;
|
||||
use Sabre\DAV\Xml\Property\Href;
|
||||
use Sabre\DAVACL\IACL;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
/**
|
||||
|
@ -50,12 +44,10 @@ abstract class AbstractCalDavBackendTest extends TestCase {
|
|||
|
||||
/** @var Principal | \PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $principal;
|
||||
|
||||
/** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userManager;
|
||||
|
||||
/** var OCP\IConfig */
|
||||
protected $config;
|
||||
/** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $dispatcher;
|
||||
|
||||
/** @var ISecureRandom */
|
||||
private $random;
|
||||
|
@ -67,9 +59,8 @@ abstract class AbstractCalDavBackendTest extends TestCase {
|
|||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->userManager = $this->getMockBuilder('OCP\IUserManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
|
||||
|
@ -83,21 +74,28 @@ abstract class AbstractCalDavBackendTest extends TestCase {
|
|||
->willReturn([self::UNIT_TEST_GROUP]);
|
||||
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$this->config = \OC::$server->getConfig();
|
||||
$this->random = \OC::$server->getSecureRandom();
|
||||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->config, $this->random);
|
||||
$this->tearDown();
|
||||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->random, $this->dispatcher);
|
||||
|
||||
$this->cleanUpBackend();
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
$this->cleanUpBackend();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function cleanUpBackend() {
|
||||
if (is_null($this->backend)) {
|
||||
return;
|
||||
}
|
||||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||
foreach ($books as $book) {
|
||||
$this->backend->deleteCalendar($book['id']);
|
||||
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||
foreach ($calendars as $calendar) {
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar');
|
||||
|
||||
$this->backend->deleteCalendar($calendar['id']);
|
||||
}
|
||||
$subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER);
|
||||
foreach ($subscriptions as $subscription) {
|
||||
|
@ -106,6 +104,10 @@ abstract class AbstractCalDavBackendTest extends TestCase {
|
|||
}
|
||||
|
||||
protected function createTestCalendar() {
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendar');
|
||||
|
||||
$this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [
|
||||
'{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF'
|
||||
]);
|
||||
|
@ -143,6 +145,11 @@ END:VEVENT
|
|||
END:VCALENDAR
|
||||
EOD;
|
||||
$uri0 = $this->getUniqueID('event');
|
||||
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject');
|
||||
|
||||
$this->backend->createCalendarObject($calendarId, $uri0, $calData);
|
||||
|
||||
return $uri0;
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Tests\unit\CalDAV\Activity;
|
||||
|
||||
use OCA\DAV\CalDAV\Activity\Backend;
|
||||
use OCA\DAV\CalDAV\Activity\Extension;
|
||||
use OCP\Activity\IEvent;
|
||||
use OCP\Activity\IManager;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use Test\TestCase;
|
||||
|
||||
class BackendTest extends TestCase {
|
||||
|
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $activityManager;
|
||||
|
||||
/** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $groupManager;
|
||||
|
||||
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userSession;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->activityManager = $this->createMock(IManager::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $methods
|
||||
* @return Backend|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function getBackend(array $methods = []) {
|
||||
if (empty($methods)) {
|
||||
return new Backend(
|
||||
$this->activityManager,
|
||||
$this->groupManager,
|
||||
$this->userSession
|
||||
);
|
||||
} else {
|
||||
return $this->getMockBuilder(Backend::class)
|
||||
->setConstructorArgs([
|
||||
$this->activityManager,
|
||||
$this->groupManager,
|
||||
$this->userSession,
|
||||
])
|
||||
->setMethods($methods)
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
||||
public function dataCallTriggerCalendarActivity() {
|
||||
return [
|
||||
['onCalendarAdd', [['data']], Extension::SUBJECT_ADD, [['data'], [], []]],
|
||||
['onCalendarUpdate', [['data'], ['shares'], ['changed-properties']], Extension::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]],
|
||||
['onCalendarDelete', [['data'], ['shares']], Extension::SUBJECT_DELETE, [['data'], ['shares'], []]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataCallTriggerCalendarActivity
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $payload
|
||||
* @param string $expectedSubject
|
||||
* @param array $expectedPayload
|
||||
*/
|
||||
public function testCallTriggerCalendarActivity($method, array $payload, $expectedSubject, array $expectedPayload) {
|
||||
$backend = $this->getBackend(['triggerCalendarActivity']);
|
||||
$backend->expects($this->once())
|
||||
->method('triggerCalendarActivity')
|
||||
->willReturnCallback(function() use($expectedPayload, $expectedSubject) {
|
||||
$arguments = func_get_args();
|
||||
$this->assertSame($expectedSubject, array_shift($arguments));
|
||||
$this->assertEquals($expectedPayload, $arguments);
|
||||
});
|
||||
|
||||
call_user_func_array([$backend, $method], $payload);
|
||||
}
|
||||
|
||||
public function dataTriggerCalendarActivity() {
|
||||
return [
|
||||
// Add calendar
|
||||
[Extension::SUBJECT_ADD, [], [], [], '', '', null, []],
|
||||
[Extension::SUBJECT_ADD, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], [], [], '', 'admin', null, ['admin']],
|
||||
[Extension::SUBJECT_ADD, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], [], [], 'test2', 'test2', null, ['admin']],
|
||||
|
||||
// Update calendar
|
||||
[Extension::SUBJECT_UPDATE, [], [], [], '', '', null, []],
|
||||
// No visible change - owner only
|
||||
[Extension::SUBJECT_UPDATE, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], ['shares'], [], '', 'admin', null, ['admin']],
|
||||
// Visible change
|
||||
[Extension::SUBJECT_UPDATE, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], ['shares'], ['{DAV:}displayname' => 'Name'], '', 'admin', ['user1'], ['user1', 'admin']],
|
||||
[Extension::SUBJECT_UPDATE, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], ['shares'], ['{DAV:}displayname' => 'Name'], 'test2', 'test2', ['user1'], ['user1', 'admin']],
|
||||
|
||||
// Delete calendar
|
||||
[Extension::SUBJECT_DELETE, [], [], [], '', '', null, []],
|
||||
[Extension::SUBJECT_DELETE, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], ['shares'], [], '', 'admin', [], ['admin']],
|
||||
[Extension::SUBJECT_DELETE, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], ['shares'], [], '', 'admin', ['user1'], ['user1', 'admin']],
|
||||
[Extension::SUBJECT_DELETE, [
|
||||
'principaluri' => 'principal/user/admin',
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'Name of calendar',
|
||||
], ['shares'], [], 'test2', 'test2', ['user1'], ['user1', 'admin']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTriggerCalendarActivity
|
||||
* @param string $action
|
||||
* @param array $data
|
||||
* @param array $shares
|
||||
* @param array $changedProperties
|
||||
* @param string $currentUser
|
||||
* @param string $author
|
||||
* @param string[]|null $shareUsers
|
||||
* @param string[] $users
|
||||
*/
|
||||
public function testTriggerCalendarActivity($action, array $data, array $shares, array $changedProperties, $currentUser, $author, $shareUsers, array $users) {
|
||||
$backend = $this->getBackend(['getUsersForShares']);
|
||||
|
||||
if ($shareUsers === null) {
|
||||
$backend->expects($this->never())
|
||||
->method('getUsersForShares');
|
||||
} else {
|
||||
$backend->expects($this->once())
|
||||
->method('getUsersForShares')
|
||||
->with($shares)
|
||||
->willReturn($shareUsers);
|
||||
}
|
||||
|
||||
if ($author !== '') {
|
||||
if ($currentUser !== '') {
|
||||
$this->userSession->expects($this->once())
|
||||
->method('getUser')
|
||||
->willReturn($this->getUserMock($currentUser));
|
||||
} else {
|
||||
$this->userSession->expects($this->once())
|
||||
->method('getUser')
|
||||
->willReturn(null);
|
||||
}
|
||||
|
||||
$event = $this->createMock(IEvent::class);
|
||||
$this->activityManager->expects($this->once())
|
||||
->method('generateEvent')
|
||||
->willReturn($event);
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('setApp')
|
||||
->with('dav')
|
||||
->willReturnSelf();
|
||||
$event->expects($this->once())
|
||||
->method('setObject')
|
||||
->with(Extension::CALENDAR, $data['id'])
|
||||
->willReturnSelf();
|
||||
$event->expects($this->once())
|
||||
->method('setType')
|
||||
->with(Extension::CALENDAR)
|
||||
->willReturnSelf();
|
||||
$event->expects($this->once())
|
||||
->method('setAuthor')
|
||||
->with($author)
|
||||
->willReturnSelf();
|
||||
|
||||
$event->expects($this->exactly(sizeof($users)))
|
||||
->method('setAffectedUser')
|
||||
->willReturnSelf();
|
||||
$event->expects($this->exactly(sizeof($users)))
|
||||
->method('setSubject')
|
||||
->willReturnSelf();
|
||||
$this->activityManager->expects($this->exactly(sizeof($users)))
|
||||
->method('publish')
|
||||
->with($event);
|
||||
} else {
|
||||
$this->activityManager->expects($this->never())
|
||||
->method('generateEvent');
|
||||
}
|
||||
|
||||
$this->invokePrivate($backend, 'triggerCalendarActivity', [$action, $data, $shares, $changedProperties]);
|
||||
}
|
||||
|
||||
public function dataGetUsersForShares() {
|
||||
return [
|
||||
[
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
],
|
||||
[
|
||||
[
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user1'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user3'],
|
||||
],
|
||||
[],
|
||||
['user1', 'user2', 'user3'],
|
||||
],
|
||||
[
|
||||
[
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user1'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/groups/group2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/groups/group3'],
|
||||
],
|
||||
['group2' => null, 'group3' => null],
|
||||
['user1', 'user2'],
|
||||
],
|
||||
[
|
||||
[
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user1'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/groups/group2'],
|
||||
['{http://owncloud.org/ns}principal' => 'principal/groups/group3'],
|
||||
],
|
||||
['group2' => ['user1', 'user2', 'user3'], 'group3' => ['user2', 'user3', 'user4']],
|
||||
['user1', 'user2', 'user3', 'user4'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetUsersForShares
|
||||
* @param array $shares
|
||||
* @param array $groups
|
||||
* @param array $expected
|
||||
*/
|
||||
public function testGetUsersForShares(array $shares, array $groups, array $expected) {
|
||||
$backend = $this->getBackend();
|
||||
|
||||
$getGroups = [];
|
||||
foreach ($groups as $gid => $members) {
|
||||
if ($members === null) {
|
||||
$getGroups[] = [$gid, null];
|
||||
continue;
|
||||
}
|
||||
|
||||
$group = $this->createMock(IGroup::class);
|
||||
$group->expects($this->once())
|
||||
->method('getUsers')
|
||||
->willReturn($this->getUsers($members));
|
||||
|
||||
$getGroups[] = [$gid, $group];
|
||||
}
|
||||
|
||||
$this->groupManager->expects($this->exactly(sizeof($getGroups)))
|
||||
->method('get')
|
||||
->willReturnMap($getGroups);
|
||||
|
||||
$users = $this->invokePrivate($backend, 'getUsersForShares', [$shares]);
|
||||
sort($users);
|
||||
$this->assertEquals($expected, $users);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $users
|
||||
* @return IUser[]|\PHPUnit_Framework_MockObject_MockObject[]
|
||||
*/
|
||||
protected function getUsers(array $users) {
|
||||
$list = [];
|
||||
foreach ($users as $user) {
|
||||
$list[] = $this->getUserMock($user);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return IUser|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function getUserMock($uid) {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->expects($this->once())
|
||||
->method('getUID')
|
||||
->willReturn($uid);
|
||||
return $user;
|
||||
}
|
||||
}
|
|
@ -51,6 +51,9 @@ class CalDavBackendTest extends AbstractCalDavBackendTest {
|
|||
'{DAV:}displayname' => 'Unit test',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar used for unit testing'
|
||||
]);
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar');
|
||||
$this->backend->updateCalendar($calendarId, $patch);
|
||||
$patch->commit();
|
||||
$this->assertEquals(1, $this->backend->getCalendarsForUserCount(self::UNIT_TEST_USER));
|
||||
|
@ -60,6 +63,9 @@ class CalDavBackendTest extends AbstractCalDavBackendTest {
|
|||
$this->assertEquals('Calendar used for unit testing', $books[0]['{urn:ietf:params:xml:ns:caldav}calendar-description']);
|
||||
|
||||
// delete the address book
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar');
|
||||
$this->backend->deleteCalendar($books[0]['id']);
|
||||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||
$this->assertEquals(0, count($books));
|
||||
|
@ -106,6 +112,9 @@ class CalDavBackendTest extends AbstractCalDavBackendTest {
|
|||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||
$this->assertEquals(1, count($books));
|
||||
$calendar = new Calendar($this->backend, $books[0], $l10n);
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::updateShares');
|
||||
$this->backend->updateShares($calendar, $add, []);
|
||||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER1);
|
||||
$this->assertEquals(1, count($books));
|
||||
|
@ -138,6 +147,9 @@ END:VEVENT
|
|||
END:VCALENDAR
|
||||
EOD;
|
||||
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject');
|
||||
$this->backend->createCalendarObject($calendarId, $uri, $calData);
|
||||
|
||||
/** @var IACL $child */
|
||||
|
@ -151,6 +163,9 @@ EOD;
|
|||
$this->assertAccess($groupCanWrite, self::UNIT_TEST_GROUP, '{DAV:}write', $acl);
|
||||
|
||||
// delete the address book
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar');
|
||||
$this->backend->deleteCalendar($books[0]['id']);
|
||||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
|
||||
$this->assertEquals(0, count($books));
|
||||
|
@ -179,6 +194,9 @@ END:VEVENT
|
|||
END:VCALENDAR
|
||||
EOD;
|
||||
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject');
|
||||
$this->backend->createCalendarObject($calendarId, $uri, $calData);
|
||||
|
||||
// get all the cards
|
||||
|
@ -214,11 +232,17 @@ DTEND;VALUE=DATE-TIME:20130912T140000Z
|
|||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
EOD;
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject');
|
||||
$this->backend->updateCalendarObject($calendarId, $uri, $calData);
|
||||
$calendarObject = $this->backend->getCalendarObject($calendarId, $uri);
|
||||
$this->assertEquals($calData, $calendarObject['calendardata']);
|
||||
|
||||
// delete the card
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject');
|
||||
$this->backend->deleteCalendarObject($calendarId, $uri);
|
||||
$calendarObjects = $this->backend->getCalendarObjects($calendarId);
|
||||
$this->assertEquals(0, count($calendarObjects));
|
||||
|
@ -246,10 +270,19 @@ END:VEVENT
|
|||
END:VCALENDAR
|
||||
EOD;
|
||||
$uri0 = $this->getUniqueID('card');
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject');
|
||||
$this->backend->createCalendarObject($calendarId, $uri0, $calData);
|
||||
$uri1 = $this->getUniqueID('card');
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject');
|
||||
$this->backend->createCalendarObject($calendarId, $uri1, $calData);
|
||||
$uri2 = $this->getUniqueID('card');
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject');
|
||||
$this->backend->createCalendarObject($calendarId, $uri2, $calData);
|
||||
|
||||
// get all the cards
|
||||
|
@ -270,8 +303,17 @@ EOD;
|
|||
}
|
||||
|
||||
// delete the card
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject');
|
||||
$this->backend->deleteCalendarObject($calendarId, $uri0);
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject');
|
||||
$this->backend->deleteCalendarObject($calendarId, $uri1);
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject');
|
||||
$this->backend->deleteCalendarObject($calendarId, $uri2);
|
||||
$calendarObjects = $this->backend->getCalendarObjects($calendarId);
|
||||
$this->assertEquals(0, count($calendarObjects));
|
||||
|
@ -335,6 +377,10 @@ EOD;
|
|||
}
|
||||
|
||||
public function testPublications() {
|
||||
$this->dispatcher->expects($this->at(0))
|
||||
->method('dispatch')
|
||||
->with('\OCA\DAV\CalDAV\CalDavBackend::createCalendar');
|
||||
|
||||
$this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', []);
|
||||
|
||||
$calendarInfo = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER)[0];
|
||||
|
@ -357,10 +403,8 @@ EOD;
|
|||
$calendar->setPublishStatus(false);
|
||||
$this->assertEquals(false, $calendar->getPublishStatus());
|
||||
|
||||
$publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId());
|
||||
$this->setExpectedException('Sabre\DAV\Exception\NotFound');
|
||||
$publicCalendar = $this->backend->getPublicCalendar($publicCalendarURI);
|
||||
|
||||
$this->backend->getPublicCalendar($publicCalendarURI);
|
||||
}
|
||||
|
||||
public function testSubscriptions() {
|
||||
|
|
|
@ -9,6 +9,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
|||
use OCA\DAV\CalDAV\PublicCalendarRoot;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
/**
|
||||
|
@ -27,12 +28,11 @@ class PublicCalendarRootTest extends TestCase {
|
|||
private $publicCalendarRoot;
|
||||
/** @var IL10N */
|
||||
private $l10n;
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
/** @var Principal */
|
||||
/** @var Principal|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $principal;
|
||||
/** var IConfig */
|
||||
protected $config;
|
||||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userManager;
|
||||
|
||||
/** @var ISecureRandom */
|
||||
private $random;
|
||||
|
||||
|
@ -40,19 +40,17 @@ class PublicCalendarRootTest extends TestCase {
|
|||
parent::setUp();
|
||||
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->config = \OC::$server->getConfig();
|
||||
$this->userManager = $this->getMockBuilder('\OCP\IUserManager')->getMock();
|
||||
$this->principal = $this->createMock('OCA\DAV\Connector\Sabre\Principal');
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->random = \OC::$server->getSecureRandom();
|
||||
$dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
|
||||
$this->backend = new CalDavBackend(
|
||||
$db,
|
||||
$this->principal,
|
||||
$this->userManager,
|
||||
$this->config,
|
||||
$this->random
|
||||
$this->random,
|
||||
$dispatcher
|
||||
);
|
||||
|
||||
$this->publicCalendarRoot = new PublicCalendarRoot($this->backend);
|
||||
|
|
Loading…
Reference in New Issue