aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/Sabre/CalDAV/Plugin.php
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/Sabre/CalDAV/Plugin.php')
-rwxr-xr-x3rdparty/Sabre/CalDAV/Plugin.php579
1 files changed, 99 insertions, 480 deletions
diff --git a/3rdparty/Sabre/CalDAV/Plugin.php b/3rdparty/Sabre/CalDAV/Plugin.php
index f3d11969c8b..c56ab384844 100755
--- a/3rdparty/Sabre/CalDAV/Plugin.php
+++ b/3rdparty/Sabre/CalDAV/Plugin.php
@@ -1,7 +1,5 @@
<?php
-use Sabre\VObject;
-
/**
* CalDAV plugin
*
@@ -27,6 +25,16 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
/**
+ * The following constants are used to differentiate
+ * the various filters for the calendar-query report
+ */
+ const FILTER_COMPFILTER = 1;
+ const FILTER_TIMERANGE = 3;
+ const FILTER_PROPFILTER = 4;
+ const FILTER_PARAMFILTER = 5;
+ const FILTER_TEXTMATCH = 6;
+
+ /**
* The hardcoded root for calendar objects. It is unfortunate
* that we're stuck with it, but it will have to do for now
*/
@@ -164,19 +172,16 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
$server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
$server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent'));
$server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile'));
- $server->subscribeEvent('beforeMethod', array($this,'beforeMethod'));
$server->xmlNamespaces[self::NS_CALDAV] = 'cal';
$server->xmlNamespaces[self::NS_CALENDARSERVER] = 'cs';
$server->propertyMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre_CalDAV_Property_SupportedCalendarComponentSet';
- $server->propertyMap['{' . self::NS_CALDAV . '}schedule-calendar-transp'] = 'Sabre_CalDAV_Property_ScheduleCalendarTransp';
$server->resourceTypeMapping['Sabre_CalDAV_ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar';
$server->resourceTypeMapping['Sabre_CalDAV_Schedule_IOutbox'] = '{urn:ietf:params:xml:ns:caldav}schedule-outbox';
$server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read';
$server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write';
- $server->resourceTypeMapping['Sabre_CalDAV_Notifications_ICollection'] = '{' . self::NS_CALENDARSERVER . '}notification';
array_push($server->protectedProperties,
@@ -200,9 +205,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
// CalendarServer extensions
'{' . self::NS_CALENDARSERVER . '}getctag',
'{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for',
- '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for',
- '{' . self::NS_CALENDARSERVER . '}notification-URL',
- '{' . self::NS_CALENDARSERVER . '}notificationtype'
+ '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for'
);
}
@@ -223,13 +226,6 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
// unknownMethod event.
return false;
case 'POST' :
-
- // Checking if this is a text/calendar content type
- $contentType = $this->server->httpRequest->getHeader('Content-Type');
- if (strpos($contentType, 'text/calendar')!==0) {
- return;
- }
-
// Checking if we're talking to an outbox
try {
$node = $this->server->tree->getNodeForPath($uri);
@@ -239,7 +235,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if (!$node instanceof Sabre_CalDAV_Schedule_IOutbox)
return;
- $this->outboxRequest($node, $uri);
+ $this->outboxRequest($node);
return false;
}
@@ -352,7 +348,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if (in_array($calProp,$requestedProperties)) {
$addresses = $node->getAlternateUriSet();
- $addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl() . '/';
+ $addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl();
unset($requestedProperties[$calProp]);
$returnedProperties[200][$calProp] = new Sabre_DAV_Property_HrefList($addresses, false);
@@ -394,31 +390,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
- // notification-URL property
- $notificationUrl = '{' . self::NS_CALENDARSERVER . '}notification-URL';
- if (($index = array_search($notificationUrl, $requestedProperties)) !== false) {
- $principalId = $node->getName();
- $calendarHomePath = 'calendars/' . $principalId . '/notifications/';
- unset($requestedProperties[$index]);
- $returnedProperties[200][$notificationUrl] = new Sabre_DAV_Property_Href($calendarHomePath);
- }
-
} // instanceof IPrincipal
- if ($node instanceof Sabre_CalDAV_Notifications_INode) {
-
- $propertyName = '{' . self::NS_CALENDARSERVER . '}notificationtype';
- if (($index = array_search($propertyName, $requestedProperties)) !== false) {
-
- $returnedProperties[200][$propertyName] =
- $node->getNotificationType();
-
- unset($requestedProperties[$index]);
-
- }
-
- } // instanceof Notifications_INode
-
if ($node instanceof Sabre_CalDAV_ICalendarObject) {
// The calendar-data property is not supposed to be a 'real'
@@ -451,11 +424,11 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
public function calendarMultiGetReport($dom) {
$properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
- $hrefElems = $dom->getElementsByTagNameNS('DAV:','href');
+ $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href');
$xpath = new DOMXPath($dom);
$xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
- $xpath->registerNameSpace('dav','DAV:');
+ $xpath->registerNameSpace('dav','urn:DAV');
$expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand');
if ($expand->length>0) {
@@ -465,8 +438,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if(!$start || !$end) {
throw new Sabre_DAV_Exception_BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element');
}
- $start = VObject\DateTimeParser::parseDateTime($start);
- $end = VObject\DateTimeParser::parseDateTime($end);
+ $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+ $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
if ($end <= $start) {
throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
@@ -485,7 +458,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
list($objProps) = $this->server->getPropertiesForPath($uri,$properties);
if ($expand && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) {
- $vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
+ $vObject = Sabre_VObject_Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
$vObject->expand($start, $end);
$objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
}
@@ -494,12 +467,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
- $prefer = $this->server->getHTTPPRefer();
-
$this->server->httpResponse->sendStatus(207);
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
- $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
- $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList, $prefer['return-minimal']));
+ $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList));
}
@@ -517,95 +487,54 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
$parser = new Sabre_CalDAV_CalendarQueryParser($dom);
$parser->parse();
- $node = $this->server->tree->getNodeForPath($this->server->getRequestUri());
- $depth = $this->server->getHTTPDepth(0);
-
- // The default result is an empty array
- $result = array();
+ $requestedCalendarData = true;
+ $requestedProperties = $parser->requestedProperties;
- // The calendarobject was requested directly. In this case we handle
- // this locally.
- if ($depth == 0 && $node instanceof Sabre_CalDAV_ICalendarObject) {
+ if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
- $requestedCalendarData = true;
- $requestedProperties = $parser->requestedProperties;
+ // We always retrieve calendar-data, as we need it for filtering.
+ $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data';
- if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
-
- // We always retrieve calendar-data, as we need it for filtering.
- $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data';
-
- // If calendar-data wasn't explicitly requested, we need to remove
- // it after processing.
- $requestedCalendarData = false;
- }
+ // If calendar-data wasn't explicitly requested, we need to remove
+ // it after processing.
+ $requestedCalendarData = false;
+ }
- $properties = $this->server->getPropertiesForPath(
- $this->server->getRequestUri(),
- $requestedProperties,
- 0
- );
+ // These are the list of nodes that potentially match the requirement
+ $candidateNodes = $this->server->getPropertiesForPath(
+ $this->server->getRequestUri(),
+ $requestedProperties,
+ $this->server->getHTTPDepth(0)
+ );
- // This array should have only 1 element, the first calendar
- // object.
- $properties = current($properties);
+ $verifiedNodes = array();
- // If there wasn't any calendar-data returned somehow, we ignore
- // this.
- if (isset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) {
+ $validator = new Sabre_CalDAV_CalendarQueryValidator();
- $validator = new Sabre_CalDAV_CalendarQueryValidator();
- $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
- if ($validator->validate($vObject,$parser->filters)) {
+ foreach($candidateNodes as $node) {
- // If the client didn't require the calendar-data property,
- // we won't give it back.
- if (!$requestedCalendarData) {
- unset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
- } else {
- if ($parser->expand) {
- $vObject->expand($parser->expand['start'], $parser->expand['end']);
- $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
- }
- }
+ // If the node didn't have a calendar-data property, it must not be a calendar object
+ if (!isset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']))
+ continue;
- $result = array($properties);
+ $vObject = Sabre_VObject_Reader::read($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
+ if ($validator->validate($vObject,$parser->filters)) {
+ if (!$requestedCalendarData) {
+ unset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
}
-
- }
-
- }
- // If we're dealing with a calendar, the calendar itself is responsible
- // for the calendar-query.
- if ($node instanceof Sabre_CalDAV_ICalendar && $depth = 1) {
-
- $nodePaths = $node->calendarQuery($parser->filters);
-
- foreach($nodePaths as $path) {
-
- list($properties) =
- $this->server->getPropertiesForPath($this->server->getRequestUri() . '/' . $path, $parser->requestedProperties);
-
if ($parser->expand) {
- // We need to do some post-processing
- $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
$vObject->expand($parser->expand['start'], $parser->expand['end']);
- $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+ $node[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
}
-
- $result[] = $properties;
-
+ $verifiedNodes[] = $node;
}
}
- $prefer = $this->server->getHTTPPRefer();
-
$this->server->httpResponse->sendStatus(207);
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
- $this->server->httpResponse->setHeader('Vary','Brief,Prefer');
- $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
+ $this->server->httpResponse->sendBody($this->server->generateMultiStatus($verifiedNodes));
}
@@ -632,10 +561,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
if ($start) {
- $start = VObject\DateTimeParser::parseDateTime($start);
+ $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
}
if ($end) {
- $end = VObject\DateTimeParser::parseDateTime($end);
+ $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
}
if (!$start && !$end) {
@@ -654,33 +583,15 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
throw new Sabre_DAV_Exception_NotImplemented('The free-busy-query REPORT is only implemented on calendars');
}
- // Doing a calendar-query first, to make sure we get the most
- // performance.
- $urls = $calendar->calendarQuery(array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
- 'is-not-defined' => false,
- 'time-range' => array(
- 'start' => $start,
- 'end' => $end,
- ),
- ),
- ),
- 'prop-filters' => array(),
- 'is-not-defined' => false,
- 'time-range' => null,
- ));
-
- $objects = array_map(function($url) use ($calendar) {
- $obj = $calendar->getChild($url)->get();
+ $objects = array_map(function($child) {
+ $obj = $child->get();
+ if (is_resource($obj)) {
+ $obj = stream_get_contents($obj);
+ }
return $obj;
- }, $urls);
+ }, $calendar->getChildren());
- $generator = new VObject\FreeBusyGenerator();
+ $generator = new Sabre_VObject_FreeBusyGenerator();
$generator->setObjects($objects);
$generator->setTimeRange($start, $end);
$result = $generator->getResult();
@@ -709,7 +620,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if (!$node instanceof Sabre_CalDAV_ICalendarObject)
return;
- $this->validateICalendar($data, $path);
+ $this->validateICalendar($data);
}
@@ -729,52 +640,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if (!$parentNode instanceof Sabre_CalDAV_Calendar)
return;
- $this->validateICalendar($data, $path);
-
- }
-
- /**
- * This event is triggered before any HTTP request is handled.
- *
- * We use this to intercept GET calls to notification nodes, and return the
- * proper response.
- *
- * @param string $method
- * @param string $path
- * @return void
- */
- public function beforeMethod($method, $path) {
-
- if ($method!=='GET') return;
-
- try {
- $node = $this->server->tree->getNodeForPath($path);
- } catch (Sabre_DAV_Exception_NotFound $e) {
- return;
- }
-
- if (!$node instanceof Sabre_CalDAV_Notifications_INode)
- return;
-
- if (!$this->server->checkPreconditions(true)) return false;
-
- $dom = new DOMDocument('1.0', 'UTF-8');
- $dom->formatOutput = true;
-
- $root = $dom->createElement('cs:notification');
- foreach($this->server->xmlNamespaces as $namespace => $prefix) {
- $root->setAttribute('xmlns:' . $prefix, $namespace);
- }
-
- $dom->appendChild($root);
- $node->getNotificationType()->serializeBody($this->server, $root);
-
- $this->server->httpResponse->setHeader('Content-Type','application/xml');
- $this->server->httpResponse->setHeader('ETag',$node->getETag());
- $this->server->httpResponse->sendStatus(200);
- $this->server->httpResponse->sendBody($dom->saveXML());
-
- return false;
+ $this->validateICalendar($data);
}
@@ -784,10 +650,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
* An exception is thrown if it's not.
*
* @param resource|string $data
- * @param string $path
* @return void
*/
- protected function validateICalendar(&$data, $path) {
+ protected function validateICalendar(&$data) {
// If it's a stream, we convert it to a string first.
if (is_resource($data)) {
@@ -799,9 +664,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
try {
- $vobj = VObject\Reader::read($data);
+ $vobj = Sabre_VObject_Reader::read($data);
- } catch (VObject\ParseException $e) {
+ } catch (Sabre_VObject_ParseException $e) {
throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: ' . $e->getMessage());
@@ -811,11 +676,6 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support iCalendar objects.');
}
- // Get the Supported Components for the target calendar
- list($parentPath,$object) = Sabre_Dav_URLUtil::splitPath($path);
- $calendarProperties = $this->server->getProperties($parentPath,array('{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'));
- $supportedComponents = $calendarProperties['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue();
-
$foundType = null;
$foundUID = null;
foreach($vobj->getComponents() as $component) {
@@ -827,9 +687,6 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
case 'VJOURNAL' :
if (is_null($foundType)) {
$foundType = $component->name;
- if (!in_array($foundType, $supportedComponents)) {
- throw new Sabre_CalDAV_Exception_InvalidComponentType('This calendar only supports ' . implode(', ', $supportedComponents) . '. We found a ' . $foundType);
- }
if (!isset($component->UID)) {
throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' component must have an UID');
}
@@ -854,81 +711,12 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * This method handles POST requests to the schedule-outbox.
- *
- * Currently, two types of requests are support:
- * * FREEBUSY requests from RFC 6638
- * * Simple iTIP messages from draft-desruisseaux-caldav-sched-04
- *
- * The latter is from an expired early draft of the CalDAV scheduling
- * extensions, but iCal depends on a feature from that spec, so we
- * implement it.
+ * This method handles POST requests to the schedule-outbox
*
* @param Sabre_CalDAV_Schedule_IOutbox $outboxNode
- * @param string $outboxUri
- * @return void
- */
- public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode, $outboxUri) {
-
- // Parsing the request body
- try {
- $vObject = VObject\Reader::read($this->server->httpRequest->getBody(true));
- } catch (VObject\ParseException $e) {
- throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
- }
-
- // The incoming iCalendar object must have a METHOD property, and a
- // component. The combination of both determines what type of request
- // this is.
- $componentType = null;
- foreach($vObject->getComponents() as $component) {
- if ($component->name !== 'VTIMEZONE') {
- $componentType = $component->name;
- break;
- }
- }
- if (is_null($componentType)) {
- throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
- }
-
- // Validating the METHOD
- $method = strtoupper((string)$vObject->METHOD);
- if (!$method) {
- throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages');
- }
-
- // So we support two types of requests:
- //
- // REQUEST with a VFREEBUSY component
- // REQUEST, REPLY, ADD, CANCEL on VEVENT components
-
- $acl = $this->server->getPlugin('acl');
-
- if ($componentType === 'VFREEBUSY' && $method === 'REQUEST') {
-
- $acl && $acl->checkPrivileges($outboxUri,'{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy');
- $this->handleFreeBusyRequest($outboxNode, $vObject);
-
- } elseif ($componentType === 'VEVENT' && in_array($method, array('REQUEST','REPLY','ADD','CANCEL'))) {
-
- $acl && $acl->checkPrivileges($outboxUri,'{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-post-vevent');
- $this->handleEventNotification($outboxNode, $vObject);
-
- } else {
-
- throw new Sabre_DAV_Exception_NotImplemented('SabreDAV supports only VFREEBUSY (REQUEST) and VEVENT (REQUEST, REPLY, ADD, CANCEL)');
-
- }
-
- }
-
- /**
- * This method handles the REQUEST, REPLY, ADD and CANCEL methods for
- * VEVENT iTip messages.
- *
* @return void
*/
- protected function handleEventNotification(Sabre_CalDAV_Schedule_IOutbox $outboxNode, VObject\Component $vObject) {
+ public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode) {
$originator = $this->server->httpRequest->getHeader('Originator');
$recipients = $this->server->httpRequest->getHeader('Recipient');
@@ -972,10 +760,38 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header');
}
- $result = $this->iMIPMessage($originator, $recipients, $vObject, $principal);
- $this->server->httpResponse->sendStatus(200);
- $this->server->httpResponse->setHeader('Content-Type','application/xml');
- $this->server->httpResponse->sendBody($this->generateScheduleResponse($result));
+ try {
+ $vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true));
+ } catch (Sabre_VObject_ParseException $e) {
+ throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
+ }
+
+ // Checking for the object type
+ $componentType = null;
+ foreach($vObject->getComponents() as $component) {
+ if ($component->name !== 'VTIMEZONE') {
+ $componentType = $component->name;
+ break;
+ }
+ }
+ if (is_null($componentType)) {
+ throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
+ }
+
+ // Validating the METHOD
+ $method = strtoupper((string)$vObject->METHOD);
+ if (!$method) {
+ throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages');
+ }
+
+ if (in_array($method, array('REQUEST','REPLY','ADD','CANCEL')) && $componentType==='VEVENT') {
+ $result = $this->iMIPMessage($originator, $recipients, $vObject);
+ $this->server->httpResponse->sendStatus(200);
+ $this->server->httpResponse->setHeader('Content-Type','application/xml');
+ $this->server->httpResponse->sendBody($this->generateScheduleResponse($result));
+ } else {
+ throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented');
+ }
}
@@ -997,15 +813,15 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
*
* @param string $originator
* @param array $recipients
- * @param Sabre\VObject\Component $vObject
+ * @param Sabre_VObject_Component $vObject
* @return array
*/
- protected function iMIPMessage($originator, array $recipients, VObject\Component $vObject, $principal) {
+ protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
if (!$this->imipHandler) {
$resultStatus = '5.2;This server does not support this operation';
} else {
- $this->imipHandler->sendMessage($originator, $recipients, $vObject, $principal);
+ $this->imipHandler->sendMessage($originator, $recipients, $vObject);
$resultStatus = '2.0;Success';
}
@@ -1016,6 +832,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
return $result;
+
}
/**
@@ -1061,204 +878,6 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * This method is responsible for parsing a free-busy query request and
- * returning it's result.
- *
- * @param Sabre_CalDAV_Schedule_IOutbox $outbox
- * @param string $request
- * @return string
- */
- protected function handleFreeBusyRequest(Sabre_CalDAV_Schedule_IOutbox $outbox, VObject\Component $vObject) {
-
- $vFreeBusy = $vObject->VFREEBUSY;
- $organizer = $vFreeBusy->organizer;
-
- $organizer = (string)$organizer;
-
- // Validating if the organizer matches the owner of the inbox.
- $owner = $outbox->getOwner();
-
- $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
-
- $uas = $caldavNS . 'calendar-user-address-set';
- $props = $this->server->getProperties($owner,array($uas));
-
- if (empty($props[$uas]) || !in_array($organizer, $props[$uas]->getHrefs())) {
- throw new Sabre_DAV_Exception_Forbidden('The organizer in the request did not match any of the addresses for the owner of this inbox');
- }
-
- if (!isset($vFreeBusy->ATTENDEE)) {
- throw new Sabre_DAV_Exception_BadRequest('You must at least specify 1 attendee');
- }
-
- $attendees = array();
- foreach($vFreeBusy->ATTENDEE as $attendee) {
- $attendees[]= (string)$attendee;
- }
-
-
- if (!isset($vFreeBusy->DTSTART) || !isset($vFreeBusy->DTEND)) {
- throw new Sabre_DAV_Exception_BadRequest('DTSTART and DTEND must both be specified');
- }
-
- $startRange = $vFreeBusy->DTSTART->getDateTime();
- $endRange = $vFreeBusy->DTEND->getDateTime();
-
- $results = array();
- foreach($attendees as $attendee) {
- $results[] = $this->getFreeBusyForEmail($attendee, $startRange, $endRange, $vObject);
- }
-
- $dom = new DOMDocument('1.0','utf-8');
- $dom->formatOutput = true;
- $scheduleResponse = $dom->createElement('cal:schedule-response');
- foreach($this->server->xmlNamespaces as $namespace=>$prefix) {
-
- $scheduleResponse->setAttribute('xmlns:' . $prefix,$namespace);
-
- }
- $dom->appendChild($scheduleResponse);
-
- foreach($results as $result) {
- $response = $dom->createElement('cal:response');
-
- $recipient = $dom->createElement('cal:recipient');
- $recipientHref = $dom->createElement('d:href');
-
- $recipientHref->appendChild($dom->createTextNode($result['href']));
- $recipient->appendChild($recipientHref);
- $response->appendChild($recipient);
-
- $reqStatus = $dom->createElement('cal:request-status');
- $reqStatus->appendChild($dom->createTextNode($result['request-status']));
- $response->appendChild($reqStatus);
-
- if (isset($result['calendar-data'])) {
-
- $calendardata = $dom->createElement('cal:calendar-data');
- $calendardata->appendChild($dom->createTextNode(str_replace("\r\n","\n",$result['calendar-data']->serialize())));
- $response->appendChild($calendardata);
-
- }
- $scheduleResponse->appendChild($response);
- }
-
- $this->server->httpResponse->sendStatus(200);
- $this->server->httpResponse->setHeader('Content-Type','application/xml');
- $this->server->httpResponse->sendBody($dom->saveXML());
-
- }
-
- /**
- * Returns free-busy information for a specific address. The returned
- * data is an array containing the following properties:
- *
- * calendar-data : A VFREEBUSY VObject
- * request-status : an iTip status code.
- * href: The principal's email address, as requested
- *
- * The following request status codes may be returned:
- * * 2.0;description
- * * 3.7;description
- *
- * @param string $email address
- * @param DateTime $start
- * @param DateTime $end
- * @param Sabre_VObject_Component $request
- * @return Sabre_VObject_Component
- */
- protected function getFreeBusyForEmail($email, DateTime $start, DateTime $end, VObject\Component $request) {
-
- $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
-
- $aclPlugin = $this->server->getPlugin('acl');
- if (substr($email,0,7)==='mailto:') $email = substr($email,7);
-
- $result = $aclPlugin->principalSearch(
- array('{http://sabredav.org/ns}email-address' => $email),
- array(
- '{DAV:}principal-URL', $caldavNS . 'calendar-home-set',
- '{http://sabredav.org/ns}email-address',
- )
- );
-
- if (!count($result)) {
- return array(
- 'request-status' => '3.7;Could not find principal',
- 'href' => 'mailto:' . $email,
- );
- }
-
- if (!isset($result[0][200][$caldavNS . 'calendar-home-set'])) {
- return array(
- 'request-status' => '3.7;No calendar-home-set property found',
- 'href' => 'mailto:' . $email,
- );
- }
- $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref();
-
- // Grabbing the calendar list
- $objects = array();
- foreach($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) {
- if (!$node instanceof Sabre_CalDAV_ICalendar) {
- continue;
- }
- $aclPlugin->checkPrivileges($homeSet . $node->getName() ,$caldavNS . 'read-free-busy');
-
- // Getting the list of object uris within the time-range
- $urls = $node->calendarQuery(array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
- 'is-not-defined' => false,
- 'time-range' => array(
- 'start' => $start,
- 'end' => $end,
- ),
- ),
- ),
- 'prop-filters' => array(),
- 'is-not-defined' => false,
- 'time-range' => null,
- ));
-
- $calObjects = array_map(function($url) use ($node) {
- $obj = $node->getChild($url)->get();
- return $obj;
- }, $urls);
-
- $objects = array_merge($objects,$calObjects);
-
- }
-
- $vcalendar = VObject\Component::create('VCALENDAR');
- $vcalendar->VERSION = '2.0';
- $vcalendar->METHOD = 'REPLY';
- $vcalendar->CALSCALE = 'GREGORIAN';
- $vcalendar->PRODID = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
-
- $generator = new VObject\FreeBusyGenerator();
- $generator->setObjects($objects);
- $generator->setTimeRange($start, $end);
- $generator->setBaseObject($vcalendar);
-
- $result = $generator->getResult();
-
- $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email;
- $vcalendar->VFREEBUSY->UID = (string)$request->VFREEBUSY->UID;
- $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER;
-
- return array(
- 'calendar-data' => $result,
- 'request-status' => '2.0;Success',
- 'href' => 'mailto:' . $email,
- );
- }
-
- /**
* This method is used to generate HTML output for the
* Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
* can use to create new calendars.