[Pkg-owncloud-commits] [php-sabredav] 01/148: Reboot of the xml-rewrite branch.

David Prévot taffit at moszumanska.debian.org
Wed Apr 15 01:36:58 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 d9654ef6e66c1084019b2e1e4f535505b3b0408a
Author: Evert Pot <evert at rooftopsolutions.nl>
Date:   Thu Nov 13 18:06:06 2014 -0300

    Reboot of the xml-rewrite branch.
---
 composer.json                                |   1 +
 lib/DAV/CorePlugin.php                       |  17 ++-
 lib/DAV/Server.php                           |   8 ++
 lib/DAV/XML/Element/Response.php             | 197 +++++++++++++++++++++++++++
 lib/DAV/XML/Property/GetLastModified.php     | 118 ++++++++++++++++
 lib/DAV/XML/Property/Href.php                | 136 ++++++++++++++++++
 lib/DAV/XML/Property/LockDiscovery.php       | 145 ++++++++++++++++++++
 lib/DAV/XML/Property/ResourceType.php        | 112 +++++++++++++++
 lib/DAV/XML/Property/SupportedLock.php       | 101 ++++++++++++++
 lib/DAV/XML/Property/SupportedReportSet.php  | 155 +++++++++++++++++++++
 lib/DAV/XML/Request/MkCol.php                |  89 ++++++++++++
 lib/DAV/XML/Request/PropFind.php             | 114 ++++++++++++++++
 lib/DAV/XML/Request/PropPatch.php            |  99 ++++++++++++++
 lib/DAV/XML/Request/SyncCollectionReport.php | 141 +++++++++++++++++++
 lib/DAV/XML/Response/MultiStatus.php         | 141 +++++++++++++++++++
 lib/DAV/XMLUtil.php                          |  29 ++++
 16 files changed, 1599 insertions(+), 4 deletions(-)

diff --git a/composer.json b/composer.json
index 6502114..9def71f 100644
--- a/composer.json
+++ b/composer.json
@@ -18,6 +18,7 @@
         "sabre/vobject": "~3.3.4",
         "sabre/event" : "~2.0.0",
         "sabre/http" : "~3.0.4",
+        "sabre/xml"  : "dev-master",
         "ext-dom": "*",
         "ext-pcre": "*",
         "ext-spl": "*",
diff --git a/lib/DAV/CorePlugin.php b/lib/DAV/CorePlugin.php
index 69f65f9..a1c2df4 100644
--- a/lib/DAV/CorePlugin.php
+++ b/lib/DAV/CorePlugin.php
@@ -49,6 +49,10 @@ class CorePlugin extends ServerPlugin {
         $server->on('propFind',         [$this, 'propFindNode'], 120);
         $server->on('propFind',         [$this, 'propFindLate'], 200);
 
+        $server->xml->elementMap += [
+            '{DAV:}propfind' => 'Sabre\\XML\\Request\\PropFind',
+        ];
+
     }
 
     /**
@@ -316,15 +320,20 @@ class CorePlugin extends ServerPlugin {
 
         $path = $request->getPath();
 
-        $requestedProperties = $this->server->parsePropFindRequest(
-            $request->getBodyAsString()
-        );
+        $requestBody = $request->getBodyAsString();
+        if (strlen($requestBody)) {
+            $propFindXml = $this->server->xml->parse($requestBody);
+            print_r($propFindXml);
+            $properties = $propFindXml['{DAV:}prop'];
+        } else {
+            $properties = [];
+        }
 
         $depth = $this->server->getHTTPDepth(1);
         // The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled
         if (!$this->server->enablePropfindDepthInfinity && $depth != 0) $depth = 1;
 
-        $newProperties = $this->server->getPropertiesForPath($path, $requestedProperties, $depth);
+        $newProperties = $this->server->getPropertiesForPath($path, $properties, $depth);
 
         // This is a multi-status response
         $response->setStatus(207);
diff --git a/lib/DAV/Server.php b/lib/DAV/Server.php
index f3a3f6a..fd78de1 100644
--- a/lib/DAV/Server.php
+++ b/lib/DAV/Server.php
@@ -175,6 +175,13 @@ class Server extends EventEmitter {
     public $enablePropfindDepthInfinity = false;
 
     /**
+     * Reference to the XML utility object.
+     *
+     * @var XMLUtil
+     */
+    public $xml;
+
+    /**
      * If this setting is turned off, SabreDAV's version number will be hidden
      * from various places.
      *
@@ -225,6 +232,7 @@ class Server extends EventEmitter {
             throw new Exception('Invalid argument passed to constructor. Argument must either be an instance of Sabre\\DAV\\Tree, Sabre\\DAV\\INode, an array or null');
         }
 
+        $this->xml = new XMLUtil();
         $this->sapi = new HTTP\Sapi();
         $this->httpResponse = new HTTP\Response();
         $this->httpRequest = $this->sapi->getRequest();
diff --git a/lib/DAV/XML/Element/Response.php b/lib/DAV/XML/Element/Response.php
new file mode 100644
index 0000000..6cbe474
--- /dev/null
+++ b/lib/DAV/XML/Element/Response.php
@@ -0,0 +1,197 @@
+<?php
+
+namespace Sabre\DAV\XML\Element;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\DAV\Exception\CannotSerialize;
+
+/**
+ * WebDAV {DAV:}response parser
+ *
+ * This class parses the {DAV:}response element, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc4918#section-14.24
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Response implements Element {
+
+    /**
+     * Url for the response
+     *
+     * @var string
+     */
+    protected $href;
+
+    /**
+     * Propertylist, ordered by HTTP status code
+     *
+     * @var array
+     */
+    protected $responseProperties;
+
+    /**
+     * The HTTP status for an entire response.
+     *
+     * This is currently only used in WebDAV-Sync
+     *
+     * @var string
+     */
+    protected $httpStatus;
+
+    /**
+     * The href argument is a url relative to the root of the server. This
+     * class will calculate the full path.
+     *
+     * The responseProperties argument is a list of properties
+     * within an array with keys representing HTTP status codes
+     *
+     * Besides specific properties, the entire {DAV:}response element may also
+     * have a http status code.
+     * In most cases you don't need it.
+     *
+     * This is currently used by the Sync extension to indicate that a node is
+     * deleted.
+     *
+     * @param string $href
+     * @param array $responseProperties
+     * @param string $httpStatus
+     */
+    public function __construct($href, array $responseProperties, $httpStatus = null) {
+
+        $this->href = $href;
+        $this->responseProperties = $responseProperties;
+        $this->httpStatus = $httpStatus;
+
+    }
+
+    /**
+     * Returns the url
+     *
+     * @return string
+     */
+    public function getHref() {
+
+        return $this->href;
+
+    }
+
+    /**
+     * Returns the httpStatus value
+     *
+     * @return string
+     */
+    public function getHttpStatus() {
+
+        return $this->httpStatus;
+
+    }
+
+    /**
+     * Returns the property list
+     *
+     * @return array
+     */
+    public function getResponseProperties() {
+
+        return $this->responseProperties;
+
+    }
+
+
+    /**
+     * 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) {
+
+        if ($status = $this->getHTTPStatus()) {
+            $writer->writeElement('{DAV:}status', \Sabre\HTTP\Response::getStatusMessage($status));
+        }
+        $writer->writeElement('{DAV:}href', $writer->baseUri . $this->getHref());
+        foreach($this->getResponseProperties() as $status => $properties) {
+
+            // Skipping empty lists
+            if (!$properties || (!ctype_digit($status) && !is_int($status))) {
+                continue;
+            }
+            $writer->startElement('{DAV:}propstat');
+            $writer->writeElement('{DAV:}prop', $properties);
+            $writer->writeElement('{DAV:}status', \Sabre\HTTP\Response::getStatusMessage($status));
+            $writer->endElement(); // {DAV:}propstat
+
+        }
+
+    }
+
+    /**
+     * 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) {
+
+        $elems = $reader->parseInnerTree();
+
+        $href = null;
+        $propertyLists = [];
+        $statusCode = null;
+
+        foreach($elems as $elem) {
+
+            switch($elem['name']) {
+
+                case '{DAV:}href' :
+                    $href = $elem['value'];
+                    break;
+                case '{DAV:}propstat' :
+                    $status = $elem['value']['{DAV:}status'];
+                    list(, $status, ) = explode(' ', $status,3);
+                    $properties = $elem['value']['{DAV:}prop'];
+                    $propertyLists[$status] = $properties;
+                    break;
+                case '{DAV:}status' :
+                    list(, $statusCode, ) = explode(' ', $elem['value'],3);
+                    break;
+
+            }
+
+        }
+
+        return new self($href, $propertyLists, $statusCode);
+
+    }
+
+}
diff --git a/lib/DAV/XML/Property/GetLastModified.php b/lib/DAV/XML/Property/GetLastModified.php
new file mode 100644
index 0000000..209e751
--- /dev/null
+++ b/lib/DAV/XML/Property/GetLastModified.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Sabre\DAV\XML\Property;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\HTTP;
+
+/**
+ * This property represents the {DAV:}getlastmodified property.
+ *
+ * Defined in:
+ * http://tools.ietf.org/html/rfc4918#section-15.7
+ *
+ * Although this is normally a simple property, windows requires us to add
+ * some new attributes.
+ *
+ * This class uses unix timestamps internally, and converts them to RFC 1123 times for
+ * serialization
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class GetLastModified implements Element {
+
+    /**
+     * time
+     *
+     * @var \DateTime
+     */
+    public $time;
+
+    /**
+     * Constructor 
+     *
+     * @param int|DateTime $time
+     */
+    public function __construct($time) {
+
+        if ($time instanceof \DateTime) {
+            $this->time = $time;
+        } elseif (is_int($time) || ctype_digit($time)) {
+            $this->time = new \DateTime('@' . $time);
+        } else {
+            $this->time = new \DateTime($time);
+        }
+
+        // Setting timezone to UTC
+        $this->time->setTimezone(new \DateTimeZone('UTC'));
+
+    }
+
+    /**
+     * getTime
+     *
+     * @return \DateTime
+     */
+    public function getTime() {
+
+        return $this->time;
+
+    }
+
+    /**
+     * 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) {
+
+        $writer->write(
+            HTTP\Util::toHTTPDate($this->time)
+        );
+
+    }
+
+    /**
+     * 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) {
+
+        return
+            new self($reader->parseInnerTree());
+
+    }
+}
+
diff --git a/lib/DAV/XML/Property/Href.php b/lib/DAV/XML/Property/Href.php
new file mode 100644
index 0000000..529e106
--- /dev/null
+++ b/lib/DAV/XML/Property/Href.php
@@ -0,0 +1,136 @@
+<?php
+
+namespace Sabre\DAV\XML\Property;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer;
+
+/**
+ * Href property
+ *
+ * This class represents any WebDAV property that contains a {DAV:}href
+ * element, and there are many.
+ *
+ * It can support either 1 or more hrefs. If while unserializing no valid
+ * {DAV:}href elements were found, this property will unserialize itself as
+ * null.
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Href implements Element {
+
+    /**
+     * List of uris
+     *
+     * @var array
+     */
+    protected $hrefs;
+
+    /**
+     * Automatically prefix the url with the server base directory
+     *
+     * @var bool
+     */
+    protected $autoPrefix = true;
+
+    /**
+     * Constructor
+     *
+     * You must either pass a string for a single href, or an array of hrefs.
+     *
+     * If auto-prefix is set to false, the hrefs will be treated as absolute
+     * and not relative to the servers base uri.
+     *
+     * @param string|string[] $href
+     * @param bool $autoPrefix
+     */
+    public function __construct($hrefs, $autoPrefix = true) {
+
+        if (is_string($hrefs)) {
+            $hrefs = [$hrefs];
+        }
+        $this->hrefs = $hrefs;
+        $this->autoPrefix = $autoPrefix;
+
+
+    }
+
+    /**
+     * Returns the hrefs as an array
+     *
+     * @return array
+     */
+    public function getHrefs() {
+
+        return $this->hrefs;
+
+    }
+
+    /**
+     * 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) {
+
+        foreach($this->getHrefs() as $href) {
+            if ($this->autoPrefix) {
+                $href = $writer->baseUri . $href;
+            }
+            $writer->writeElement('{DAV:}href', $href);
+        }
+
+    }
+
+    /**
+     * 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) {
+
+        $hrefs = [];
+        foreach($reader->parseInnerTree() as $elem) {
+            if ($elem['name'] !== '{DAV:}href')
+                continue;
+
+            $hrefs[] = $elem['value'];
+
+        }
+        if ($hrefs) {
+            return new self($hrefs);
+        }
+
+    }
+
+}
diff --git a/lib/DAV/XML/Property/LockDiscovery.php b/lib/DAV/XML/Property/LockDiscovery.php
new file mode 100644
index 0000000..bd8f5f7
--- /dev/null
+++ b/lib/DAV/XML/Property/LockDiscovery.php
@@ -0,0 +1,145 @@
+<?php
+
+namespace Sabre\DAV\XML\Property;
+
+use
+    Sabre\DAV,
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer;
+
+/**
+ * Represents {DAV:}lockdiscovery property.
+ *
+ * This property is defined here:
+ * http://tools.ietf.org/html/rfc4918#section-15.8
+ *
+ * This property contains all the open locks on a given resource
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class LockDiscovery implements Element {
+
+    /**
+     * locks
+     *
+     * @var \Sabre\DAV\Locks\LockInfo[]
+     */
+    public $locks;
+
+    /**
+     * Should we show the locktoken as well?
+     *
+     * @var bool
+     */
+    public $revealLockToken;
+
+    /**
+     * Hides the {DAV:}lockroot element from the response.
+     *
+     * It was reported that showing the lockroot in the response can break
+     * Office 2000 compatibility.
+     *
+     * @var bool
+     */
+    static public $hideLockRoot = false;
+
+    /**
+     * __construct
+     *
+     * @param \Sabre\DAV\Locks\LockInfo[] $locks
+     * @param bool $revealLockToken
+     */
+    public function __construct($locks, $revealLockToken = false) {
+
+        $this->locks = $locks;
+        $this->revealLockToken = $revealLockToken;
+
+    }
+
+    /**
+     * 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) {
+
+        foreach($this->locks as $lock) {
+
+            $writer->startElement('{DAV:}activelock');
+
+            $writer->startElement('{DAV:}lockscope');
+            if ($lock->scope === 'shared') {
+                $writer->writeElement('{DAV:}shared');
+            } else {
+                $writer->writeElement('{DAV:}exclusive');
+            }
+
+            $writer->endElement(); // {DAV:}lockscope
+
+            $writer->startElement('{DAV:}locktype');
+            $writer->writeElement('{DAV:}write');
+            $writer->endElement(); // {DAV:}locktype
+
+            if (!self::$hideLockRoot) {
+                $writer->startElement('{DAV:}lockroot');
+                $writer->writeElement('{DAV:}href', $writer->baseUri . $lock->uri);
+                $writer->endElement(); // {DAV:}lockroot
+            }
+            $writer->writeElement('{DAV:}depth', ($lock->depth == DAV\Server::DEPTH_INFINITY?'infinity':$lock->depth));
+            $writer->writeElement('{DAV:}timeout','Second-' . $lock->timeout);
+
+            if ($this->revealLockToken) {
+                $writer->startElement('{DAV:}locktoken');
+                $writer->writeElement('{DAV:}href', 'opaquelocktoken:' . $lock->token);
+                $writer->endElement(); // {DAV:}locktoken
+
+            }
+
+            $writer->writeElement('{DAV:}owner', $lock->owner);
+            $writer->endElement(); // {DAV:}activelock
+
+        }
+
+    }
+
+    /**
+     * 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) {
+
+        throw new CannotDeserialize('This element does not have a deserializer');
+
+    }
+}
+
diff --git a/lib/DAV/XML/Property/ResourceType.php b/lib/DAV/XML/Property/ResourceType.php
new file mode 100644
index 0000000..0ec6847
--- /dev/null
+++ b/lib/DAV/XML/Property/ResourceType.php
@@ -0,0 +1,112 @@
+<?php
+
+namespace Sabre\DAV\XML\Property;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\DAV\Exception\CannotSerialize;
+
+/**
+ * {DAV:}resourcetype property
+ *
+ * This class represents the {DAV:}resourcetype property, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc4918#section-15.9 
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class ResourceType extends Element\Elements {
+
+    /**
+     * Constructor
+     *
+     * You can either pass null (for no resourcetype), a string (for a single
+     * resourcetype) or an array (for multiple).
+     *
+     * The resourcetype must be specified in clark-notation
+     *
+     * @param array|string|null $resourceType
+     */
+    public function __construct($resourceTypes = null) {
+
+        if (is_null($resourceTypes)) {
+            parent::__construct([]);
+        } elseif (is_array($resourceTypes)) {
+            parent::__construct($resourceTypes);
+        } else {
+            parent::__construct([$resourceTypes]);
+        }
+
+    }
+
+    /**
+     * Returns the values in clark-notation
+     *
+     * For example array('{DAV:}collection')
+     *
+     * @return array
+     */
+    public function getValue() {
+
+        return $this->value;
+
+    }
+
+    /**
+     * Checks if the principal contains a certain value
+     *
+     * @param string $type
+     * @return bool
+     */
+    public function is($type) {
+
+        return in_array($type, $this->value);
+
+    }
+
+    /**
+     * Adds a resourcetype value to this property
+     *
+     * @param string $type
+     * @return void
+     */
+    public function add($type) {
+
+        $this->value[] = $type;
+        $this->value = array_unique($this->value);
+
+    }
+
+    /**
+     * 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) {
+
+        return
+            new self(parent::deserializeXml($reader));
+
+    }
+
+}
diff --git a/lib/DAV/XML/Property/SupportedLock.php b/lib/DAV/XML/Property/SupportedLock.php
new file mode 100644
index 0000000..b668d0d
--- /dev/null
+++ b/lib/DAV/XML/Property/SupportedLock.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace Sabre\DAV\XML\Property;
+
+use
+    Sabre\DAV,
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer;
+
+/**
+ * This class represents the {DAV:}supportedlock property.
+ *
+ * This property is defined here:
+ * http://tools.ietf.org/html/rfc4918#section-15.10
+ *
+ * This property contains information about what kind of locks
+ * this server supports.
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class SupportedLock implements Element {
+
+    /**
+     * supportsLocks
+     *
+     * @var bool
+     */
+    public $supportsLocks = false;
+
+    /**
+     * __construct
+     *
+     * @param bool $supportsLocks
+     */
+    public function __construct($supportsLocks) {
+
+        $this->supportsLocks = $supportsLocks;
+
+    }
+
+    /**
+     * 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) {
+
+        if (!$this->supportsLocks) return null;
+
+        $writer->writeElement('{DAV:}lockentry', [
+            '{DAV:}lockscope' => ['{DAV:}exclusive' => null],        
+            '{DAV:}locktype' =>  ['{DAV:}write' => null],        
+        ]);
+        $writer->writeElement('{DAV:}lockentry', [
+            '{DAV:}lockscope' => ['{DAV:}shared' => null],        
+            '{DAV:}locktype' =>  ['{DAV:}write' => null],        
+        ]);
+
+    }
+
+    /**
+     * 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) {
+
+        throw new CannotDeserialize('This element does not have a deserializer');
+
+    }
+}
+
diff --git a/lib/DAV/XML/Property/SupportedReportSet.php b/lib/DAV/XML/Property/SupportedReportSet.php
new file mode 100644
index 0000000..053452d
--- /dev/null
+++ b/lib/DAV/XML/Property/SupportedReportSet.php
@@ -0,0 +1,155 @@
+<?php
+
+namespace Sabre\DAV\XML\Property;
+
+use
+    Sabre\DAV,
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\XML\Element\Elements;
+
+/**
+ * supported-report-set property.
+ *
+ * This property is defined in RFC3253, but since it's
+ * so common in other webdav-related specs, it is part of the core server.
+ *
+ * This property is defined here:
+ * http://tools.ietf.org/html/rfc3253#section-3.1.5
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class SupportedReportSet implements Element {
+
+    /**
+     * List of reports
+     *
+     * @var array
+     */
+    protected $reports = array();
+
+    /**
+     * Creates the property
+     *
+     * Any reports passed in the constructor
+     * should be valid report-types in clark-notation.
+     *
+     * Either a string or an array of strings must be passed.
+     *
+     * @param string|string[] $reports
+     */
+    public function __construct($reports = null) {
+
+        if (!is_null($reports))
+            $this->addReport($reports);
+
+    }
+
+    /**
+     * Adds a report to this property
+     *
+     * The report must be a string in clark-notation.
+     * Multiple reports can be specified as an array.
+     *
+     * @param mixed $report
+     * @return void
+     */
+    public function addReport($report) {
+
+        if (!is_array($report)) $report = array($report);
+
+        foreach($report as $r) {
+
+            if (!preg_match('/^{([^}]*)}(.*)$/',$r))
+                throw new DAV\Exception('Reportname must be in clark-notation');
+
+            $this->reports[] = $r;
+
+        }
+
+    }
+
+    /**
+     * Returns the list of supported reports
+     *
+     * @return string[]
+     */
+    public function getValue() {
+
+        return $this->reports;
+
+    }
+
+    /**
+     * Returns true or false if the property contains a specific report.
+     *
+     * @param string $reportName
+     * @return bool
+     */
+    public function has($reportName) {
+
+        return in_array(
+            $reportName,
+            $this->reports
+        );
+
+    }
+
+    /**
+     * 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) {
+
+        foreach($this->getValue() as $val) {
+            $writer->startElement('{DAV:}supported-report');
+            $writer->startElement('{DAV:}report');
+            $writer->writeElement($val);
+            $writer->endElement();
+            $writer->endElement();
+        }
+
+    }
+
+    /**
+     * 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) {
+
+        throw new CannotDeserialize('This element does not have a deserializer');
+
+    }
+
+}
diff --git a/lib/DAV/XML/Request/MkCol.php b/lib/DAV/XML/Request/MkCol.php
new file mode 100644
index 0000000..eb86c7d
--- /dev/null
+++ b/lib/DAV/XML/Request/MkCol.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Sabre\DAV\XML\Request;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\DAV\Exception\CannotSerialize;
+
+/**
+ * WebDAV Extended MKCOL request parser.
+ *
+ * This class parses the {DAV:}mkol request, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc5689#section-5.1
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class MkCol implements Element {
+
+    /**
+     * The list of properties that will be set.
+     *
+     * @var array
+     */
+    public $properties = [];
+
+    /**
+     * 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) {
+
+        $self = new self();
+
+        $elems = $reader->parseInnerTree();
+
+        foreach($elems as $elem) {
+            if ($elem['name'] === '{DAV:}set') {
+                $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']);
+            }
+        }
+
+        return $self;
+
+    }
+
+}
diff --git a/lib/DAV/XML/Request/PropFind.php b/lib/DAV/XML/Request/PropFind.php
new file mode 100644
index 0000000..2c7d85c
--- /dev/null
+++ b/lib/DAV/XML/Request/PropFind.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace Sabre\DAV\XML\Request;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Element\Elements,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\DAV\Exception\CannotSerialize;
+
+/**
+ * WebDAV PROPFIND request parser.
+ *
+ * This class parses the {DAV:}propfind request, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc4918#section-14.20
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class PropFind implements Element {
+
+    /**
+     * If this is set to true, this was an 'allprop' request.
+     *
+     * @var bool
+     */
+    public $allProp = false;
+
+    /**
+     * The property list
+     *
+     * @var null|array
+     */
+    public $properties;
+
+    /**
+     * 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) {
+
+        $self = new self();
+
+        $reader->read();
+
+        do {
+
+            if ($reader->nodeType === Reader::ELEMENT) {
+
+                $clark = $reader->getClark();
+                switch($reader->getClark()) {
+
+                    case '{DAV:}allprop' :
+                        $self->allProp = true;
+                        break;
+                    case '{DAV:}prop' :
+                        $self->properties = Elements::deserializeXml($reader);
+                        break;
+                }
+                $reader->next();
+
+            } else {
+                $reader->read();
+            }
+
+        } while ($reader->nodeType !== Reader::END_ELEMENT);
+
+        $reader->read();
+        return $self;
+
+    }
+
+}
diff --git a/lib/DAV/XML/Request/PropPatch.php b/lib/DAV/XML/Request/PropPatch.php
new file mode 100644
index 0000000..9776c1f
--- /dev/null
+++ b/lib/DAV/XML/Request/PropPatch.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Sabre\DAV\XML\Request;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\DAV\Exception\CannotSerialize;
+
+/**
+ * WebDAV PROPPATCH request parser.
+ *
+ * This class parses the {DAV:}propertyupdate request, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc4918#section-14.20
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class PropPatch implements Element {
+
+    /**
+     * The list of properties that will be updated and removed.
+     *
+     * If a property will be removed, it's value will be set to null.
+     *
+     * @var array
+     */
+    public $properties = [];
+
+    /**
+     * 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) {
+
+        $self = new self();
+
+        $elems = $reader->parseInnerTree();
+
+        foreach($elems as $elem) {
+            if ($elem['name'] === '{DAV:}set') {
+                $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']);
+            }
+            if ($elem['name'] === '{DAV:}remove') {
+
+                // Ensuring there are no values.
+                foreach($elem['value']['{DAV:}prop'] as $remove=>$value) {
+                    $self->properties[$remove] = null;
+                }
+
+            }
+        }
+
+        return $self;
+
+    }
+
+}
diff --git a/lib/DAV/XML/Request/SyncCollectionReport.php b/lib/DAV/XML/Request/SyncCollectionReport.php
new file mode 100644
index 0000000..e07f1f8
--- /dev/null
+++ b/lib/DAV/XML/Request/SyncCollectionReport.php
@@ -0,0 +1,141 @@
+<?php
+
+namespace Sabre\DAV\XML\Request;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\XML\Element\KeyValue,
+    Sabre\DAV\Exception\CannotSerialize,
+    Sabre\DAV\Exception\BadRequest;
+
+/**
+ * SyncCollection request parser.
+ *
+ * This class parses the {DAV:}sync-collection reprot, as defined in:
+ *
+ * http://tools.ietf.org/html/rfc6578#section-3.2
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class SyncCollectionReport implements Element {
+
+    /**
+     * The sync-token the client supplied for the report.
+     *
+     * @var string|null
+     */
+    public $syncToken;
+
+    /**
+     * The 'depth' of the sync the client is interested in.
+     *
+     * @var int
+     */
+    public $syncLevel;
+
+    /**
+     * Maximum amount of items returned.
+     *
+     * @var int|null
+     */
+    public $limit;
+
+    /**
+     * The list of properties that are being requested for every change.
+     *
+     * @var null|array
+     */
+    public $properties;
+
+    /**
+     * 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) {
+
+        $self = new self();
+
+        $elems = KeyValue::deserializeXml($reader);
+
+        $required = [
+            '{DAV:}sync-token',
+            '{DAV:}prop',
+            ];
+
+        foreach($required as $elem) {
+            if (!array_key_exists($elem, $elems)) {
+                throw new BadRequest('The '.$elem.' element in the {DAV:}sync-collection report is required');
+            }
+        }
+
+
+        $self->properties = array_keys($elems['{DAV:}prop']);
+        $self->syncToken = $elems['{DAV:}sync-token'];
+
+        if (isset($elems['{DAV:}limit'])) {
+            $nresults = null;
+            foreach($elems['{DAV:}limit'] as $child) {
+                if ($child['name'] === '{DAV:}nresults') {
+                    $nresults = (int)$child['value'];
+                }
+            }
+            $self->limit = $nresults;
+        }
+
+        if (isset($elems['{DAV:}sync-level'])) {
+
+            $value = $elems['{DAV:}sync-level'];
+            if ($value==='infinity') {
+                $value = \Sabre\DAV\Server::DEPTH_INFINITY;
+            }
+            $self->syncLevel = $value;
+
+        }
+
+        return $self;
+
+    }
+
+}
diff --git a/lib/DAV/XML/Response/MultiStatus.php b/lib/DAV/XML/Response/MultiStatus.php
new file mode 100644
index 0000000..13239cb
--- /dev/null
+++ b/lib/DAV/XML/Response/MultiStatus.php
@@ -0,0 +1,141 @@
+<?php
+
+namespace Sabre\DAV\XML\Response;
+
+use
+    Sabre\XML\Element,
+    Sabre\XML\Reader,
+    Sabre\XML\Writer,
+    Sabre\DAV\Exception\CannotSerialize;
+
+/**
+ * WebDAV MultiStatus parser
+ *
+ * This class parses the {DAV:}multistatus response, as defined in:
+ * https://tools.ietf.org/html/rfc4918#section-14.16
+ *
+ * And it also adds the {DAV:}synctoken change from:
+ * http://tools.ietf.org/html/rfc6578#section-6.4
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class MultiStatus implements Element {
+
+    /**
+     * The responses
+     *
+     * @var \Sabre\DAV\XML\Element\Response[]
+     */
+    protected $responses;
+
+    /**
+     * A sync token (from RFC6578).
+     *
+     * @var string
+     */
+    protected $syncToken;
+
+    /**
+     * Constructor
+     *
+     * @param \Sabre\DAV\XML\Element\Response[] $responses
+     */
+    public function __construct(array $responses, $syncToken = null) {
+
+        $this->responses = $responses;
+        $this->syncToken = $syncToken;
+
+    }
+
+    /**
+     * Returns the response list.
+     *
+     * @return \Sabre\DAV\XML\Element\Response[]
+     */
+    public function getResponses() {
+
+        return $this->responses;
+
+    }
+
+    /**
+     * Returns the sync-token, if available.
+     *
+     * @return string|null
+     */
+    public function getSyncToken() {
+
+        return $this->syncToken;
+
+    }
+
+    /**
+     * 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) {
+
+        foreach($this->getResponses() as $response) {
+            $writer->writeElement('{DAV:}response', $response);
+        }
+        if ($syncToken = $this->getSyncToken()) {
+            $writer->writeElement('{DAV:}sync-token', $syncToken);
+        }
+
+    }
+
+    /**
+     * 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) {
+
+        $elements = $reader->parseInnerTree();
+
+        $responses = [];
+        $syncToken = null;
+
+        if ($elements) foreach($elements as $elem) {
+            if ($elem['name'] === '{DAV:}response') {
+                $responses[] = $elem['value'];
+            }
+            if ($elem['name'] === '{DAV:}sync-token') {
+                $syncToken = $elem['value'];
+            }
+        }
+
+        return new self($responses, $syncToken);
+
+    }
+
+}
diff --git a/lib/DAV/XMLUtil.php b/lib/DAV/XMLUtil.php
index b0a09e2..3ecab3b 100644
--- a/lib/DAV/XMLUtil.php
+++ b/lib/DAV/XMLUtil.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Sabre\DAV;
+use Sabre\XML;
 
 /**
  * XML utilities for WebDAV
@@ -12,6 +13,34 @@ namespace Sabre\DAV;
 class XMLUtil {
 
     /**
+     * This is a list of XML elements that we automatically map to PHP classes.
+     *
+     * For instance, this list may contain an entry `{DAV:}propfind` that would
+     * be mapped to Sabre\DAV\XML\Request\PropFind
+     */
+    public $elementMap = [];
+
+    /**
+     * Parses an XML file.
+     * This method parses an xml file and maps all known properties to their
+     * respective objects.
+     *
+     * @param string|resource|\Sabre\HTTP\MessageInterface $input
+     * @return mixed
+     */
+    function parse($input) {
+
+        $reader = new XML\Reader();
+        if ($input instanceof \Sabre\HTTP\MessageInterface) {
+            $reader->xml($input->getBodyAsString());
+        } else {
+            $reader->xml($input);
+        }
+        return $reader->parse();
+
+    }
+
+    /**
      * Returns the 'clark notation' for an element.
      *
      * For example, and element encoded as:

-- 
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