4 * Abstract Calendaring backend. Extend this class to create your own backends.
8 * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
9 * @author Evert Pot (http://www.rooftopsolutions.nl/)
10 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
12 abstract class Sabre_CalDAV_Backend_Abstract {
15 * Returns a list of calendars for a principal.
17 * Every project is an array with the following keys:
18 * * id, a unique id that will be used by other functions to modify the
19 * calendar. This can be the same as the uri or a database key.
20 * * uri, which the basename of the uri with which the calendar is
22 * * principaluri. The owner of the calendar. Almost always the same as
23 * principalUri passed to this method.
25 * Furthermore it can contain webdav properties in clark notation. A very
26 * common one is '{DAV:}displayname'.
28 * @param string $principalUri
31 abstract function getCalendarsForUser($principalUri);
34 * Creates a new calendar for a principal.
36 * If the creation was a success, an id must be returned that can be used to reference
37 * this calendar in other methods, such as updateCalendar.
39 * @param string $principalUri
40 * @param string $calendarUri
41 * @param array $properties
44 abstract function createCalendar($principalUri,$calendarUri,array $properties);
47 * Updates properties for a calendar.
49 * The mutations array uses the propertyName in clark-notation as key,
50 * and the array value for the property value. In the case a property
51 * should be deleted, the property value will be null.
53 * This method must be atomic. If one property cannot be changed, the
54 * entire operation must fail.
56 * If the operation was successful, true can be returned.
57 * If the operation failed, false can be returned.
59 * Deletion of a non-existent property is always successful.
61 * Lastly, it is optional to return detailed information about any
62 * failures. In this case an array should be returned with the following
67 * '{DAV:}displayname' => null,
70 * '{DAV:}owner' => null,
74 * In this example it was forbidden to update {DAV:}displayname.
75 * (403 Forbidden), which in turn also caused {DAV:}owner to fail
76 * (424 Failed Dependency) because the request needs to be atomic.
78 * @param mixed $calendarId
79 * @param array $mutations
82 public function updateCalendar($calendarId, array $mutations) {
89 * Delete a calendar and all it's objects
91 * @param mixed $calendarId
94 abstract function deleteCalendar($calendarId);
97 * Returns all calendar objects within a calendar.
99 * Every item contains an array with the following keys:
100 * * id - unique identifier which will be used for subsequent updates
101 * * calendardata - The iCalendar-compatible calendar data
102 * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
103 * * lastmodified - a timestamp of the last modification time
104 * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
106 * * calendarid - The calendarid as it was passed to this function.
107 * * size - The size of the calendar objects, in bytes.
109 * Note that the etag is optional, but it's highly encouraged to return for
112 * The calendardata is also optional. If it's not returned
113 * 'getCalendarObject' will be called later, which *is* expected to return
116 * If neither etag or size are specified, the calendardata will be
117 * used/fetched to determine these numbers. If both are specified the
118 * amount of times this is needed is reduced by a great degree.
120 * @param mixed $calendarId
123 abstract function getCalendarObjects($calendarId);
126 * Returns information from a single calendar object, based on it's object
129 * The returned array must have the same keys as getCalendarObjects. The
130 * 'calendardata' object is required here though, while it's not required
131 * for getCalendarObjects.
133 * @param mixed $calendarId
134 * @param string $objectUri
137 abstract function getCalendarObject($calendarId,$objectUri);
140 * Creates a new calendar object.
142 * It is possible return an etag from this function, which will be used in
143 * the response to this PUT request. Note that the ETag must be surrounded
146 * However, you should only really return this ETag if you don't mangle the
147 * calendar-data. If the result of a subsequent GET to this object is not
148 * the exact same as this request body, you should omit the ETag.
150 * @param mixed $calendarId
151 * @param string $objectUri
152 * @param string $calendarData
153 * @return string|null
155 abstract function createCalendarObject($calendarId,$objectUri,$calendarData);
158 * Updates an existing calendarobject, based on it's uri.
160 * It is possible return an etag from this function, which will be used in
161 * the response to this PUT request. Note that the ETag must be surrounded
164 * However, you should only really return this ETag if you don't mangle the
165 * calendar-data. If the result of a subsequent GET to this object is not
166 * the exact same as this request body, you should omit the ETag.
168 * @param mixed $calendarId
169 * @param string $objectUri
170 * @param string $calendarData
171 * @return string|null
173 abstract function updateCalendarObject($calendarId,$objectUri,$calendarData);
176 * Deletes an existing calendar object.
178 * @param mixed $calendarId
179 * @param string $objectUri
182 abstract function deleteCalendarObject($calendarId,$objectUri);
185 * Performs a calendar-query on the contents of this calendar.
187 * The calendar-query is defined in RFC4791 : CalDAV. Using the
188 * calendar-query it is possible for a client to request a specific set of
189 * object, based on contents of iCalendar properties, date-ranges and
190 * iCalendar component types (VTODO, VEVENT).
192 * This method should just return a list of (relative) urls that match this
195 * The list of filters are specified as an array. The exact array is
196 * documented by Sabre_CalDAV_CalendarQueryParser.
198 * Note that it is extremely likely that getCalendarObject for every path
199 * returned from this method will be called almost immediately after. You
200 * may want to anticipate this to speed up these requests.
202 * This method provides a default implementation, which parses *all* the
203 * iCalendar objects in the specified calendar.
205 * This default may well be good enough for personal use, and calendars
206 * that aren't very large. But if you anticipate high usage, big calendars
207 * or high loads, you are strongly adviced to optimize certain paths.
209 * The best way to do so is override this method and to optimize
210 * specifically for 'common filters'.
212 * Requests that are extremely common are:
213 * * requests for just VEVENTS
214 * * requests for just VTODO
215 * * requests with a time-range-filter on either VEVENT or VTODO.
217 * ..and combinations of these requests. It may not be worth it to try to
218 * handle every possible situation and just rely on the (relatively
219 * easy to use) CalendarQueryValidator to handle the rest.
221 * Note that especially time-range-filters may be difficult to parse. A
222 * time-range filter specified on a VEVENT must for instance also handle
223 * recurrence rules correctly.
224 * A good example of how to interprete all these filters can also simply
225 * be found in Sabre_CalDAV_CalendarQueryFilter. This class is as correct
226 * as possible, so it gives you a good idea on what type of stuff you need
229 * @param mixed $calendarId
230 * @param array $filters
233 public function calendarQuery($calendarId, array $filters) {
236 $objects = $this->getCalendarObjects($calendarId);
238 $validator = new Sabre_CalDAV_CalendarQueryValidator();
240 foreach($objects as $object) {
242 if ($this->validateFilterForObject($object, $filters)) {
243 $result[] = $object['uri'];
253 * This method validates if a filters (as passed to calendarQuery) matches
256 * @param array $object
257 * @param array $filter
260 protected function validateFilterForObject(array $object, array $filters) {
262 // Unfortunately, setting the 'calendardata' here is optional. If
263 // it was excluded, we actually need another call to get this as
265 if (!isset($object['calendardata'])) {
266 $object = $this->getCalendarObject($object['calendarid'], $object['uri']);
269 $vObject = Sabre_VObject_Reader::read($object['calendardata']);
271 $validator = new Sabre_CalDAV_CalendarQueryValidator();
272 return $validator->validate($vObject, $filters);