[Pkg-owncloud-commits] [php-sabredav] 76/148: Automatically mapping complex property values to Complex class.
David Prévot
taffit at moszumanska.debian.org
Wed Apr 15 01:37:18 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 989eed4f86d95ebc488adb46430c355e26f62c6e
Author: Evert Pot <me at evertpot.com>
Date: Fri Mar 20 19:04:53 2015 -0400
Automatically mapping complex property values to Complex class.
---
lib/CalDAV/Xml/Request/MkCalendar.php | 5 +-
lib/DAV/Xml/Element/Prop.php | 124 +++++++++++++++++++++++++++
lib/DAV/Xml/Property/Complex.php | 91 ++++++++++++++++++++
lib/DAV/Xml/Request/MkCol.php | 7 +-
lib/DAV/Xml/Request/PropFind.php | 8 +-
lib/DAV/Xml/Request/PropPatch.php | 7 +-
lib/DAV/Xml/Request/SyncCollectionReport.php | 9 +-
lib/DAV/Xml/Response/MultiStatus.php | 4 +-
lib/DAV/Xml/Service.php | 3 -
9 files changed, 249 insertions(+), 9 deletions(-)
diff --git a/lib/CalDAV/Xml/Request/MkCalendar.php b/lib/CalDAV/Xml/Request/MkCalendar.php
index 69dcced..41a162a 100644
--- a/lib/CalDAV/Xml/Request/MkCalendar.php
+++ b/lib/CalDAV/Xml/Request/MkCalendar.php
@@ -61,7 +61,10 @@ class MkCalendar implements XmlDeserializable {
$self = new self();
- $elems = $reader->parseInnerTree();
+ $elementMap = $reader->elementMap;
+ $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
+ $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
+ $elems = $reader->parseInnerTree($elementMap);
foreach($elems as $elem) {
if ($elem['name'] === '{DAV:}set') {
diff --git a/lib/DAV/Xml/Element/Prop.php b/lib/DAV/Xml/Element/Prop.php
new file mode 100644
index 0000000..1ee02cb
--- /dev/null
+++ b/lib/DAV/Xml/Element/Prop.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace Sabre\DAV\Xml\Element;
+
+use
+ Sabre\DAV\Xml\Property\Complex,
+ Sabre\Xml\XmlDeserializable,
+ Sabre\Xml\Reader;
+
+/**
+ * This class is responsible for decoding the {DAV:}prop element as it appears
+ * in {DAV:}property-update.
+ *
+ * This class doesn't return an instance of itself. It just returns a
+ * key->value array.
+ *
+ * @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 Prop 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.
+ *
+ * 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) {
+
+ // If there's no children, we don't do anything.
+ if ($reader->isEmptyElement) {
+ $reader->next();
+ return [];
+ }
+
+ $values = [];
+
+ $reader->read();
+ do {
+
+ if ($reader->nodeType === Reader::ELEMENT) {
+
+ $clark = $reader->getClark();
+ $values[$clark] = self::parseCurrentElement($reader)['value'];
+
+ } else {
+ $reader->read();
+ }
+
+ } while ($reader->nodeType !== Reader::END_ELEMENT);
+
+ $reader->read();
+
+ return $values;
+
+ }
+
+ /**
+ * This function behaves similar to Sabre\Xml\Reader::parseCurrentElement,
+ * but instead of creating deep xml array structures, it will turn any
+ * top-level element it doesn't recognize into either a string, or an
+ * XmlFragment class.
+ *
+ * This method returns arn array with 3 properties:
+ * * name - A clark-notation XML element name.
+ * * value - The parsed value.
+ * * attributes - A key-value list of attributes.
+ *
+ * @return array
+ */
+ static private function parseCurrentElement(Reader $reader) {
+
+ $name = $reader->getClark();
+
+ $attributes = [];
+
+ if ($reader->hasAttributes) {
+ $attributes = $reader->parseAttributes();
+ }
+
+ if (array_key_exists($name, $reader->elementMap)) {
+ $deserializer = $reader->elementMap[$name];
+ if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) {
+ $value = call_user_func( [ $deserializer, 'xmlDeserialize' ], $reader);
+ } elseif (is_callable($deserializer)) {
+ $value = call_user_func($deserializer, $reader);
+ } else {
+ $type = gettype($deserializer);
+ if ($type==='string') {
+ $type.=' (' . $deserializer . ')';
+ } elseif ($type==='object') {
+ $type.=' (' . get_class($deserializer) . ')';
+ }
+ throw new \LogicException('Could not use this type as a deserializer: ' . $type );
+ }
+ } else {
+ $value = Complex::xmlDeserialize($reader);
+ }
+
+ return [
+ 'name' => $name,
+ 'value' => $value,
+ 'attributes' => $attributes,
+ ];
+
+ }
+
+}
diff --git a/lib/DAV/Xml/Property/Complex.php b/lib/DAV/Xml/Property/Complex.php
new file mode 100644
index 0000000..7d14b4c
--- /dev/null
+++ b/lib/DAV/Xml/Property/Complex.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Sabre\DAV\Xml\Property;
+
+use
+ Sabre\Xml\Element\XmlFragment,
+ Sabre\Xml\Reader;
+
+/**
+ * This class represents a 'complex' property that didn't have a default
+ * decoder.
+ *
+ * It's basically a container for an xml snippet.
+ *
+ * @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 Complex extends XmlFragment {
+
+ /**
+ * 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.
+ *
+ * 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) {
+
+ $xml = $reader->readInnerXml();
+
+ if ($reader->nodeType === Reader::ELEMENT && $reader->isEmptyElement) {
+ // Easy!
+ $reader->next();
+ return null;
+ }
+ // Now we have a copy of the inner xml, we need to traverse it to get
+ // all the strings. If there's no non-string data, we just return the
+ // string, otherwise we return an instance of this class.
+ $reader->read();
+
+ $nonText = false;
+ $text = '';
+
+ while(true) {
+
+ switch($reader->nodeType) {
+ case Reader::ELEMENT :
+ $nonText = true;
+ $reader->next();
+ continue 2;
+ case Reader::TEXT :
+ case Reader::CDATA :
+ $text.=$reader->value;
+ break;
+ case Reader::END_ELEMENT :
+ break 2;
+ }
+ $reader->read();
+
+ }
+
+ // Make sure we advance the cursor one step further.
+ $reader->read();
+
+ if ($nonText) {
+ $new = new self($xml);
+ return $new;
+ } else {
+ return $text;
+ }
+
+ }
+
+
+}
+
diff --git a/lib/DAV/Xml/Request/MkCol.php b/lib/DAV/Xml/Request/MkCol.php
index d9236d6..30fd14a 100644
--- a/lib/DAV/Xml/Request/MkCol.php
+++ b/lib/DAV/Xml/Request/MkCol.php
@@ -62,7 +62,12 @@ class MkCol implements XmlDeserializable {
$self = new self();
- $elems = $reader->parseInnerTree();
+ $elementMap = $reader->elementMap;
+ $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
+ $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
+ $elementMap['{DAV:}remove'] = 'Sabre\Xml\Element\KeyValue';
+
+ $elems = $reader->parseInnerTree($elementMap);
foreach($elems as $elem) {
if ($elem['name'] === '{DAV:}set') {
diff --git a/lib/DAV/Xml/Request/PropFind.php b/lib/DAV/Xml/Request/PropFind.php
index cadfbc6..ee5b3f1 100644
--- a/lib/DAV/Xml/Request/PropFind.php
+++ b/lib/DAV/Xml/Request/PropFind.php
@@ -58,11 +58,14 @@ class PropFind implements XmlDeserializable {
$self = new self();
+ $reader->pushContext();
+ $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Element\Elements';
+
foreach(KeyValue::xmlDeserialize($reader) as $k=>$v) {
switch($k) {
case '{DAV:}prop' :
- $self->properties = array_keys($v);
+ $self->properties = $v;
break;
case '{DAV:}allprop' :
$self->allProp = true;
@@ -70,6 +73,9 @@ class PropFind implements XmlDeserializable {
}
}
+
+ $reader->popContext();
+
return $self;
}
diff --git a/lib/DAV/Xml/Request/PropPatch.php b/lib/DAV/Xml/Request/PropPatch.php
index c080a44..fef8c4d 100644
--- a/lib/DAV/Xml/Request/PropPatch.php
+++ b/lib/DAV/Xml/Request/PropPatch.php
@@ -52,7 +52,12 @@ class PropPatch implements XmlDeserializable {
$self = new self();
- $elems = $reader->parseInnerTree();
+ $elementMap = $reader->elementMap;
+ $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
+ $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
+ $elementMap['{DAV:}remove'] = 'Sabre\Xml\Element\KeyValue';
+
+ $elems = $reader->parseInnerTree($elementMap);
foreach($elems as $elem) {
if ($elem['name'] === '{DAV:}set') {
diff --git a/lib/DAV/Xml/Request/SyncCollectionReport.php b/lib/DAV/Xml/Request/SyncCollectionReport.php
index 8725b04..035d2ba 100644
--- a/lib/DAV/Xml/Request/SyncCollectionReport.php
+++ b/lib/DAV/Xml/Request/SyncCollectionReport.php
@@ -73,8 +73,15 @@ class SyncCollectionReport implements XmlDeserializable {
$self = new self();
+ $elementMap = $reader->elementMap;
+
+ $reader->pushContext();
+
+ $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Element\Elements';
$elems = KeyValue::xmlDeserialize($reader);
+ $reader->popContext();
+
$required = [
'{DAV:}sync-token',
'{DAV:}prop',
@@ -87,7 +94,7 @@ class SyncCollectionReport implements XmlDeserializable {
}
- $self->properties = array_keys($elems['{DAV:}prop']);
+ $self->properties = $elems['{DAV:}prop'];
$self->syncToken = $elems['{DAV:}sync-token'];
if (isset($elems['{DAV:}limit'])) {
diff --git a/lib/DAV/Xml/Response/MultiStatus.php b/lib/DAV/Xml/Response/MultiStatus.php
index 2f157ce..0c46dc0 100644
--- a/lib/DAV/Xml/Response/MultiStatus.php
+++ b/lib/DAV/Xml/Response/MultiStatus.php
@@ -118,7 +118,9 @@ class MultiStatus implements Element {
*/
static function xmlDeserialize(Reader $reader) {
- $elements = $reader->parseInnerTree();
+ $elementMap = $reader->elementMap;
+ $elementMap['{DAV:}prop'] = 'Sabre\\DAV\\Xml\\Element\\Prop';
+ $elements = $reader->parseInnerTree($elementMap);
$responses = [];
$syncToken = null;
diff --git a/lib/DAV/Xml/Service.php b/lib/DAV/Xml/Service.php
index a24c713..45f5e6b 100644
--- a/lib/DAV/Xml/Service.php
+++ b/lib/DAV/Xml/Service.php
@@ -21,9 +21,6 @@ class Service extends \Sabre\Xml\Service {
'{DAV:}multistatus' => 'Sabre\\DAV\\Xml\\Response\\MultiStatus',
'{DAV:}response' => 'Sabre\\DAV\\Xml\\Element\\Response',
'{DAV:}propstat' => 'Sabre\\Xml\\Element\\KeyValue',
- '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
- '{DAV:}set' => 'Sabre\\Xml\\Element\\KeyValue',
- '{DAV:}remove' => 'Sabre\\Xml\\Element\\KeyValue',
// Requests
'{DAV:}propfind' => 'Sabre\\DAV\\Xml\\Request\\PropFind',
--
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