Skip to content

Commit 26a474d

Browse files
committed
WIP: integrate Dav app with Calendar API
1 parent df6f3bd commit 26a474d

5 files changed

Lines changed: 293 additions & 3 deletions

File tree

apps/dav/appinfo/app.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,11 @@ function(GenericEvent $event) use ($app) {
5454
$app->setupContactsProvider($cm, $user->getUID());
5555
}
5656
});
57+
58+
$calendarManager = \OC::$server->getCalendarManager();
59+
$calendarManager->register(function() use ($calendarManager, $app) {
60+
$user = \OC::$server->getUserSession()->getUser();
61+
if ($user !== null) {
62+
$app->setupCalendarProvider($calendarManager, $user->getUID());
63+
}
64+
});

apps/dav/lib/AppInfo/Application.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@
2828
use OCA\DAV\CalDAV\Activity\Backend;
2929
use OCA\DAV\CalDAV\Activity\Provider\Event;
3030
use OCA\DAV\CalDAV\BirthdayService;
31+
use OCA\DAV\CalDAV\CalendarManager;
3132
use OCA\DAV\Capabilities;
3233
use OCA\DAV\CardDAV\ContactsManager;
3334
use OCA\DAV\CardDAV\PhotoCache;
3435
use OCA\DAV\CardDAV\SyncService;
3536
use OCA\DAV\HookManager;
3637
use \OCP\AppFramework\App;
37-
use OCP\Contacts\IManager;
38+
use OCP\Contacts\IManager as IContactsManager;
39+
use OCP\Calendar\IManager as ICalendarManager;
3840
use OCP\IUser;
3941
use Symfony\Component\EventDispatcher\GenericEvent;
4042

@@ -62,16 +64,25 @@ public function __construct() {
6264
}
6365

6466
/**
65-
* @param IManager $contactsManager
67+
* @param IContactsManager $contactsManager
6668
* @param string $userID
6769
*/
68-
public function setupContactsProvider(IManager $contactsManager, $userID) {
70+
public function setupContactsProvider(IContactsManager $contactsManager, $userID) {
6971
/** @var ContactsManager $cm */
7072
$cm = $this->getContainer()->query(ContactsManager::class);
7173
$urlGenerator = $this->getContainer()->getServer()->getURLGenerator();
7274
$cm->setupContactsProvider($contactsManager, $userID, $urlGenerator);
7375
}
7476

77+
/**
78+
* @param ICalendarManager $calendarManager
79+
* @param string $userId
80+
*/
81+
public function setupCalendarProvider(ICalendarManager $calendarManager, $userId) {
82+
$cm = $this->getContainer()->query(CalendarManager::class);
83+
$cm->setupCalendarProvider($calendarManager, $userId);
84+
}
85+
7586
public function registerHooks() {
7687
/** @var HookManager $hm */
7788
$hm = $this->getContainer()->query(HookManager::class);

apps/dav/lib/CalDAV/CalDavBackend.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,87 @@ public function calendarSearch($principalUri, array $filters, $limit=null, $offs
13231323
return $result;
13241324
}
13251325

1326+
/**
1327+
* used for Nextcloud's calendar API
1328+
*
1329+
* @param array $calendarInfo
1330+
* @param string $pattern
1331+
* @param array $searchProperties
1332+
* @param array $options
1333+
* @param integer|null $limit
1334+
* @param integer|null $offset
1335+
*
1336+
* @return array
1337+
*/
1338+
public function search(array $calendarInfo, $pattern, array $searchProperties,
1339+
array $options, $limit, $offset) {
1340+
$outerQuery = $this->db->getQueryBuilder();
1341+
$innerQuery = $this->db->getQueryBuilder();
1342+
1343+
$innerQuery->selectDistinct('op.objectid')
1344+
->from($this->dbObjectPropertiesTable, 'op')
1345+
->andWhere($innerQuery->expr()->eq('op.calendarid',
1346+
$innerQuery->createNamedParameter($calendarInfo['id'])));
1347+
1348+
// only return public items for shared calendars for now
1349+
if ($calendarInfo['principaluri'] !== $calendarInfo['{http://owncloud.org/ns}owner-principal']) {
1350+
$innerQuery->andWhere($innerQuery->expr()->eq('c.classification',
1351+
$innerQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1352+
}
1353+
1354+
$or = $innerQuery->expr()->orX();
1355+
foreach($searchProperties as $searchProperty) {
1356+
$or->add($innerQuery->expr()->eq('op.name',
1357+
$innerQuery->createNamedParameter($searchProperty)));
1358+
}
1359+
$innerQuery->andWhere($or);
1360+
1361+
// TODO - add component-type
1362+
1363+
if ($pattern !== '') {
1364+
$innerQuery->andWhere($innerQuery->expr()->iLike('op.value',
1365+
'%' . $this->db->escapeLikeParameter($pattern) . '%'));
1366+
}
1367+
1368+
$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid')
1369+
->from('calendarobjects', 'c');
1370+
1371+
if (isset($options['timerange'])) {
1372+
if (isset($options['timerange']['start'])) {
1373+
$outerQuery->andWhere($outerQuery->expr()->gt('lastoccurence',
1374+
$outerQuery->createNamedParameter($options['timerange']['start']->getTimeStamp)));
1375+
1376+
}
1377+
if (isset($options['timerange']['end'])) {
1378+
$outerQuery->andWhere($outerQuery->expr()->lt('firstoccurence',
1379+
$outerQuery->createNamedParameter($options['timerange']['end']->getTimeStamp)));
1380+
}
1381+
1382+
}
1383+
1384+
$outerQuery->andWhere($outerQuery->expr()->in('c.id',
1385+
$outerQuery->createFunction($innerQuery->getSQL())));
1386+
1387+
if ($offset) {
1388+
$outerQuery->setFirstResult($offset);
1389+
}
1390+
if ($limit) {
1391+
$outerQuery->setMaxResults($limit);
1392+
}
1393+
1394+
$result = $outerQuery->execute();
1395+
$calendarObjects = $result->fetchAll();
1396+
1397+
return array_map(function($o) {
1398+
return [
1399+
'id' => $o['id'],
1400+
'type' => $o['componenttype'],
1401+
'uid' => $o['uid'],
1402+
'objects' => [],
1403+
];
1404+
}, $calendarObjects);
1405+
}
1406+
13261407
/**
13271408
* Searches through all of a users calendars and calendar objects to find
13281409
* an object with a specific UID.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
/**
3+
* @copyright 2017, Georg Ehrke <oc.list@georgehrke.com>
4+
*
5+
* @author Georg Ehrke <oc.list@georgehrke.com>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
namespace OCA\DAV\CalDAV;
25+
26+
use OCP\Constants;
27+
use OCP\Calendar\ICalendar;
28+
29+
class CalendarImpl implements ICalendar {
30+
31+
/** @var CalDavBackend */
32+
private $backend;
33+
34+
/** @var Calendar */
35+
private $calendar;
36+
37+
/** @var array */
38+
private $calendarInfo;
39+
40+
/**
41+
* CalendarImpl constructor.
42+
*
43+
* @param Calendar $calendar
44+
* @param array $calendarInfo
45+
* @param CalDavBackend $backend
46+
*/
47+
public function __construct(Calendar $calendar, array $calendarInfo,
48+
CalDavBackend $backend) {
49+
$this->calendar = $calendar;
50+
$this->calendarInfo = $calendarInfo;
51+
$this->backend = $backend;
52+
}
53+
54+
/**
55+
* @return string defining the technical unique key
56+
* @since 13.0.0
57+
*/
58+
public function getKey() {
59+
return $this->calendarInfo['id'];
60+
}
61+
62+
/**
63+
* In comparison to getKey() this function returns a human readable (maybe translated) name
64+
* @return null|string
65+
* @since 13.0.0
66+
*/
67+
public function getDisplayName() {
68+
return $this->calendarInfo['{DAV:}displayname'];
69+
}
70+
71+
/**
72+
* Calendar color
73+
* @return null|string
74+
* @since 13.0.0
75+
*/
76+
public function getDisplayColor() {
77+
return $this->calendarInfo['{http://apple.com/ns/ical/}calendar-color'];
78+
}
79+
80+
/**
81+
* @param string $pattern which should match within the $searchProperties
82+
* @param array $searchProperties defines the properties within the query pattern should match
83+
* @param array $options - optional parameters:
84+
* ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]]
85+
* @param integer|null $limit - limit number of search results
86+
* @param integer|null $offset - offset for paging of search results
87+
* @return array an array of events/journals/todos which are arrays of key-value-pairs
88+
* @since 13.0.0
89+
*/
90+
public function search($pattern, array $searchProperties=[], array $options=[], $limit=null, $offset=null) {
91+
return $this->backend->calendarAPISearch($this->calendarInfo, $pattern,
92+
$searchProperties, $options, $limit, $offset);
93+
}
94+
95+
/**
96+
* @return integer build up using \OCP\Constants
97+
* @since 13.0.0
98+
*/
99+
public function getPermissions() {
100+
$permissions = $this->calendar->getACL();
101+
$result = 0;
102+
foreach ($permissions as $permission) {
103+
switch($permission['privilege']) {
104+
case '{DAV:}read':
105+
$result |= Constants::PERMISSION_READ;
106+
break;
107+
case '{DAV:}write':
108+
$result |= Constants::PERMISSION_CREATE;
109+
$result |= Constants::PERMISSION_UPDATE;
110+
break;
111+
case '{DAV:}all':
112+
$result |= Constants::PERMISSION_ALL;
113+
break;
114+
}
115+
}
116+
117+
return $result;
118+
}
119+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* @copyright 2017, Georg Ehrke <oc.list@georgehrke.com>
4+
*
5+
* @author Georg Ehrke <oc.list@georgehrke.com>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
namespace OCA\DAV\CalDAV;
25+
26+
use OCP\Calendar\IManager;
27+
use OCP\IL10N;
28+
29+
class CalendarManager {
30+
31+
/** @var CalDavBackend */
32+
private $backend;
33+
34+
/** @var IL10N */
35+
private $l10n;
36+
37+
/**
38+
* CalendarManager constructor.
39+
*
40+
* @param CalDavBackend $backend
41+
* @param IL10N $l10n
42+
*/
43+
public function __construct(CalDavBackend $backend, IL10N $l10n) {
44+
$this->backend = $backend;
45+
$this->l10n = $l10n;
46+
}
47+
48+
/**
49+
* @param IManager $cm
50+
* @param string $userId
51+
*/
52+
public function setupCalendarProvider(IManager $cm, $userId) {
53+
$calendars = $this->backend->getCalendarsForUser("principals/users/$userId");
54+
$this->register($cm, $calendars);
55+
}
56+
57+
/**
58+
* @param IManager $cm
59+
* @param array $calendars
60+
*/
61+
private function register(IManager $cm, array $calendars) {
62+
foreach($calendars as $calendarInfo) {
63+
$calendar = new Calendar($this->backend, $calendarInfo, $this->l10n);
64+
$cm->registerCalendar(new CalendarImpl(
65+
$calendar,
66+
$calendarInfo,
67+
$this->backend
68+
));
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)