aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/xml/lib
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/xml/lib')
-rw-r--r--vendor/sabre/xml/lib/ContextStackTrait.php123
-rw-r--r--vendor/sabre/xml/lib/Deserializer/functions.php255
-rw-r--r--vendor/sabre/xml/lib/Element.php20
-rw-r--r--vendor/sabre/xml/lib/Element/Base.php91
-rw-r--r--vendor/sabre/xml/lib/Element/Cdata.php64
-rw-r--r--vendor/sabre/xml/lib/Element/Elements.php108
-rw-r--r--vendor/sabre/xml/lib/Element/KeyValue.php108
-rw-r--r--vendor/sabre/xml/lib/Element/Uri.php104
-rw-r--r--vendor/sabre/xml/lib/Element/XmlFragment.php147
-rw-r--r--vendor/sabre/xml/lib/LibXMLException.php53
-rw-r--r--vendor/sabre/xml/lib/ParseException.php17
-rw-r--r--vendor/sabre/xml/lib/Reader.php308
-rw-r--r--vendor/sabre/xml/lib/Serializer/functions.php249
-rw-r--r--vendor/sabre/xml/lib/Service.php291
-rw-r--r--vendor/sabre/xml/lib/Version.php19
-rw-r--r--vendor/sabre/xml/lib/Writer.php266
-rw-r--r--vendor/sabre/xml/lib/XmlDeserializable.php38
-rw-r--r--vendor/sabre/xml/lib/XmlSerializable.php36
18 files changed, 2297 insertions, 0 deletions
diff --git a/vendor/sabre/xml/lib/ContextStackTrait.php b/vendor/sabre/xml/lib/ContextStackTrait.php
new file mode 100644
index 000000000..ee3a3baca
--- /dev/null
+++ b/vendor/sabre/xml/lib/ContextStackTrait.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Sabre\Xml;
+
+/**
+ * Context Stack
+ *
+ * The Context maintains information about a document during either reading or
+ * writing.
+ *
+ * During this process, it may be neccesary to override this context
+ * information.
+ *
+ * This trait allows easy access to the context, and allows the end-user to
+ * override its settings for document fragments, and easily restore it again
+ * later.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+trait ContextStackTrait {
+
+ /**
+ * This is the element map. It contains a list of XML elements (in clark
+ * notation) as keys and PHP class names as values.
+ *
+ * The PHP class names must implement Sabre\Xml\Element.
+ *
+ * Values may also be a callable. In that case the function will be called
+ * directly.
+ *
+ * @var array
+ */
+ public $elementMap = [];
+
+ /**
+ * A contextUri pointing to the document being parsed / written.
+ * This uri may be used to resolve relative urls that may appear in the
+ * document.
+ *
+ * The reader and writer don't use this property, but as it's an extremely
+ * common use-case for parsing XML documents, it's added here as a
+ * convenience.
+ *
+ * @var string
+ */
+ public $contextUri;
+
+ /**
+ * This is a list of namespaces that you want to give default prefixes.
+ *
+ * You must make sure you create this entire list before starting to write.
+ * They should be registered on the root element.
+ *
+ * @var array
+ */
+ public $namespaceMap = [];
+
+ /**
+ * This is a list of custom serializers for specific classes.
+ *
+ * The writer may use this if you attempt to serialize an object with a
+ * class that does not implement XmlSerializable.
+ *
+ * Instead it will look at this classmap to see if there is a custom
+ * serializer here. This is useful if you don't want your value objects
+ * to be responsible for serializing themselves.
+ *
+ * The keys in this classmap need to be fully qualified PHP class names,
+ * the values must be callbacks. The callbacks take two arguments. The
+ * writer class, and the value that must be written.
+ *
+ * function (Writer $writer, object $value)
+ *
+ * @var array
+ */
+ public $classMap = [];
+
+ /**
+ * Backups of previous contexts.
+ *
+ * @var array
+ */
+ protected $contextStack = [];
+
+ /**
+ * Create a new "context".
+ *
+ * This allows you to safely modify the elementMap, contextUri or
+ * namespaceMap. After you're done, you can restore the old data again
+ * with popContext.
+ *
+ * @return null
+ */
+ function pushContext() {
+
+ $this->contextStack[] = [
+ $this->elementMap,
+ $this->contextUri,
+ $this->namespaceMap,
+ $this->classMap
+ ];
+
+ }
+
+ /**
+ * Restore the previous "context".
+ *
+ * @return null
+ */
+ function popContext() {
+
+ list(
+ $this->elementMap,
+ $this->contextUri,
+ $this->namespaceMap,
+ $this->classMap
+ ) = array_pop($this->contextStack);
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Deserializer/functions.php b/vendor/sabre/xml/lib/Deserializer/functions.php
new file mode 100644
index 000000000..fe88a6db8
--- /dev/null
+++ b/vendor/sabre/xml/lib/Deserializer/functions.php
@@ -0,0 +1,255 @@
+<?php
+
+namespace Sabre\Xml\Deserializer;
+
+use Sabre\Xml\Reader;
+
+/**
+ * This class provides a number of 'deserializer' helper functions.
+ * These can be used to easily specify custom deserializers for specific
+ * XML elements.
+ *
+ * You can either use these functions from within the $elementMap in the
+ * Service or Reader class, or you can call them from within your own
+ * deserializer functions.
+ */
+
+/*
+ * The 'keyValue' deserializer parses all child elements, and outputs them as
+ * a "key=>value" array.
+ *
+ * For example, keyvalue will parse:
+ *
+ * <?xml version="1.0"?>
+ * <s:root xmlns:s="http://sabredav.org/ns">
+ * <s:elem1>value1</s:elem1>
+ * <s:elem2>value2</s:elem2>
+ * <s:elem3 />
+ * </s:root>
+ *
+ * Into:
+ *
+ * [
+ * "{http://sabredav.org/ns}elem1" => "value1",
+ * "{http://sabredav.org/ns}elem2" => "value2",
+ * "{http://sabredav.org/ns}elem3" => null,
+ * ];
+ *
+ * If you specify the 'namespace' argument, the deserializer will remove
+ * the namespaces of the keys that match that namespace.
+ *
+ * For example, if you call keyValue like this:
+ *
+ * keyValue($reader, 'http://sabredav.org/ns')
+ *
+ * it's output will instead be:
+ *
+ * [
+ * "elem1" => "value1",
+ * "elem2" => "value2",
+ * "elem3" => null,
+ * ];
+ *
+ * Attributes will be removed from the top-level elements. If elements with
+ * the same name appear twice in the list, only the last one will be kept.
+ *
+ *
+ * @param Reader $reader
+ * @param string $namespace
+ * @return array
+ */
+function keyValue(Reader $reader, $namespace = null) {
+
+ // 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) {
+ if ($namespace !== null && $reader->namespaceURI === $namespace) {
+ $values[$reader->localName] = $reader->parseCurrentElement()['value'];
+ } else {
+ $clark = $reader->getClark();
+ $values[$clark] = $reader->parseCurrentElement()['value'];
+ }
+ } else {
+ $reader->read();
+ }
+ } while ($reader->nodeType !== Reader::END_ELEMENT);
+
+ $reader->read();
+
+ return $values;
+
+}
+
+/**
+ * The 'enum' deserializer parses elements into a simple list
+ * without values or attributes.
+ *
+ * For example, Elements will parse:
+ *
+ * <?xml version="1.0"? >
+ * <s:root xmlns:s="http://sabredav.org/ns">
+ * <s:elem1 />
+ * <s:elem2 />
+ * <s:elem3 />
+ * <s:elem4>content</s:elem4>
+ * <s:elem5 attr="val" />
+ * </s:root>
+ *
+ * Into:
+ *
+ * [
+ * "{http://sabredav.org/ns}elem1",
+ * "{http://sabredav.org/ns}elem2",
+ * "{http://sabredav.org/ns}elem3",
+ * "{http://sabredav.org/ns}elem4",
+ * "{http://sabredav.org/ns}elem5",
+ * ];
+ *
+ * This is useful for 'enum'-like structures.
+ *
+ * If the $namespace argument is specified, it will strip the namespace
+ * for all elements that match that.
+ *
+ * For example,
+ *
+ * enum($reader, 'http://sabredav.org/ns')
+ *
+ * would return:
+ *
+ * [
+ * "elem1",
+ * "elem2",
+ * "elem3",
+ * "elem4",
+ * "elem5",
+ * ];
+ *
+ * @param Reader $reader
+ * @param string $namespace
+ * @return string[]
+ */
+function enum(Reader $reader, $namespace = null) {
+
+ // If there's no children, we don't do anything.
+ if ($reader->isEmptyElement) {
+ $reader->next();
+ return [];
+ }
+ $reader->read();
+ $currentDepth = $reader->depth;
+
+ $values = [];
+ do {
+
+ if ($reader->nodeType !== Reader::ELEMENT) {
+ continue;
+ }
+ if (!is_null($namespace) && $namespace === $reader->namespaceURI) {
+ $values[] = $reader->localName;
+ } else {
+ $values[] = $reader->getClark();
+ }
+
+ } while ($reader->depth >= $currentDepth && $reader->next());
+
+ $reader->next();
+ return $values;
+
+}
+
+/**
+ * The valueObject deserializer turns an xml element into a PHP object of
+ * a specific class.
+ *
+ * This is primarily used by the mapValueObject function from the Service
+ * class, but it can also easily be used for more specific situations.
+ *
+ * @param Reader $reader
+ * @param string $className
+ * @param string $namespace
+ * @return object
+ */
+function valueObject(Reader $reader, $className, $namespace) {
+
+ $valueObject = new $className();
+ if ($reader->isEmptyElement) {
+ $reader->next();
+ return $valueObject;
+ }
+
+ $defaultProperties = get_class_vars($className);
+
+ $reader->read();
+ do {
+
+ if ($reader->nodeType === Reader::ELEMENT && $reader->namespaceURI == $namespace) {
+
+ if (property_exists($valueObject, $reader->localName)) {
+ if (is_array($defaultProperties[$reader->localName])) {
+ $valueObject->{$reader->localName}[] = $reader->parseCurrentElement()['value'];
+ } else {
+ $valueObject->{$reader->localName} = $reader->parseCurrentElement()['value'];
+ }
+ } else {
+ // Ignore property
+ $reader->next();
+ }
+ } else {
+ $reader->read();
+ }
+ } while ($reader->nodeType !== Reader::END_ELEMENT);
+
+ $reader->read();
+ return $valueObject;
+
+}
+
+/*
+ * This deserializer helps you deserialize xml structures that look like
+ * this:
+ *
+ * <collection>
+ * <item>...</item>
+ * <item>...</item>
+ * <item>...</item>
+ * </collection>
+ *
+ * Many XML documents use patterns like that, and this deserializer
+ * allow you to get all the 'items' as an array.
+ *
+ * In that previous example, you would register the deserializer as such:
+ *
+ * $reader->elementMap['{}collection'] = function($reader) {
+ * return repeatingElements($reader, '{}item');
+ * }
+ *
+ * The repeatingElements deserializer simply returns everything as an array.
+ *
+ * @param Reader $reader
+ * @param string $childElementName Element name in clark-notation
+ * @return array
+ */
+function repeatingElements(Reader $reader, $childElementName) {
+
+ $result = [];
+
+ foreach ($reader->parseGetElements() as $element) {
+
+ if ($element['name'] === $childElementName) {
+ $result[] = $element['value'];
+ }
+
+ }
+
+ return $result;
+
+}
diff --git a/vendor/sabre/xml/lib/Element.php b/vendor/sabre/xml/lib/Element.php
new file mode 100644
index 000000000..dd89c5888
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Sabre\Xml;
+
+/**
+ * This is the XML element interface.
+ *
+ * Elements are responsible for serializing and deserializing part of an XML
+ * document into PHP values.
+ *
+ * It combines XmlSerializable and XmlDeserializable into one logical class
+ * that does both.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+interface Element extends XmlSerializable, XmlDeserializable {
+
+}
diff --git a/vendor/sabre/xml/lib/Element/Base.php b/vendor/sabre/xml/lib/Element/Base.php
new file mode 100644
index 000000000..f59ba49a0
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element/Base.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Sabre\Xml\Element;
+
+use Sabre\Xml;
+
+/**
+ * The Base XML element is the standard parser & generator that's used by the
+ * XML reader and writer.
+ *
+ * It spits out a simple PHP array structure during deserialization, that can
+ * also be directly injected back into Writer::write.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Base implements Xml\Element {
+
+ /**
+ * PHP value to serialize.
+ *
+ * @var mixed
+ */
+ protected $value;
+
+ /**
+ * Constructor
+ *
+ * @param mixed $value
+ */
+ function __construct($value = null) {
+
+ $this->value = $value;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializable should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Xml\Writer $writer) {
+
+ $writer->write($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 Xml\Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Xml\Reader $reader) {
+
+ $subTree = $reader->parseInnerTree();
+ return $subTree;
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Element/Cdata.php b/vendor/sabre/xml/lib/Element/Cdata.php
new file mode 100644
index 000000000..5f42c4c6e
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element/Cdata.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Sabre\Xml\Element;
+
+use Sabre\Xml;
+
+/**
+ * CDATA element.
+ *
+ * This element allows you to easily inject CDATA.
+ *
+ * Note that we strongly recommend avoiding CDATA nodes, unless you definitely
+ * know what you're doing, or you're working with unchangable systems that
+ * require CDATA.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Cdata implements Xml\XmlSerializable
+{
+ /**
+ * CDATA element value.
+ *
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * Constructor
+ *
+ * @param string $value
+ */
+ function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Xml\Writer $writer) {
+
+ $writer->writeCData($this->value);
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Element/Elements.php b/vendor/sabre/xml/lib/Element/Elements.php
new file mode 100644
index 000000000..9eefd1bf8
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element/Elements.php
@@ -0,0 +1,108 @@
+<?php
+
+namespace Sabre\Xml\Element;
+
+use Sabre\Xml;
+use Sabre\Xml\Deserializer;
+use Sabre\Xml\Serializer;
+
+/**
+ * 'Elements' is a simple list of elements, without values or attributes.
+ * For example, Elements will parse:
+ *
+ * <?xml version="1.0"?>
+ * <s:root xmlns:s="http://sabredav.org/ns">
+ * <s:elem1 />
+ * <s:elem2 />
+ * <s:elem3 />
+ * <s:elem4>content</s:elem4>
+ * <s:elem5 attr="val" />
+ * </s:root>
+ *
+ * Into:
+ *
+ * [
+ * "{http://sabredav.org/ns}elem1",
+ * "{http://sabredav.org/ns}elem2",
+ * "{http://sabredav.org/ns}elem3",
+ * "{http://sabredav.org/ns}elem4",
+ * "{http://sabredav.org/ns}elem5",
+ * ];
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Elements implements Xml\Element {
+
+ /**
+ * Value to serialize
+ *
+ * @var array
+ */
+ protected $value;
+
+ /**
+ * Constructor
+ *
+ * @param array $value
+ */
+ function __construct(array $value = []) {
+
+ $this->value = $value;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Xml\Writer $writer) {
+
+ Serializer\enum($writer, $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->parseSubTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Xml\Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Xml\Reader $reader) {
+
+ return Deserializer\enum($reader);
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Element/KeyValue.php b/vendor/sabre/xml/lib/Element/KeyValue.php
new file mode 100644
index 000000000..7ce53bf4c
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element/KeyValue.php
@@ -0,0 +1,108 @@
+<?php
+
+namespace Sabre\Xml\Element;
+
+use Sabre\Xml;
+use Sabre\Xml\Deserializer;
+
+/**
+ * 'KeyValue' parses out all child elements from a single node, and outputs a
+ * key=>value struct.
+ *
+ * Attributes will be removed, and duplicate child elements are discarded.
+ * Complex values within the elements will be parsed by the 'standard' parser.
+ *
+ * For example, KeyValue will parse:
+ *
+ * <?xml version="1.0"?>
+ * <s:root xmlns:s="http://sabredav.org/ns">
+ * <s:elem1>value1</s:elem1>
+ * <s:elem2>value2</s:elem2>
+ * <s:elem3 />
+ * </s:root>
+ *
+ * Into:
+ *
+ * [
+ * "{http://sabredav.org/ns}elem1" => "value1",
+ * "{http://sabredav.org/ns}elem2" => "value2",
+ * "{http://sabredav.org/ns}elem3" => null,
+ * ];
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class KeyValue implements Xml\Element {
+
+ /**
+ * Value to serialize
+ *
+ * @var array
+ */
+ protected $value;
+
+ /**
+ * Constructor
+ *
+ * @param array $value
+ */
+ function __construct(array $value = []) {
+
+ $this->value = $value;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Xml\Writer $writer) {
+
+ $writer->write($this->value);
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called staticly, 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 Xml\Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Xml\Reader $reader) {
+
+ return Deserializer\keyValue($reader);
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Element/Uri.php b/vendor/sabre/xml/lib/Element/Uri.php
new file mode 100644
index 000000000..8f45c0027
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element/Uri.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Sabre\Xml\Element;
+
+use Sabre\Xml;
+
+/**
+ * Uri element.
+ *
+ * This represents a single uri. An example of how this may be encoded:
+ *
+ * <link>/foo/bar</link>
+ * <d:href xmlns:d="DAV:">http://example.org/hi</d:href>
+ *
+ * If the uri is relative, it will be automatically expanded to an absolute
+ * url during writing and reading, if the contextUri property is set on the
+ * reader and/or writer.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Uri implements Xml\Element {
+
+ /**
+ * Uri element value.
+ *
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * Constructor
+ *
+ * @param string $value
+ */
+ function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Xml\Writer $writer) {
+
+ $writer->text(
+ \Sabre\Uri\resolve(
+ $writer->contextUri,
+ $this->value
+ )
+ );
+
+ }
+
+ /**
+ * This method is called during xml parsing.
+ *
+ * This method is called statically, 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->parseSubTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Xml\Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Xml\Reader $reader) {
+
+ return new self(
+ \Sabre\Uri\resolve(
+ $reader->contextUri,
+ $reader->readText()
+ )
+ );
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Element/XmlFragment.php b/vendor/sabre/xml/lib/Element/XmlFragment.php
new file mode 100644
index 000000000..0abfac132
--- /dev/null
+++ b/vendor/sabre/xml/lib/Element/XmlFragment.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace Sabre\Xml\Element;
+
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+use Sabre\Xml\Element;
+
+/**
+ * The XmlFragment element allows you to extract a portion of your xml tree,
+ * and get a well-formed xml string.
+ *
+ * This goes a bit beyond `innerXml` and friends, as we'll also match all the
+ * correct namespaces.
+ *
+ * Please note that the XML fragment:
+ *
+ * 1. Will not have an <?xml declaration.
+ * 2. Or a DTD
+ * 3. It will have all the relevant xmlns attributes.
+ * 4. It may not have a root element.
+ */
+class XmlFragment implements Element {
+
+ protected $xml;
+
+ function __construct($xml) {
+
+ $this->xml = $xml;
+
+ }
+
+ function getXml() {
+
+ return $this->xml;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ $reader = new Reader();
+
+ // Wrapping the xml in a container, so root-less values can still be
+ // parsed.
+ $xml = <<<XML
+<?xml version="1.0"?>
+<xml-fragment xmlns="http://sabre.io/ns">{$this->getXml()}</xml-fragment>
+XML;
+
+ $reader->xml($xml);
+
+ while ($reader->read()) {
+
+ if ($reader->depth < 1) {
+ // Skipping the root node.
+ continue;
+ }
+
+ switch ($reader->nodeType) {
+
+ case Reader::ELEMENT :
+ $writer->startElement(
+ $reader->getClark()
+ );
+ $empty = $reader->isEmptyElement;
+ while ($reader->moveToNextAttribute()) {
+ switch ($reader->namespaceURI) {
+ case '' :
+ $writer->writeAttribute($reader->localName, $reader->value);
+ break;
+ case 'http://www.w3.org/2000/xmlns/' :
+ // Skip namespace declarations
+ break;
+ default :
+ $writer->writeAttribute($reader->getClark(), $reader->value);
+ break;
+ }
+ }
+ if ($empty) {
+ $writer->endElement();
+ }
+ break;
+ case Reader::CDATA :
+ case Reader::TEXT :
+ $writer->text(
+ $reader->value
+ );
+ break;
+ case Reader::END_ELEMENT :
+ $writer->endElement();
+ break;
+
+ }
+
+ }
+
+ }
+
+ /**
+ * 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) {
+
+ $result = new self($reader->readInnerXml());
+ $reader->next();
+ return $result;
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/LibXMLException.php b/vendor/sabre/xml/lib/LibXMLException.php
new file mode 100644
index 000000000..f0190eb51
--- /dev/null
+++ b/vendor/sabre/xml/lib/LibXMLException.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Sabre\Xml;
+
+use
+ LibXMLError;
+
+/**
+ * This exception is thrown when the Readers runs into a parsing error.
+ *
+ * This exception effectively wraps 1 or more LibXMLError objects.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class LibXMLException extends ParseException {
+
+ /**
+ * The error list.
+ *
+ * @var LibXMLError[]
+ */
+ protected $errors;
+
+ /**
+ * Creates the exception.
+ *
+ * You should pass a list of LibXMLError objects in its constructor.
+ *
+ * @param LibXMLError[] $errors
+ * @param int $code
+ * @param Exception $previousException
+ */
+ function __construct(array $errors, $code = null, Exception $previousException = null) {
+
+ $this->errors = $errors;
+ parent::__construct($errors[0]->message . ' on line ' . $errors[0]->line . ', column ' . $errors[0]->column, $code, $previousException);
+
+ }
+
+ /**
+ * Returns the LibXML errors
+ *
+ * @return void
+ */
+ function getErrors() {
+
+ return $this->errors;
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/ParseException.php b/vendor/sabre/xml/lib/ParseException.php
new file mode 100644
index 000000000..3a6883b2f
--- /dev/null
+++ b/vendor/sabre/xml/lib/ParseException.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\Xml;
+
+use
+ Exception;
+
+/**
+ * This is a base exception for any exception related to parsing xml files.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class ParseException extends Exception {
+
+}
diff --git a/vendor/sabre/xml/lib/Reader.php b/vendor/sabre/xml/lib/Reader.php
new file mode 100644
index 000000000..7cba76c59
--- /dev/null
+++ b/vendor/sabre/xml/lib/Reader.php
@@ -0,0 +1,308 @@
+<?php
+
+namespace Sabre\Xml;
+
+use XMLReader;
+
+/**
+ * The Reader class expands upon PHP's built-in XMLReader.
+ *
+ * The intended usage, is to assign certain XML elements to PHP classes. These
+ * need to be registered using the $elementMap public property.
+ *
+ * After this is done, a single call to parse() will parse the entire document,
+ * and delegate sub-sections of the document to element classes.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Reader extends XMLReader {
+
+ use ContextStackTrait;
+
+ /**
+ * Returns the current nodename in clark-notation.
+ *
+ * For example: "{http://www.w3.org/2005/Atom}feed".
+ * Or if no namespace is defined: "{}feed".
+ *
+ * This method returns null if we're not currently on an element.
+ *
+ * @return string|null
+ */
+ function getClark() {
+
+ if (! $this->localName) {
+ return null;
+ }
+
+ return '{' . $this->namespaceURI . '}' . $this->localName;
+
+ }
+
+ /**
+ * Reads the entire document.
+ *
+ * This function returns an array with the following three elements:
+ * * name - The root element name.
+ * * value - The value for the root element.
+ * * attributes - An array of attributes.
+ *
+ * This function will also disable the standard libxml error handler (which
+ * usually just results in PHP errors), and throw exceptions instead.
+ *
+ * @return array
+ */
+ function parse() {
+
+ $previousEntityState = libxml_disable_entity_loader(true);
+ $previousSetting = libxml_use_internal_errors(true);
+
+ // Really sorry about the silence operator, seems like I have no
+ // choice. See:
+ //
+ // https://bugs.php.net/bug.php?id=64230
+ while ($this->nodeType !== self::ELEMENT && @$this->read()) {
+ // noop
+ }
+ $result = $this->parseCurrentElement();
+
+ $errors = libxml_get_errors();
+ libxml_clear_errors();
+ libxml_use_internal_errors($previousSetting);
+ libxml_disable_entity_loader($previousEntityState);
+
+ if ($errors) {
+ throw new LibXMLException($errors);
+ }
+
+ return $result;
+ }
+
+
+
+ /**
+ * parseGetElements parses everything in the current sub-tree,
+ * and returns a an array of elements.
+ *
+ * Each element has a 'name', 'value' and 'attributes' key.
+ *
+ * If the the element didn't contain sub-elements, an empty array is always
+ * returned. If there was any text inside the element, it will be
+ * discarded.
+ *
+ * If the $elementMap argument is specified, the existing elementMap will
+ * be overridden while parsing the tree, and restored after this process.
+ *
+ * @param array $elementMap
+ * @return array
+ */
+ function parseGetElements(array $elementMap = null) {
+
+ $result = $this->parseInnerTree($elementMap);
+ if (!is_array($result)) {
+ return [];
+ }
+ return $result;
+
+ }
+
+ /**
+ * Parses all elements below the current element.
+ *
+ * This method will return a string if this was a text-node, or an array if
+ * there were sub-elements.
+ *
+ * If there's both text and sub-elements, the text will be discarded.
+ *
+ * If the $elementMap argument is specified, the existing elementMap will
+ * be overridden while parsing the tree, and restored after this process.
+ *
+ * @param array $elementMap
+ * @return array|string
+ */
+ function parseInnerTree(array $elementMap = null) {
+
+ $text = null;
+ $elements = [];
+
+ if ($this->nodeType === self::ELEMENT && $this->isEmptyElement) {
+ // Easy!
+ $this->next();
+ return null;
+ }
+
+ if (!is_null($elementMap)) {
+ $this->pushContext();
+ $this->elementMap = $elementMap;
+ }
+
+ // Really sorry about the silence operator, seems like I have no
+ // choice. See:
+ //
+ // https://bugs.php.net/bug.php?id=64230
+ if (!@$this->read()) return false;
+
+ while (true) {
+
+ if (!$this->isValid()) {
+
+ $errors = libxml_get_errors();
+
+ if ($errors) {
+ libxml_clear_errors();
+ throw new LibXMLException($errors);
+ }
+ }
+
+ switch ($this->nodeType) {
+ case self::ELEMENT :
+ $elements[] = $this->parseCurrentElement();
+ break;
+ case self::TEXT :
+ case self::CDATA :
+ $text .= $this->value;
+ $this->read();
+ break;
+ case self::END_ELEMENT :
+ // Ensuring we are moving the cursor after the end element.
+ $this->read();
+ break 2;
+ case self::NONE :
+ throw new ParseException('We hit the end of the document prematurely. This likely means that some parser "eats" too many elements. Do not attempt to continue parsing.');
+ default :
+ // Advance to the next element
+ $this->read();
+ break;
+ }
+
+ }
+
+ if (!is_null($elementMap)) {
+ $this->popContext();
+ }
+ return ($elements ? $elements : $text);
+
+ }
+
+ /**
+ * Reads all text below the current element, and returns this as a string.
+ *
+ * @return string
+ */
+ function readText() {
+
+ $result = '';
+ $previousDepth = $this->depth;
+
+ while ($this->read() && $this->depth != $previousDepth) {
+ if (in_array($this->nodeType, [XMLReader::TEXT, XMLReader::CDATA, XMLReader::WHITESPACE])) {
+ $result .= $this->value;
+ }
+ }
+ return $result;
+
+ }
+
+ /**
+ * Parses the current XML element.
+ *
+ * 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
+ */
+ function parseCurrentElement() {
+
+ $name = $this->getClark();
+
+ $attributes = [];
+
+ if ($this->hasAttributes) {
+ $attributes = $this->parseAttributes();
+ }
+
+ $value = call_user_func(
+ $this->getDeserializerForElementName($name),
+ $this
+ );
+
+ return [
+ 'name' => $name,
+ 'value' => $value,
+ 'attributes' => $attributes,
+ ];
+ }
+
+
+ /**
+ * Grabs all the attributes from the current element, and returns them as a
+ * key-value array.
+ *
+ * If the attributes are part of the same namespace, they will simply be
+ * short keys. If they are defined on a different namespace, the attribute
+ * name will be retured in clark-notation.
+ *
+ * @return array
+ */
+ function parseAttributes() {
+
+ $attributes = [];
+
+ while ($this->moveToNextAttribute()) {
+ if ($this->namespaceURI) {
+
+ // Ignoring 'xmlns', it doesn't make any sense.
+ if ($this->namespaceURI === 'http://www.w3.org/2000/xmlns/') {
+ continue;
+ }
+
+ $name = $this->getClark();
+ $attributes[$name] = $this->value;
+
+ } else {
+ $attributes[$this->localName] = $this->value;
+ }
+ }
+ $this->moveToElement();
+
+ return $attributes;
+
+ }
+
+ /**
+ * Returns the function that should be used to parse the element identified
+ * by it's clark-notation name.
+ *
+ * @param string $name
+ * @return callable
+ */
+ function getDeserializerForElementName($name) {
+
+ if (!array_key_exists($name, $this->elementMap)) {
+ return ['Sabre\\Xml\\Element\\Base', 'xmlDeserialize'];
+ }
+
+ $deserializer = $this->elementMap[$name];
+ if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) {
+ return [ $deserializer, 'xmlDeserialize' ];
+ }
+
+ if (is_callable($deserializer)) {
+ return $deserializer;
+ }
+
+ $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 . ' for element: ' . $name);
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Serializer/functions.php b/vendor/sabre/xml/lib/Serializer/functions.php
new file mode 100644
index 000000000..21448017d
--- /dev/null
+++ b/vendor/sabre/xml/lib/Serializer/functions.php
@@ -0,0 +1,249 @@
+<?php
+
+namespace Sabre\Xml\Serializer;
+
+use InvalidArgumentException;
+use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
+
+/**
+ * This file provides a number of 'serializer' helper functions.
+ *
+ * These helper functions can be used to easily xml-encode common PHP
+ * data structures, or can be placed in the $classMap.
+ */
+
+/**
+ * The 'enum' serializer writes simple list of elements.
+ *
+ * For example, calling:
+ *
+ * enum($writer, [
+ * "{http://sabredav.org/ns}elem1",
+ * "{http://sabredav.org/ns}elem2",
+ * "{http://sabredav.org/ns}elem3",
+ * "{http://sabredav.org/ns}elem4",
+ * "{http://sabredav.org/ns}elem5",
+ * ]);
+ *
+ * Will generate something like this (if the correct namespace is declared):
+ *
+ * <s:elem1 />
+ * <s:elem2 />
+ * <s:elem3 />
+ * <s:elem4>content</s:elem4>
+ * <s:elem5 attr="val" />
+ *
+ * @param Writer $writer
+ * @param string[] $values
+ * @return void
+ */
+function enum(Writer $writer, array $values) {
+
+ foreach ($values as $value) {
+ $writer->writeElement($value);
+ }
+}
+
+/**
+ * The valueObject serializer turns a simple PHP object into a classname.
+ *
+ * Every public property will be encoded as an xml element with the same
+ * name, in the XML namespace as specified.
+ *
+ * Values that are set to null or an empty array are not serialized. To
+ * serialize empty properties, you must specify them as an empty string.
+ *
+ * @param Writer $writer
+ * @param object $valueObject
+ * @param string $namespace
+ */
+function valueObject(Writer $writer, $valueObject, $namespace) {
+ foreach (get_object_vars($valueObject) as $key => $val) {
+ if (is_array($val)) {
+ // If $val is an array, it has a special meaning. We need to
+ // generate one child element for each item in $val
+ foreach ($val as $child) {
+ $writer->writeElement('{' . $namespace . '}' . $key, $child);
+ }
+
+ } elseif ($val !== null) {
+ $writer->writeElement('{' . $namespace . '}' . $key, $val);
+ }
+ }
+}
+
+
+/**
+ * This serializer helps you serialize xml structures that look like
+ * this:
+ *
+ * <collection>
+ * <item>...</item>
+ * <item>...</item>
+ * <item>...</item>
+ * </collection>
+ *
+ * In that previous example, this serializer just serializes the item element,
+ * and this could be called like this:
+ *
+ * repeatingElements($writer, $items, '{}item');
+ *
+ * @param Writer $writer
+ * @param array $items A list of items sabre/xml can serialize.
+ * @param string $childElementName Element name in clark-notation
+ * @return void
+ */
+function repeatingElements(Writer $writer, array $items, $childElementName) {
+
+ foreach ($items as $item) {
+ $writer->writeElement($childElementName, $item);
+ }
+
+}
+
+/**
+ * This function is the 'default' serializer that is able to serialize most
+ * things, and delegates to other serializers if needed.
+ *
+ * The standardSerializer supports a wide-array of values.
+ *
+ * $value may be a string or integer, it will just write out the string as text.
+ * $value may be an instance of XmlSerializable or Element, in which case it
+ * calls it's xmlSerialize() method.
+ * $value may be a PHP callback/function/closure, in case we call the callback
+ * and give it the Writer as an argument.
+ * $value may be a an object, and if it's in the classMap we automatically call
+ * the correct serializer for it.
+ * $value may be null, in which case we do nothing.
+ *
+ * If $value is an array, the array must look like this:
+ *
+ * [
+ * [
+ * 'name' => '{namespaceUri}element-name',
+ * 'value' => '...',
+ * 'attributes' => [ 'attName' => 'attValue' ]
+ * ]
+ * [,
+ * 'name' => '{namespaceUri}element-name2',
+ * 'value' => '...',
+ * ]
+ * ]
+ *
+ * This would result in xml like:
+ *
+ * <element-name xmlns="namespaceUri" attName="attValue">
+ * ...
+ * </element-name>
+ * <element-name2>
+ * ...
+ * </element-name2>
+ *
+ * The value property may be any value standardSerializer supports, so you can
+ * nest data-structures this way. Both value and attributes are optional.
+ *
+ * Alternatively, you can also specify the array using this syntax:
+ *
+ * [
+ * [
+ * '{namespaceUri}element-name' => '...',
+ * '{namespaceUri}element-name2' => '...',
+ * ]
+ * ]
+ *
+ * This is excellent for simple key->value structures, and here you can also
+ * specify anything for the value.
+ *
+ * You can even mix the two array syntaxes.
+ *
+ * @param Writer $writer
+ * @param string|int|float|bool|array|object
+ * @return void
+ */
+function standardSerializer(Writer $writer, $value) {
+
+ if (is_scalar($value)) {
+
+ // String, integer, float, boolean
+ $writer->text($value);
+
+ } elseif ($value instanceof XmlSerializable) {
+
+ // XmlSerializable classes or Element classes.
+ $value->xmlSerialize($writer);
+
+ } elseif (is_object($value) && isset($writer->classMap[get_class($value)])) {
+
+ // It's an object which class appears in the classmap.
+ $writer->classMap[get_class($value)]($writer, $value);
+
+ } elseif (is_callable($value)) {
+
+ // A callback
+ $value($writer);
+
+ } elseif (is_null($value)) {
+
+ // nothing!
+
+ } elseif (is_array($value) && array_key_exists('name', $value)) {
+
+ // if the array had a 'name' element, we assume that this array
+ // describes a 'name' and optionally 'attributes' and 'value'.
+
+ $name = $value['name'];
+ $attributes = isset($value['attributes']) ? $value['attributes'] : [];
+ $value = isset($value['value']) ? $value['value'] : null;
+
+ $writer->startElement($name);
+ $writer->writeAttributes($attributes);
+ $writer->write($value);
+ $writer->endElement();
+
+ } elseif (is_array($value)) {
+
+ foreach ($value as $name => $item) {
+
+ if (is_int($name)) {
+
+ // This item has a numeric index. We just loop through the
+ // array and throw it back in the writer.
+ standardSerializer($writer, $item);
+
+ } elseif (is_string($name) && is_array($item) && isset($item['attributes'])) {
+
+ // The key is used for a name, but $item has 'attributes' and
+ // possibly 'value'
+ $writer->startElement($name);
+ $writer->writeAttributes($item['attributes']);
+ if (isset($item['value'])) {
+ $writer->write($item['value']);
+ }
+ $writer->endElement();
+
+ } elseif (is_string($name)) {
+
+ // This was a plain key-value array.
+ $writer->startElement($name);
+ $writer->write($item);
+ $writer->endElement();
+
+ } else {
+
+ throw new InvalidArgumentException('The writer does not know how to serialize arrays with keys of type: ' . gettype($name));
+
+ }
+ }
+
+ } elseif (is_object($value)) {
+
+ throw new InvalidArgumentException('The writer cannot serialize objects of class: ' . get_class($value));
+
+ } else {
+
+ throw new InvalidArgumentException('The writer cannot serialize values of type: ' . gettype($value));
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/Service.php b/vendor/sabre/xml/lib/Service.php
new file mode 100644
index 000000000..b2603a4c7
--- /dev/null
+++ b/vendor/sabre/xml/lib/Service.php
@@ -0,0 +1,291 @@
+<?php
+
+namespace Sabre\Xml;
+
+/**
+ * XML parsing and writing service.
+ *
+ * You are encouraged to make a instance of this for your application and
+ * potentially extend it, as a central API point for dealing with xml and
+ * configuring the reader and writer.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Service {
+
+ /**
+ * This is the element map. It contains a list of XML elements (in clark
+ * notation) as keys and PHP class names as values.
+ *
+ * The PHP class names must implement Sabre\Xml\Element.
+ *
+ * Values may also be a callable. In that case the function will be called
+ * directly.
+ *
+ * @var array
+ */
+ public $elementMap = [];
+
+ /**
+ * This is a list of namespaces that you want to give default prefixes.
+ *
+ * You must make sure you create this entire list before starting to write.
+ * They should be registered on the root element.
+ *
+ * @var array
+ */
+ public $namespaceMap = [];
+
+ /**
+ * This is a list of custom serializers for specific classes.
+ *
+ * The writer may use this if you attempt to serialize an object with a
+ * class that does not implement XmlSerializable.
+ *
+ * Instead it will look at this classmap to see if there is a custom
+ * serializer here. This is useful if you don't want your value objects
+ * to be responsible for serializing themselves.
+ *
+ * The keys in this classmap need to be fully qualified PHP class names,
+ * the values must be callbacks. The callbacks take two arguments. The
+ * writer class, and the value that must be written.
+ *
+ * function (Writer $writer, object $value)
+ *
+ * @var array
+ */
+ public $classMap = [];
+
+ /**
+ * Returns a fresh XML Reader
+ *
+ * @return Reader
+ */
+ function getReader() {
+
+ $r = new Reader();
+ $r->elementMap = $this->elementMap;
+ return $r;
+
+ }
+
+ /**
+ * Returns a fresh xml writer
+ *
+ * @return Writer
+ */
+ function getWriter() {
+
+ $w = new Writer();
+ $w->namespaceMap = $this->namespaceMap;
+ $w->classMap = $this->classMap;
+ return $w;
+
+ }
+
+ /**
+ * Parses a document in full.
+ *
+ * Input may be specified as a string or readable stream resource.
+ * The returned value is the value of the root document.
+ *
+ * Specifying the $contextUri allows the parser to figure out what the URI
+ * of the document was. This allows relative URIs within the document to be
+ * expanded easily.
+ *
+ * The $rootElementName is specified by reference and will be populated
+ * with the root element name of the document.
+ *
+ * @param string|resource $input
+ * @param string|null $contextUri
+ * @param string|null $rootElementName
+ * @throws ParseException
+ * @return array|object|string
+ */
+ function parse($input, $contextUri = null, &$rootElementName = null) {
+
+ if (is_resource($input)) {
+ // Unfortunately the XMLReader doesn't support streams. When it
+ // does, we can optimize this.
+ $input = stream_get_contents($input);
+ }
+ $r = $this->getReader();
+ $r->contextUri = $contextUri;
+ $r->xml($input);
+
+ $result = $r->parse();
+ $rootElementName = $result['name'];
+ return $result['value'];
+
+ }
+
+ /**
+ * Parses a document in full, and specify what the expected root element
+ * name is.
+ *
+ * This function works similar to parse, but the difference is that the
+ * user can specify what the expected name of the root element should be,
+ * in clark notation.
+ *
+ * This is useful in cases where you expected a specific document to be
+ * passed, and reduces the amount of if statements.
+ *
+ * It's also possible to pass an array of expected rootElements if your
+ * code may expect more than one document type.
+ *
+ * @param string|string[] $rootElementName
+ * @param string|resource $input
+ * @param string|null $contextUri
+ * @return void
+ */
+ function expect($rootElementName, $input, $contextUri = null) {
+
+ if (is_resource($input)) {
+ // Unfortunately the XMLReader doesn't support streams. When it
+ // does, we can optimize this.
+ $input = stream_get_contents($input);
+ }
+ $r = $this->getReader();
+ $r->contextUri = $contextUri;
+ $r->xml($input);
+
+ $result = $r->parse();
+ if (!in_array($result['name'], (array)$rootElementName, true)) {
+ throw new ParseException('Expected ' . implode(' or ', (array)$rootElementName) . ' but received ' . $result['name'] . ' as the root element');
+ }
+ return $result['value'];
+
+ }
+
+ /**
+ * Generates an XML document in one go.
+ *
+ * The $rootElement must be specified in clark notation.
+ * The value must be a string, an array or an object implementing
+ * XmlSerializable. Basically, anything that's supported by the Writer
+ * object.
+ *
+ * $contextUri can be used to specify a sort of 'root' of the PHP application,
+ * in case the xml document is used as a http response.
+ *
+ * This allows an implementor to easily create URI's relative to the root
+ * of the domain.
+ *
+ * @param string $rootElementName
+ * @param string|array|XmlSerializable $value
+ * @param string|null $contextUri
+ */
+ function write($rootElementName, $value, $contextUri = null) {
+
+ $w = $this->getWriter();
+ $w->openMemory();
+ $w->contextUri = $contextUri;
+ $w->setIndent(true);
+ $w->startDocument();
+ $w->writeElement($rootElementName, $value);
+ return $w->outputMemory();
+
+ }
+
+ /**
+ * Map an xml element to a PHP class.
+ *
+ * Calling this function will automatically setup the Reader and Writer
+ * classes to turn a specific XML element to a PHP class.
+ *
+ * For example, given a class such as :
+ *
+ * class Author {
+ * public $firstName;
+ * public $lastName;
+ * }
+ *
+ * and an XML element such as:
+ *
+ * <author xmlns="http://example.org/ns">
+ * <firstName>...</firstName>
+ * <lastName>...</lastName>
+ * </author>
+ *
+ * These can easily be mapped by calling:
+ *
+ * $service->mapValueObject('{http://example.org}author', 'Author');
+ *
+ * @param string $elementName
+ * @param object $className
+ * @return void
+ */
+ function mapValueObject($elementName, $className) {
+ list($namespace) = self::parseClarkNotation($elementName);
+
+ $this->elementMap[$elementName] = function(Reader $reader) use ($className, $namespace) {
+ return \Sabre\Xml\Deserializer\valueObject($reader, $className, $namespace);
+ };
+ $this->classMap[$className] = function(Writer $writer, $valueObject) use ($namespace) {
+ return \Sabre\Xml\Serializer\valueObject($writer, $valueObject, $namespace);
+ };
+ $this->valueObjectMap[$className] = $elementName;
+ }
+
+ /**
+ * Writes a value object.
+ *
+ * This function largely behaves similar to write(), except that it's
+ * intended specifically to serialize a Value Object into an XML document.
+ *
+ * The ValueObject must have been previously registered using
+ * mapValueObject().
+ *
+ * @param object $object
+ * @param string $contextUri
+ * @return void
+ */
+ function writeValueObject($object, $contextUri = null) {
+
+ if (!isset($this->valueObjectMap[get_class($object)])) {
+ throw new \InvalidArgumentException('"' . get_class($object) . '" is not a registered value object class. Register your class with mapValueObject.');
+ }
+ return $this->write(
+ $this->valueObjectMap[get_class($object)],
+ $object,
+ $contextUri
+ );
+
+ }
+
+ /**
+ * Parses a clark-notation string, and returns the namespace and element
+ * name components.
+ *
+ * If the string was invalid, it will throw an InvalidArgumentException.
+ *
+ * @param string $str
+ * @throws InvalidArgumentException
+ * @return array
+ */
+ static function parseClarkNotation($str) {
+ static $cache = [];
+
+ if (!isset($cache[$str])) {
+
+ if (!preg_match('/^{([^}]*)}(.*)$/', $str, $matches)) {
+ throw new \InvalidArgumentException('\'' . $str . '\' is not a valid clark-notation formatted string');
+ }
+
+ $cache[$str] = [
+ $matches[1],
+ $matches[2]
+ ];
+ }
+
+ return $cache[$str];
+ }
+
+ /**
+ * A list of classes and which XML elements they map to.
+ */
+ protected $valueObjectMap = [];
+
+}
diff --git a/vendor/sabre/xml/lib/Version.php b/vendor/sabre/xml/lib/Version.php
new file mode 100644
index 000000000..f199e7158
--- /dev/null
+++ b/vendor/sabre/xml/lib/Version.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Sabre\Xml;
+
+/**
+ * This class contains the version number for this package.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/
+ */
+class Version {
+
+ /**
+ * Full version number
+ */
+ const VERSION = '1.4.1';
+
+}
diff --git a/vendor/sabre/xml/lib/Writer.php b/vendor/sabre/xml/lib/Writer.php
new file mode 100644
index 000000000..adfbe0cb0
--- /dev/null
+++ b/vendor/sabre/xml/lib/Writer.php
@@ -0,0 +1,266 @@
+<?php
+
+namespace Sabre\Xml;
+
+use XMLWriter;
+
+/**
+ * The XML Writer class.
+ *
+ * This class works exactly as PHP's built-in XMLWriter, with a few additions.
+ *
+ * Namespaces can be registered beforehand, globally. When the first element is
+ * written, namespaces will automatically be declared.
+ *
+ * The writeAttribute, startElement and writeElement can now take a
+ * clark-notation element name (example: {http://www.w3.org/2005/Atom}link).
+ *
+ * If, when writing the namespace is a known one a prefix will automatically be
+ * selected, otherwise a random prefix will be generated.
+ *
+ * Instead of standard string values, the writer can take Element classes (as
+ * defined by this library) to delegate the serialization.
+ *
+ * The write() method can take array structures to quickly write out simple xml
+ * trees.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Writer extends XMLWriter {
+
+ use ContextStackTrait;
+
+ /**
+ * Any namespace that the writer is asked to write, will be added here.
+ *
+ * Any of these elements will get a new namespace definition *every single
+ * time* they are used, but this array allows the writer to make sure that
+ * the prefixes are consistent anyway.
+ *
+ * @var array
+ */
+ protected $adhocNamespaces = [];
+
+ /**
+ * When the first element is written, this flag is set to true.
+ *
+ * This ensures that the namespaces in the namespaces map are only written
+ * once.
+ *
+ * @var bool
+ */
+ protected $namespacesWritten = false;
+
+ /**
+ * Writes a value to the output stream.
+ *
+ * The following values are supported:
+ * 1. Scalar values will be written as-is, as text.
+ * 2. Null values will be skipped (resulting in a short xml tag).
+ * 3. If a value is an instance of an Element class, writing will be
+ * delegated to the object.
+ * 4. If a value is an array, two formats are supported.
+ *
+ * Array format 1:
+ * [
+ * "{namespace}name1" => "..",
+ * "{namespace}name2" => "..",
+ * ]
+ *
+ * One element will be created for each key in this array. The values of
+ * this array support any format this method supports (this method is
+ * called recursively).
+ *
+ * Array format 2:
+ *
+ * [
+ * [
+ * "name" => "{namespace}name1"
+ * "value" => "..",
+ * "attributes" => [
+ * "attr" => "attribute value",
+ * ]
+ * ],
+ * [
+ * "name" => "{namespace}name1"
+ * "value" => "..",
+ * "attributes" => [
+ * "attr" => "attribute value",
+ * ]
+ * ]
+ * ]
+ *
+ * @param mixed $value
+ * @return void
+ */
+ function write($value) {
+
+ Serializer\standardSerializer($this, $value);
+
+ }
+
+ /**
+ * Opens a new element.
+ *
+ * You can either just use a local elementname, or you can use clark-
+ * notation to start a new element.
+ *
+ * Example:
+ *
+ * $writer->startElement('{http://www.w3.org/2005/Atom}entry');
+ *
+ * Would result in something like:
+ *
+ * <entry xmlns="http://w3.org/2005/Atom">
+ *
+ * @param string $name
+ * @return bool
+ */
+ function startElement($name) {
+
+ if ($name[0] === '{') {
+
+ list($namespace, $localName) =
+ Service::parseClarkNotation($name);
+
+ if (array_key_exists($namespace, $this->namespaceMap)) {
+ $result = $this->startElementNS(
+ $this->namespaceMap[$namespace] === '' ? null : $this->namespaceMap[$namespace],
+ $localName,
+ null
+ );
+ } else {
+
+ // An empty namespace means it's the global namespace. This is
+ // allowed, but it mustn't get a prefix.
+ if ($namespace === "" || $namespace === null) {
+ $result = $this->startElement($localName);
+ $this->writeAttribute('xmlns', '');
+ } else {
+ if (!isset($this->adhocNamespaces[$namespace])) {
+ $this->adhocNamespaces[$namespace] = 'x' . (count($this->adhocNamespaces) + 1);
+ }
+ $result = $this->startElementNS($this->adhocNamespaces[$namespace], $localName, $namespace);
+ }
+ }
+
+ } else {
+ $result = parent::startElement($name);
+ }
+
+ if (!$this->namespacesWritten) {
+
+ foreach ($this->namespaceMap as $namespace => $prefix) {
+ $this->writeAttribute(($prefix ? 'xmlns:' . $prefix : 'xmlns'), $namespace);
+ }
+ $this->namespacesWritten = true;
+
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * Write a full element tag and it's contents.
+ *
+ * This method automatically closes the element as well.
+ *
+ * The element name may be specified in clark-notation.
+ *
+ * Examples:
+ *
+ * $writer->writeElement('{http://www.w3.org/2005/Atom}author',null);
+ * becomes:
+ * <author xmlns="http://www.w3.org/2005" />
+ *
+ * $writer->writeElement('{http://www.w3.org/2005/Atom}author', [
+ * '{http://www.w3.org/2005/Atom}name' => 'Evert Pot',
+ * ]);
+ * becomes:
+ * <author xmlns="http://www.w3.org/2005" /><name>Evert Pot</name></author>
+ *
+ * @param string $name
+ * @param string $content
+ * @return bool
+ */
+ function writeElement($name, $content = null) {
+
+ $this->startElement($name);
+ if (!is_null($content)) {
+ $this->write($content);
+ }
+ $this->endElement();
+
+ }
+
+ /**
+ * Writes a list of attributes.
+ *
+ * Attributes are specified as a key->value array.
+ *
+ * The key is an attribute name. If the key is a 'localName', the current
+ * xml namespace is assumed. If it's a 'clark notation key', this namespace
+ * will be used instead.
+ *
+ * @param array $attributes
+ * @return void
+ */
+ function writeAttributes(array $attributes) {
+
+ foreach ($attributes as $name => $value) {
+ $this->writeAttribute($name, $value);
+ }
+
+ }
+
+ /**
+ * Writes a new attribute.
+ *
+ * The name may be specified in clark-notation.
+ *
+ * Returns true when successful.
+ *
+ * @param string $name
+ * @param string $value
+ * @return bool
+ */
+ function writeAttribute($name, $value) {
+
+ if ($name[0] === '{') {
+
+ list(
+ $namespace,
+ $localName
+ ) = Service::parseClarkNotation($name);
+
+ if (array_key_exists($namespace, $this->namespaceMap)) {
+ // It's an attribute with a namespace we know
+ $this->writeAttribute(
+ $this->namespaceMap[$namespace] . ':' . $localName,
+ $value
+ );
+ } else {
+
+ // We don't know the namespace, we must add it in-line
+ if (!isset($this->adhocNamespaces[$namespace])) {
+ $this->adhocNamespaces[$namespace] = 'x' . (count($this->adhocNamespaces) + 1);
+ }
+ $this->writeAttributeNS(
+ $this->adhocNamespaces[$namespace],
+ $localName,
+ $namespace,
+ $value
+ );
+
+ }
+
+ } else {
+ return parent::writeAttribute($name, $value);
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/xml/lib/XmlDeserializable.php b/vendor/sabre/xml/lib/XmlDeserializable.php
new file mode 100644
index 000000000..fa857e82c
--- /dev/null
+++ b/vendor/sabre/xml/lib/XmlDeserializable.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Sabre\Xml;
+
+/**
+ * Implementing the XmlDeserializable interface allows you to use a class as a
+ * deserializer for a specific element.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+interface XmlDeserializable {
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statically, 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);
+
+}
diff --git a/vendor/sabre/xml/lib/XmlSerializable.php b/vendor/sabre/xml/lib/XmlSerializable.php
new file mode 100644
index 000000000..3e2c528b9
--- /dev/null
+++ b/vendor/sabre/xml/lib/XmlSerializable.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Sabre\Xml;
+
+/**
+ * Objects implementing XmlSerializable can control how they are represented in
+ * Xml.
+ *
+ * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+interface XmlSerializable {
+
+ /**
+ * The xmlSerialize method is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer);
+
+}