commit vendor
This commit is contained in:
27
vendor/sabre/xml/LICENSE
vendored
Normal file
27
vendor/sabre/xml/LICENSE
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name Sabre nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
118
vendor/sabre/xml/lib/ContextStackTrait.php
vendored
Normal file
118
vendor/sabre/xml/lib/ContextStackTrait.php
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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|null
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public function pushContext()
|
||||
{
|
||||
$this->contextStack[] = [
|
||||
$this->elementMap,
|
||||
$this->contextUri,
|
||||
$this->namespaceMap,
|
||||
$this->classMap,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the previous "context".
|
||||
*/
|
||||
public function popContext()
|
||||
{
|
||||
list(
|
||||
$this->elementMap,
|
||||
$this->contextUri,
|
||||
$this->namespaceMap,
|
||||
$this->classMap
|
||||
) = array_pop($this->contextStack);
|
||||
}
|
||||
}
|
||||
359
vendor/sabre/xml/lib/Deserializer/functions.php
vendored
Normal file
359
vendor/sabre/xml/lib/Deserializer/functions.php
vendored
Normal file
@ -0,0 +1,359 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*/
|
||||
function keyValue(Reader $reader, string $namespace = null): array
|
||||
{
|
||||
// If there's no children, we don't do anything.
|
||||
if ($reader->isEmptyElement) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!$reader->read()) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
if (Reader::END_ELEMENT === $reader->nodeType) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$values = [];
|
||||
|
||||
do {
|
||||
if (Reader::ELEMENT === $reader->nodeType) {
|
||||
if (null !== $namespace && $reader->namespaceURI === $namespace) {
|
||||
$values[$reader->localName] = $reader->parseCurrentElement()['value'];
|
||||
} else {
|
||||
$clark = $reader->getClark();
|
||||
$values[$clark] = $reader->parseCurrentElement()['value'];
|
||||
}
|
||||
} else {
|
||||
if (!$reader->read()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (Reader::END_ELEMENT !== $reader->nodeType);
|
||||
|
||||
$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",
|
||||
* ];
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
function enum(Reader $reader, string $namespace = null): array
|
||||
{
|
||||
// If there's no children, we don't do anything.
|
||||
if ($reader->isEmptyElement) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
if (!$reader->read()) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
if (Reader::END_ELEMENT === $reader->nodeType) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
$currentDepth = $reader->depth;
|
||||
|
||||
$values = [];
|
||||
do {
|
||||
if (Reader::ELEMENT !== $reader->nodeType) {
|
||||
continue;
|
||||
}
|
||||
if (!is_null($namespace) && $namespace === $reader->namespaceURI) {
|
||||
$values[] = $reader->localName;
|
||||
} else {
|
||||
$values[] = (string) $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.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
function valueObject(Reader $reader, string $className, string $namespace)
|
||||
{
|
||||
$valueObject = new $className();
|
||||
if ($reader->isEmptyElement) {
|
||||
$reader->next();
|
||||
|
||||
return $valueObject;
|
||||
}
|
||||
|
||||
$defaultProperties = get_class_vars($className);
|
||||
|
||||
$reader->read();
|
||||
do {
|
||||
if (Reader::ELEMENT === $reader->nodeType && $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 {
|
||||
if (!$reader->read()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (Reader::END_ELEMENT !== $reader->nodeType);
|
||||
|
||||
$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.
|
||||
*
|
||||
* $childElementName must either be a a clark-notation element name, or if no
|
||||
* namespace is used, the bare element name.
|
||||
*/
|
||||
function repeatingElements(Reader $reader, string $childElementName): array
|
||||
{
|
||||
if ('{' !== $childElementName[0]) {
|
||||
$childElementName = '{}'.$childElementName;
|
||||
}
|
||||
$result = [];
|
||||
|
||||
foreach ($reader->parseGetElements() as $element) {
|
||||
if ($element['name'] === $childElementName) {
|
||||
$result[] = $element['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This deserializer helps you to deserialize structures which contain mixed content like this:.
|
||||
*
|
||||
* <p>some text <extref>and a inline tag</extref>and even more text</p>
|
||||
*
|
||||
* The above example will return
|
||||
*
|
||||
* [
|
||||
* 'some text',
|
||||
* [
|
||||
* 'name' => '{}extref',
|
||||
* 'value' => 'and a inline tag',
|
||||
* 'attributes' => []
|
||||
* ],
|
||||
* 'and even more text'
|
||||
* ]
|
||||
*
|
||||
* In strict XML documents you wont find this kind of markup but in html this is a quite common pattern.
|
||||
*/
|
||||
function mixedContent(Reader $reader): array
|
||||
{
|
||||
// If there's no children, we don't do anything.
|
||||
if ($reader->isEmptyElement) {
|
||||
$reader->next();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$previousDepth = $reader->depth;
|
||||
|
||||
$content = [];
|
||||
$reader->read();
|
||||
while (true) {
|
||||
if (Reader::ELEMENT == $reader->nodeType) {
|
||||
$content[] = $reader->parseCurrentElement();
|
||||
} elseif ($reader->depth >= $previousDepth && in_array($reader->nodeType, [Reader::TEXT, Reader::CDATA, Reader::WHITESPACE])) {
|
||||
$content[] = $reader->value;
|
||||
$reader->read();
|
||||
} elseif (Reader::END_ELEMENT == $reader->nodeType) {
|
||||
// Ensuring we are moving the cursor after the end element.
|
||||
$reader->read();
|
||||
break;
|
||||
} else {
|
||||
$reader->read();
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* The functionCaller deserializer turns an xml element into whatever your callable return.
|
||||
*
|
||||
* You can use, e.g., a named constructor (factory method) to create an object using
|
||||
* this function.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function functionCaller(Reader $reader, callable $func, string $namespace)
|
||||
{
|
||||
if ($reader->isEmptyElement) {
|
||||
$reader->next();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$funcArgs = [];
|
||||
$func = is_string($func) && false !== strpos($func, '::') ? explode('::', $func) : $func;
|
||||
$ref = is_array($func) ? new \ReflectionMethod($func[0], $func[1]) : new \ReflectionFunction($func);
|
||||
foreach ($ref->getParameters() as $parameter) {
|
||||
$funcArgs[$parameter->getName()] = null;
|
||||
}
|
||||
|
||||
$reader->read();
|
||||
do {
|
||||
if (Reader::ELEMENT === $reader->nodeType && $reader->namespaceURI == $namespace) {
|
||||
if (array_key_exists($reader->localName, $funcArgs)) {
|
||||
$funcArgs[$reader->localName] = $reader->parseCurrentElement()['value'];
|
||||
} else {
|
||||
// Ignore property
|
||||
$reader->next();
|
||||
}
|
||||
} else {
|
||||
$reader->read();
|
||||
}
|
||||
} while (Reader::END_ELEMENT !== $reader->nodeType);
|
||||
$reader->read();
|
||||
|
||||
return $func(...array_values($funcArgs));
|
||||
}
|
||||
22
vendor/sabre/xml/lib/Element.php
vendored
Normal file
22
vendor/sabre/xml/lib/Element.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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
|
||||
{
|
||||
}
|
||||
84
vendor/sabre/xml/lib/Element/Base.php
vendored
Normal file
84
vendor/sabre/xml/lib/Element/Base.php
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public 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.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function xmlDeserialize(Xml\Reader $reader)
|
||||
{
|
||||
$subTree = $reader->parseInnerTree();
|
||||
|
||||
return $subTree;
|
||||
}
|
||||
}
|
||||
59
vendor/sabre/xml/lib/Element/Cdata.php
vendored
Normal file
59
vendor/sabre/xml/lib/Element/Cdata.php
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*/
|
||||
public function __construct(string $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.
|
||||
*/
|
||||
public function xmlSerialize(Xml\Writer $writer)
|
||||
{
|
||||
$writer->writeCData($this->value);
|
||||
}
|
||||
}
|
||||
100
vendor/sabre/xml/lib/Element/Elements.php
vendored
Normal file
100
vendor/sabre/xml/lib/Element/Elements.php
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public 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.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function xmlDeserialize(Xml\Reader $reader)
|
||||
{
|
||||
return Deserializer\enum($reader);
|
||||
}
|
||||
}
|
||||
100
vendor/sabre/xml/lib/Element/KeyValue.php
vendored
Normal file
100
vendor/sabre/xml/lib/Element/KeyValue.php
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public 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.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function xmlDeserialize(Xml\Reader $reader)
|
||||
{
|
||||
return Deserializer\keyValue($reader);
|
||||
}
|
||||
}
|
||||
99
vendor/sabre/xml/lib/Element/Uri.php
vendored
Normal file
99
vendor/sabre/xml/lib/Element/Uri.php
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public 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.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function xmlDeserialize(Xml\Reader $reader)
|
||||
{
|
||||
return new self(
|
||||
\Sabre\Uri\resolve(
|
||||
(string) $reader->contextUri,
|
||||
$reader->readText()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
148
vendor/sabre/xml/lib/Element/XmlFragment.php
vendored
Normal file
148
vendor/sabre/xml/lib/Element/XmlFragment.php
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\Xml\Element;
|
||||
|
||||
use Sabre\Xml\Element;
|
||||
use Sabre\Xml\Reader;
|
||||
use Sabre\Xml\Writer;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
/**
|
||||
* The inner XML value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $xml;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(string $xml)
|
||||
{
|
||||
$this->xml = $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inner XML document.
|
||||
*/
|
||||
public function getXml(): string
|
||||
{
|
||||
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.
|
||||
*/
|
||||
public 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(
|
||||
(string) $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((string) $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.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = new self($reader->readInnerXml());
|
||||
$reader->next();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
49
vendor/sabre/xml/lib/LibXMLException.php
vendored
Normal file
49
vendor/sabre/xml/lib/LibXMLException.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\Xml;
|
||||
|
||||
use LibXMLError;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 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 Throwable $previousException
|
||||
*/
|
||||
public function __construct(array $errors, int $code = 0, Throwable $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.
|
||||
*/
|
||||
public function getErrors(): array
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
}
|
||||
19
vendor/sabre/xml/lib/ParseException.php
vendored
Normal file
19
vendor/sabre/xml/lib/ParseException.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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
|
||||
{
|
||||
}
|
||||
301
vendor/sabre/xml/lib/Reader.php
vendored
Normal file
301
vendor/sabre/xml/lib/Reader.php
vendored
Normal file
@ -0,0 +1,301 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public function parse(): array
|
||||
{
|
||||
$previousEntityState = libxml_disable_entity_loader(true);
|
||||
$previousSetting = libxml_use_internal_errors(true);
|
||||
|
||||
try {
|
||||
while (self::ELEMENT !== $this->nodeType) {
|
||||
if (!$this->read()) {
|
||||
$errors = libxml_get_errors();
|
||||
libxml_clear_errors();
|
||||
if ($errors) {
|
||||
throw new LibXMLException($errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
$result = $this->parseCurrentElement();
|
||||
|
||||
// last line of defense in case errors did occur above
|
||||
$errors = libxml_get_errors();
|
||||
libxml_clear_errors();
|
||||
if ($errors) {
|
||||
throw new LibXMLException($errors);
|
||||
}
|
||||
} finally {
|
||||
libxml_use_internal_errors($previousSetting);
|
||||
libxml_disable_entity_loader($previousEntityState);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
public function parseGetElements(array $elementMap = null): array
|
||||
{
|
||||
$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.
|
||||
*
|
||||
* @return array|string|null
|
||||
*/
|
||||
public function parseInnerTree(array $elementMap = null)
|
||||
{
|
||||
$text = null;
|
||||
$elements = [];
|
||||
|
||||
if (self::ELEMENT === $this->nodeType && $this->isEmptyElement) {
|
||||
// Easy!
|
||||
$this->next();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!is_null($elementMap)) {
|
||||
$this->pushContext();
|
||||
$this->elementMap = $elementMap;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$this->read()) {
|
||||
$errors = libxml_get_errors();
|
||||
libxml_clear_errors();
|
||||
if ($errors) {
|
||||
throw new LibXMLException($errors);
|
||||
}
|
||||
throw new ParseException('This should never happen (famous last words)');
|
||||
}
|
||||
|
||||
$keepOnParsing = true;
|
||||
|
||||
while ($keepOnParsing) {
|
||||
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();
|
||||
$keepOnParsing = false;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (!is_null($elementMap)) {
|
||||
$this->popContext();
|
||||
}
|
||||
}
|
||||
|
||||
return $elements ? $elements : $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all text below the current element, and returns this as a string.
|
||||
*/
|
||||
public function readText(): string
|
||||
{
|
||||
$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.
|
||||
*/
|
||||
public function parseCurrentElement(): array
|
||||
{
|
||||
$name = $this->getClark();
|
||||
|
||||
$attributes = [];
|
||||
|
||||
if ($this->hasAttributes) {
|
||||
$attributes = $this->parseAttributes();
|
||||
}
|
||||
|
||||
$value = call_user_func(
|
||||
$this->getDeserializerForElementName((string) $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.
|
||||
*/
|
||||
public function parseAttributes(): array
|
||||
{
|
||||
$attributes = [];
|
||||
|
||||
while ($this->moveToNextAttribute()) {
|
||||
if ($this->namespaceURI) {
|
||||
// Ignoring 'xmlns', it doesn't make any sense.
|
||||
if ('http://www.w3.org/2000/xmlns/' === $this->namespaceURI) {
|
||||
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.
|
||||
*/
|
||||
public function getDeserializerForElementName(string $name): callable
|
||||
{
|
||||
if (!array_key_exists($name, $this->elementMap)) {
|
||||
if ('{}' == substr($name, 0, 2) && array_key_exists(substr($name, 2), $this->elementMap)) {
|
||||
$name = substr($name, 2);
|
||||
} else {
|
||||
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 ('string' === $type) {
|
||||
$type .= ' ('.$deserializer.')';
|
||||
} elseif ('object' === $type) {
|
||||
$type .= ' ('.get_class($deserializer).')';
|
||||
}
|
||||
throw new \LogicException('Could not use this type as a deserializer: '.$type.' for element: '.$name);
|
||||
}
|
||||
}
|
||||
208
vendor/sabre/xml/lib/Serializer/functions.php
vendored
Normal file
208
vendor/sabre/xml/lib/Serializer/functions.php
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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 string[] $values
|
||||
*/
|
||||
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 object $valueObject
|
||||
*/
|
||||
function valueObject(Writer $writer, $valueObject, string $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 (null !== $val) {
|
||||
$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');
|
||||
*/
|
||||
function repeatingElements(Writer $writer, array $items, string $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 string|int|float|bool|array|object $value
|
||||
*/
|
||||
function standardSerializer(Writer $writer, $value)
|
||||
{
|
||||
if (is_scalar($value)) {
|
||||
// String, integer, float, boolean
|
||||
$writer->text((string) $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_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));
|
||||
} elseif (!is_null($value)) {
|
||||
throw new InvalidArgumentException('The writer cannot serialize values of type: '.gettype($value));
|
||||
}
|
||||
}
|
||||
310
vendor/sabre/xml/lib/Service.php
vendored
Normal file
310
vendor/sabre/xml/lib/Service.php
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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 = [];
|
||||
|
||||
/**
|
||||
* A bitmask of the LIBXML_* constants.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $options = 0;
|
||||
|
||||
/**
|
||||
* Returns a fresh XML Reader.
|
||||
*/
|
||||
public function getReader(): Reader
|
||||
{
|
||||
$r = new Reader();
|
||||
$r->elementMap = $this->elementMap;
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fresh xml writer.
|
||||
*/
|
||||
public function getWriter(): Writer
|
||||
{
|
||||
$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
|
||||
*
|
||||
* @throws ParseException
|
||||
*
|
||||
* @return array|object|string
|
||||
*/
|
||||
public function parse($input, string $contextUri = null, string &$rootElementName = null)
|
||||
{
|
||||
if (is_resource($input)) {
|
||||
// Unfortunately the XMLReader doesn't support streams. When it
|
||||
// does, we can optimize this.
|
||||
$input = (string) stream_get_contents($input);
|
||||
|
||||
// If input is an empty string, then its safe to throw exception
|
||||
if ('' === $input) {
|
||||
throw new ParseException('The input element to parse is empty. Do not attempt to parse');
|
||||
}
|
||||
}
|
||||
$r = $this->getReader();
|
||||
$r->contextUri = $contextUri;
|
||||
$r->XML($input, null, $this->options);
|
||||
|
||||
$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
|
||||
*
|
||||
* @throws ParseException
|
||||
*
|
||||
* @return array|object|string
|
||||
*/
|
||||
public function expect($rootElementName, $input, string $contextUri = null)
|
||||
{
|
||||
if (is_resource($input)) {
|
||||
// Unfortunately the XMLReader doesn't support streams. When it
|
||||
// does, we can optimize this.
|
||||
$input = (string) stream_get_contents($input);
|
||||
|
||||
// If input is empty string, then its safe to throw exception
|
||||
if ('' === $input) {
|
||||
throw new ParseException('The input element to parse is empty. Do not attempt to parse');
|
||||
}
|
||||
}
|
||||
$r = $this->getReader();
|
||||
$r->contextUri = $contextUri;
|
||||
$r->XML($input, null, $this->options);
|
||||
|
||||
$rootElementName = (array) $rootElementName;
|
||||
|
||||
foreach ($rootElementName as &$rEl) {
|
||||
if ('{' !== $rEl[0]) {
|
||||
$rEl = '{}'.$rEl;
|
||||
}
|
||||
}
|
||||
|
||||
$result = $r->parse();
|
||||
if (!in_array($result['name'], $rootElementName, true)) {
|
||||
throw new ParseException('Expected '.implode(' or ', $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|array|object|XmlSerializable $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write(string $rootElementName, $value, string $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');
|
||||
*/
|
||||
public function mapValueObject(string $elementName, string $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
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function writeValueObject($object, string $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.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function parseClarkNotation(string $str): array
|
||||
{
|
||||
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 = [];
|
||||
}
|
||||
20
vendor/sabre/xml/lib/Version.php
vendored
Normal file
20
vendor/sabre/xml/lib/Version.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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 = '2.2.0';
|
||||
}
|
||||
257
vendor/sabre/xml/lib/Writer.php
vendored
Normal file
257
vendor/sabre/xml/lib/Writer.php
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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
|
||||
*/
|
||||
public 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">
|
||||
*
|
||||
* Note: this function doesn't have the string typehint, because PHP's
|
||||
* XMLWriter::startElement doesn't either.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function startElement($name): bool
|
||||
{
|
||||
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 || null === $namespace) {
|
||||
$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>
|
||||
*
|
||||
* Note: this function doesn't have the string typehint, because PHP's
|
||||
* XMLWriter::startElement doesn't either.
|
||||
*
|
||||
* @param array|string|object|null $content
|
||||
*/
|
||||
public function writeElement($name, $content = null): bool
|
||||
{
|
||||
$this->startElement($name);
|
||||
if (!is_null($content)) {
|
||||
$this->write($content);
|
||||
}
|
||||
$this->endElement();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public 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.
|
||||
*
|
||||
* Note: this function doesn't have typehints, because for some reason
|
||||
* PHP's XMLWriter::writeAttribute doesn't either.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public function writeAttribute($name, $value): bool
|
||||
{
|
||||
if ('{' !== $name[0]) {
|
||||
return parent::writeAttribute($name, $value);
|
||||
}
|
||||
|
||||
list(
|
||||
$namespace,
|
||||
$localName
|
||||
) = Service::parseClarkNotation($name);
|
||||
|
||||
if (array_key_exists($namespace, $this->namespaceMap)) {
|
||||
// It's an attribute with a namespace we know
|
||||
return $this->writeAttribute(
|
||||
$this->namespaceMap[$namespace].':'.$localName,
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
return $this->writeAttributeNS(
|
||||
$this->adhocNamespaces[$namespace],
|
||||
$localName,
|
||||
$namespace,
|
||||
$value
|
||||
);
|
||||
}
|
||||
}
|
||||
38
vendor/sabre/xml/lib/XmlDeserializable.php
vendored
Normal file
38
vendor/sabre/xml/lib/XmlDeserializable.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function xmlDeserialize(Reader $reader);
|
||||
}
|
||||
34
vendor/sabre/xml/lib/XmlSerializable.php
vendored
Normal file
34
vendor/sabre/xml/lib/XmlSerializable.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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.
|
||||
*/
|
||||
public function xmlSerialize(Writer $writer);
|
||||
}
|
||||
6
vendor/sabre/xml/phpstan.neon
vendored
Normal file
6
vendor/sabre/xml/phpstan.neon
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
parameters:
|
||||
level: 5
|
||||
ignoreErrors:
|
||||
-
|
||||
message: '!Parameter #3 \$uri of method XMLWriter::startElementNs\(\) expects string, null given.!'
|
||||
path: lib/Writer.php
|
||||
Reference in New Issue
Block a user