Merge pull request #22198 from owncloud/birthday-calendar
Sync a users contacts birthday to the users birthday calendar
This commit is contained in:
commit
ffc2950393
14 changed files with 548 additions and 41 deletions
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
namespace OCA\Dav\AppInfo;
|
||||
|
||||
use OCA\DAV\CalDAV\BirthdayService;
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\CardDAV\ContactsManager;
|
||||
|
@ -34,6 +35,7 @@ use \OCP\AppFramework\App;
|
|||
use OCP\AppFramework\IAppContainer;
|
||||
use OCP\Contacts\IManager;
|
||||
use OCP\IUser;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
class Application extends App {
|
||||
|
||||
|
@ -74,12 +76,12 @@ class Application extends App {
|
|||
$container->registerService('CardDavBackend', function($c) {
|
||||
/** @var IAppContainer $c */
|
||||
$db = $c->getServer()->getDatabaseConnection();
|
||||
$logger = $c->getServer()->getLogger();
|
||||
$dispatcher = $c->getServer()->getEventDispatcher();
|
||||
$principal = new \OCA\DAV\Connector\Sabre\Principal(
|
||||
$c->getServer()->getUserManager(),
|
||||
$c->getServer()->getGroupManager()
|
||||
);
|
||||
return new CardDavBackend($db, $principal, $logger);
|
||||
return new CardDavBackend($db, $principal, $dispatcher);
|
||||
});
|
||||
|
||||
$container->registerService('CalDavBackend', function($c) {
|
||||
|
@ -109,6 +111,15 @@ class Application extends App {
|
|||
$c->query('CalDavBackend')
|
||||
);
|
||||
});
|
||||
|
||||
$container->registerService('BirthdayService', function($c) {
|
||||
/** @var IAppContainer $c */
|
||||
return new BirthdayService(
|
||||
$c->query('CalDavBackend'),
|
||||
$c->query('CardDavBackend')
|
||||
);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,6 +136,30 @@ class Application extends App {
|
|||
/** @var HookManager $hm */
|
||||
$hm = $this->getContainer()->query('HookManager');
|
||||
$hm->setup();
|
||||
|
||||
$listener = function($event) {
|
||||
if ($event instanceof GenericEvent) {
|
||||
$b = $this->getContainer()->query('BirthdayService');
|
||||
$b->onCardChanged(
|
||||
$event->getArgument('addressBookId'),
|
||||
$event->getArgument('cardUri'),
|
||||
$event->getArgument('cardData')
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
$dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
|
||||
$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $listener);
|
||||
$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $listener);
|
||||
$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function($event) {
|
||||
if ($event instanceof GenericEvent) {
|
||||
$b = $this->getContainer()->query('BirthdayService');
|
||||
$b->onCardDeleted(
|
||||
$event->getArgument('addressBookId'),
|
||||
$event->getArgument('cardUri')
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getSyncService() {
|
||||
|
|
|
@ -24,21 +24,21 @@ use OCA\DAV\Command\CreateAddressBook;
|
|||
use OCA\DAV\Command\CreateCalendar;
|
||||
use OCA\Dav\Command\MigrateAddressbooks;
|
||||
use OCA\Dav\Command\MigrateCalendars;
|
||||
use OCA\DAV\Command\SyncBirthdayCalendar;
|
||||
use OCA\DAV\Command\SyncSystemAddressBook;
|
||||
|
||||
$config = \OC::$server->getConfig();
|
||||
$dbConnection = \OC::$server->getDatabaseConnection();
|
||||
$userManager = OC::$server->getUserManager();
|
||||
$groupManager = OC::$server->getGroupManager();
|
||||
$config = \OC::$server->getConfig();
|
||||
$logger = \OC::$server->getLogger();
|
||||
|
||||
$app = new Application();
|
||||
|
||||
/** @var Symfony\Component\Console\Application $application */
|
||||
$application->add(new CreateAddressBook($userManager, $groupManager, $dbConnection, $logger));
|
||||
$application->add(new CreateCalendar($userManager, $groupManager, $dbConnection));
|
||||
$application->add(new CreateAddressBook($userManager, $app->getContainer()->query('CardDavBackend')));
|
||||
$application->add(new SyncSystemAddressBook($app->getSyncService()));
|
||||
$application->add(new SyncBirthdayCalendar($userManager, $app->getContainer()->query('BirthdayService')));
|
||||
|
||||
// the occ tool is *for now* only available in debug mode for developers to test
|
||||
if ($config->getSystemValue('debug', false)){
|
||||
|
|
|
@ -36,33 +36,21 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
class CreateAddressBook extends Command {
|
||||
|
||||
/** @var IUserManager */
|
||||
protected $userManager;
|
||||
private $userManager;
|
||||
|
||||
/** @var \OCP\IDBConnection */
|
||||
protected $dbConnection;
|
||||
|
||||
/** @var ILogger */
|
||||
private $logger;
|
||||
|
||||
/** @var IGroupManager $groupManager */
|
||||
private $groupManager;
|
||||
/** @var CardDavBackend */
|
||||
private $cardDavBackend;
|
||||
|
||||
/**
|
||||
* @param IUserManager $userManager
|
||||
* @param IDBConnection $dbConnection
|
||||
* @param IConfig $config
|
||||
* @param ILogger $logger
|
||||
* @param CardDavBackend $cardDavBackend
|
||||
*/
|
||||
function __construct(IUserManager $userManager,
|
||||
IGroupManager $groupManager,
|
||||
IDBConnection $dbConnection,
|
||||
ILogger $logger
|
||||
CardDavBackend $cardDavBackend
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->dbConnection = $dbConnection;
|
||||
$this->logger = $logger;
|
||||
$this->cardDavBackend = $cardDavBackend;
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
|
@ -82,13 +70,8 @@ class CreateAddressBook extends Command {
|
|||
if (!$this->userManager->userExists($user)) {
|
||||
throw new \InvalidArgumentException("User <$user> in unknown.");
|
||||
}
|
||||
$principalBackend = new Principal(
|
||||
$this->userManager,
|
||||
$this->groupManager
|
||||
);
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
$carddav = new CardDavBackend($this->dbConnection, $principalBackend, $this->logger);
|
||||
$carddav->createAddressBook("principals/users/$user", $name, []);
|
||||
$this->cardDavBackend->createAddressBook("principals/users/$user", $name, []);
|
||||
}
|
||||
}
|
||||
|
|
85
apps/dav/command/syncbirthdaycalendar.php
Normal file
85
apps/dav/command/syncbirthdaycalendar.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Command;
|
||||
|
||||
use OCA\DAV\CalDAV\BirthdayService;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SyncBirthdayCalendar extends Command {
|
||||
|
||||
/** @var BirthdayService */
|
||||
private $birthdayService;
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* @param IUserManager $userManager
|
||||
* @param BirthdayService $birthdayService
|
||||
*/
|
||||
function __construct(IUserManager $userManager, BirthdayService $birthdayService) {
|
||||
parent::__construct();
|
||||
$this->birthdayService = $birthdayService;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
$this
|
||||
->setName('dav:sync-birthday-calendar')
|
||||
->setDescription('Synchronizes the birthday calendar')
|
||||
->addArgument('user',
|
||||
InputArgument::OPTIONAL,
|
||||
'User for whom the birthday calendar will be synchronized');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
if ($input->hasArgument('user')) {
|
||||
$user = $input->getArgument('user');
|
||||
if (!$this->userManager->userExists($user)) {
|
||||
throw new \InvalidArgumentException("User <$user> in unknown.");
|
||||
}
|
||||
$output->writeln("Start birthday calendar sync for $user");
|
||||
$this->birthdayService->syncUser($user);
|
||||
return;
|
||||
}
|
||||
$output->writeln("Start birthday calendar sync for all users ...");
|
||||
$p = new ProgressBar($output);
|
||||
$p->start();
|
||||
$this->userManager->callForAllUsers(function($user) use ($p) {
|
||||
$p->advance();
|
||||
/** @var IUser $user */
|
||||
$this->birthdayService->syncUser($user->getUID());
|
||||
});
|
||||
|
||||
$p->finish();
|
||||
$output->writeln('');
|
||||
}
|
||||
}
|
|
@ -34,7 +34,6 @@ class SyncSystemAddressBook extends Command {
|
|||
private $syncService;
|
||||
|
||||
/**
|
||||
* @param IUserManager $userManager
|
||||
* @param SyncService $syncService
|
||||
*/
|
||||
function __construct(SyncService $syncService) {
|
||||
|
|
187
apps/dav/lib/caldav/birthdayservice.php
Normal file
187
apps/dav/lib/caldav/birthdayservice.php
Normal file
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\CalDAV;
|
||||
|
||||
use Exception;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use Sabre\VObject\Component\VCalendar;
|
||||
use Sabre\VObject\Reader;
|
||||
|
||||
class BirthdayService {
|
||||
|
||||
const BIRTHDAY_CALENDAR_URI = 'contact_birthdays';
|
||||
|
||||
/**
|
||||
* BirthdayService constructor.
|
||||
*
|
||||
* @param CalDavBackend $calDavBackEnd
|
||||
* @param CardDavBackend $cardDavBackEnd
|
||||
*/
|
||||
public function __construct($calDavBackEnd, $cardDavBackEnd) {
|
||||
$this->calDavBackEnd = $calDavBackEnd;
|
||||
$this->cardDavBackEnd = $cardDavBackEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressBookId
|
||||
* @param string $cardUri
|
||||
* @param string $cardData
|
||||
*/
|
||||
public function onCardChanged($addressBookId, $cardUri, $cardData) {
|
||||
|
||||
$book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
|
||||
$principalUri = $book['principaluri'];
|
||||
$calendarUri = self::BIRTHDAY_CALENDAR_URI;
|
||||
$calendar = $this->ensureCalendarExists($principalUri, $calendarUri, []);
|
||||
$objectUri = $book['uri'] . '-' . $cardUri. '.ics';
|
||||
$calendarData = $this->buildBirthdayFromContact($cardData);
|
||||
$existing = $this->calDavBackEnd->getCalendarObject($calendar['id'], $objectUri);
|
||||
if (is_null($calendarData)) {
|
||||
if (!is_null($existing)) {
|
||||
$this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri);
|
||||
}
|
||||
} else {
|
||||
if (is_null($existing)) {
|
||||
$this->calDavBackEnd->createCalendarObject($calendar['id'], $objectUri, $calendarData->serialize());
|
||||
} else {
|
||||
if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) {
|
||||
$this->calDavBackEnd->updateCalendarObject($calendar['id'], $objectUri, $calendarData->serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressBookId
|
||||
* @param string $cardUri
|
||||
*/
|
||||
public function onCardDeleted($addressBookId, $cardUri) {
|
||||
$book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
|
||||
$principalUri = $book['principaluri'];
|
||||
$calendarUri = self::BIRTHDAY_CALENDAR_URI;
|
||||
$calendar = $this->ensureCalendarExists($principalUri, $calendarUri, []);
|
||||
$objectUri = $book['uri'] . '-' . $cardUri. '.ics';
|
||||
$this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $principal
|
||||
* @param string $id
|
||||
* @param array $properties
|
||||
* @return array|null
|
||||
* @throws \Sabre\DAV\Exception\BadRequest
|
||||
*/
|
||||
public function ensureCalendarExists($principal, $id, $properties) {
|
||||
$book = $this->calDavBackEnd->getCalendarByUri($principal, $id);
|
||||
if (!is_null($book)) {
|
||||
return $book;
|
||||
}
|
||||
$this->calDavBackEnd->createCalendar($principal, $id, $properties);
|
||||
|
||||
return $this->calDavBackEnd->getCalendarByUri($principal, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cardData
|
||||
* @return null|VCalendar
|
||||
*/
|
||||
public function buildBirthdayFromContact($cardData) {
|
||||
if (empty($cardData)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$doc = Reader::read($cardData);
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($doc->BDAY)) {
|
||||
return null;
|
||||
}
|
||||
$birthday = $doc->BDAY;
|
||||
if (!(string)$birthday) {
|
||||
return null;
|
||||
}
|
||||
$title = str_replace('{name}',
|
||||
strtr((string)$doc->FN, array('\,' => ',', '\;' => ';')),
|
||||
'{name}\'s Birthday'
|
||||
);
|
||||
try {
|
||||
$date = new \DateTime($birthday);
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
$vCal = new VCalendar();
|
||||
$vCal->VERSION = '2.0';
|
||||
$vEvent = $vCal->createComponent('VEVENT');
|
||||
$vEvent->add('DTSTART');
|
||||
$vEvent->DTSTART->setDateTime(
|
||||
$date
|
||||
);
|
||||
$vEvent->DTSTART['VALUE'] = 'DATE';
|
||||
$vEvent->add('DTEND');
|
||||
$date->add(new \DateInterval('P1D'));
|
||||
$vEvent->DTEND->setDateTime(
|
||||
$date
|
||||
);
|
||||
$vEvent->DTEND['VALUE'] = 'DATE';
|
||||
$vEvent->{'UID'} = $doc->UID;
|
||||
$vEvent->{'RRULE'} = 'FREQ=YEARLY';
|
||||
$vEvent->{'SUMMARY'} = $title . ' (' . $date->format('Y') . ')';
|
||||
$vEvent->{'TRANSP'} = 'TRANSPARENT';
|
||||
$vCal->add($vEvent);
|
||||
return $vCal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*/
|
||||
public function syncUser($user) {
|
||||
$books = $this->cardDavBackEnd->getAddressBooksForUser('principals/users/'.$user);
|
||||
foreach($books as $book) {
|
||||
$cards = $this->cardDavBackEnd->getCards($book['id']);
|
||||
foreach($cards as $card) {
|
||||
$this->onCardChanged($book['id'], $card['uri'], $card['carddata']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $existingCalendarData
|
||||
* @param VCalendar $newCalendarData
|
||||
* @return bool
|
||||
*/
|
||||
public function birthdayEvenChanged($existingCalendarData, $newCalendarData) {
|
||||
try {
|
||||
$existingBirthday = Reader::read($existingCalendarData);
|
||||
} catch (Exception $ex) {
|
||||
return true;
|
||||
}
|
||||
if ($newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
|
||||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -235,6 +235,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
return array_values($calendars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $principal
|
||||
* @param string $uri
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCalendarByUri($principal, $uri) {
|
||||
$fields = array_values($this->propertyMap);
|
||||
$fields[] = 'id';
|
||||
|
@ -1367,4 +1372,5 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
public function applyShareAcl($resourceId, $acl) {
|
||||
return $this->sharingBackend->applyShareAcl($resourceId, $acl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -80,6 +80,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
|||
}
|
||||
|
||||
function delete() {
|
||||
if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
|
||||
$principal = 'principal:' . parent::getOwner();
|
||||
$shares = $this->getShares();
|
||||
|
|
|
@ -37,6 +37,8 @@ use Sabre\DAV\Exception\BadRequest;
|
|||
use Sabre\HTTP\URLUtil;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Reader;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
class CardDavBackend implements BackendInterface, SyncSupport {
|
||||
|
||||
|
@ -64,15 +66,22 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
|||
const ACCESS_READ_WRITE = 2;
|
||||
const ACCESS_READ = 3;
|
||||
|
||||
/** @var EventDispatcherInterface */
|
||||
private $dispatcher;
|
||||
|
||||
/**
|
||||
* CardDavBackend constructor.
|
||||
*
|
||||
* @param IDBConnection $db
|
||||
* @param Principal $principalBackend
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(IDBConnection $db, Principal $principalBackend) {
|
||||
public function __construct(IDBConnection $db,
|
||||
Principal $principalBackend,
|
||||
$dispatcher ) {
|
||||
$this->db = $db;
|
||||
$this->principalBackend = $principalBackend;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->sharingBackend = new Backend($this->db, $principalBackend, 'addressbook');
|
||||
}
|
||||
|
||||
|
@ -492,6 +501,14 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
|||
$this->addChange($addressBookId, $cardUri, 1);
|
||||
$this->updateProperties($addressBookId, $cardUri, $cardData);
|
||||
|
||||
if (!is_null($this->dispatcher)) {
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::createCard',
|
||||
new GenericEvent(null, [
|
||||
'addressBookId' => $addressBookId,
|
||||
'cardUri' => $cardUri,
|
||||
'cardData' => $cardData]));
|
||||
}
|
||||
|
||||
return '"' . $etag . '"';
|
||||
}
|
||||
|
||||
|
@ -536,6 +553,14 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
|||
$this->addChange($addressBookId, $cardUri, 2);
|
||||
$this->updateProperties($addressBookId, $cardUri, $cardData);
|
||||
|
||||
if (!is_null($this->dispatcher)) {
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::updateCard',
|
||||
new GenericEvent(null, [
|
||||
'addressBookId' => $addressBookId,
|
||||
'cardUri' => $cardUri,
|
||||
'cardData' => $cardData]));
|
||||
}
|
||||
|
||||
return '"' . $etag . '"';
|
||||
}
|
||||
|
||||
|
@ -560,6 +585,13 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
|||
|
||||
$this->addChange($addressBookId, $cardUri, 3);
|
||||
|
||||
if (!is_null($this->dispatcher)) {
|
||||
$this->dispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::deleteCard',
|
||||
new GenericEvent(null, [
|
||||
'addressBookId' => $addressBookId,
|
||||
'cardUri' => $cardUri]));
|
||||
}
|
||||
|
||||
if ($ret === 1) {
|
||||
if ($cardId !== null) {
|
||||
$this->purgeProperties($addressBookId, $cardId);
|
||||
|
|
|
@ -36,6 +36,7 @@ class RootCollection extends SimpleCollection {
|
|||
public function __construct() {
|
||||
$config = \OC::$server->getConfig();
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$dispatcher = \OC::$server->getEventDispatcher();
|
||||
$userPrincipalBackend = new Principal(
|
||||
\OC::$server->getUserManager(),
|
||||
\OC::$server->getGroupManager()
|
||||
|
@ -79,11 +80,11 @@ class RootCollection extends SimpleCollection {
|
|||
\OC::$server->getLogger()
|
||||
);
|
||||
|
||||
$usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend);
|
||||
$usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher);
|
||||
$usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, 'principals/users');
|
||||
$usersAddressBookRoot->disableListing = $disableListing;
|
||||
|
||||
$systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend);
|
||||
$systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher);
|
||||
$systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system');
|
||||
$systemAddressBookRoot->disableListing = $disableListing;
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ sleep 30
|
|||
# run the tests
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail --basedir "$SCRIPTPATH/../caldavtest/" -o cdt.txt \
|
||||
"CalDAV/current-user-principal.xml" \
|
||||
"CalDAV/sync-report.xml" \
|
||||
"CalDAV/sharing-calendars.xml"
|
||||
|
||||
RESULT=$?
|
||||
|
|
|
@ -37,7 +37,8 @@ class CalendarTest extends TestCase {
|
|||
$calendarInfo = [
|
||||
'{http://owncloud.org/ns}owner-principal' => 'user1',
|
||||
'principaluri' => 'user2',
|
||||
'id' => 666
|
||||
'id' => 666,
|
||||
'uri' => 'cal',
|
||||
];
|
||||
$c = new Calendar($backend, $calendarInfo);
|
||||
$c->delete();
|
||||
|
@ -56,7 +57,8 @@ class CalendarTest extends TestCase {
|
|||
$calendarInfo = [
|
||||
'{http://owncloud.org/ns}owner-principal' => 'user1',
|
||||
'principaluri' => 'user2',
|
||||
'id' => 666
|
||||
'id' => 666,
|
||||
'uri' => 'cal',
|
||||
];
|
||||
$c = new Calendar($backend, $calendarInfo);
|
||||
$c->delete();
|
||||
|
|
171
apps/dav/tests/unit/carddav/birthdayservicetest.php
Normal file
171
apps/dav/tests/unit/carddav/birthdayservicetest.php
Normal file
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Tests\Unit\CardDAV;
|
||||
|
||||
use OCA\DAV\CalDAV\BirthdayService;
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use Sabre\VObject\Component\VCalendar;
|
||||
use Sabre\VObject\Reader;
|
||||
use Test\TestCase;
|
||||
|
||||
class BirthdayServiceTest extends TestCase {
|
||||
|
||||
/** @var BirthdayService */
|
||||
private $service;
|
||||
/** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $calDav;
|
||||
/** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $cardDav;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->calDav = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock();
|
||||
$this->cardDav = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->service = new BirthdayService($this->calDav, $this->cardDav);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesVCards
|
||||
* @param boolean $nullExpected
|
||||
* @param string | null $data
|
||||
*/
|
||||
public function testBuildBirthdayFromContact($nullExpected, $data) {
|
||||
$cal = $this->service->buildBirthdayFromContact($data);
|
||||
if ($nullExpected) {
|
||||
$this->assertNull($cal);
|
||||
} else {
|
||||
$this->assertInstanceOf('Sabre\VObject\Component\VCalendar', $cal);
|
||||
$this->assertTrue(isset($cal->VEVENT));
|
||||
$this->assertEquals('FREQ=YEARLY', $cal->VEVENT->RRULE->getValue());
|
||||
$this->assertEquals('12345\'s Birthday (1900)', $cal->VEVENT->SUMMARY->getValue());
|
||||
$this->assertEquals('TRANSPARENT', $cal->VEVENT->TRANSP->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public function testOnCardDeleted() {
|
||||
$this->cardDav->expects($this->once())->method('getAddressBookById')
|
||||
->with(666)
|
||||
->willReturn([
|
||||
'principaluri' => 'principals/users/user01',
|
||||
'uri' => 'default'
|
||||
]);
|
||||
$this->calDav->expects($this->once())->method('getCalendarByUri')
|
||||
->with('principals/users/user01', 'contact_birthdays')
|
||||
->willReturn([
|
||||
'id' => 1234
|
||||
]);
|
||||
$this->calDav->expects($this->once())->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics');
|
||||
|
||||
$this->service->onCardDeleted(666, 'gump.vcf');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesCardChanges
|
||||
*/
|
||||
public function testOnCardChanged($expectedOp) {
|
||||
$this->cardDav->expects($this->once())->method('getAddressBookById')
|
||||
->with(666)
|
||||
->willReturn([
|
||||
'principaluri' => 'principals/users/user01',
|
||||
'uri' => 'default'
|
||||
]);
|
||||
$this->calDav->expects($this->once())->method('getCalendarByUri')
|
||||
->with('principals/users/user01', 'contact_birthdays')
|
||||
->willReturn([
|
||||
'id' => 1234
|
||||
]);
|
||||
|
||||
/** @var BirthdayService | \PHPUnit_Framework_MockObject_MockObject $service */
|
||||
$service = $this->getMock('\OCA\DAV\CalDAV\BirthdayService',
|
||||
['buildBirthdayFromContact', 'birthdayEvenChanged'], [$this->calDav, $this->cardDav]);
|
||||
|
||||
if ($expectedOp === 'delete') {
|
||||
$this->calDav->expects($this->once())->method('getCalendarObject')->willReturn('');
|
||||
$service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(null);
|
||||
$this->calDav->expects($this->once())->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics');
|
||||
}
|
||||
if ($expectedOp === 'create') {
|
||||
$service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(new VCalendar());
|
||||
$this->calDav->expects($this->once())->method('createCalendarObject')->with(1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n");
|
||||
}
|
||||
if ($expectedOp === 'update') {
|
||||
$service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(new VCalendar());
|
||||
$service->expects($this->once())->method('birthdayEvenChanged')->willReturn(true);
|
||||
$this->calDav->expects($this->once())->method('getCalendarObject')->willReturn([
|
||||
'calendardata' => '']);
|
||||
$this->calDav->expects($this->once())->method('updateCalendarObject')->with(1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n");
|
||||
}
|
||||
|
||||
$service->onCardChanged(666, 'gump.vcf', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesBirthday
|
||||
* @param $expected
|
||||
* @param $old
|
||||
* @param $new
|
||||
*/
|
||||
public function testBirthdayEvenChanged($expected, $old, $new) {
|
||||
$new = Reader::read($new);
|
||||
$this->assertEquals($expected, $this->service->birthdayEvenChanged($old, $new));
|
||||
}
|
||||
|
||||
public function providesBirthday() {
|
||||
return [
|
||||
[true,
|
||||
'',
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
|
||||
[false,
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
|
||||
[true,
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:4567's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
|
||||
[true,
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000102\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"]
|
||||
];
|
||||
}
|
||||
|
||||
public function providesCardChanges(){
|
||||
return[
|
||||
['delete'],
|
||||
['create'],
|
||||
['update']
|
||||
];
|
||||
}
|
||||
|
||||
public function providesVCards() {
|
||||
return [
|
||||
[true, null],
|
||||
[true, ''],
|
||||
[true, 'yasfewf'],
|
||||
[true, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
|
||||
[true, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
|
||||
[true, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:someday\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
|
||||
[false, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:1900-01-01\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -77,7 +77,7 @@ class CardDavBackendTest extends TestCase {
|
|||
|
||||
$this->db = \OC::$server->getDatabaseConnection();
|
||||
|
||||
$this->backend = new CardDavBackend($this->db, $this->principal);
|
||||
$this->backend = new CardDavBackend($this->db, $this->principal, null);
|
||||
|
||||
// start every test with a empty cards_properties and cards table
|
||||
$query = $this->db->getQueryBuilder();
|
||||
|
@ -155,7 +155,7 @@ class CardDavBackendTest extends TestCase {
|
|||
|
||||
/** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backend */
|
||||
$backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
|
||||
->setConstructorArgs([$this->db, $this->principal])
|
||||
->setConstructorArgs([$this->db, $this->principal, null])
|
||||
->setMethods(['updateProperties', 'purgeProperties'])->getMock();
|
||||
|
||||
// create a new address book
|
||||
|
@ -201,7 +201,7 @@ class CardDavBackendTest extends TestCase {
|
|||
public function testMultiCard() {
|
||||
|
||||
$this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
|
||||
->setConstructorArgs([$this->db, $this->principal])
|
||||
->setConstructorArgs([$this->db, $this->principal, null])
|
||||
->setMethods(['updateProperties'])->getMock();
|
||||
|
||||
// create a new address book
|
||||
|
@ -248,7 +248,7 @@ class CardDavBackendTest extends TestCase {
|
|||
public function testDeleteWithoutCard() {
|
||||
|
||||
$this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
|
||||
->setConstructorArgs([$this->db, $this->principal])
|
||||
->setConstructorArgs([$this->db, $this->principal, null])
|
||||
->setMethods([
|
||||
'getCardId',
|
||||
'addChange',
|
||||
|
@ -289,7 +289,7 @@ class CardDavBackendTest extends TestCase {
|
|||
public function testSyncSupport() {
|
||||
|
||||
$this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
|
||||
->setConstructorArgs([$this->db, $this->principal])
|
||||
->setConstructorArgs([$this->db, $this->principal, null])
|
||||
->setMethods(['updateProperties'])->getMock();
|
||||
|
||||
// create a new address book
|
||||
|
@ -347,7 +347,7 @@ class CardDavBackendTest extends TestCase {
|
|||
$cardId = 2;
|
||||
|
||||
$backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
|
||||
->setConstructorArgs([$this->db, $this->principal])
|
||||
->setConstructorArgs([$this->db, $this->principal, null])
|
||||
->setMethods(['getCardId'])->getMock();
|
||||
|
||||
$backend->expects($this->any())->method('getCardId')->willReturn($cardId);
|
||||
|
|
Loading…
Reference in a new issue