123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- <?php
- namespace Sabre\CalDAV\Backend;
- use Sabre\VObject;
- use Sabre\CalDAV;
- /**
- * Abstract Calendaring backend. Extend this class to create your own backends.
- *
- * Checkout the BackendInterface for all the methods that must be implemented.
- *
- * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
- abstract class AbstractBackend implements BackendInterface {
- /**
- * Updates properties for a calendar.
- *
- * The list of mutations is stored in a Sabre\DAV\PropPatch object.
- * To do the actual updates, you must tell this object which properties
- * you're going to process with the handle() method.
- *
- * Calling the handle method is like telling the PropPatch object "I
- * promise I can handle updating this property".
- *
- * Read the PropPatch documenation for more info and examples.
- *
- * @param string $path
- * @param \Sabre\DAV\PropPatch $propPatch
- * @return void
- */
- function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
- }
- /**
- * Returns a list of calendar objects.
- *
- * This method should work identical to getCalendarObject, but instead
- * return all the calendar objects in the list as an array.
- *
- * If the backend supports this, it may allow for some speed-ups.
- *
- * @param mixed $calendarId
- * @param array $uris
- * @return array
- */
- function getMultipleCalendarObjects($calendarId, array $uris) {
- return array_map(function($uri) use ($calendarId) {
- return $this->getCalendarObject($calendarId, $uri);
- }, $uris);
- }
- /**
- * Performs a calendar-query on the contents of this calendar.
- *
- * The calendar-query is defined in RFC4791 : CalDAV. Using the
- * calendar-query it is possible for a client to request a specific set of
- * object, based on contents of iCalendar properties, date-ranges and
- * iCalendar component types (VTODO, VEVENT).
- *
- * This method should just return a list of (relative) urls that match this
- * query.
- *
- * The list of filters are specified as an array. The exact array is
- * documented by \Sabre\CalDAV\CalendarQueryParser.
- *
- * Note that it is extremely likely that getCalendarObject for every path
- * returned from this method will be called almost immediately after. You
- * may want to anticipate this to speed up these requests.
- *
- * This method provides a default implementation, which parses *all* the
- * iCalendar objects in the specified calendar.
- *
- * This default may well be good enough for personal use, and calendars
- * that aren't very large. But if you anticipate high usage, big calendars
- * or high loads, you are strongly adviced to optimize certain paths.
- *
- * The best way to do so is override this method and to optimize
- * specifically for 'common filters'.
- *
- * Requests that are extremely common are:
- * * requests for just VEVENTS
- * * requests for just VTODO
- * * requests with a time-range-filter on either VEVENT or VTODO.
- *
- * ..and combinations of these requests. It may not be worth it to try to
- * handle every possible situation and just rely on the (relatively
- * easy to use) CalendarQueryValidator to handle the rest.
- *
- * Note that especially time-range-filters may be difficult to parse. A
- * time-range filter specified on a VEVENT must for instance also handle
- * recurrence rules correctly.
- * A good example of how to interprete all these filters can also simply
- * be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct
- * as possible, so it gives you a good idea on what type of stuff you need
- * to think of.
- *
- * @param mixed $calendarId
- * @param array $filters
- * @return array
- */
- function calendarQuery($calendarId, array $filters) {
- $result = [];
- $objects = $this->getCalendarObjects($calendarId);
- foreach ($objects as $object) {
- if ($this->validateFilterForObject($object, $filters)) {
- $result[] = $object['uri'];
- }
- }
- return $result;
- }
- /**
- * This method validates if a filter (as passed to calendarQuery) matches
- * the given object.
- *
- * @param array $object
- * @param array $filters
- * @return bool
- */
- protected function validateFilterForObject(array $object, array $filters) {
- // Unfortunately, setting the 'calendardata' here is optional. If
- // it was excluded, we actually need another call to get this as
- // well.
- if (!isset($object['calendardata'])) {
- $object = $this->getCalendarObject($object['calendarid'], $object['uri']);
- }
- $vObject = VObject\Reader::read($object['calendardata']);
- $validator = new CalDAV\CalendarQueryValidator();
- $result = $validator->validate($vObject, $filters);
- // Destroy circular references so PHP will GC the object.
- $vObject->destroy();
- return $result;
- }
- /**
- * Searches through all of a users calendars and calendar objects to find
- * an object with a specific UID.
- *
- * This method should return the path to this object, relative to the
- * calendar home, so this path usually only contains two parts:
- *
- * calendarpath/objectpath.ics
- *
- * If the uid is not found, return null.
- *
- * This method should only consider * objects that the principal owns, so
- * any calendars owned by other principals that also appear in this
- * collection should be ignored.
- *
- * @param string $principalUri
- * @param string $uid
- * @return string|null
- */
- function getCalendarObjectByUID($principalUri, $uid) {
- // Note: this is a super slow naive implementation of this method. You
- // are highly recommended to optimize it, if your backend allows it.
- foreach ($this->getCalendarsForUser($principalUri) as $calendar) {
- // We must ignore calendars owned by other principals.
- if ($calendar['principaluri'] !== $principalUri) {
- continue;
- }
- // Ignore calendars that are shared.
- if (isset($calendar['{http://sabredav.org/ns}owner-principal']) && $calendar['{http://sabredav.org/ns}owner-principal'] !== $principalUri) {
- continue;
- }
- $results = $this->calendarQuery(
- $calendar['id'],
- [
- 'name' => 'VCALENDAR',
- 'prop-filters' => [],
- 'comp-filters' => [
- [
- 'name' => 'VEVENT',
- 'is-not-defined' => false,
- 'time-range' => null,
- 'comp-filters' => [],
- 'prop-filters' => [
- [
- 'name' => 'UID',
- 'is-not-defined' => false,
- 'time-range' => null,
- 'text-match' => [
- 'value' => $uid,
- 'negate-condition' => false,
- 'collation' => 'i;octet',
- ],
- 'param-filters' => [],
- ],
- ]
- ]
- ],
- ]
- );
- if ($results) {
- // We have a match
- return $calendar['uri'] . '/' . $results[0];
- }
- }
- }
- }
|