[Pkg-owncloud-commits] [php-sabredav] 38/148: Moved calendar-query and calendar-multiget reports to new XML system.

David Prévot taffit at moszumanska.debian.org
Wed Apr 15 01:37:09 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository php-sabredav.

commit 52a42fb95a019712613bc39e7b612f5f60278322
Author: Evert Pot <me at evertpot.com>
Date:   Wed Feb 11 00:12:02 2015 -0500

    Moved calendar-query and calendar-multiget reports to new XML system.
---
 lib/CalDAV/CalendarQueryParser.php                | 299 ------------
 lib/CalDAV/Plugin.php                             | 109 ++---
 lib/CalDAV/Xml/CalendarData.php                   | 117 -----
 lib/CalDAV/Xml/Filter/CalendarData.php            |  86 ++++
 lib/CalDAV/Xml/Filter/CompFilter.php              |  43 +-
 lib/CalDAV/Xml/Property/Invite.php                |   4 +-
 lib/CalDAV/Xml/Request/CalendarMultiGetReport.php |  72 ++-
 lib/CalDAV/Xml/Request/CalendarQueryReport.php    |  82 ++--
 lib/DAV/CorePlugin.php                            |   7 +-
 tests/Sabre/CalDAV/CalendarQueryParserTest.php    | 540 ----------------------
 tests/Sabre/CalDAV/JCalTransformTest.php          |   6 +-
 tests/Sabre/CalDAV/PluginTest.php                 |   1 -
 12 files changed, 209 insertions(+), 1157 deletions(-)

diff --git a/lib/CalDAV/CalendarQueryParser.php b/lib/CalDAV/CalendarQueryParser.php
deleted file mode 100644
index 60a2ae6..0000000
--- a/lib/CalDAV/CalendarQueryParser.php
+++ /dev/null
@@ -1,299 +0,0 @@
-<?php
-
-namespace Sabre\CalDAV;
-
-use Sabre\VObject;
-
-/**
- * Parses the calendar-query report request body.
- *
- * Whoever designed this format, and the CalDAV equivalent even more so,
- * has no feel for design.
- *
- * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class CalendarQueryParser {
-
-    /**
-     * List of requested properties the client wanted
-     *
-     * @var array
-     */
-    public $requestedProperties;
-
-    /**
-     * List of property/component filters.
-     *
-     * @var array
-     */
-    public $filters;
-
-    /**
-     * This property will contain null if CALDAV:expand was not specified,
-     * otherwise it will contain an array with 2 elements (start, end). Each
-     * contain a DateTime object.
-     *
-     * If expand is specified, recurring calendar objects are to be expanded
-     * into their individual components, and only the components that fall
-     * within the specified time-range are to be returned.
-     *
-     * For more details, see rfc4791, section 9.6.5.
-     *
-     * @var null|array
-     */
-    public $expand;
-
-    /**
-     * DOM Document
-     *
-     * @var DOMDocument
-     */
-    protected $dom;
-
-    /**
-     * DOM XPath object
-     *
-     * @var DOMXPath
-     */
-    protected $xpath;
-
-    /**
-     * Creates the parser
-     *
-     * @param \DOMDocument $dom
-     */
-    function __construct(\DOMDocument $dom) {
-
-        $this->dom = $dom;
-        $this->xpath = new \DOMXPath($dom);
-        $this->xpath->registerNameSpace('cal',Plugin::NS_CALDAV);
-        $this->xpath->registerNameSpace('dav','urn:DAV');
-
-    }
-
-    /**
-     * Parses the request.
-     *
-     * @return void
-     */
-    function parse() {
-
-        $filter = $this->xpath->query('/cal:calendar-query/cal:filter');
-        if ($filter->length !== 1) {
-            throw new \Sabre\DAV\Exception\BadRequest('Only one filter element is allowed');
-        }
-
-        $compFilters = $this->parseCompFilters($filter->item(0));
-        if (count($compFilters)!==1) {
-            throw new \Sabre\DAV\Exception\BadRequest('There must be exactly 1 top-level comp-filter.');
-        }
-
-        $this->filters = $compFilters[0];
-        $this->requestedProperties = array_keys(\Sabre\DAV\XMLUtil::parseProperties($this->dom->firstChild));
-
-        $expand = $this->xpath->query('/cal:calendar-query/dav:prop/cal:calendar-data/cal:expand');
-        if ($expand->length>0) {
-            $this->expand = $this->parseExpand($expand->item(0));
-        }
-
-
-    }
-
-    /**
-     * Parses all the 'comp-filter' elements from a node
-     *
-     * @param \DOMElement $parentNode
-     * @return array
-     */
-    protected function parseCompFilters(\DOMElement $parentNode) {
-
-        $compFilterNodes = $this->xpath->query('cal:comp-filter', $parentNode);
-        $result = [];
-
-        for($ii=0; $ii < $compFilterNodes->length; $ii++) {
-
-            $compFilterNode = $compFilterNodes->item($ii);
-
-            $compFilter = [];
-            $compFilter['name'] = $compFilterNode->getAttribute('name');
-            $compFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $compFilterNode)->length>0;
-            $compFilter['comp-filters'] = $this->parseCompFilters($compFilterNode);
-            $compFilter['prop-filters'] = $this->parsePropFilters($compFilterNode);
-            $compFilter['time-range'] = $this->parseTimeRange($compFilterNode);
-
-            if ($compFilter['time-range'] && !in_array($compFilter['name'], [
-                'VEVENT',
-                'VTODO',
-                'VJOURNAL',
-                'VFREEBUSY',
-                'VALARM',
-            ])) {
-                throw new \Sabre\DAV\Exception\BadRequest('The time-range filter is not defined for the ' . $compFilter['name'] . ' component');
-            };
-
-            $result[] = $compFilter;
-
-        }
-
-        return $result;
-
-    }
-
-    /**
-     * Parses all the prop-filter elements from a node
-     *
-     * @param \DOMElement $parentNode
-     * @return array
-     */
-    protected function parsePropFilters(\DOMElement $parentNode) {
-
-        $propFilterNodes = $this->xpath->query('cal:prop-filter', $parentNode);
-        $result = [];
-
-        for ($ii=0; $ii < $propFilterNodes->length; $ii++) {
-
-            $propFilterNode = $propFilterNodes->item($ii);
-            $propFilter = [];
-            $propFilter['name'] = $propFilterNode->getAttribute('name');
-            $propFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $propFilterNode)->length>0;
-            $propFilter['param-filters'] = $this->parseParamFilters($propFilterNode);
-            $propFilter['text-match'] = $this->parseTextMatch($propFilterNode);
-            $propFilter['time-range'] = $this->parseTimeRange($propFilterNode);
-
-            $result[] = $propFilter;
-
-        }
-
-        return $result;
-
-    }
-
-    /**
-     * Parses the param-filter element
-     *
-     * @param \DOMElement $parentNode
-     * @return array
-     */
-    protected function parseParamFilters(\DOMElement $parentNode) {
-
-        $paramFilterNodes = $this->xpath->query('cal:param-filter', $parentNode);
-        $result = [];
-
-        for($ii=0;$ii<$paramFilterNodes->length;$ii++) {
-
-            $paramFilterNode = $paramFilterNodes->item($ii);
-            $paramFilter = [];
-            $paramFilter['name'] = $paramFilterNode->getAttribute('name');
-            $paramFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $paramFilterNode)->length>0;
-            $paramFilter['text-match'] = $this->parseTextMatch($paramFilterNode);
-
-            $result[] = $paramFilter;
-
-        }
-
-        return $result;
-
-    }
-
-    /**
-     * Parses the text-match element
-     *
-     * @param \DOMElement $parentNode
-     * @return array|null
-     */
-    protected function parseTextMatch(\DOMElement $parentNode) {
-
-        $textMatchNodes = $this->xpath->query('cal:text-match', $parentNode);
-
-        if ($textMatchNodes->length === 0)
-            return null;
-
-        $textMatchNode = $textMatchNodes->item(0);
-        $negateCondition = $textMatchNode->getAttribute('negate-condition');
-        $negateCondition = $negateCondition==='yes';
-        $collation = $textMatchNode->getAttribute('collation');
-        if (!$collation) $collation = 'i;ascii-casemap';
-
-        return [
-            'negate-condition' => $negateCondition,
-            'collation' => $collation,
-            'value' => $textMatchNode->nodeValue
-        ];
-
-    }
-
-    /**
-     * Parses the time-range element
-     *
-     * @param \DOMElement $parentNode
-     * @return array|null
-     */
-    protected function parseTimeRange(\DOMElement $parentNode) {
-
-        $timeRangeNodes = $this->xpath->query('cal:time-range', $parentNode);
-        if ($timeRangeNodes->length === 0) {
-            return null;
-        }
-
-        $timeRangeNode = $timeRangeNodes->item(0);
-
-        if ($start = $timeRangeNode->getAttribute('start')) {
-            $start = VObject\DateTimeParser::parseDateTime($start);
-        } else {
-            $start = null;
-        }
-        if ($end = $timeRangeNode->getAttribute('end')) {
-            $end = VObject\DateTimeParser::parseDateTime($end);
-        } else {
-            $end = null;
-        }
-
-        if (!is_null($start) && !is_null($end) && $end <= $start) {
-            throw new \Sabre\DAV\Exception\BadRequest('The end-date must be larger than the start-date in the time-range filter');
-        }
-
-        return [
-            'start' => $start,
-            'end' => $end,
-        ];
-
-    }
-
-    /**
-     * Parses the CALDAV:expand element.
-     *
-     * This method returns an array with two elements: start and end. Each are
-     * a PHP DateTime object.
-     *
-     * @param \DOMElement $parentNode
-     * @return array
-     */
-    protected function parseExpand(\DOMElement $parentNode) {
-
-        $start = $parentNode->getAttribute('start');
-        if(!$start) {
-            throw new \Sabre\DAV\Exception\BadRequest('The "start" attribute is required for the CALDAV:expand element');
-        }
-        $start = VObject\DateTimeParser::parseDateTime($start);
-
-        $end = $parentNode->getAttribute('end');
-        if(!$end) {
-            throw new \Sabre\DAV\Exception\BadRequest('The "end" attribute is required for the CALDAV:expand element');
-        }
-
-        $end = 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.');
-        }
-
-        return [
-            'start' => $start,
-            'end' => $end,
-        ];
-
-    }
-
-}
diff --git a/lib/CalDAV/Plugin.php b/lib/CalDAV/Plugin.php
index eff21f8..0bea2bd 100644
--- a/lib/CalDAV/Plugin.php
+++ b/lib/CalDAV/Plugin.php
@@ -8,7 +8,7 @@ use Sabre\DAV\Xml\Property\Href;
 use Sabre\DAVACL;
 use Sabre\VObject;
 use Sabre\HTTP;
-use Sabre\HTTP\URLUtil;
+use Sabre\Uri;
 use Sabre\HTTP\RequestInterface;
 use Sabre\HTTP\ResponseInterface;
 
@@ -68,7 +68,7 @@ class Plugin extends DAV\ServerPlugin {
 
         // The MKCALENDAR is only available on unmapped uri's, whose
         // parents extend IExtendedCollection
-        list($parent, $name) = URLUtil::splitPath($uri);
+        list($parent, $name) = Uri\split($uri);
 
         $node = $this->server->tree->getNodeForPath($parent);
 
@@ -94,7 +94,7 @@ class Plugin extends DAV\ServerPlugin {
     function getCalendarHomeForPrincipal($principalUrl) {
 
         // The default is a bit naive, but it can be overwritten.
-        list(, $nodeName) = URLUtil::splitPath($principalUrl);
+        list(, $nodeName) = Uri\split($principalUrl);
 
         return self::CALENDAR_ROOT . '/' . $nodeName;
 
@@ -176,14 +176,11 @@ class Plugin extends DAV\ServerPlugin {
         $server->on('beforeWriteContent',  [$this,'beforeWriteContent']);
         $server->on('afterMethod:GET',     [$this,'httpAfterGET']);
 
-        $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->xml->elementMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet';
 
+        $server->xml->elementMap['{' . self::NS_CALDAV . '}calendar-query'] = 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport';
+        $server->xml->elementMap['{' . self::NS_CALDAV . '}calendar-multiget'] = 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport';
         $server->xml->elementMap['{' . self::NS_CALDAV . '}mkcalendar'] = 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar';
-        $server->xml->elementMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet';
 
         $server->resourceTypeMapping['\\Sabre\\CalDAV\\ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar';
 
@@ -363,10 +360,10 @@ class Plugin extends DAV\ServerPlugin {
                     // group, we grab the parent principal and add it to the
                     // list.
                     if ($groupNode instanceof Principal\IProxyRead) {
-                        list($readList[]) = URLUtil::splitPath($group);
+                        list($readList[]) = Uri\split($group);
                     }
                     if ($groupNode instanceof Principal\IProxyWrite) {
-                        list($writeList[]) = URLUtil::splitPath($group);
+                        list($writeList[]) = Uri\split($group);
                     }
 
                 }
@@ -403,59 +400,24 @@ class Plugin extends DAV\ServerPlugin {
      * This report is used by the client to fetch the content of a series
      * of urls. Effectively avoiding a lot of redundant requests.
      *
-     * @param \DOMNode $dom
+     * @param CalendarMultiGetReport $report
      * @return void
      */
-    function calendarMultiGetReport($dom) {
-
-        $properties = array_keys(DAV\XMLUtil::parseProperties($dom->firstChild));
-        $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href');
-
-        $xpath = new \DOMXPath($dom);
-        $xpath->registerNameSpace('cal',Plugin::NS_CALDAV);
-        $xpath->registerNameSpace('dav','urn:DAV');
-
-        $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand');
-        if ($expand->length > 0) {
-            $expandElem = $expand->item(0);
-            $start = $expandElem->getAttribute('start');
-            $end = $expandElem->getAttribute('end');
-            if(!$start || !$end) {
-                throw new 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);
+    function calendarMultiGetReport($report) {
 
-            if ($end <= $start) {
-                throw new DAV\Exception\BadRequest('The end-date must be larger than the start-date in the expand element.');
-            }
-
-            $expand = true;
-
-        } else {
-
-            $expand = false;
-
-        }
-
-        $needsJson = $xpath->evaluate("boolean(/cal:calendar-multiget/dav:prop/cal:calendar-data[@content-type='application/calendar+json'])");
-
-        $uris = [];
-        foreach($hrefElems as $elem) {
-            $uris[] = $this->server->calculateUri($elem->nodeValue);
-        }
+        $needsJson = $report->contentType === 'application/calendar+json';
 
         $timeZones = [];
 
-        foreach($this->server->getPropertiesForMultiplePaths($uris, $properties) as $uri=>$objProps) {
+        foreach($this->server->getPropertiesForMultiplePaths($report->hrefs, $report->properties) as $uri=>$objProps) {
 
-            if (($needsJson || $expand) && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) {
+            if (($needsJson || $report->expand) && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) {
                 $vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
 
-                if ($expand) {
+                if ($report->expand) {
                     // We're expanding, and for that we need to figure out the
                     // calendar's timezone.
-                    list($calendarPath) = URLUtil::splitPath($uri);
+                    list($calendarPath) = Uri\split($uri);
                     if (!isset($timeZones[$calendarPath])) {
                         // Checking the calendar-timezone property.
                         $tzProp = '{' . self::NS_CALDAV . '}calendar-timezone';
@@ -472,7 +434,7 @@ class Plugin extends DAV\ServerPlugin {
                         $timeZones[$calendarPath] = $timeZone;
                     }
 
-                    $vObject->expand($start, $end, $timeZones[$calendarPath]);
+                    $vObject->expand($report->expand['start'], $report->expand['end'], $timeZones[$calendarPath]);
                 }
                 if ($needsJson) {
                     $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = json_encode($vObject->jsonSerialize());
@@ -500,21 +462,14 @@ class Plugin extends DAV\ServerPlugin {
      * This report is used by clients to request calendar objects based on
      * complex conditions.
      *
-     * @param \DOMNode $dom
+     * @param Xml\Request\CalendarQueryReport $report
      * @return void
      */
-    function calendarQueryReport($dom) {
-
-        $parser = new CalendarQueryParser($dom);
-        $parser->parse();
+    function calendarQueryReport($report) {
 
         $path = $this->server->getRequestUri();
 
-        // TODO: move this into CalendarQueryParser
-        $xpath = new \DOMXPath($dom);
-        $xpath->registerNameSpace('cal',Plugin::NS_CALDAV);
-        $xpath->registerNameSpace('dav','urn:DAV');
-        $needsJson = $xpath->evaluate("boolean(/cal:calendar-query/dav:prop/cal:calendar-data[@content-type='application/calendar+json'])");
+        $needsJson = $report->contentType === 'application/calendar+json';
 
         $node = $this->server->tree->getNodeForPath($this->server->getRequestUri());
         $depth = $this->server->getHTTPDepth(0);
@@ -523,7 +478,7 @@ class Plugin extends DAV\ServerPlugin {
         $result = [];
 
         $calendarTimeZone = null;
-        if ($parser->expand) {
+        if ($report->expand) {
             // We're expanding, and for that we need to figure out the
             // calendar's timezone.
             $tzProp = '{' . self::NS_CALDAV . '}calendar-timezone';
@@ -545,7 +500,7 @@ class Plugin extends DAV\ServerPlugin {
         if ($depth == 0 && $node instanceof ICalendarObject) {
 
             $requestedCalendarData = true;
-            $requestedProperties = $parser->requestedProperties;
+            $requestedProperties = $report->properties;
 
             if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
 
@@ -574,7 +529,7 @@ class Plugin extends DAV\ServerPlugin {
                 $validator = new CalendarQueryValidator();
 
                 $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
-                if ($validator->validate($vObject,$parser->filters)) {
+                if ($validator->validate($vObject,$report->filters)) {
 
                     // If the client didn't require the calendar-data property,
                     // we won't give it back.
@@ -583,12 +538,12 @@ class Plugin extends DAV\ServerPlugin {
                     } else {
 
 
-                        if ($parser->expand) {
-                            $vObject->expand($parser->expand['start'], $parser->expand['end'], $calendarTimeZone);
+                        if ($report->expand) {
+                            $vObject->expand($report->expand['start'], $report->expand['end'], $calendarTimeZone);
                         }
                         if ($needsJson) {
                             $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = json_encode($vObject->jsonSerialize());
-                        } elseif ($parser->expand) {
+                        } elseif ($report->expand) {
                             $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
                         }
                     }
@@ -605,18 +560,18 @@ class Plugin extends DAV\ServerPlugin {
         // for the calendar-query.
         if ($node instanceof ICalendarObjectContainer && $depth == 1) {
 
-            $nodePaths = $node->calendarQuery($parser->filters);
+            $nodePaths = $node->calendarQuery($report->filters);
 
             foreach($nodePaths as $path) {
 
                 list($properties) =
-                    $this->server->getPropertiesForPath($this->server->getRequestUri() . '/' . $path, $parser->requestedProperties);
+                    $this->server->getPropertiesForPath($this->server->getRequestUri() . '/' . $path, $report->properties);
 
-                if (($needsJson || $parser->expand)) {
+                if (($needsJson || $report->expand)) {
                     $vObject = VObject\Reader::read($properties[200]['{' . self::NS_CALDAV . '}calendar-data']);
 
-                    if ($parser->expand) {
-                        $vObject->expand($parser->expand['start'], $parser->expand['end'], $calendarTimeZone);
+                    if ($report->expand) {
+                        $vObject->expand($report->expand['start'], $report->expand['end'], $calendarTimeZone);
                     }
 
                     if ($needsJson) {
@@ -758,7 +713,7 @@ class Plugin extends DAV\ServerPlugin {
         // We're onyl interested in ICalendarObject nodes that are inside of a
         // real calendar. This is to avoid triggering validation and scheduling
         // for non-calendars (such as an inbox).
-        list($parent) = URLUtil::splitPath($path);
+        list($parent) = Uri\split($path);
         $parentNode = $this->server->tree->getNodeForPath($parent);
 
         if (!$parentNode instanceof ICalendar)
@@ -859,7 +814,7 @@ class Plugin extends DAV\ServerPlugin {
         $sCCS = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
 
         // Get the Supported Components for the target calendar
-        list($parentPath) = URLUtil::splitPath($path);
+        list($parentPath) = Uri\split($path);
         $calendarProperties = $this->server->getProperties($parentPath, [$sCCS]);
 
         if (isset($calendarProperties[$sCCS])) {
diff --git a/lib/CalDAV/Xml/CalendarData.php b/lib/CalDAV/Xml/CalendarData.php
deleted file mode 100644
index 6141540..0000000
--- a/lib/CalDAV/Xml/CalendarData.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-namespace Sabre\CalDAV\XML;
-
-use
-    Sabre\Xml\Element,
-    Sabre\Xml\Reader,
-    Sabre\Xml\Writer,
-    Sabre\DAV\Exception\CannotSerialize,
-    Sabre\DAV\Exception\BadRequest,
-    Sabre\CalDAV\Plugin,
-    Sabre\VObject\DateTimeParser;
-
-
-/**
- * CalendarData parser.
- *
- * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-data XML
- * element, as defined in:
- *
- * https://tools.ietf.org/html/rfc4791#section-9.6
- *
- * This element is used for three distinct purposes:
- *
- * 1. To return calendar-data in a response, in which case this deserializer
- *    will just spit out a string.
- * 2. Information on how calendar-data should be returned, from a
- *    calendar-multiget or calendar-query REPORT, in which case this
- *    deserializer will spit out and array with the relevant information.
- * 3. A list of supported media-types, nested in the supported-calendar-data
- *    property. This case is currently not handled.
- *
- * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class CalendarData implements Element {
-
-    /**
-     * The serialize method is called during xml writing.
-     *
-     * It should use the $writer argument to encode this object into XML.
-     *
-     * Important note: it is not needed to create the parent element. The
-     * parent element is already created, and we only have to worry about
-     * attributes, child elements and text (if any).
-     *
-     * Important note 2: If you are writing any new elements, you are also
-     * responsible for closing them.
-     *
-     * @param Writer $writer
-     * @return void
-     */
-    public function serializeXml(Writer $writer) {
-
-        throw new CannotSerialize('This element cannot be serialized.');
-
-    }
-
-    /**
-     * The deserialize method is called during xml parsing.
-     *
-     * This method is called statictly, this is because in theory this method
-     * may be used as a type of constructor, or factory method.
-     *
-     * Often you want to return an instance of the current class, but you are
-     * free to return other data as well.
-     *
-     * Important note 2: You are responsible for advancing the reader to the
-     * next element. Not doing anything will result in a never-ending loop.
-     *
-     * If you just want to skip parsing for this element altogether, you can
-     * just call $reader->next();
-     *
-     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
-     * the next element.
-     *
-     * @param Reader $reader
-     * @return mixed
-     */
-    static public function deserializeXml(Reader $reader) {
-
-        $value = $reader->parseInnerTree();
-
-        // If we are parsing this as a string, it must have been an iCalendar
-        // blob, and we can just return it as-is.
-        if (is_string($value) || is_null($value)) {
-            return $value;
-        }
-
-        $result = [
-        ];
-        foreach($value as $elem) {
-
-            if ($elem['name'] === '{' . Plugin::NS_CALDAV . '}expand') {
-
-                $result['expand'] = [
-                    'start' => isset($elem['attributes']['start'])?DateTimeParser::parseDateTime($elem['attributes']['start']):null,
-                    'end' => isset($elem['attributes']['end'])?DateTimeParser::parseDateTime($elem['attributes']['end']):null,
-                ];
-
-                if (!$result['expand']['start'] || !$result['expand']['end']) {
-                    throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data');
-                }
-                if ($result['expand']['end'] <= $result['expand']['start']) {
-                    throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data');
-                }
-
-            }
-
-        }
-
-        return $result;
-
-    }
-
-}
diff --git a/lib/CalDAV/Xml/Filter/CalendarData.php b/lib/CalDAV/Xml/Filter/CalendarData.php
new file mode 100644
index 0000000..91cceae
--- /dev/null
+++ b/lib/CalDAV/Xml/Filter/CalendarData.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Sabre\CalDAV\Xml\Filter;
+
+use Sabre\Xml\Element\KeyValue;
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\CalDAV\Plugin;
+use Sabre\VObject\DateTimeParser;
+
+
+/**
+ * CalendarData parser.
+ *
+ * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-data XML
+ * element, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc4791#section-9.6
+ *
+ * This element is used in three distinct places in the caldav spec, but in
+ * this case, this element class only implements the calendar-data element as
+ * it appears in a DAV:prop element, in a calendar-query or calendar-multiget
+ * REPORT request. 
+ *
+ * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class CalendarData implements XmlDeserializable {
+
+    /**
+     * The deserialize method is called during xml parsing.
+     *
+     * This method is called statictly, this is because in theory this method
+     * may be used as a type of constructor, or factory method.
+     *
+     * Often you want to return an instance of the current class, but you are
+     * free to return other data as well.
+     *
+     * Important note 2: You are responsible for advancing the reader to the
+     * next element. Not doing anything will result in a never-ending loop.
+     *
+     * If you just want to skip parsing for this element altogether, you can
+     * just call $reader->next();
+     *
+     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+     * the next element.
+     *
+     * @param Reader $reader
+     * @return mixed
+     */
+    static function xmlDeserialize(Reader $reader) {
+
+        $result = [
+            'contentType' => $reader->getAttribute('content-type')?:'text/calendar',
+            'version'     => $reader->getAttribute('version')?:'2.0',
+        ];
+
+        $elems = (array)$reader->parseInnerTree();
+        foreach($elems as $elem) {
+
+            switch($elem['name']) {
+                case '{' . Plugin::NS_CALDAV . '}expand' :
+
+                    $result['expand'] = [
+                        'start' => isset($elem['attributes']['start'])?DateTimeParser::parseDateTime($elem['attributes']['start']):null,
+                        'end' => isset($elem['attributes']['end'])?DateTimeParser::parseDateTime($elem['attributes']['end']):null,
+                    ];
+
+                    if (!$result['expand']['start'] || !$result['expand']['end']) {
+                        throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data');
+                    }
+                    if ($result['expand']['end'] <= $result['expand']['start']) {
+                        throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data');
+                    }
+                    break;
+            }
+
+        }
+
+        return $result;
+
+    }
+
+}
diff --git a/lib/CalDAV/Xml/Filter/CompFilter.php b/lib/CalDAV/Xml/Filter/CompFilter.php
index 91e985f..19250a2 100644
--- a/lib/CalDAV/Xml/Filter/CompFilter.php
+++ b/lib/CalDAV/Xml/Filter/CompFilter.php
@@ -2,14 +2,12 @@
 
 namespace Sabre\CalDAV\Xml\Filter;
 
-use
-    Sabre\Xml\Element,
-    Sabre\Xml\Reader,
-    Sabre\Xml\Writer,
-    Sabre\DAV\Exception\CannotSerialize,
-    Sabre\DAV\Exception\BadRequest,
-    Sabre\CalDAV\Plugin,
-    Sabre\VObject\DateTimeParser;
+
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\CalDAV\Plugin;
+use Sabre\VObject\DateTimeParser;
 
 
 /**
@@ -26,28 +24,7 @@ use
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class CompFilter implements Element {
-
-    /**
-     * The serialize method is called during xml writing.
-     *
-     * It should use the $writer argument to encode this object into XML.
-     *
-     * Important note: it is not needed to create the parent element. The
-     * parent element is already created, and we only have to worry about
-     * attributes, child elements and text (if any).
-     *
-     * Important note 2: If you are writing any new elements, you are also
-     * responsible for closing them.
-     *
-     * @param Writer $writer
-     * @return void
-     */
-    public function serializeXml(Writer $writer) {
-
-        throw new CannotSerialize('This element cannot be serialized.');
-
-    }
+class CompFilter implements XmlDeserializable {
 
     /**
      * The deserialize method is called during xml parsing.
@@ -58,8 +35,8 @@ class CompFilter implements Element {
      * Often you want to return an instance of the current class, but you are
      * free to return other data as well.
      *
-     * Important note 2: You are responsible for advancing the reader to the
-     * next element. Not doing anything will result in a never-ending loop.
+     * You are responsible for advancing the reader to the next element. Not
+     * doing anything will result in a never-ending loop.
      *
      * If you just want to skip parsing for this element altogether, you can
      * just call $reader->next();
@@ -70,7 +47,7 @@ class CompFilter implements Element {
      * @param Reader $reader
      * @return mixed
      */
-    static public function deserializeXml(Reader $reader) {
+    static function xmlDeserialize(Reader $reader) {
 
         $result = [
             'name' => null,
diff --git a/lib/CalDAV/Xml/Property/Invite.php b/lib/CalDAV/Xml/Property/Invite.php
index ed7690a..468b419 100644
--- a/lib/CalDAV/Xml/Property/Invite.php
+++ b/lib/CalDAV/Xml/Property/Invite.php
@@ -172,8 +172,8 @@ class Invite implements Element {
      * Often you want to return an instance of the current class, but you are
      * free to return other data as well.
      *
-     * Important note 2: You are responsible for advancing the reader to the
-     * next element. Not doing anything will result in a never-ending loop.
+     * You are responsible for advancing the reader to the next element. Not
+     * doing anything will result in a never-ending loop.
      *
      * If you just want to skip parsing for this element altogether, you can
      * just call $reader->next();
diff --git a/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php b/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php
index 032fc36..afcb905 100644
--- a/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php
+++ b/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php
@@ -2,12 +2,10 @@
 
 namespace Sabre\CalDAV\Xml\Request;
 
-use
-    Sabre\Xml\Element,
-    Sabre\Xml\Reader,
-    Sabre\Xml\Writer,
-    Sabre\DAV\Exception\CannotSerialize,
-    Sabre\CalDAV\Plugin;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\Xml\Reader;
+use Sabre\CalDAV\Plugin;
+use Sabre\Uri;
 
 /**
  * CalendarMultiGetReport request parser.
@@ -21,7 +19,7 @@ use
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class CalendarMultiGetReport implements Element {
+class CalendarMultiGetReport implements XmlDeserializable {
 
     /**
      * An array with requested properties.
@@ -48,25 +46,20 @@ class CalendarMultiGetReport implements Element {
     public $expand = null;
 
     /**
-     * The serialize method is called during xml writing.
+     * The mimetype of the content that should be returend. Usually
+     * text/calendar.
      *
-     * It should use the $writer argument to encode this object into XML.
-     *
-     * Important note: it is not needed to create the parent element. The
-     * parent element is already created, and we only have to worry about
-     * attributes, child elements and text (if any).
-     *
-     * Important note 2: If you are writing any new elements, you are also
-     * responsible for closing them.
-     *
-     * @param Writer $writer
-     * @return void
+     * @var string
      */
-    public function serializeXml(Writer $writer) {
+    public $contentType = null;
 
-        throw new CannotSerialize('This element cannot be serialized.');
-
-    }
+    /**
+     * The version of calendar-data that should be returned. Usually '2.0',
+     * referring to iCalendar 2.0.
+     *
+     * @var string
+     */
+    public $version = null;
 
     /**
      * The deserialize method is called during xml parsing.
@@ -77,8 +70,8 @@ class CalendarMultiGetReport implements Element {
      * Often you want to return an instance of the current class, but you are
      * free to return other data as well.
      *
-     * Important note 2: You are responsible for advancing the reader to the
-     * next element. Not doing anything will result in a never-ending loop.
+     * You are responsible for advancing the reader to the next element. Not
+     * doing anything will result in a never-ending loop.
      *
      * If you just want to skip parsing for this element altogether, you can
      * just call $reader->next();
@@ -89,27 +82,30 @@ class CalendarMultiGetReport implements Element {
      * @param Reader $reader
      * @return mixed
      */
-    static public function deserializeXml(Reader $reader) {
+    static function xmlDeserialize(Reader $reader) {
 
-        $elems = $reader->parseInnerTree();
-        $hrefs = [];
+        $elems = $reader->parseInnerTree([
+            '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData',
+            '{DAV:}prop'                                   => 'Sabre\\Xml\\Element\\KeyValue',
+        ]);
 
-        $properties = null;
-
-        $expand = false;
+        $newProps = [
+            'hrefs' => [],
+            'properties' => [],
+        ];
 
         foreach($elems as $elem) {
 
             switch($elem['name']) {
 
                 case '{DAV:}prop' :
-                    if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data']['expand'])) {
-                        $expand = $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data']['expand'];
+                    $newProps['properties'] = array_keys($elem['value']);
+                    if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
+                        $newProps+=$elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'];
                     }
-                    $properties = array_keys($elem['value']);
                     break;
                 case '{DAV:}href' :
-                    $hrefs[] = $elem['value'];
+                    $newProps['hrefs'][] = Uri\resolve($reader->baseUri, $elem['value']);
                     break;
 
             }
@@ -117,9 +113,9 @@ class CalendarMultiGetReport implements Element {
         }
 
         $obj = new self();
-        $obj->properties = $properties;
-        $obj->hrefs = $hrefs;
-        $obj->expand = $expand;
+        foreach($newProps as $key=>$value) {
+            $obj->$key = $value;
+        }
 
         return $obj;
 
diff --git a/lib/CalDAV/Xml/Request/CalendarQueryReport.php b/lib/CalDAV/Xml/Request/CalendarQueryReport.php
index 1e74ff3..b3f7109 100644
--- a/lib/CalDAV/Xml/Request/CalendarQueryReport.php
+++ b/lib/CalDAV/Xml/Request/CalendarQueryReport.php
@@ -2,13 +2,10 @@
 
 namespace Sabre\CalDAV\Xml\Request;
 
-use
-    Sabre\Xml\Element,
-    Sabre\Xml\Reader,
-    Sabre\Xml\Writer,
-    Sabre\DAV\Exception\CannotSerialize,
-    Sabre\DAV\Exception\BadRequest,
-    Sabre\CalDAV\Plugin;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\Xml\Reader;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\CalDAV\Plugin;
 
 /**
  * CalendarQueryReport request parser.
@@ -22,7 +19,7 @@ use
  * @author Evert Pot (http://www.rooftopsolutions.nl/)
  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  */
-class CalendarQueryReport implements Element {
+class CalendarQueryReport implements XmlDeserializable {
 
     /**
      * An array with requested properties.
@@ -36,7 +33,7 @@ class CalendarQueryReport implements Element {
      *
      * @var array
      */
-    public $filter;
+    public $filters;
 
     /**
      * If the calendar data must be expanded, this will contain an array with 2
@@ -49,25 +46,20 @@ class CalendarQueryReport implements Element {
     public $expand = null;
 
     /**
-     * The serialize method is called during xml writing.
+     * The mimetype of the content that should be returend. Usually
+     * text/calendar.
      *
-     * It should use the $writer argument to encode this object into XML.
-     *
-     * Important note: it is not needed to create the parent element. The
-     * parent element is already created, and we only have to worry about
-     * attributes, child elements and text (if any).
-     *
-     * Important note 2: If you are writing any new elements, you are also
-     * responsible for closing them.
-     *
-     * @param Writer $writer
-     * @return void
+     * @var string
      */
-    public function serializeXml(Writer $writer) {
+    public $contentType = null;
 
-        throw new CannotSerialize('This element cannot be serialized.');
-
-    }
+    /**
+     * The version of calendar-data that should be returned. Usually '2.0',
+     * referring to iCalendar 2.0.
+     *
+     * @var string
+     */
+    public $version = null;
 
     /**
      * The deserialize method is called during xml parsing.
@@ -78,8 +70,8 @@ class CalendarQueryReport implements Element {
      * Often you want to return an instance of the current class, but you are
      * free to return other data as well.
      *
-     * Important note 2: You are responsible for advancing the reader to the
-     * next element. Not doing anything will result in a never-ending loop.
+     * You are responsible for advancing the reader to the next element. Not
+     * doing anything will result in a never-ending loop.
      *
      * If you just want to skip parsing for this element altogether, you can
      * just call $reader->next();
@@ -90,13 +82,20 @@ class CalendarQueryReport implements Element {
      * @param Reader $reader
      * @return mixed
      */
-    static public function deserializeXml(Reader $reader) {
+    static function xmlDeserialize(Reader $reader) {
 
-        $elems = $reader->parseInnerTree();
+        $elems = $reader->parseInnerTree([
+            '{urn:ietf:params:xml:ns:caldav}comp-filter'   => 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter',
+            '{urn:ietf:params:xml:ns:caldav}prop-filter'   => 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter',
+            '{urn:ietf:params:xml:ns:caldav}param-filter'  => 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter',
+            '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData',
+            '{DAV:}prop'                                   => 'Sabre\\Xml\\Element\\KeyValue',
+        ]);
 
-        $properties = null;
-        $expand = false;
-        $filter = null;
+        $newProps = [
+            'filters' => null,
+            'properties' => [],
+        ];
 
         if (!is_array($elems)) $elems = [];
 
@@ -105,18 +104,18 @@ class CalendarQueryReport implements Element {
             switch($elem['name']) {
 
                 case '{DAV:}prop' :
-                    if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data']['expand'])) {
-                        $expand = $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data']['expand'];
+                    $newProps['properties'] = array_keys($elem['value']);
+                    if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
+                        $newProps+=$elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'];
                     }
-                    $properties = array_keys($elem['value']);
                     break;
                 case '{'.Plugin::NS_CALDAV.'}filter' :
                     foreach($elem['value'] as $subElem) {
                         if ($subElem['name'] === '{' . Plugin::NS_CALDAV . '}comp-filter') {
-                            if (!is_null($filter)) {
+                            if (!is_null($newProps['filters'])) {
                                 throw new BadRequest('Only one top-level comp-filter may be defined');
                             }
-                            $filter = $subElem['value'];
+                            $newProps['filters'] = $subElem['value'];
                         }
                     }
                     break;
@@ -125,15 +124,14 @@ class CalendarQueryReport implements Element {
 
         }
 
-        if (is_null($filter)) {
+        if (is_null($newProps['filters'])) {
             throw new BadRequest('The {' . Plugin::NS_CALDAV . '}filter element is required for this request');
         }
 
         $obj = new self();
-        $obj->properties = $properties;
-        $obj->filter = $filter;
-        $obj->expand = $expand;
-
+        foreach($newProps as $key=>$value) {
+            $obj->$key = $value;
+        }
         return $obj;
 
     }
diff --git a/lib/DAV/CorePlugin.php b/lib/DAV/CorePlugin.php
index e92cdcf..5ca8530 100644
--- a/lib/DAV/CorePlugin.php
+++ b/lib/DAV/CorePlugin.php
@@ -706,12 +706,9 @@ class CorePlugin extends ServerPlugin {
 
         $path = $request->getPath();
 
-        $body = $request->getBodyAsString();
-        $dom = XMLUtil::loadDOMDocument($body);
+        $result = $this->server->xml->parse($request->getBody());
 
-        $reportName = XMLUtil::toClarkNotation($dom->firstChild);
-
-        if ($this->server->emit('report', [$reportName, $dom, $path])) {
+        if ($this->server->emit('report', [$result['name'], $result['value'], $path])) {
 
             // If emit returned true, it means the report was not supported
             throw new Exception\ReportNotSupported();
diff --git a/tests/Sabre/CalDAV/CalendarQueryParserTest.php b/tests/Sabre/CalDAV/CalendarQueryParserTest.php
deleted file mode 100644
index fdfe4de..0000000
--- a/tests/Sabre/CalDAV/CalendarQueryParserTest.php
+++ /dev/null
@@ -1,540 +0,0 @@
-<?php
-
-namespace Sabre\CalDAV;
-use Sabre\DAV;
-
-class CalendarQueryParserTest extends \PHPUnit_Framework_TestCase {
-
-    function parse($xml) {
-
-        $xml =
-'<?xml version="1.0"?>
-<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
-' . implode("\n", $xml) . '
-</c:calendar-query>';
-
-        $dom = DAV\XMLUtil::loadDOMDocument($xml);
-
-        $q = new CalendarQueryParser($dom);
-        $q->parse();
-        return $q->filters;
-
-    }
-
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testNoFilter() {
-
-        $xml = array();
-        $this->parse($xml);
-
-    }
-
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testTwoCompFilter() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VEVENT" />',
-            '  <c:comp-filter name="VEVENT" />',
-            '</c:filter>'
-        );
-        $this->parse($xml);
-
-    }
-
-    function testBasicFilter() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR" />',
-            '</c:filter>'
-        );
-        $result = $this->parse($xml);
-
-        $expected = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(),
-            'prop-filters' => array(),
-            'is-not-defined' => false,
-            'time-range' => false
-        );
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-
-    function testCompIsNotDefined() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR">',
-            '    <c:comp-filter name="VEVENT">',
-            '       <c:is-not-defined/>',
-            '    </c:comp-filter>',
-            '  </c:comp-filter>',
-            '</c:filter>'
-        );
-        $result = $this->parse($xml);
-
-        $expected = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(
-                array(
-                    'name' => 'VEVENT',
-                    'comp-filters' => array(),
-                    'prop-filters' => array(),
-                    'is-not-defined' => true,
-                    'time-range' => false
-                ),
-            ),
-            'prop-filters' => array(),
-            'is-not-defined' => false,
-            'time-range' => false
-        );
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testCompTimeRangeOnVCALENDAR() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR">',
-            '     <c:time-range start="20110101T000000Z" end="20111231T235959Z" />',
-            '  </c:comp-filter>',
-            '</c:filter>'
-        );
-        $result = $this->parse($xml);
-
-    }
-
-    function testCompTimeRange() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR">',
-            '    <c:comp-filter name="VEVENT">',
-            '       <c:time-range start="20110101T000000Z" end="20111231T235959Z" />',
-            '    </c:comp-filter>',
-            '    <c:comp-filter name="VTODO">',
-            '       <c:time-range start="20110101T000000Z" />',
-            '    </c:comp-filter>',
-            '    <c:comp-filter name="VJOURNAL">',
-            '       <c:time-range end="20111231T235959Z" />',
-            '    </c:comp-filter>',
-            '  </c:comp-filter>',
-            '</c:filter>'
-        );
-        $result = $this->parse($xml);
-
-        $expected = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(
-                array(
-                    'name' => 'VEVENT',
-                    'comp-filters' => array(),
-                    'prop-filters' => array(),
-                    'is-not-defined' => false,
-                    'time-range' => array(
-                        'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('GMT')),
-                        'end' => new \DateTime('2011-12-31 23:59:59', new \DateTimeZone('GMT')),
-                    ),
-                ),
-                array(
-                    'name' => 'VTODO',
-                    'comp-filters' => array(),
-                    'prop-filters' => array(),
-                    'is-not-defined' => false,
-                    'time-range' => array(
-                        'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('GMT')),
-                        'end' => null,
-                    ),
-                ),
-                array(
-                    'name' => 'VJOURNAL',
-                    'comp-filters' => array(),
-                    'prop-filters' => array(),
-                    'is-not-defined' => false,
-                    'time-range' => array(
-                        'start' => null,
-                        'end' => new \DateTime('2011-12-31 23:59:59', new \DateTimeZone('GMT')),
-                    ),
-                ),
-            ),
-            'prop-filters' => array(),
-            'is-not-defined' => false,
-            'time-range' => false
-        );
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testCompTimeRangeBadRange() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR">',
-            '    <c:comp-filter name="VEVENT">',
-            '       <c:time-range start="20110101T000000Z" end="20100101T000000Z" />',
-            '    </c:comp-filter>',
-            '  </c:comp-filter>',
-            '</c:filter>'
-        );
-        $this->parse($xml);
-
-    }
-
-    function testProp() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR">',
-            '    <c:comp-filter name="VEVENT">',
-            '       <c:prop-filter name="SUMMARY">',
-            '           <c:text-match>vacation</c:text-match>',
-            '       </c:prop-filter>',
-            '    </c:comp-filter>',
-            '  </c:comp-filter>',
-            '</c:filter>'
-        );
-        $result = $this->parse($xml);
-
-        $expected = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(
-                array(
-                    'name' => 'VEVENT',
-                    'is-not-defined' => false,
-                    'comp-filters' => array(),
-                    'prop-filters' => array(
-                        array(
-                            'name' => 'SUMMARY',
-                            'is-not-defined' => false,
-                            'param-filters' => array(),
-                            'text-match' => array(
-                                'negate-condition' => false,
-                                'collation' => 'i;ascii-casemap',
-                                'value' => 'vacation',
-                            ),
-                            'time-range' => null,
-                       ),
-                    ),
-                    'time-range' => null,
-                ),
-            ),
-            'prop-filters' => array(),
-            'is-not-defined' => false,
-            'time-range' => false
-        );
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-
-    function testComplex() {
-
-        $xml = array(
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR">',
-            '    <c:comp-filter name="VEVENT">',
-            '       <c:prop-filter name="SUMMARY">',
-            '           <c:text-match collation="i;unicode-casemap">vacation</c:text-match>',
-            '       </c:prop-filter>',
-            '       <c:prop-filter name="DTSTAMP">',
-            '           <c:time-range start="20110704T000000Z" />',
-            '       </c:prop-filter>',
-            '       <c:prop-filter name="ORGANIZER">',
-            '           <c:is-not-defined />',
-            '       </c:prop-filter>',
-            '       <c:prop-filter name="DTSTART">',
-            '           <c:param-filter name="VALUE">',
-            '               <c:text-match negate-condition="yes">DATE</c:text-match>',
-            '           </c:param-filter>',
-            '       </c:prop-filter>',
-            '    </c:comp-filter>',
-            '  </c:comp-filter>',
-            '</c:filter>'
-        );
-        $result = $this->parse($xml);
-
-        $expected = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(
-                array(
-                    'name' => 'VEVENT',
-                    'is-not-defined' => false,
-                    'comp-filters' => array(),
-                    'prop-filters' => array(
-                        array(
-                            'name' => 'SUMMARY',
-                            'is-not-defined' => false,
-                            'param-filters' => array(),
-                            'text-match' => array(
-                                'negate-condition' => false,
-                                'collation' => 'i;unicode-casemap',
-                                'value' => 'vacation',
-                            ),
-                            'time-range' => null,
-                        ),
-                        array(
-                            'name' => 'DTSTAMP',
-                            'is-not-defined' => false,
-                            'param-filters' => array(),
-                            'text-match' => null,
-                            'time-range' => array(
-                                'start' => new \DateTime('2011-07-04 00:00:00', new \DateTimeZone('GMT')),
-                                'end' => null,
-                            ),
-                        ),
-                        array(
-                            'name' => 'ORGANIZER',
-                            'is-not-defined' => true,
-                            'param-filters' => array(),
-                            'text-match' => null,
-                            'time-range' => null,
-                        ),
-                        array(
-                            'name' => 'DTSTART',
-                            'is-not-defined' => false,
-                            'param-filters' => array(
-                                array(
-                                    'name' => 'VALUE',
-                                    'is-not-defined' => false,
-                                    'text-match' => array(
-                                        'negate-condition' => true,
-                                        'value' => 'DATE',
-                                        'collation' => 'i;ascii-casemap',
-                                    ),
-                                ),
-                            ),
-                            'text-match' => null,
-                            'time-range' => null,
-                        ),
-                    ),
-                    'time-range' => null,
-                ),
-            ),
-            'prop-filters' => array(),
-            'is-not-defined' => false,
-            'time-range' => false
-        );
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-
-    function testOther1() {
-
-        // This body was exactly sent to us from the sabredav mailing list. Checking if this parses correctly.
-
-        $body = <<<BLA
-<?xml version="1.0" encoding="utf-8" ?>
-<C:calendar-query xmlns:D="DAV:"
-xmlns:C="urn:ietf:params:xml:ns:caldav">
- <D:prop>
-   <C:calendar-data/>
-   <D:getetag/>
- </D:prop>
- <C:filter>
-   <C:comp-filter name="VCALENDAR">
-     <C:comp-filter name="VEVENT">
-       <C:time-range start="20090101T000000Z" end="20121202T000000Z"/>
-     </C:comp-filter>
-   </C:comp-filter>
- </C:filter>
-</C:calendar-query>
-BLA;
-
-        $dom = DAV\XMLUtil::loadDOMDocument($body);
-
-        $q = new CalendarQueryParser($dom);
-        $q->parse();
-
-        $this->assertEquals(array(
-            '{urn:ietf:params:xml:ns:caldav}calendar-data',
-            '{DAV:}getetag',
-        ), $q->requestedProperties);
-
-        $expectedFilters = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(
-                array(
-                    'name' => 'VEVENT',
-                    'comp-filters' => array(),
-                    'prop-filters' => array(),
-                    'time-range' => array(
-                        'start' => new \DateTime('2009-01-01 00:00:00', new \DateTimeZone('UTC')),
-                        'end' => new \DateTime('2012-12-02 00:00:00', new \DateTimeZone('UTC')),
-                    ),
-                    'is-not-defined' => false,
-                ),
-            ),
-            'prop-filters' => array(),
-            'time-range' => null,
-            'is-not-defined' => false,
-        );
-
-        $this->assertEquals($expectedFilters, $q->filters);
-
-    }
-
-    function testExpand() {
-
-        $xml = array(
-            '<d:prop>',
-            '  <c:calendar-data>',
-            '     <c:expand start="20110101T000000Z" end="20120101T000000Z"/>',
-            '  </c:calendar-data>',
-            '</d:prop>',
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR" />',
-            '</c:filter>'
-        );
-
-        $xml =
-'<?xml version="1.0"?>
-<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
-' . implode("\n", $xml) . '
-</c:calendar-query>';
-
-        $dom = DAV\XMLUtil::loadDOMDocument($xml);
-        $q = new CalendarQueryParser($dom);
-        $q->parse();
-
-
-        $expected = array(
-            'name' => 'VCALENDAR',
-            'comp-filters' => array(),
-            'prop-filters' => array(),
-            'is-not-defined' => false,
-            'time-range' => false
-        );
-
-        $this->assertEquals(
-            $expected,
-            $q->filters
-        );
-
-        $this->assertEquals(array(
-            '{urn:ietf:params:xml:ns:caldav}calendar-data',
-        ), $q->requestedProperties);
-
-        $this->assertEquals(
-            array(
-                'start' => new \DateTime('2011-01-01 00:00:00', new \DateTimeZone('UTC')),
-                'end' => new \DateTime('2012-01-01 00:00:00', new \DateTimeZone('UTC')),
-            ),
-            $q->expand
-        );
-
-    }
-
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testExpandNoStart() {
-
-        $xml = array(
-            '<d:prop>',
-            '  <c:calendar-data>',
-            '     <c:expand end="20120101T000000Z"/>',
-            '  </c:calendar-data>',
-            '</d:prop>',
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR" />',
-            '</c:filter>'
-        );
-
-        $xml =
-'<?xml version="1.0"?>
-<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
-' . implode("\n", $xml) . '
-</c:calendar-query>';
-
-        $dom = DAV\XMLUtil::loadDOMDocument($xml);
-        $q = new CalendarQueryParser($dom);
-        $q->parse();
-
-    }
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testExpandNoEnd() {
-
-        $xml = array(
-            '<d:prop>',
-            '  <c:calendar-data>',
-            '     <c:expand start="20120101T000000Z"/>',
-            '  </c:calendar-data>',
-            '</d:prop>',
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR" />',
-            '</c:filter>'
-        );
-
-        $xml =
-'<?xml version="1.0"?>
-<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
-' . implode("\n", $xml) . '
-</c:calendar-query>';
-
-        $dom = DAV\XMLUtil::loadDOMDocument($xml);
-        $q = new CalendarQueryParser($dom);
-        $q->parse();
-
-    }
-    /**
-     * @expectedException Sabre\DAV\Exception\BadRequest
-     */
-    function testExpandBadTimes() {
-
-        $xml = array(
-            '<d:prop>',
-            '  <c:calendar-data>',
-            '     <c:expand start="20120101T000000Z" end="19980101T000000Z"/>',
-            '  </c:calendar-data>',
-            '</d:prop>',
-            '<c:filter>',
-            '  <c:comp-filter name="VCALENDAR" />',
-            '</c:filter>'
-        );
-
-        $xml =
-'<?xml version="1.0"?>
-<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
-' . implode("\n", $xml) . '
-</c:calendar-query>';
-
-        $dom = DAV\XMLUtil::loadDOMDocument($xml);
-        $q = new CalendarQueryParser($dom);
-        $q->parse();
-
-    }
-}
diff --git a/tests/Sabre/CalDAV/JCalTransformTest.php b/tests/Sabre/CalDAV/JCalTransformTest.php
index 344bad9..e7a1457 100644
--- a/tests/Sabre/CalDAV/JCalTransformTest.php
+++ b/tests/Sabre/CalDAV/JCalTransformTest.php
@@ -86,9 +86,9 @@ XML;
 
         $response = $responses[0]->getResponseProperties()[200]["{urn:ietf:params:xml:ns:caldav}calendar-data"];
 
-        $response = json_decode($response,true);
+        $jresponse = json_decode($response,true);
         if (json_last_error()) {
-            $this->fail('Json decoding error: ' . json_last_error_msg());
+            $this->fail('Json decoding error: ' . json_last_error_msg() . '. Full response: ' . $response);
         }
         $this->assertEquals(
             [
@@ -102,7 +102,7 @@ XML;
                     ],
                 ],
             ],
-            $response
+            $jresponse
         );
 
     }
diff --git a/tests/Sabre/CalDAV/PluginTest.php b/tests/Sabre/CalDAV/PluginTest.php
index a840742..61b5deb 100644
--- a/tests/Sabre/CalDAV/PluginTest.php
+++ b/tests/Sabre/CalDAV/PluginTest.php
@@ -97,7 +97,6 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
 
         $this->assertEquals(array('MKCALENDAR'), $this->plugin->getHTTPMethods('calendars/user1/randomnewcalendar'));
         $this->assertEquals(array('calendar-access','calendar-proxy'), $this->plugin->getFeatures());
-        $this->assertArrayHasKey('urn:ietf:params:xml:ns:caldav', $this->server->xmlNamespaces);
 
     }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/php-sabredav.git



More information about the Pkg-owncloud-commits mailing list