xref: /plugin/davcal/calendarBackendDokuwiki.php (revision d99db92ea6d030c67c6b91dc1125e4f4b360c150)
1a1a3b679SAndreas Boehler<?php
2a1a3b679SAndreas Boehler
3a1a3b679SAndreas Boehleruse \Sabre\VObject;
4a1a3b679SAndreas Boehleruse \Sabre\CalDAV;
5a1a3b679SAndreas Boehleruse \Sabre\DAV;
6a1a3b679SAndreas Boehleruse \Sabre\DAV\Exception\Forbidden;
7a1a3b679SAndreas Boehler/**
8a1a3b679SAndreas Boehler * PDO CalDAV backend for DokuWiki - based on Sabre's CalDAV backend
9a1a3b679SAndreas Boehler *
10a1a3b679SAndreas Boehler * This backend is used to store calendar-data in a PDO database, such as
11a1a3b679SAndreas Boehler * sqlite or MySQL
12a1a3b679SAndreas Boehler *
13a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
14a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
15a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
16a1a3b679SAndreas Boehler */
17d5703f5aSAndreas Boehlerclass DokuWikiSabreCalendarBackend extends \Sabre\CalDAV\Backend\AbstractBackend
18d5703f5aSAndreas Boehler{
19a1a3b679SAndreas Boehler
20a1a3b679SAndreas Boehler
21a1a3b679SAndreas Boehler    /**
22a1a3b679SAndreas Boehler     * DokuWiki PlugIn Helper
23a1a3b679SAndreas Boehler     */
24a1a3b679SAndreas Boehler    protected $hlp = null;
25a1a3b679SAndreas Boehler    /**
26a1a3b679SAndreas Boehler
27a1a3b679SAndreas Boehler    /**
28a1a3b679SAndreas Boehler     * List of CalDAV properties, and how they map to database fieldnames
29a1a3b679SAndreas Boehler     * Add your own properties by simply adding on to this array.
30a1a3b679SAndreas Boehler     *
31a1a3b679SAndreas Boehler     * Note that only string-based properties are supported here.
32a1a3b679SAndreas Boehler     *
33a1a3b679SAndreas Boehler     * @var array
34a1a3b679SAndreas Boehler     */
35d5703f5aSAndreas Boehler    public $propertyMap = array(
36a1a3b679SAndreas Boehler        '{DAV:}displayname'                                   => 'displayname',
37a1a3b679SAndreas Boehler        '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description',
38a1a3b679SAndreas Boehler        '{urn:ietf:params:xml:ns:caldav}calendar-timezone'    => 'timezone',
39d5703f5aSAndreas Boehler        //'{http://apple.com/ns/ical/}calendar-order'           => 'calendarorder',
40d5703f5aSAndreas Boehler        //'{http://apple.com/ns/ical/}calendar-color'           => 'calendarcolor',
41d5703f5aSAndreas Boehler    );
42a1a3b679SAndreas Boehler
43a1a3b679SAndreas Boehler    /**
44a1a3b679SAndreas Boehler     * Creates the backend
45a1a3b679SAndreas Boehler     *
46a1a3b679SAndreas Boehler     * @param \PDO $pdo
47a1a3b679SAndreas Boehler     */
48d5703f5aSAndreas Boehler    function __construct(&$hlp)
49d5703f5aSAndreas Boehler    {
50a1a3b679SAndreas Boehler
51d5703f5aSAndreas Boehler        $this->hlp = $hlp;
52a1a3b679SAndreas Boehler
53a1a3b679SAndreas Boehler    }
54a1a3b679SAndreas Boehler
55a1a3b679SAndreas Boehler    /**
56a1a3b679SAndreas Boehler     * Returns a list of calendars for a principal.
57a1a3b679SAndreas Boehler     *
58a1a3b679SAndreas Boehler     * Every project is an array with the following keys:
59a1a3b679SAndreas Boehler     *  * id, a unique id that will be used by other functions to modify the
60a1a3b679SAndreas Boehler     *    calendar. This can be the same as the uri or a database key.
61a1a3b679SAndreas Boehler     *  * uri. This is just the 'base uri' or 'filename' of the calendar.
62a1a3b679SAndreas Boehler     *  * principaluri. The owner of the calendar. Almost always the same as
63a1a3b679SAndreas Boehler     *    principalUri passed to this method.
64a1a3b679SAndreas Boehler     *
65a1a3b679SAndreas Boehler     * Furthermore it can contain webdav properties in clark notation. A very
66a1a3b679SAndreas Boehler     * common one is '{DAV:}displayname'.
67a1a3b679SAndreas Boehler     *
68a1a3b679SAndreas Boehler     * Many clients also require:
69a1a3b679SAndreas Boehler     * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
70a1a3b679SAndreas Boehler     * For this property, you can just return an instance of
71a1a3b679SAndreas Boehler     * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet.
72a1a3b679SAndreas Boehler     *
73a1a3b679SAndreas Boehler     * If you return {http://sabredav.org/ns}read-only and set the value to 1,
74a1a3b679SAndreas Boehler     * ACL will automatically be put in read-only mode.
75a1a3b679SAndreas Boehler     *
76a1a3b679SAndreas Boehler     * @param string $principalUri
77a1a3b679SAndreas Boehler     * @return array
78a1a3b679SAndreas Boehler     */
79d5703f5aSAndreas Boehler    function getCalendarsForUser($principalUri)
80d5703f5aSAndreas Boehler    {
81c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getCalendarsForUser called for: '.$principalUri, __FILE__, __LINE__);
82a1a3b679SAndreas Boehler        $fields = array_values($this->propertyMap);
83a1a3b679SAndreas Boehler        $fields[] = 'id';
84a1a3b679SAndreas Boehler        $fields[] = 'uri';
85a1a3b679SAndreas Boehler        $fields[] = 'synctoken';
86a1a3b679SAndreas Boehler        $fields[] = 'components';
87a1a3b679SAndreas Boehler        $fields[] = 'principaluri';
88a1a3b679SAndreas Boehler        $fields[] = 'transparent';
89a1a3b679SAndreas Boehler
90a1a3b679SAndreas Boehler        $idInfo = $this->hlp->getCalendarIdsForUser($principalUri);
91d5703f5aSAndreas Boehler        $calendars = array();
92d5703f5aSAndreas Boehler        foreach($idInfo as $id => $data)
93d5703f5aSAndreas Boehler        {
94d5703f5aSAndreas Boehler            $row = $this->hlp->getCalendarSettings($id);
95*d99db92eSscottleechua
96*d99db92eSscottleechua            // Skip this calendar if settings couldn't be retrieved
97*d99db92eSscottleechua            if (!$row) {
98*d99db92eSscottleechua                \dokuwiki\Logger::debug('DAVCAL', 'Skipping calendar '.$id.' - settings not found', __FILE__, __LINE__);
99*d99db92eSscottleechua                continue;
100*d99db92eSscottleechua            }
101*d99db92eSscottleechua
102d5703f5aSAndreas Boehler            $components = array();
103d5703f5aSAndreas Boehler            if ($row['components'])
104d5703f5aSAndreas Boehler            {
105a1a3b679SAndreas Boehler                $components = explode(',', $row['components']);
106a1a3b679SAndreas Boehler            }
107a1a3b679SAndreas Boehler
108d5703f5aSAndreas Boehler            $calendar = array(
109a1a3b679SAndreas Boehler                'id'                                                                 => $row['id'],
110a1a3b679SAndreas Boehler                'uri'                                                                => $row['uri'],
111d5703f5aSAndreas Boehler                'principaluri'                                                       => $principalUri,//Overwrite principaluri from database, we actually don't need it.
112a1a3b679SAndreas Boehler                '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}getctag'                  => 'http://sabre.io/ns/sync/' . ($row['synctoken'] ? $row['synctoken'] : '0'),
113a1a3b679SAndreas Boehler                '{http://sabredav.org/ns}sync-token'                                 => $row['synctoken'] ? $row['synctoken'] : '0',
114a1a3b679SAndreas Boehler                '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet($components),
115d5703f5aSAndreas Boehler                //'{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp'         => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
116d5703f5aSAndreas Boehler            );
117*d99db92eSscottleechua            if(isset($idInfo[$id]['readonly']) && $idInfo[$id]['readonly'] === true)
118a1a3b679SAndreas Boehler                $calendar['{http://sabredav.org/ns}read-only'] = '1';
119a1a3b679SAndreas Boehler
120a1a3b679SAndreas Boehler
121d5703f5aSAndreas Boehler            foreach ($this->propertyMap as $xmlName => $dbName)
122d5703f5aSAndreas Boehler            {
123a1a3b679SAndreas Boehler                $calendar[$xmlName] = $row[$dbName];
124a1a3b679SAndreas Boehler            }
125a1a3b679SAndreas Boehler
126a1a3b679SAndreas Boehler            $calendars[] = $calendar;
127a1a3b679SAndreas Boehler
128a1a3b679SAndreas Boehler        }
129c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Calendars returned: '.count($calendars), __FILE__, __LINE__);
130a1a3b679SAndreas Boehler        return $calendars;
131a1a3b679SAndreas Boehler
132a1a3b679SAndreas Boehler    }
133a1a3b679SAndreas Boehler
134a1a3b679SAndreas Boehler    /**
135a1a3b679SAndreas Boehler     * Creates a new calendar for a principal.
136a1a3b679SAndreas Boehler     *
137a1a3b679SAndreas Boehler     * If the creation was a success, an id must be returned that can be used
138a1a3b679SAndreas Boehler     * to reference this calendar in other methods, such as updateCalendar.
139a1a3b679SAndreas Boehler     *
140a1a3b679SAndreas Boehler     * @param string $principalUri
141a1a3b679SAndreas Boehler     * @param string $calendarUri
142a1a3b679SAndreas Boehler     * @param array $properties
143a1a3b679SAndreas Boehler     * @return string
144a1a3b679SAndreas Boehler     */
145d5703f5aSAndreas Boehler    function createCalendar($principalUri, $calendarUri, array $properties)
146d5703f5aSAndreas Boehler    {
147c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'createCalendar called, returning false', __FILE__, __LINE__);
148a1a3b679SAndreas Boehler        return false;
149a1a3b679SAndreas Boehler    }
150a1a3b679SAndreas Boehler
151a1a3b679SAndreas Boehler    /**
152a1a3b679SAndreas Boehler     * Updates properties for a calendar.
153a1a3b679SAndreas Boehler     *
154a1a3b679SAndreas Boehler     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
155a1a3b679SAndreas Boehler     * To do the actual updates, you must tell this object which properties
156a1a3b679SAndreas Boehler     * you're going to process with the handle() method.
157a1a3b679SAndreas Boehler     *
158a1a3b679SAndreas Boehler     * Calling the handle method is like telling the PropPatch object "I
159a1a3b679SAndreas Boehler     * promise I can handle updating this property".
160a1a3b679SAndreas Boehler     *
161a1a3b679SAndreas Boehler     * Read the PropPatch documenation for more info and examples.
162a1a3b679SAndreas Boehler     *
163a1a3b679SAndreas Boehler     * @param string $calendarId
164a1a3b679SAndreas Boehler     * @param \Sabre\DAV\PropPatch $propPatch
165a1a3b679SAndreas Boehler     * @return void
166a1a3b679SAndreas Boehler     */
167d5703f5aSAndreas Boehler    function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch)
168d5703f5aSAndreas Boehler    {
169c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'updateCalendar for calendarId '.$calendarId, __FILE__, __LINE__);
170a1a3b679SAndreas Boehler        $supportedProperties = array_keys($this->propertyMap);
171a1a3b679SAndreas Boehler
172d5703f5aSAndreas Boehler        $propPatch->handle($supportedProperties, function($mutations) use ($calendarId)
173d5703f5aSAndreas Boehler        {
174d5703f5aSAndreas Boehler            foreach ($mutations as $propertyName => $propertyValue)
175d5703f5aSAndreas Boehler            {
176a1a3b679SAndreas Boehler
177d5703f5aSAndreas Boehler                switch ($propertyName)
178d5703f5aSAndreas Boehler                {
179d5703f5aSAndreas Boehler                    case '{DAV:}displayname' :
180c42afaebSscottleechua                        \dokuwiki\Logger::debug('DAVCAL', 'updateCalendarName', __FILE__, __LINE__);
181d5703f5aSAndreas Boehler                        $this->hlp->updateCalendarName($calendarId, $propertyValue);
182d5703f5aSAndreas Boehler                        break;
183d5703f5aSAndreas Boehler                    case '{urn:ietf:params:xml:ns:caldav}calendar-description':
184c42afaebSscottleechua                        \dokuwiki\Logger::debug('DAVCAL', 'updateCalendarDescription', __FILE__, __LINE__);
185d5703f5aSAndreas Boehler                        $this->hlp->updateCalendarDescription($calendarId, $propertyValue);
186d5703f5aSAndreas Boehler                        break;
187d5703f5aSAndreas Boehler                    case '{urn:ietf:params:xml:ns:caldav}calendar-timezone':
188c42afaebSscottleechua                        \dokuwiki\Logger::debug('DAVCAL', 'updateCalendarTimezone', __FILE__, __LINE__);
189d5703f5aSAndreas Boehler                        $this->hlp->updateCalendarTimezone($calendarId, $propertyValue);
190a1a3b679SAndreas Boehler                        break;
191a1a3b679SAndreas Boehler                    default :
192a1a3b679SAndreas Boehler                        break;
193a1a3b679SAndreas Boehler                }
194a1a3b679SAndreas Boehler
195a1a3b679SAndreas Boehler            }
196a1a3b679SAndreas Boehler            return true;
197a1a3b679SAndreas Boehler
198a1a3b679SAndreas Boehler        });
199a1a3b679SAndreas Boehler
200a1a3b679SAndreas Boehler    }
201a1a3b679SAndreas Boehler
202a1a3b679SAndreas Boehler    /**
203a1a3b679SAndreas Boehler     * Delete a calendar and all it's objects
204a1a3b679SAndreas Boehler     *
205a1a3b679SAndreas Boehler     * @param string $calendarId
206a1a3b679SAndreas Boehler     * @return void
207a1a3b679SAndreas Boehler     */
208d5703f5aSAndreas Boehler    function deleteCalendar($calendarId)
209d5703f5aSAndreas Boehler    {
210c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'deleteCalendar called, returning false', __FILE__, __LINE__);
211d5703f5aSAndreas Boehler        return;
212a1a3b679SAndreas Boehler    }
213a1a3b679SAndreas Boehler
214a1a3b679SAndreas Boehler    /**
215a1a3b679SAndreas Boehler     * Returns all calendar objects within a calendar.
216a1a3b679SAndreas Boehler     *
217a1a3b679SAndreas Boehler     * Every item contains an array with the following keys:
218a1a3b679SAndreas Boehler     *   * calendardata - The iCalendar-compatible calendar data
219a1a3b679SAndreas Boehler     *   * uri - a unique key which will be used to construct the uri. This can
220a1a3b679SAndreas Boehler     *     be any arbitrary string, but making sure it ends with '.ics' is a
221a1a3b679SAndreas Boehler     *     good idea. This is only the basename, or filename, not the full
222a1a3b679SAndreas Boehler     *     path.
223a1a3b679SAndreas Boehler     *   * lastmodified - a timestamp of the last modification time
224a1a3b679SAndreas Boehler     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
225a1a3b679SAndreas Boehler     *   '  "abcdef"')
226a1a3b679SAndreas Boehler     *   * size - The size of the calendar objects, in bytes.
227a1a3b679SAndreas Boehler     *   * component - optional, a string containing the type of object, such
228a1a3b679SAndreas Boehler     *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
229a1a3b679SAndreas Boehler     *     the Content-Type header.
230a1a3b679SAndreas Boehler     *
231a1a3b679SAndreas Boehler     * Note that the etag is optional, but it's highly encouraged to return for
232a1a3b679SAndreas Boehler     * speed reasons.
233a1a3b679SAndreas Boehler     *
234a1a3b679SAndreas Boehler     * The calendardata is also optional. If it's not returned
235a1a3b679SAndreas Boehler     * 'getCalendarObject' will be called later, which *is* expected to return
236a1a3b679SAndreas Boehler     * calendardata.
237a1a3b679SAndreas Boehler     *
238a1a3b679SAndreas Boehler     * If neither etag or size are specified, the calendardata will be
239a1a3b679SAndreas Boehler     * used/fetched to determine these numbers. If both are specified the
240a1a3b679SAndreas Boehler     * amount of times this is needed is reduced by a great degree.
241a1a3b679SAndreas Boehler     *
242a1a3b679SAndreas Boehler     * @param string $calendarId
243a1a3b679SAndreas Boehler     * @return array
244a1a3b679SAndreas Boehler     */
245d5703f5aSAndreas Boehler    function getCalendarObjects($calendarId)
246d5703f5aSAndreas Boehler    {
247c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getCalendarObjects for calendarId '.$calendarId, __FILE__, __LINE__);
248d5703f5aSAndreas Boehler        $arr = $this->hlp->getCalendarObjects($calendarId);
249d5703f5aSAndreas Boehler        $result = array();
250d5703f5aSAndreas Boehler        foreach ($arr as $row)
251d5703f5aSAndreas Boehler        {
252d5703f5aSAndreas Boehler            $result[] = array(
253a1a3b679SAndreas Boehler                'id'           => $row['id'],
254a1a3b679SAndreas Boehler                'uri'          => $row['uri'],
255a1a3b679SAndreas Boehler                'lastmodified' => $row['lastmodified'],
256a1a3b679SAndreas Boehler                'etag'         => '"' . $row['etag'] . '"',
257a1a3b679SAndreas Boehler                'calendarid'   => $row['calendarid'],
258a1a3b679SAndreas Boehler                'size'         => (int)$row['size'],
259a1a3b679SAndreas Boehler                'component'    => strtolower($row['componenttype']),
260d5703f5aSAndreas Boehler            );
261a1a3b679SAndreas Boehler        }
262c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Calendar objects returned: '.count($result), __FILE__, __LINE__);
263a1a3b679SAndreas Boehler        return $result;
264a1a3b679SAndreas Boehler
265a1a3b679SAndreas Boehler    }
266a1a3b679SAndreas Boehler
267a1a3b679SAndreas Boehler    /**
268a1a3b679SAndreas Boehler     * Returns information from a single calendar object, based on it's object
269a1a3b679SAndreas Boehler     * uri.
270a1a3b679SAndreas Boehler     *
271a1a3b679SAndreas Boehler     * The object uri is only the basename, or filename and not a full path.
272a1a3b679SAndreas Boehler     *
273a1a3b679SAndreas Boehler     * The returned array must have the same keys as getCalendarObjects. The
274a1a3b679SAndreas Boehler     * 'calendardata' object is required here though, while it's not required
275a1a3b679SAndreas Boehler     * for getCalendarObjects.
276a1a3b679SAndreas Boehler     *
277a1a3b679SAndreas Boehler     * This method must return null if the object did not exist.
278a1a3b679SAndreas Boehler     *
279a1a3b679SAndreas Boehler     * @param string $calendarId
280a1a3b679SAndreas Boehler     * @param string $objectUri
281a1a3b679SAndreas Boehler     * @return array|null
282a1a3b679SAndreas Boehler     */
283d5703f5aSAndreas Boehler    function getCalendarObject($calendarId, $objectUri)
284d5703f5aSAndreas Boehler    {
285c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getCalendarObject for calendarId '.$calendarId.' and objectUri '.$objectUri, __FILE__, __LINE__);
286d5703f5aSAndreas Boehler        $row = $this->hlp->getCalendarObjectByUri($calendarId, $objectUri);
287c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Calendar object row: '.($row ? 'found' : 'not found'), __FILE__, __LINE__);
288d5703f5aSAndreas Boehler        if (!$row)
289d5703f5aSAndreas Boehler            return null;
290a1a3b679SAndreas Boehler
291d5703f5aSAndreas Boehler        return array(
292a1a3b679SAndreas Boehler            'id'            => $row['id'],
293a1a3b679SAndreas Boehler            'uri'           => $row['uri'],
294a1a3b679SAndreas Boehler            'lastmodified'  => $row['lastmodified'],
295a1a3b679SAndreas Boehler            'etag'          => '"' . $row['etag'] . '"',
296a1a3b679SAndreas Boehler            'calendarid'    => $row['calendarid'],
297a1a3b679SAndreas Boehler            'size'          => (int)$row['size'],
298a1a3b679SAndreas Boehler            'calendardata'  => $row['calendardata'],
299a1a3b679SAndreas Boehler            'component'     => strtolower($row['componenttype']),
300d5703f5aSAndreas Boehler         );
301a1a3b679SAndreas Boehler
302a1a3b679SAndreas Boehler    }
303a1a3b679SAndreas Boehler
304a1a3b679SAndreas Boehler    /**
305a1a3b679SAndreas Boehler     * Returns a list of calendar objects.
306a1a3b679SAndreas Boehler     *
307a1a3b679SAndreas Boehler     * This method should work identical to getCalendarObject, but instead
308a1a3b679SAndreas Boehler     * return all the calendar objects in the list as an array.
309a1a3b679SAndreas Boehler     *
310a1a3b679SAndreas Boehler     * If the backend supports this, it may allow for some speed-ups.
311a1a3b679SAndreas Boehler     *
312a1a3b679SAndreas Boehler     * @param mixed $calendarId
313a1a3b679SAndreas Boehler     * @param array $uris
314a1a3b679SAndreas Boehler     * @return array
315a1a3b679SAndreas Boehler     */
316d5703f5aSAndreas Boehler    function getMultipleCalendarObjects($calendarId, array $uris)
317d5703f5aSAndreas Boehler    {
318c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getMultipleCalendarObjects for calendarId '.$calendarId, __FILE__, __LINE__);
319c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'URIs requested: '.count($uris), __FILE__, __LINE__);
320d5703f5aSAndreas Boehler        $arr = $this->hlp->getMultipleCalendarObjectsByUri($calendarId, $uris);
321a1a3b679SAndreas Boehler
322d5703f5aSAndreas Boehler        $result = array();
323d5703f5aSAndreas Boehler        foreach($arr as $row)
324d5703f5aSAndreas Boehler        {
325a1a3b679SAndreas Boehler
326d5703f5aSAndreas Boehler            $result[] = array(
327a1a3b679SAndreas Boehler                'id'           => $row['id'],
328a1a3b679SAndreas Boehler                'uri'          => $row['uri'],
329a1a3b679SAndreas Boehler                'lastmodified' => $row['lastmodified'],
330a1a3b679SAndreas Boehler                'etag'         => '"' . $row['etag'] . '"',
331a1a3b679SAndreas Boehler                'calendarid'   => $row['calendarid'],
332a1a3b679SAndreas Boehler                'size'         => (int)$row['size'],
333a1a3b679SAndreas Boehler                'calendardata' => $row['calendardata'],
334a1a3b679SAndreas Boehler                'component'    => strtolower($row['componenttype']),
335d5703f5aSAndreas Boehler            );
336a1a3b679SAndreas Boehler
337a1a3b679SAndreas Boehler        }
338c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Multiple calendar objects returned: '.count($result), __FILE__, __LINE__);
339a1a3b679SAndreas Boehler        return $result;
340a1a3b679SAndreas Boehler
341a1a3b679SAndreas Boehler    }
342a1a3b679SAndreas Boehler
343a1a3b679SAndreas Boehler
344a1a3b679SAndreas Boehler    /**
345a1a3b679SAndreas Boehler     * Creates a new calendar object.
346a1a3b679SAndreas Boehler     *
347a1a3b679SAndreas Boehler     * The object uri is only the basename, or filename and not a full path.
348a1a3b679SAndreas Boehler     *
349a1a3b679SAndreas Boehler     * It is possible return an etag from this function, which will be used in
350a1a3b679SAndreas Boehler     * the response to this PUT request. Note that the ETag must be surrounded
351a1a3b679SAndreas Boehler     * by double-quotes.
352a1a3b679SAndreas Boehler     *
353a1a3b679SAndreas Boehler     * However, you should only really return this ETag if you don't mangle the
354a1a3b679SAndreas Boehler     * calendar-data. If the result of a subsequent GET to this object is not
355a1a3b679SAndreas Boehler     * the exact same as this request body, you should omit the ETag.
356a1a3b679SAndreas Boehler     *
357a1a3b679SAndreas Boehler     * @param mixed $calendarId
358a1a3b679SAndreas Boehler     * @param string $objectUri
359a1a3b679SAndreas Boehler     * @param string $calendarData
360a1a3b679SAndreas Boehler     * @return string|null
361a1a3b679SAndreas Boehler     */
362d5703f5aSAndreas Boehler    function createCalendarObject($calendarId, $objectUri, $calendarData)
363d5703f5aSAndreas Boehler    {
364c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'createCalendarObject for calendarId '.$calendarId.' and objectUri '.$objectUri, __FILE__, __LINE__);
365c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Calendar data length: '.strlen($calendarData), __FILE__, __LINE__);
366d5703f5aSAndreas Boehler        $etag = $this->hlp->addCalendarEntryToCalendarByICS($calendarId, $objectUri, $calendarData);
367c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'ETag generated: '.$etag, __FILE__, __LINE__);
368a1a3b679SAndreas Boehler
369d5703f5aSAndreas Boehler        return '"' . $etag . '"';
370a1a3b679SAndreas Boehler    }
371a1a3b679SAndreas Boehler
372a1a3b679SAndreas Boehler    /**
373a1a3b679SAndreas Boehler     * Updates an existing calendarobject, based on it's uri.
374a1a3b679SAndreas Boehler     *
375a1a3b679SAndreas Boehler     * The object uri is only the basename, or filename and not a full path.
376a1a3b679SAndreas Boehler     *
377a1a3b679SAndreas Boehler     * It is possible return an etag from this function, which will be used in
378a1a3b679SAndreas Boehler     * the response to this PUT request. Note that the ETag must be surrounded
379a1a3b679SAndreas Boehler     * by double-quotes.
380a1a3b679SAndreas Boehler     *
381a1a3b679SAndreas Boehler     * However, you should only really return this ETag if you don't mangle the
382a1a3b679SAndreas Boehler     * calendar-data. If the result of a subsequent GET to this object is not
383a1a3b679SAndreas Boehler     * the exact same as this request body, you should omit the ETag.
384a1a3b679SAndreas Boehler     *
385a1a3b679SAndreas Boehler     * @param mixed $calendarId
386a1a3b679SAndreas Boehler     * @param string $objectUri
387a1a3b679SAndreas Boehler     * @param string $calendarData
388a1a3b679SAndreas Boehler     * @return string|null
389a1a3b679SAndreas Boehler     */
390d5703f5aSAndreas Boehler    function updateCalendarObject($calendarId, $objectUri, $calendarData)
391d5703f5aSAndreas Boehler    {
392c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'updateCalendarObject for calendarId '.$calendarId.' and objectUri '.$objectUri, __FILE__, __LINE__);
393c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Calendar data length: '.strlen($calendarData), __FILE__, __LINE__);
394d5703f5aSAndreas Boehler        $etag = $this->hlp->editCalendarEntryToCalendarByICS($calendarId, $objectUri, $calendarData);
395c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'ETag generated: '.$etag, __FILE__, __LINE__);
396d5703f5aSAndreas Boehler        return '"' . $etag. '"';
397a1a3b679SAndreas Boehler
398a1a3b679SAndreas Boehler    }
399a1a3b679SAndreas Boehler
400a1a3b679SAndreas Boehler
401a1a3b679SAndreas Boehler
402a1a3b679SAndreas Boehler    /**
403a1a3b679SAndreas Boehler     * Deletes an existing calendar object.
404a1a3b679SAndreas Boehler     *
405a1a3b679SAndreas Boehler     * The object uri is only the basename, or filename and not a full path.
406a1a3b679SAndreas Boehler     *
407a1a3b679SAndreas Boehler     * @param string $calendarId
408a1a3b679SAndreas Boehler     * @param string $objectUri
409a1a3b679SAndreas Boehler     * @return void
410a1a3b679SAndreas Boehler     */
411d5703f5aSAndreas Boehler    function deleteCalendarObject($calendarId, $objectUri)
412d5703f5aSAndreas Boehler    {
413c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'deleteCalendarObject for calendarId '.$calendarId.' and objectUri '.$objectUri, __FILE__, __LINE__);
414d5703f5aSAndreas Boehler        $this->hlp->deleteCalendarEntryForCalendarByUri($calendarId, $objectUri);
415a1a3b679SAndreas Boehler
416a1a3b679SAndreas Boehler    }
417a1a3b679SAndreas Boehler
418a1a3b679SAndreas Boehler    /**
419a1a3b679SAndreas Boehler     * Performs a calendar-query on the contents of this calendar.
420a1a3b679SAndreas Boehler     *
421a1a3b679SAndreas Boehler     * The calendar-query is defined in RFC4791 : CalDAV. Using the
422a1a3b679SAndreas Boehler     * calendar-query it is possible for a client to request a specific set of
423a1a3b679SAndreas Boehler     * object, based on contents of iCalendar properties, date-ranges and
424a1a3b679SAndreas Boehler     * iCalendar component types (VTODO, VEVENT).
425a1a3b679SAndreas Boehler     *
426a1a3b679SAndreas Boehler     * This method should just return a list of (relative) urls that match this
427a1a3b679SAndreas Boehler     * query.
428a1a3b679SAndreas Boehler     *
429a1a3b679SAndreas Boehler     * The list of filters are specified as an array. The exact array is
430a1a3b679SAndreas Boehler     * documented by \Sabre\CalDAV\CalendarQueryParser.
431a1a3b679SAndreas Boehler     *
432a1a3b679SAndreas Boehler     * Note that it is extremely likely that getCalendarObject for every path
433a1a3b679SAndreas Boehler     * returned from this method will be called almost immediately after. You
434a1a3b679SAndreas Boehler     * may want to anticipate this to speed up these requests.
435a1a3b679SAndreas Boehler     *
436a1a3b679SAndreas Boehler     * This method provides a default implementation, which parses *all* the
437a1a3b679SAndreas Boehler     * iCalendar objects in the specified calendar.
438a1a3b679SAndreas Boehler     *
439a1a3b679SAndreas Boehler     * This default may well be good enough for personal use, and calendars
440a1a3b679SAndreas Boehler     * that aren't very large. But if you anticipate high usage, big calendars
441a1a3b679SAndreas Boehler     * or high loads, you are strongly adviced to optimize certain paths.
442a1a3b679SAndreas Boehler     *
443a1a3b679SAndreas Boehler     * The best way to do so is override this method and to optimize
444a1a3b679SAndreas Boehler     * specifically for 'common filters'.
445a1a3b679SAndreas Boehler     *
446a1a3b679SAndreas Boehler     * Requests that are extremely common are:
447a1a3b679SAndreas Boehler     *   * requests for just VEVENTS
448a1a3b679SAndreas Boehler     *   * requests for just VTODO
449a1a3b679SAndreas Boehler     *   * requests with a time-range-filter on a VEVENT.
450a1a3b679SAndreas Boehler     *
451a1a3b679SAndreas Boehler     * ..and combinations of these requests. It may not be worth it to try to
452a1a3b679SAndreas Boehler     * handle every possible situation and just rely on the (relatively
453a1a3b679SAndreas Boehler     * easy to use) CalendarQueryValidator to handle the rest.
454a1a3b679SAndreas Boehler     *
455a1a3b679SAndreas Boehler     * Note that especially time-range-filters may be difficult to parse. A
456a1a3b679SAndreas Boehler     * time-range filter specified on a VEVENT must for instance also handle
457a1a3b679SAndreas Boehler     * recurrence rules correctly.
458a1a3b679SAndreas Boehler     * A good example of how to interprete all these filters can also simply
459a1a3b679SAndreas Boehler     * be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct
460a1a3b679SAndreas Boehler     * as possible, so it gives you a good idea on what type of stuff you need
461a1a3b679SAndreas Boehler     * to think of.
462a1a3b679SAndreas Boehler     *
463a1a3b679SAndreas Boehler     * This specific implementation (for the PDO) backend optimizes filters on
464a1a3b679SAndreas Boehler     * specific components, and VEVENT time-ranges.
465a1a3b679SAndreas Boehler     *
466a1a3b679SAndreas Boehler     * @param string $calendarId
467a1a3b679SAndreas Boehler     * @param array $filters
468a1a3b679SAndreas Boehler     * @return array
469a1a3b679SAndreas Boehler     */
470d5703f5aSAndreas Boehler    function calendarQuery($calendarId, array $filters)
471d5703f5aSAndreas Boehler    {
472c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'calendarQuery for calendarId '.$calendarId, __FILE__, __LINE__);
473c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Filters count: '.count($filters), __FILE__, __LINE__);
474d5703f5aSAndreas Boehler        $result = $this->hlp->calendarQuery($calendarId, $filters);
475c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Query results: '.count($result), __FILE__, __LINE__);
476a1a3b679SAndreas Boehler        return $result;
477a1a3b679SAndreas Boehler    }
478a1a3b679SAndreas Boehler
479a1a3b679SAndreas Boehler    /**
480a1a3b679SAndreas Boehler     * Searches through all of a users calendars and calendar objects to find
481a1a3b679SAndreas Boehler     * an object with a specific UID.
482a1a3b679SAndreas Boehler     *
483a1a3b679SAndreas Boehler     * This method should return the path to this object, relative to the
484a1a3b679SAndreas Boehler     * calendar home, so this path usually only contains two parts:
485a1a3b679SAndreas Boehler     *
486a1a3b679SAndreas Boehler     * calendarpath/objectpath.ics
487a1a3b679SAndreas Boehler     *
488a1a3b679SAndreas Boehler     * If the uid is not found, return null.
489a1a3b679SAndreas Boehler     *
490a1a3b679SAndreas Boehler     * This method should only consider * objects that the principal owns, so
491a1a3b679SAndreas Boehler     * any calendars owned by other principals that also appear in this
492a1a3b679SAndreas Boehler     * collection should be ignored.
493a1a3b679SAndreas Boehler     *
494a1a3b679SAndreas Boehler     * @param string $principalUri
495a1a3b679SAndreas Boehler     * @param string $uid
496a1a3b679SAndreas Boehler     * @return string|null
497a1a3b679SAndreas Boehler     */
498d5703f5aSAndreas Boehler    function getCalendarObjectByUID($principalUri, $uid)
499d5703f5aSAndreas Boehler    {
500c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getCalendarObjectByUID for principalUri '.$principalUri.' and uid '.$uid, __FILE__, __LINE__);
501d5703f5aSAndreas Boehler        $calids = array_keys($this->hlp->getCalendarIsForUser($principalUri));
502d5703f5aSAndreas Boehler        $event = $this->hlp->getEventWithUid($uid);
503a1a3b679SAndreas Boehler
504d5703f5aSAndreas Boehler        if(in_array($event['calendarid'], $calids))
505d5703f5aSAndreas Boehler        {
506d5703f5aSAndreas Boehler            $settings = $this->hlp->getCalendarSettings($event['calendarid']);
507d5703f5aSAndreas Boehler            return $settings['uri'] . '/' . $event['uri'];
508a1a3b679SAndreas Boehler        }
509d5703f5aSAndreas Boehler        return null;
510a1a3b679SAndreas Boehler    }
511a1a3b679SAndreas Boehler
512a1a3b679SAndreas Boehler    /**
513a1a3b679SAndreas Boehler     * The getChanges method returns all the changes that have happened, since
514a1a3b679SAndreas Boehler     * the specified syncToken in the specified calendar.
515a1a3b679SAndreas Boehler     *
516a1a3b679SAndreas Boehler     * This function should return an array, such as the following:
517a1a3b679SAndreas Boehler     *
518a1a3b679SAndreas Boehler     * [
519a1a3b679SAndreas Boehler     *   'syncToken' => 'The current synctoken',
520a1a3b679SAndreas Boehler     *   'added'   => [
521a1a3b679SAndreas Boehler     *      'new.txt',
522a1a3b679SAndreas Boehler     *   ],
523a1a3b679SAndreas Boehler     *   'modified'   => [
524a1a3b679SAndreas Boehler     *      'modified.txt',
525a1a3b679SAndreas Boehler     *   ],
526a1a3b679SAndreas Boehler     *   'deleted' => [
527a1a3b679SAndreas Boehler     *      'foo.php.bak',
528a1a3b679SAndreas Boehler     *      'old.txt'
529a1a3b679SAndreas Boehler     *   ]
530a1a3b679SAndreas Boehler     * ];
531a1a3b679SAndreas Boehler     *
532a1a3b679SAndreas Boehler     * The returned syncToken property should reflect the *current* syncToken
533a1a3b679SAndreas Boehler     * of the calendar, as reported in the {http://sabredav.org/ns}sync-token
534a1a3b679SAndreas Boehler     * property this is needed here too, to ensure the operation is atomic.
535a1a3b679SAndreas Boehler     *
536a1a3b679SAndreas Boehler     * If the $syncToken argument is specified as null, this is an initial
537a1a3b679SAndreas Boehler     * sync, and all members should be reported.
538a1a3b679SAndreas Boehler     *
539a1a3b679SAndreas Boehler     * The modified property is an array of nodenames that have changed since
540a1a3b679SAndreas Boehler     * the last token.
541a1a3b679SAndreas Boehler     *
542a1a3b679SAndreas Boehler     * The deleted property is an array with nodenames, that have been deleted
543a1a3b679SAndreas Boehler     * from collection.
544a1a3b679SAndreas Boehler     *
545a1a3b679SAndreas Boehler     * The $syncLevel argument is basically the 'depth' of the report. If it's
546a1a3b679SAndreas Boehler     * 1, you only have to report changes that happened only directly in
547a1a3b679SAndreas Boehler     * immediate descendants. If it's 2, it should also include changes from
548a1a3b679SAndreas Boehler     * the nodes below the child collections. (grandchildren)
549a1a3b679SAndreas Boehler     *
550a1a3b679SAndreas Boehler     * The $limit argument allows a client to specify how many results should
551a1a3b679SAndreas Boehler     * be returned at most. If the limit is not specified, it should be treated
552a1a3b679SAndreas Boehler     * as infinite.
553a1a3b679SAndreas Boehler     *
554a1a3b679SAndreas Boehler     * If the limit (infinite or not) is higher than you're willing to return,
555a1a3b679SAndreas Boehler     * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception.
556a1a3b679SAndreas Boehler     *
557a1a3b679SAndreas Boehler     * If the syncToken is expired (due to data cleanup) or unknown, you must
558a1a3b679SAndreas Boehler     * return null.
559a1a3b679SAndreas Boehler     *
560a1a3b679SAndreas Boehler     * The limit is 'suggestive'. You are free to ignore it.
561a1a3b679SAndreas Boehler     *
562a1a3b679SAndreas Boehler     * @param string $calendarId
563a1a3b679SAndreas Boehler     * @param string $syncToken
564a1a3b679SAndreas Boehler     * @param int $syncLevel
565a1a3b679SAndreas Boehler     * @param int $limit
566a1a3b679SAndreas Boehler     * @return array
567a1a3b679SAndreas Boehler     */
568d5703f5aSAndreas Boehler    function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null)
569d5703f5aSAndreas Boehler    {
570c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getChangesForCalendar for calendarId '.$calendarId.' and syncToken '.$syncToken.' and syncLevel '.$syncLevel, __FILE__, __LINE__);
571d5703f5aSAndreas Boehler        $result = $this->hlp->getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit);
572c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'Changes result: '.($result ? 'found' : 'not found'), __FILE__, __LINE__);
573a1a3b679SAndreas Boehler        return $result;
574a1a3b679SAndreas Boehler    }
575a1a3b679SAndreas Boehler
576a1a3b679SAndreas Boehler    /**
577a1a3b679SAndreas Boehler     * Returns a list of subscriptions for a principal.
578a1a3b679SAndreas Boehler     *
579a1a3b679SAndreas Boehler     * Every subscription is an array with the following keys:
580a1a3b679SAndreas Boehler     *  * id, a unique id that will be used by other functions to modify the
581a1a3b679SAndreas Boehler     *    subscription. This can be the same as the uri or a database key.
582a1a3b679SAndreas Boehler     *  * uri. This is just the 'base uri' or 'filename' of the subscription.
583a1a3b679SAndreas Boehler     *  * principaluri. The owner of the subscription. Almost always the same as
584a1a3b679SAndreas Boehler     *    principalUri passed to this method.
585a1a3b679SAndreas Boehler     *  * source. Url to the actual feed
586a1a3b679SAndreas Boehler     *
587a1a3b679SAndreas Boehler     * Furthermore, all the subscription info must be returned too:
588a1a3b679SAndreas Boehler     *
589a1a3b679SAndreas Boehler     * 1. {DAV:}displayname
590a1a3b679SAndreas Boehler     * 2. {http://apple.com/ns/ical/}refreshrate
591a1a3b679SAndreas Boehler     * 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
592a1a3b679SAndreas Boehler     *    should not be stripped).
593a1a3b679SAndreas Boehler     * 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
594a1a3b679SAndreas Boehler     *    should not be stripped).
595a1a3b679SAndreas Boehler     * 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
596a1a3b679SAndreas Boehler     *    attachments should not be stripped).
597a1a3b679SAndreas Boehler     * 7. {http://apple.com/ns/ical/}calendar-color
598a1a3b679SAndreas Boehler     * 8. {http://apple.com/ns/ical/}calendar-order
599a1a3b679SAndreas Boehler     * 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
600a1a3b679SAndreas Boehler     *    (should just be an instance of
601a1a3b679SAndreas Boehler     *    Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of
602a1a3b679SAndreas Boehler     *    default components).
603a1a3b679SAndreas Boehler     *
604a1a3b679SAndreas Boehler     * @param string $principalUri
605a1a3b679SAndreas Boehler     * @return array
606a1a3b679SAndreas Boehler     */
607d5703f5aSAndreas Boehler    function getSubscriptionsForUser($principalUri)
608d5703f5aSAndreas Boehler    {
609c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getSubscriptionsForUser with principalUri '.$principalUri.', returning empty array()', __FILE__, __LINE__);
610d5703f5aSAndreas Boehler        return array();
611a1a3b679SAndreas Boehler
612a1a3b679SAndreas Boehler    }
613a1a3b679SAndreas Boehler
614a1a3b679SAndreas Boehler    /**
615a1a3b679SAndreas Boehler     * Creates a new subscription for a principal.
616a1a3b679SAndreas Boehler     *
617a1a3b679SAndreas Boehler     * If the creation was a success, an id must be returned that can be used to reference
618a1a3b679SAndreas Boehler     * this subscription in other methods, such as updateSubscription.
619a1a3b679SAndreas Boehler     *
620a1a3b679SAndreas Boehler     * @param string $principalUri
621a1a3b679SAndreas Boehler     * @param string $uri
622a1a3b679SAndreas Boehler     * @param array $properties
623a1a3b679SAndreas Boehler     * @return mixed
624a1a3b679SAndreas Boehler     */
625d5703f5aSAndreas Boehler    function createSubscription($principalUri, $uri, array $properties)
626d5703f5aSAndreas Boehler    {
627c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'createSubscription for principalUri '.$principalUri.' and uri '.$uri.', returning null', __FILE__, __LINE__);
628d5703f5aSAndreas Boehler        return null;
629a1a3b679SAndreas Boehler
630a1a3b679SAndreas Boehler    }
631a1a3b679SAndreas Boehler
632a1a3b679SAndreas Boehler    /**
633a1a3b679SAndreas Boehler     * Updates a subscription
634a1a3b679SAndreas Boehler     *
635a1a3b679SAndreas Boehler     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
636a1a3b679SAndreas Boehler     * To do the actual updates, you must tell this object which properties
637a1a3b679SAndreas Boehler     * you're going to process with the handle() method.
638a1a3b679SAndreas Boehler     *
639a1a3b679SAndreas Boehler     * Calling the handle method is like telling the PropPatch object "I
640a1a3b679SAndreas Boehler     * promise I can handle updating this property".
641a1a3b679SAndreas Boehler     *
642a1a3b679SAndreas Boehler     * Read the PropPatch documenation for more info and examples.
643a1a3b679SAndreas Boehler     *
644a1a3b679SAndreas Boehler     * @param mixed $subscriptionId
645a1a3b679SAndreas Boehler     * @param \Sabre\DAV\PropPatch $propPatch
646a1a3b679SAndreas Boehler     * @return void
647a1a3b679SAndreas Boehler     */
648d5703f5aSAndreas Boehler    function updateSubscription($subscriptionId, DAV\PropPatch $propPatch)
649d5703f5aSAndreas Boehler    {
650c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'updateSubscription with subscriptionId '.$subscriptionId.', returning false', __FILE__, __LINE__);
651d5703f5aSAndreas Boehler        return;
652a1a3b679SAndreas Boehler    }
653a1a3b679SAndreas Boehler
654a1a3b679SAndreas Boehler    /**
655a1a3b679SAndreas Boehler     * Deletes a subscription
656a1a3b679SAndreas Boehler     *
657a1a3b679SAndreas Boehler     * @param mixed $subscriptionId
658a1a3b679SAndreas Boehler     * @return void
659a1a3b679SAndreas Boehler     */
660d5703f5aSAndreas Boehler    function deleteSubscription($subscriptionId)
661d5703f5aSAndreas Boehler    {
662c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'deleteSubscription with subscriptionId '.$subscriptionId.', returning', __FILE__, __LINE__);
663d5703f5aSAndreas Boehler        return;
664a1a3b679SAndreas Boehler
665a1a3b679SAndreas Boehler    }
666a1a3b679SAndreas Boehler
667a1a3b679SAndreas Boehler    /**
668a1a3b679SAndreas Boehler     * Returns a single scheduling object.
669a1a3b679SAndreas Boehler     *
670a1a3b679SAndreas Boehler     * The returned array should contain the following elements:
671a1a3b679SAndreas Boehler     *   * uri - A unique basename for the object. This will be used to
672a1a3b679SAndreas Boehler     *           construct a full uri.
673a1a3b679SAndreas Boehler     *   * calendardata - The iCalendar object
674a1a3b679SAndreas Boehler     *   * lastmodified - The last modification date. Can be an int for a unix
675a1a3b679SAndreas Boehler     *                    timestamp, or a PHP DateTime object.
676a1a3b679SAndreas Boehler     *   * etag - A unique token that must change if the object changed.
677a1a3b679SAndreas Boehler     *   * size - The size of the object, in bytes.
678a1a3b679SAndreas Boehler     *
679a1a3b679SAndreas Boehler     * @param string $principalUri
680a1a3b679SAndreas Boehler     * @param string $objectUri
681a1a3b679SAndreas Boehler     * @return array
682a1a3b679SAndreas Boehler     */
683d5703f5aSAndreas Boehler    function getSchedulingObject($principalUri, $objectUri)
684d5703f5aSAndreas Boehler    {
685c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getSchedulingObject with principalUri '.$principalUri.' and objectUri '.$objectUri.', returning null', __FILE__, __LINE__);
686d5703f5aSAndreas Boehler        return null;
687a1a3b679SAndreas Boehler
688a1a3b679SAndreas Boehler    }
689a1a3b679SAndreas Boehler
690a1a3b679SAndreas Boehler    /**
691a1a3b679SAndreas Boehler     * Returns all scheduling objects for the inbox collection.
692a1a3b679SAndreas Boehler     *
693a1a3b679SAndreas Boehler     * These objects should be returned as an array. Every item in the array
694a1a3b679SAndreas Boehler     * should follow the same structure as returned from getSchedulingObject.
695a1a3b679SAndreas Boehler     *
696a1a3b679SAndreas Boehler     * The main difference is that 'calendardata' is optional.
697a1a3b679SAndreas Boehler     *
698a1a3b679SAndreas Boehler     * @param string $principalUri
699a1a3b679SAndreas Boehler     * @return array
700a1a3b679SAndreas Boehler     */
701d5703f5aSAndreas Boehler    function getSchedulingObjects($principalUri)
702d5703f5aSAndreas Boehler    {
703c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'getSchedulingObjects for principalUri '.$principalUri.', returning null', __FILE__, __LINE__);
704d5703f5aSAndreas Boehler        return null;
705a1a3b679SAndreas Boehler
706a1a3b679SAndreas Boehler    }
707a1a3b679SAndreas Boehler
708a1a3b679SAndreas Boehler    /**
709a1a3b679SAndreas Boehler     * Deletes a scheduling object
710a1a3b679SAndreas Boehler     *
711a1a3b679SAndreas Boehler     * @param string $principalUri
712a1a3b679SAndreas Boehler     * @param string $objectUri
713a1a3b679SAndreas Boehler     * @return void
714a1a3b679SAndreas Boehler     */
715d5703f5aSAndreas Boehler    function deleteSchedulingObject($principalUri, $objectUri)
716d5703f5aSAndreas Boehler    {
717c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'deleteSchedulingObject for principalUri '.$principalUri.' and objectUri '.$objectUri.', returning', __FILE__, __LINE__);
718d5703f5aSAndreas Boehler        return;
719a1a3b679SAndreas Boehler    }
720a1a3b679SAndreas Boehler
721a1a3b679SAndreas Boehler    /**
722a1a3b679SAndreas Boehler     * Creates a new scheduling object. This should land in a users' inbox.
723a1a3b679SAndreas Boehler     *
724a1a3b679SAndreas Boehler     * @param string $principalUri
725a1a3b679SAndreas Boehler     * @param string $objectUri
726a1a3b679SAndreas Boehler     * @param string $objectData
727a1a3b679SAndreas Boehler     * @return void
728a1a3b679SAndreas Boehler     */
729d5703f5aSAndreas Boehler    function createSchedulingObject($principalUri, $objectUri, $objectData)
730d5703f5aSAndreas Boehler    {
731c42afaebSscottleechua        \dokuwiki\Logger::debug('DAVCAL', 'createSchedulingObject with principalUri '.$principalUri.' and objectUri '.$objectUri.', returning', __FILE__, __LINE__);
732d5703f5aSAndreas Boehler        return;
733a1a3b679SAndreas Boehler
734a1a3b679SAndreas Boehler    }
735a1a3b679SAndreas Boehler
736a1a3b679SAndreas Boehler}
737