pax_global_header 0000666 0000000 0000000 00000000064 12660207703 0014515 g ustar 00root root 0000000 0000000 52 comment=fb07d78e232ec37f5760f579e15694d150ff0da6
sabre-xml-1.4.0/ 0000775 0000000 0000000 00000000000 12660207703 0013411 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/.gitignore 0000664 0000000 0000000 00000000153 12660207703 0015400 0 ustar 00root root 0000000 0000000 vendor
composer.lock
tests/cov
.*.swp
# Composer binaries
bin/phpunit
bin/php-cs-fixer
bin/sabre-cs-fixer
sabre-xml-1.4.0/.travis.yml 0000664 0000000 0000000 00000000406 12660207703 0015522 0 ustar 00root root 0000000 0000000 language: php
php:
- 5.4
- 5.5
- 5.6
- 7
- hhvm
matrix:
fast_finish: true
sudo: false
cache: vendor
script:
- ./bin/phpunit --configuration tests/phpunit.xml.dist
- ./bin/sabre-cs-fixer fix . --dry-run --diff
before_script: composer install
sabre-xml-1.4.0/CHANGELOG.md 0000664 0000000 0000000 00000014110 12660207703 0015217 0 ustar 00root root 0000000 0000000 ChangeLog
=========
1.4.0 (2016-02-14)
------------------
* Any array thrown into the serializer with numeric keys is now simply
traversed and each individual item is serialized. This fixes an issue
related to serializing value objects with array children.
* When serializing value objects, properties that have a null value or an
empty array are now skipped. We believe this to be the saner default, but
does constitute a BC break for those depending on this.
* Serializing array properties in value objects was broken.
1.3.0 (2015-12-29)
------------------
* The `Service` class adds a new `mapValueObject` method which provides basic
capabilities to map between ValueObjects and XML.
* #61: You can now specify serializers for specific classes, allowing you
separate the object you want to serialize from the serializer. This uses the
`$classMap` property which is defined on both the `Service` and `Writer`.
* It's now possible to pass an array of possible root elements to
`Sabre\Xml\Service::expect()`.
* Moved some parsing logic to `Reader::getDeserializerForElementName()`,
so people with more advanced use-cases can implement their own logic there.
* #63: When serializing elements using arrays, the `value` key in the array is
now optional.
* #62: Added a `keyValue` deserializer function. This can be used instead of
the `Element\KeyValue` class and is a lot more flexible. (@staabm)
* Also added an `enum` deserializer function to replace
`Element\Elements`.
* Using an empty string for a namespace prefix now has the same effect as
`null`.
1.2.0 (2015-08-30)
------------------
* #53: Added `parseGetElements`, a function like `parseInnerTree`, except
that it always returns an array of elements, or an empty array.
1.1.0 (2015-06-29)
------------------
* #44, #45: Catching broken and invalid XML better and throwing
`Sabre\Xml\LibXMLException` whenever we encounter errors. (@stefanmajoor,
@DaanBiesterbos)
1.0.0 (2015-05-25)
------------------
* No functional changes since 0.4.3. Marking it as 1.0.0 as a promise for
API stability.
* Using php-cs-fixer for automated CS enforcement.
0.4.3 (2015-04-01)
-----------------
* Minor tweaks for the public release.
0.4.2 (2015-03-20)
------------------
* Removed `constants.php` again. They messed with PHPUnit and don't really
provide a great benefit.
* #41: Correctly handle self-closing xml elements.
0.4.1 (2015-03-19)
------------------
* #40: An element with an empty namespace (xmlns="") is not allowed to have a
prefix. This is now fixed.
0.4.0 (2015-03-18)
------------------
* Added `Sabre\Xml\Service`. This is intended as a simple way to centrally
configure xml applications and easily parse/write things from there. #35, #38.
* Renamed 'baseUri' to 'contextUri' everywhere.
* #36: Added a few convenience constants to `lib/constants.php`.
* `Sabre\Xml\Util::parseClarkNotation` is now in the `Sabre\Xml\Service` class.
0.3.1 (2015-02-08)
------------------
* Added `XmlDeserializable` to match `XmlSerializable`.
0.3.0 (2015-02-06)
------------------
* Added `$elementMap` argument to parseInnerTree, for quickly overriding
parsing rules within an element.
0.2.2 (2015-02-05)
------------------
* Now depends on sabre/uri 1.0.
0.2.1 (2014-12-17)
------------------
* LibXMLException now inherits from ParseException, so it's easy for users to
catch any exception thrown by the parser.
0.2.0 (2014-12-05)
------------------
* Major BC Break: method names for the Element interface have been renamed
from `serializeXml` and `deserializeXml` to `xmlSerialize` and
`xmlDeserialize`. This is so that it matches PHP's `JsonSerializable`
interface.
* #25: Added `XmlSerializable` to allow people to write serializers without
having to implement a deserializer in the same class.
* #26: Renamed the `Sabre\XML` namespace to `Sabre\Xml`. Due to composer magic
and the fact that PHP namespace are case-insensitive, this should not affect
anyone, unless you are doing exact string matches on class names.
* #23: It's not possible to automatically extract or serialize Xml fragments
from documents using `Sabre\Xml\Element\XmlFragment`.
0.1.0 (2014-11-24)
------------------
* #16: Added ability to override `elementMap`, `namespaceMap` and `baseUri` for
a fragment of a document during reading an writing using `pushContext` and
`popContext`.
* Removed: `Writer::$context` and `Reader::$context`.
* #15: Added `Reader::$baseUri` to match `Writer::$baseUri`.
* #20: Allow callbacks to be used instead of `Element` classes in the `Reader`.
* #25: Added `readText` to quickly grab all text from a node and advance the
reader to the next node.
* #15: Added `Sabre\XML\Element\Uri`.
0.0.6 (2014-09-26)
------------------
* Added: `CData` element.
* #13: Better support for xml with no namespaces. (@kalmas)
* Switched to PSR-4 directory structure.
0.0.5 (2013-03-27)
------------------
* Added: baseUri property to the Writer class.
* Added: The writeElement method can now write complex elements.
* Added: Throwing exception when invalid objects are written.
0.0.4 (2013-03-14)
------------------
* Fixed: The KeyValue parser was skipping over elements when there was no
whitespace between them.
* Fixed: Clearing libxml errors after parsing.
* Added: Support for CDATA.
* Added: Context properties.
0.0.3 (2013-02-22)
------------------
* Changed: Reader::parse returns an array with 1 level less depth.
* Added: A LibXMLException is now thrown if the XMLReader comes across an error.
* Fixed: Both the Elements and KeyValue parsers had severe issues with
nesting.
* Fixed: The reader now detects when the end of the document is hit before it
should (because we're still parsing an element).
0.0.2 (2013-02-17)
------------------
* Added: Elements parser.
* Added: KeyValue parser.
* Change: Reader::parseSubTree is now named parseInnerTree, and returns either
a string (in case of a text-node), or an array (in case there were child
elements).
* Added: Reader::parseCurrentElement is now public.
0.0.1 (2013-02-07)
------------------
* First alpha release
Project started: 2012-11-13. First experiments in June 2009.
sabre-xml-1.4.0/LICENSE 0000664 0000000 0000000 00000003041 12660207703 0014414 0 ustar 00root root 0000000 0000000 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.
sabre-xml-1.4.0/README.md 0000664 0000000 0000000 00000001274 12660207703 0014674 0 ustar 00root root 0000000 0000000 sabre/xml
=========
[](http://travis-ci.org/fruux/sabre-xml)
The sabre/xml library is a specialized XML reader and writer.
Documentation
-------------
* [Introduction](http://sabre.io/xml/).
* [Installation](http://sabre.io/xml/install/).
* [Reading XML](http://sabre.io/xml/reading/).
* [Writing XML](http://sabre.io/xml/writing/).
Support
-------
Head over to the [SabreDAV mailing list](http://groups.google.com/group/sabredav-discuss) for any questions.
Made at fruux
-------------
This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support.
sabre-xml-1.4.0/bin/ 0000775 0000000 0000000 00000000000 12660207703 0014161 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/bin/.empty 0000664 0000000 0000000 00000000000 12660207703 0015306 0 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/composer.json 0000664 0000000 0000000 00000002427 12660207703 0016140 0 ustar 00root root 0000000 0000000 {
"name": "sabre/xml",
"description" : "sabre/xml is an XML library that you may not hate.",
"keywords" : [ "XML", "XMLReader", "XMLWriter", "DOM" ],
"homepage" : "https://sabre.io/xml/",
"license" : "BSD-3-Clause",
"require" : {
"php" : ">=5.4.1",
"ext-xmlwriter" : "*",
"ext-xmlreader" : "*",
"ext-dom" : "*",
"lib-libxml" : ">=2.6.20",
"sabre/uri" : "~1.0"
},
"authors" : [
{
"name" : "Evert Pot",
"email" : "me@evertpot.com",
"homepage" : "http://evertpot.com/",
"role" : "Developer"
},
{
"name": "Markus Staab",
"email": "markus.staab@redaxo.de",
"role" : "Developer"
}
],
"support" : {
"forum" : "https://groups.google.com/group/sabredav-discuss",
"source" : "https://github.com/fruux/sabre-xml"
},
"autoload" : {
"psr-4" : {
"Sabre\\Xml\\" : "lib/"
},
"files": [
"lib/Deserializer/functions.php",
"lib/Serializer/functions.php"
]
},
"bin" : [
],
"require-dev": {
"sabre/cs": "~0.0.2",
"phpunit/phpunit" : "*"
},
"config" : {
"bin-dir" : "bin/"
}
}
sabre-xml-1.4.0/lib/ 0000775 0000000 0000000 00000000000 12660207703 0014157 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/lib/ContextStackTrait.php 0000664 0000000 0000000 00000006343 12660207703 0020314 0 ustar 00root root 0000000 0000000 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);
}
}
sabre-xml-1.4.0/lib/Deserializer/ 0000775 0000000 0000000 00000000000 12660207703 0016601 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/lib/Deserializer/functions.php 0000664 0000000 0000000 00000014150 12660207703 0021323 0 ustar 00root root 0000000 0000000 value" array.
*
* For example, keyvalue will parse:
*
*
*
* value1
* value2
*
*
*
* 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:
*
*
*
*
*
*
* content
*
*
*
* 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:
*
*
* ...
* ...
* ...
*
*
* 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;
}
sabre-xml-1.4.0/lib/Element.php 0000664 0000000 0000000 00000001014 12660207703 0016255 0 ustar 00root root 0000000 0000000 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;
}
}
sabre-xml-1.4.0/lib/Element/Cdata.php 0000664 0000000 0000000 00000002761 12660207703 0017303 0 ustar 00root root 0000000 0000000 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);
}
}
sabre-xml-1.4.0/lib/Element/Elements.php 0000664 0000000 0000000 00000005320 12660207703 0020035 0 ustar 00root root 0000000 0000000
*
*
*
*
* content
*
*
*
* 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);
}
}
sabre-xml-1.4.0/lib/Element/KeyValue.php 0000664 0000000 0000000 00000005437 12660207703 0020017 0 ustar 00root root 0000000 0000000 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:
*
*
*
* value1
* value2
*
*
*
* 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);
}
}
sabre-xml-1.4.0/lib/Element/Uri.php 0000664 0000000 0000000 00000005264 12660207703 0017027 0 ustar 00root root 0000000 0000000 /foo/bar
* http://example.org/hi
*
* 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()
)
);
}
}
sabre-xml-1.4.0/lib/Element/XmlFragment.php 0000664 0000000 0000000 00000010136 12660207703 0020506 0 ustar 00root root 0000000 0000000 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 = <<{$this->getXml()}
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;
}
}
sabre-xml-1.4.0/lib/LibXMLException.php 0000664 0000000 0000000 00000002235 12660207703 0017640 0 ustar 00root root 0000000 0000000 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;
}
}
sabre-xml-1.4.0/lib/ParseException.php 0000664 0000000 0000000 00000000541 12660207703 0017621 0 ustar 00root root 0000000 0000000 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);
}
}
sabre-xml-1.4.0/lib/Serializer/ 0000775 0000000 0000000 00000000000 12660207703 0016270 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/lib/Serializer/functions.php 0000664 0000000 0000000 00000016015 12660207703 0021014 0 ustar 00root root 0000000 0000000
*
*
* content
*
*
* @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:
*
*
* ...
* ...
* ...
*
*
* 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:
*
*
* ...
*
*
* ...
*
*
* 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));
}
}
sabre-xml-1.4.0/lib/Service.php 0000664 0000000 0000000 00000021223 12660207703 0016270 0 ustar 00root root 0000000 0000000 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:
*
*
* ...
* ...
*
*
* 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) {
if (!preg_match('/^{([^}]*)}(.*)$/', $str, $matches)) {
throw new \InvalidArgumentException('\'' . $str . '\' is not a valid clark-notation formatted string');
}
return [
$matches[1],
$matches[2]
];
}
/**
* A list of classes and which XML elements they map to.
*/
protected $valueObjectMap = [];
}
sabre-xml-1.4.0/lib/Version.php 0000664 0000000 0000000 00000000530 12660207703 0016313 0 ustar 00root root 0000000 0000000 "..",
* "{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:
*
*
*
* @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:
*
*
* $writer->writeElement('{http://www.w3.org/2005/Atom}author', [
* '{http://www.w3.org/2005/Atom}name' => 'Evert Pot',
* ]);
* becomes:
* Evert Pot
*
* @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);
}
}
}
sabre-xml-1.4.0/lib/XmlDeserializable.php 0000664 0000000 0000000 00000002260 12660207703 0020270 0 ustar 00root root 0000000 0000000 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);
}
sabre-xml-1.4.0/lib/XmlSerializable.php 0000664 0000000 0000000 00000002003 12660207703 0017752 0 ustar 00root root 0000000 0000000 stack = $this->getMockForTrait('Sabre\\Xml\\ContextStackTrait');
}
function testPushAndPull() {
$this->stack->contextUri = '/foo/bar';
$this->stack->elementMap['{DAV:}foo'] = 'Bar';
$this->stack->namespaceMap['DAV:'] = 'd';
$this->stack->pushContext();
$this->assertEquals('/foo/bar', $this->stack->contextUri);
$this->assertEquals('Bar', $this->stack->elementMap['{DAV:}foo']);
$this->assertEquals('d', $this->stack->namespaceMap['DAV:']);
$this->stack->contextUri = '/gir/zim';
$this->stack->elementMap['{DAV:}foo'] = 'newBar';
$this->stack->namespaceMap['DAV:'] = 'dd';
$this->stack->popContext();
$this->assertEquals('/foo/bar', $this->stack->contextUri);
$this->assertEquals('Bar', $this->stack->elementMap['{DAV:}foo']);
$this->assertEquals('d', $this->stack->namespaceMap['DAV:']);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Deserializer/ 0000775 0000000 0000000 00000000000 12660207703 0020771 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/tests/Sabre/Xml/Deserializer/EnumTest.php 0000664 0000000 0000000 00000002043 12660207703 0023245 0 ustar 00root root 0000000 0000000 elementMap['{urn:test}root'] = 'Sabre\Xml\Deserializer\enum';
$xml = <<
XML;
$result = $service->parse($xml);
$expected = [
'{urn:test}foo1',
'{urn:test}foo2',
];
$this->assertEquals($expected, $result);
}
function testDeserializeDefaultNamespace() {
$service = new Service();
$service->elementMap['{urn:test}root'] = function($reader) {
return enum($reader, 'urn:test');
};
$xml = <<
XML;
$result = $service->parse($xml);
$expected = [
'foo1',
'foo2',
];
$this->assertEquals($expected, $result);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Deserializer/KeyValueTest.php 0000775 0000000 0000000 00000003536 12660207703 0024101 0 ustar 00root root 0000000 0000000
hifoofoo & bar
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}struct' => function(Reader $reader) {
return keyValue($reader, 'http://sabredav.org/ns');
}
];
$reader->xml($input);
$output = $reader->parse();
$this->assertEquals([
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}struct',
'value' => [
'elem1' => null,
'elem2' => 'hi',
'{http://sabredav.org/another-ns}elem3' => [
[
'name' => '{http://sabredav.org/another-ns}elem4',
'value' => 'foo',
'attributes' => [],
],
[
'name' => '{http://sabredav.org/another-ns}elem5',
'value' => 'foo & bar',
'attributes' => [],
],
]
],
'attributes' => [],
]
],
'attributes' => [],
], $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Deserializer/RepeatingElementsTest.php 0000664 0000000 0000000 00000001217 12660207703 0025756 0 ustar 00root root 0000000 0000000 elementMap['{urn:test}collection'] = function($reader) {
return repeatingElements($reader, '{urn:test}item');
};
$xml = <<foobar
XML;
$result = $service->parse($xml);
$expected = [
'foo',
'bar',
];
$this->assertEquals($expected, $result);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Deserializer/ValueObjectTest.php 0000664 0000000 0000000 00000007050 12660207703 0024547 0 ustar 00root root 0000000 0000000
HarryTurtle
XML;
$reader = new Reader();
$reader->xml($input);
$reader->elementMap = [
'{urn:foo}foo' => function(Reader $reader) {
return valueObject($reader, 'Sabre\\Xml\\Deserializer\\TestVo', 'urn:foo');
}
];
$output = $reader->parse();
$vo = new TestVo();
$vo->firstName = 'Harry';
$vo->lastName = 'Turtle';
$expected = [
'name' => '{urn:foo}foo',
'value' => $vo,
'attributes' => []
];
$this->assertEquals(
$expected,
$output
);
}
function testDeserializeValueObjectIgnoredElement() {
$input = <<HarryTurtleharry@example.org
XML;
$reader = new Reader();
$reader->xml($input);
$reader->elementMap = [
'{urn:foo}foo' => function(Reader $reader) {
return valueObject($reader, 'Sabre\\Xml\\Deserializer\\TestVo', 'urn:foo');
}
];
$output = $reader->parse();
$vo = new TestVo();
$vo->firstName = 'Harry';
$vo->lastName = 'Turtle';
$expected = [
'name' => '{urn:foo}foo',
'value' => $vo,
'attributes' => []
];
$this->assertEquals(
$expected,
$output
);
}
function testDeserializeValueObjectAutoArray() {
$input = <<HarryTurtle
http://example.org/
http://example.net/
XML;
$reader = new Reader();
$reader->xml($input);
$reader->elementMap = [
'{urn:foo}foo' => function(Reader $reader) {
return valueObject($reader, 'Sabre\\Xml\\Deserializer\\TestVo', 'urn:foo');
}
];
$output = $reader->parse();
$vo = new TestVo();
$vo->firstName = 'Harry';
$vo->lastName = 'Turtle';
$vo->link = [
'http://example.org/',
'http://example.net/',
];
$expected = [
'name' => '{urn:foo}foo',
'value' => $vo,
'attributes' => []
];
$this->assertEquals(
$expected,
$output
);
}
function testDeserializeValueObjectEmpty() {
$input = <<
XML;
$reader = new Reader();
$reader->xml($input);
$reader->elementMap = [
'{urn:foo}foo' => function(Reader $reader) {
return valueObject($reader, 'Sabre\\Xml\\Deserializer\\TestVo', 'urn:foo');
}
];
$output = $reader->parse();
$vo = new TestVo();
$expected = [
'name' => '{urn:foo}foo',
'value' => $vo,
'attributes' => []
];
$this->assertEquals(
$expected,
$output
);
}
}
class TestVo {
public $firstName;
public $lastName;
public $link = [];
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/ 0000775 0000000 0000000 00000000000 12660207703 0017740 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/tests/Sabre/Xml/Element/CDataTest.php 0000664 0000000 0000000 00000002207 12660207703 0022266 0 ustar 00root root 0000000 0000000
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}blabla' => 'Sabre\\Xml\\Element\\Cdata',
];
$reader->xml($input);
$output = $reader->parse();
}
function testSerialize() {
$writer = new Writer();
$writer->namespaceMap = [
'http://sabredav.org/ns' => null
];
$writer->openMemory();
$writer->startDocument('1.0');
$writer->setIndent(true);
$writer->write([
'{http://sabredav.org/ns}root' => new Cdata(''),
]);
$output = $writer->outputMemory();
$expected = <<]]>
XML;
$this->assertEquals($expected, $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/Eater.php 0000664 0000000 0000000 00000004260 12660207703 0021513 0 ustar 00root root 0000000 0000000 startElement('{http://sabredav.org/ns}elem1');
$writer->write('hiiii!');
$writer->endElement();
}
/**
* The deserialize method is called during xml parsing.
*
* This method is called statictly, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
* free to return other data as well.
*
* Important note 2: You are responsible for advancing the reader to the
* next element. Not doing anything will result in a never-ending loop.
*
* If you just want to skip parsing for this element altogether, you can
* just call $reader->next();
*
* $reader->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) {
$reader->next();
$count = 1;
while ($count) {
$reader->read();
if ($reader->nodeType === $reader::END_ELEMENT) {
$count--;
}
}
$reader->read();
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/ElementsTest.php 0000664 0000000 0000000 00000006634 12660207703 0023076 0 ustar 00root root 0000000 0000000
content
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}listThingy' => 'Sabre\\Xml\\Element\\Elements',
];
$reader->xml($input);
$output = $reader->parse();
$this->assertEquals([
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}listThingy',
'value' => [
'{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',
'{http://sabredav.org/ns}elem6',
],
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}listThingy',
'value' => [],
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}otherThing',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => null,
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}elem2',
'value' => null,
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}elem3',
'value' => null,
'attributes' => [],
],
],
'attributes' => [],
],
],
'attributes' => [],
], $output);
}
function testSerialize() {
$value = [
'{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',
'{http://sabredav.org/ns}elem6',
];
$writer = new Writer();
$writer->namespaceMap = [
'http://sabredav.org/ns' => null
];
$writer->openMemory();
$writer->startDocument('1.0');
$writer->setIndent(true);
$writer->write([
'{http://sabredav.org/ns}root' => new Elements($value),
]);
$output = $writer->outputMemory();
$expected = <<
XML;
$this->assertEquals($expected, $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/KeyValueTest.php 0000664 0000000 0000000 00000013327 12660207703 0023044 0 ustar 00root root 0000000 0000000
hifoofoo & barHithere
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}struct' => 'Sabre\\Xml\\Element\\KeyValue',
];
$reader->xml($input);
$output = $reader->parse();
$this->assertEquals([
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}struct',
'value' => [
'{http://sabredav.org/ns}elem1' => null,
'{http://sabredav.org/ns}elem2' => 'hi',
'{http://sabredav.org/ns}elem3' => [
[
'name' => '{http://sabredav.org/ns}elem4',
'value' => 'foo',
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}elem5',
'value' => 'foo & bar',
'attributes' => [],
],
],
'{http://sabredav.org/ns}elem6' => 'Hithere',
],
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}struct',
'value' => [],
'attributes' => [],
],
[
'name' => '{http://sabredav.org/ns}otherThing',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => null,
'attributes' => [],
],
],
'attributes' => [],
],
],
'attributes' => [],
], $output);
}
/**
* This test was added to find out why an element gets eaten by the
* SabreDAV MKCOL parser.
*/
function testElementEater() {
$input = <<bla
BLA;
$reader = new Reader();
$reader->elementMap = [
'{DAV:}set' => 'Sabre\\Xml\\Element\\KeyValue',
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
'{DAV:}resourcetype' => 'Sabre\\Xml\\Element\\Elements',
];
$reader->xml($input);
$expected = [
'name' => '{DAV:}mkcol',
'value' => [
[
'name' => '{DAV:}set',
'value' => [
'{DAV:}prop' => [
'{DAV:}resourcetype' => [
'{DAV:}collection',
],
'{DAV:}displayname' => 'bla',
],
],
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $reader->parse());
}
function testSerialize() {
$value = [
'{http://sabredav.org/ns}elem1' => null,
'{http://sabredav.org/ns}elem2' => 'textValue',
'{http://sabredav.org/ns}elem3' => [
'{http://sabredav.org/ns}elem4' => 'text2',
'{http://sabredav.org/ns}elem5' => null,
],
'{http://sabredav.org/ns}elem6' => 'text3',
];
$writer = new Writer();
$writer->namespaceMap = [
'http://sabredav.org/ns' => null
];
$writer->openMemory();
$writer->startDocument('1.0');
$writer->setIndent(true);
$writer->write([
'{http://sabredav.org/ns}root' => new KeyValue($value),
]);
$output = $writer->outputMemory();
$expected = <<textValuetext2text3
XML;
$this->assertEquals($expected, $output);
}
/**
* I discovered that when there's no whitespace between elements, elements
* can get skipped.
*/
function testElementSkipProblem() {
$input = <<val3val4val5
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}root' => 'Sabre\\Xml\\Element\\KeyValue',
];
$reader->xml($input);
$output = $reader->parse();
$this->assertEquals([
'name' => '{http://sabredav.org/ns}root',
'value' => [
'{http://sabredav.org/ns}elem3' => 'val3',
'{http://sabredav.org/ns}elem4' => 'val4',
'{http://sabredav.org/ns}elem5' => 'val5',
],
'attributes' => [],
], $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/Mock.php 0000664 0000000 0000000 00000003311 12660207703 0021340 0 ustar 00root root 0000000 0000000 startElement('{http://sabredav.org/ns}elem1');
$writer->write('hiiii!');
$writer->endElement();
}
/**
* The deserialize method is called during xml parsing.
*
* This method is called statictly, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
* free to return other data as well.
*
* Important note 2: You are responsible for advancing the reader to the
* next element. Not doing anything will result in a never-ending loop.
*
* If you just want to skip parsing for this element altogether, you can
* just call $reader->next();
*
* $reader->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) {
$reader->next();
return 'foobar';
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/UriTest.php 0000664 0000000 0000000 00000003342 12660207703 0022052 0 ustar 00root root 0000000 0000000
/foo/bar
BLA;
$reader = new Reader();
$reader->contextUri = 'http://example.org/';
$reader->elementMap = [
'{http://sabredav.org/ns}uri' => 'Sabre\\Xml\\Element\\Uri',
];
$reader->xml($input);
$output = $reader->parse();
$this->assertEquals(
[
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}uri',
'value' => new Uri('http://example.org/foo/bar'),
'attributes' => [],
]
],
'attributes' => [],
],
$output
);
}
function testSerialize() {
$writer = new Writer();
$writer->namespaceMap = [
'http://sabredav.org/ns' => null
];
$writer->openMemory();
$writer->startDocument('1.0');
$writer->setIndent(true);
$writer->contextUri = 'http://example.org/';
$writer->write([
'{http://sabredav.org/ns}root' => [
'{http://sabredav.org/ns}uri' => new Uri('/foo/bar'),
]
]);
$output = $writer->outputMemory();
$expected = <<http://example.org/foo/bar
XML;
$this->assertEquals($expected, $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Element/XmlFragmentTest.php 0000664 0000000 0000000 00000011173 12660207703 0023540 0 ustar 00root root 0000000 0000000
$input
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}fragment' => 'Sabre\\Xml\\Element\\XmlFragment',
];
$reader->xml($input);
$output = $reader->parse();
$this->assertEquals([
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}fragment',
'value' => new XmlFragment($expected),
'attributes' => [],
],
],
'attributes' => [],
], $output);
}
/**
* Data provider for serialize and deserialize tests.
*
* Returns three items per test:
*
* 1. Input data for the reader.
* 2. Expected output for XmlFragment deserializer
* 3. Expected output after serializing that value again.
*
* If 3 is not set, use 1 for 3.
*
* @return void
*/
function xmlProvider() {
return [
[
'hello',
'hello',
],
[
'hello',
'hello'
],
[
'hello',
'hello'
],
[
'hello',
'hello'
],
[
'hello',
'hello',
'hello',
],
[
'hello',
'hello',
'hello',
],
[
'hello',
'hello',
'hello',
],
[
'hello',
'hello',
'hello',
],
[
'',
'',
'',
],
[
'',
'',
'',
],
];
}
/**
* @dataProvider xmlProvider
*/
function testSerialize($expectedFallback, $input, $expected = null) {
if (is_null($expected)) {
$expected = $expectedFallback;
}
$writer = new Writer();
$writer->namespaceMap = [
'http://sabredav.org/ns' => null
];
$writer->openMemory();
$writer->startDocument('1.0');
//$writer->setIndent(true);
$writer->write([
'{http://sabredav.org/ns}root' => [
'{http://sabredav.org/ns}fragment' => new XmlFragment($input),
],
]);
$output = $writer->outputMemory();
$expected = <<$expected
XML;
$this->assertEquals($expected, $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/InfiteLoopTest.php 0000664 0000000 0000000 00000002373 12660207703 0021775 0 ustar 00root root 0000000 0000000
';
$reader = new Reader();
$reader->elementMap = [
'{DAV:}set' => 'Sabre\\Xml\\Element\\KeyValue',
];
$reader->xml($body);
$output = $reader->parse();
$this->assertEquals([
'name' => '{DAV:}propertyupdate',
'value' => [
[
'name' => '{DAV:}set',
'value' => [
'{DAV:}prop' => null,
],
'attributes' => [],
],
[
'name' => '{DAV:}set',
'value' => [
'{DAV:}prop' => null,
],
'attributes' => [],
],
],
'attributes' => [],
], $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/ReaderTest.php 0000664 0000000 0000000 00000030212 12660207703 0021120 0 ustar 00root root 0000000 0000000
BLA;
$reader = new Reader();
$reader->xml($input);
$reader->next();
$this->assertEquals('{http://sabredav.org/ns}root', $reader->getClark());
}
function testGetClarkNoNS() {
$input = <<
BLA;
$reader = new Reader();
$reader->xml($input);
$reader->next();
$this->assertEquals('{}root', $reader->getClark());
}
function testGetClarkNotOnAnElement() {
$input = <<
BLA;
$reader = new Reader();
$reader->xml($input);
$this->assertNull($reader->getClark());
}
function testSimple() {
$input = <<Hi!
BLA;
$reader = new Reader();
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => null,
'attributes' => [
'attr' => 'val',
],
],
[
'name' => '{http://sabredav.org/ns}elem2',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem3',
'value' => 'Hi!',
'attributes' => [],
],
],
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
function testCDATA() {
$input = <<
BLA;
$reader = new Reader();
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}foo',
'value' => 'bar',
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
function testSimpleNamespacedAttribute() {
$input = <<
BLA;
$reader = new Reader();
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => null,
'attributes' => [
'{urn:foo}attr' => 'val',
],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
function testMappedElement() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => 'Sabre\\Xml\\Element\\Mock'
];
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'foobar',
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
/**
* @expectedException \LogicException
*/
function testMappedElementBadClass() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => new \StdClass()
];
$reader->xml($input);
$reader->parse();
}
/**
* @depends testMappedElement
*/
function testMappedElementCallBack() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$reader->next();
return 'foobar';
}
];
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'foobar',
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
/**
* @depends testMappedElementCallBack
*/
function testReadText() {
$input = <<hello world
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => function(Reader $reader) {
return $reader->readText();
}
];
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'hello world',
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
function testParseProblem() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => 'Sabre\\Xml\\Element\\Mock'
];
$reader->xml($input);
try {
$output = $reader->parse();
$this->fail('We expected a ParseException to be thrown');
} catch (LibXMLException $e) {
$this->assertInternalType('array', $e->getErrors());
}
}
/**
* @expectedException \Sabre\Xml\ParseException
*/
function testBrokenParserClass() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => 'Sabre\\Xml\\Element\\Eater'
];
$reader->xml($input);
$reader->parse();
}
/**
* Test was added for Issue #10.
*
* @expectedException Sabre\Xml\LibXMLException
*/
function testBrokenXml() {
$input = <<
BLA;
$reader = new Reader();
$reader->xml($input);
$reader->parse();
}
/**
* Test was added for Issue #45.
*
* @expectedException Sabre\Xml\LibXMLException
*/
function testBrokenXml2() {
$input = <<
""Administrative w">
xml($input);
$reader->parse();
}
/**
* @depends testMappedElement
*/
function testParseInnerTree() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$innerTree = $reader->parseInnerTree(['{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$reader->next();
return "foobar";
}]);
return $innerTree;
}
];
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'foobar',
'attributes' => [],
]
],
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
/**
* @depends testParseInnerTree
*/
function testParseGetElements() {
$input = <<
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$innerTree = $reader->parseGetElements(['{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$reader->next();
return "foobar";
}]);
return $innerTree;
}
];
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'foobar',
'attributes' => [],
]
],
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
/**
* @depends testParseInnerTree
*/
function testParseGetElementsNoElements() {
$input = <<
hi
BLA;
$reader = new Reader();
$reader->elementMap = [
'{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$innerTree = $reader->parseGetElements(['{http://sabredav.org/ns}elem1' => function(Reader $reader) {
$reader->next();
return "foobar";
}]);
return $innerTree;
}
];
$reader->xml($input);
$output = $reader->parse();
$expected = [
'name' => '{http://sabredav.org/ns}root',
'value' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => [],
'attributes' => [],
],
],
'attributes' => [],
];
$this->assertEquals($expected, $output);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Serializer/ 0000775 0000000 0000000 00000000000 12660207703 0020460 5 ustar 00root root 0000000 0000000 sabre-xml-1.4.0/tests/Sabre/Xml/Serializer/EnumTest.php 0000664 0000000 0000000 00000001150 12660207703 0022732 0 ustar 00root root 0000000 0000000 namespaceMap['urn:test'] = null;
$xml = $service->write('{urn:test}root', function($writer) {
enum($writer, [
'{urn:test}foo1',
'{urn:test}foo2',
]);
});
$expected = <<
XML;
$this->assertXmlStringEqualsXmlString($expected, $xml);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/Serializer/RepeatingElementsTest.php 0000664 0000000 0000000 00000001241 12660207703 0025442 0 ustar 00root root 0000000 0000000 namespaceMap['urn:test'] = null;
$xml = $service->write('{urn:test}collection', function($writer) {
repeatingElements($writer, [
'foo',
'bar',
], '{urn:test}item');
});
$expected = <<foobar
XML;
$this->assertXmlStringEqualsXmlString($expected, $xml);
}
}
sabre-xml-1.4.0/tests/Sabre/Xml/ServiceTest.php 0000664 0000000 0000000 00000016427 12660207703 0021332 0 ustar 00root root 0000000 0000000 'Test!',
];
$util = new Service();
$util->elementMap = $elems;
$reader = $util->getReader();
$this->assertInstanceOf('Sabre\\Xml\\Reader', $reader);
$this->assertEquals($elems, $reader->elementMap);
}
function testGetWriter() {
$ns = [
'http://sabre.io/ns' => 's',
];
$util = new Service();
$util->namespaceMap = $ns;
$writer = $util->getWriter();
$this->assertInstanceOf('Sabre\\Xml\\Writer', $writer);
$this->assertEquals($ns, $writer->namespaceMap);
}
/**
* @depends testGetReader
*/
function testParse() {
$xml = <<value
XML;
$util = new Service();
$result = $util->parse($xml, null, $rootElement);
$this->assertEquals('{http://sabre.io/ns}root', $rootElement);
$expected = [
[
'name' => '{http://sabre.io/ns}child',
'value' => 'value',
'attributes' => [],
]
];
$this->assertEquals(
$expected,
$result
);
}
/**
* @depends testGetReader
*/
function testParseStream() {
$xml = <<value
XML;
$stream = fopen('php://memory', 'r+');
fwrite($stream, $xml);
rewind($stream);
$util = new Service();
$result = $util->parse($stream, null, $rootElement);
$this->assertEquals('{http://sabre.io/ns}root', $rootElement);
$expected = [
[
'name' => '{http://sabre.io/ns}child',
'value' => 'value',
'attributes' => [],
]
];
$this->assertEquals(
$expected,
$result
);
}
/**
* @depends testGetReader
*/
function testExpect() {
$xml = <<value
XML;
$util = new Service();
$result = $util->expect('{http://sabre.io/ns}root', $xml);
$expected = [
[
'name' => '{http://sabre.io/ns}child',
'value' => 'value',
'attributes' => [],
]
];
$this->assertEquals(
$expected,
$result
);
}
/**
* @depends testGetReader
*/
function testExpectStream() {
$xml = <<value
XML;
$stream = fopen('php://memory', 'r+');
fwrite($stream, $xml);
rewind($stream);
$util = new Service();
$result = $util->expect('{http://sabre.io/ns}root', $stream);
$expected = [
[
'name' => '{http://sabre.io/ns}child',
'value' => 'value',
'attributes' => [],
]
];
$this->assertEquals(
$expected,
$result
);
}
/**
* @depends testGetReader
* @expectedException \Sabre\Xml\ParseException
*/
function testExpectWrong() {
$xml = <<value
XML;
$util = new Service();
$util->expect('{http://sabre.io/ns}error', $xml);
}
/**
* @depends testGetWriter
*/
function testWrite() {
$util = new Service();
$util->namespaceMap = [
'http://sabre.io/ns' => 's',
];
$result = $util->write('{http://sabre.io/ns}root', [
'{http://sabre.io/ns}child' => 'value',
]);
$expected = <<value
XML;
$this->assertEquals(
$expected,
$result
);
}
function testMapValueObject() {
$input = <<123499.99black friday deal5
XML;
$ns = 'http://sabredav.org/ns';
$orderService = new \Sabre\Xml\Service();
$orderService->mapValueObject('{' . $ns . '}order', 'Sabre\Xml\Order');
$orderService->mapValueObject('{' . $ns . '}status', 'Sabre\Xml\OrderStatus');
$orderService->namespaceMap[$ns] = null;
$order = $orderService->parse($input);
$expected = new Order();
$expected->id = 1234;
$expected->amount = 99.99;
$expected->description = 'black friday deal';
$expected->status = new OrderStatus();
$expected->status->id = 5;
$expected->status->label = 'processed';
$this->assertEquals($expected, $order);
$writtenXml = $orderService->writeValueObject($order);
$this->assertEquals($input, $writtenXml);
}
function testMapValueObjectArrayProperty() {
$input = <<123499.99black friday deal5
http://example.org/
http://example.com/
XML;
$ns = 'http://sabredav.org/ns';
$orderService = new \Sabre\Xml\Service();
$orderService->mapValueObject('{' . $ns . '}order', 'Sabre\Xml\Order');
$orderService->mapValueObject('{' . $ns . '}status', 'Sabre\Xml\OrderStatus');
$orderService->namespaceMap[$ns] = null;
$order = $orderService->parse($input);
$expected = new Order();
$expected->id = 1234;
$expected->amount = 99.99;
$expected->description = 'black friday deal';
$expected->status = new OrderStatus();
$expected->status->id = 5;
$expected->status->label = 'processed';
$expected->link = ['http://example.org/', 'http://example.com/'];
$this->assertEquals($expected, $order);
$writtenXml = $orderService->writeValueObject($order);
$this->assertEquals($input, $writtenXml);
}
/**
* @expectedException \InvalidArgumentException
*/
function testWriteVoNotFound() {
$service = new Service();
$service->writeValueObject(new \StdClass());
}
function testParseClarkNotation() {
$this->assertEquals([
'http://sabredav.org/ns',
'elem',
], Service::parseClarkNotation('{http://sabredav.org/ns}elem'));
}
/**
* @expectedException \InvalidArgumentException
*/
function testParseClarkNotationFail() {
Service::parseClarkNotation('http://sabredav.org/ns}elem');
}
}
/**
* asset for testMapValueObject()
* @internal
*/
class Order {
public $id;
public $amount;
public $description;
public $status;
public $empty;
public $link = [];
}
/**
* asset for testMapValueObject()
* @internal
*/
class OrderStatus {
public $id;
public $label;
}
sabre-xml-1.4.0/tests/Sabre/Xml/WriterTest.php 0000664 0000000 0000000 00000022742 12660207703 0021203 0 ustar 00root root 0000000 0000000 writer = new Writer();
$this->writer->namespaceMap = [
'http://sabredav.org/ns' => 's',
];
$this->writer->openMemory();
$this->writer->setIndent(true);
$this->writer->startDocument();
}
function compare($input, $output) {
$this->writer->write($input);
$this->assertEquals($output, $this->writer->outputMemory());
}
function testSimple() {
$this->compare([
'{http://sabredav.org/ns}root' => 'text',
], <<text
HI
);
}
/**
* @depends testSimple
*/
function testSimpleQuotes() {
$this->compare([
'{http://sabredav.org/ns}root' => '"text"',
], <<"text"
HI
);
}
function testSimpleAttributes() {
$this->compare([
'{http://sabredav.org/ns}root' => [
'value' => 'text',
'attributes' => [
'attr1' => 'attribute value',
],
],
], <<text
HI
);
}
function testMixedSyntax() {
$this->compare([
'{http://sabredav.org/ns}root' => [
'{http://sabredav.org/ns}single' => 'value',
'{http://sabredav.org/ns}multiple' => [
[
'name' => '{http://sabredav.org/ns}foo',
'value' => 'bar',
],
[
'name' => '{http://sabredav.org/ns}foo',
'value' => 'foobar',
],
],
[
'name' => '{http://sabredav.org/ns}attributes',
'value' => null,
'attributes' => [
'foo' => 'bar',
],
],
[
'name' => '{http://sabredav.org/ns}verbose',
'value' => 'syntax',
'attributes' => [
'foo' => 'bar',
],
],
],
], <<valuebarfoobarsyntax
HI
);
}
function testNull() {
$this->compare([
'{http://sabredav.org/ns}root' => null,
], <<
HI
);
}
function testArrayFormat2() {
$this->compare([
'{http://sabredav.org/ns}root' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'text',
'attributes' => [
'attr1' => 'attribute value',
],
],
],
], <<text
HI
);
}
function testArrayOfValues() {
$this->compare([
'{http://sabredav.org/ns}root' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => [
'foo',
'bar',
'baz',
],
],
],
], <<foobarbaz
HI
);
}
/**
* @depends testArrayFormat2
*/
function testArrayFormat2NoValue() {
$this->compare([
'{http://sabredav.org/ns}root' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'attributes' => [
'attr1' => 'attribute value',
],
],
],
], <<
HI
);
}
function testCustomNamespace() {
$this->compare([
'{http://sabredav.org/ns}root' => [
'{urn:foo}elem1' => 'bar',
],
], <<bar
HI
);
}
function testEmptyNamespace() {
// Empty namespaces are allowed, so we should support this.
$this->compare([
'{http://sabredav.org/ns}root' => [
'{}elem1' => 'bar',
],
], <<bar
HI
);
}
function testAttributes() {
$this->compare([
'{http://sabredav.org/ns}root' => [
[
'name' => '{http://sabredav.org/ns}elem1',
'value' => 'text',
'attributes' => [
'attr1' => 'val1',
'{http://sabredav.org/ns}attr2' => 'val2',
'{urn:foo}attr3' => 'val3',
],
],
],
], <<text
HI
);
}
function testBaseElement() {
$this->compare([
'{http://sabredav.org/ns}root' => new Element\Base('hello')
], <<hello
HI
);
}
function testElementObj() {
$this->compare([
'{http://sabredav.org/ns}root' => new Element\Mock()
], <<hiiii!
HI
);
}
function testEmptyNamespacePrefix() {
$this->writer->namespaceMap['http://sabredav.org/ns'] = null;
$this->compare([
'{http://sabredav.org/ns}root' => new Element\Mock()
], <<hiiii!
HI
);
}
function testEmptyNamespacePrefixEmptyString() {
$this->writer->namespaceMap['http://sabredav.org/ns'] = '';
$this->compare([
'{http://sabredav.org/ns}root' => new Element\Mock()
], <<hiiii!
HI
);
}
function testWriteElement() {
$this->writer->writeElement("{http://sabredav.org/ns}foo", 'content');
$output = <<content
HI;
$this->assertEquals($output, $this->writer->outputMemory());
}
function testWriteElementComplex() {
$this->writer->writeElement("{http://sabredav.org/ns}foo", new Element\KeyValue(['{http://sabredav.org/ns}bar' => 'test']));
$output = <<test
HI;
$this->assertEquals($output, $this->writer->outputMemory());
}
/**
* @expectedException \InvalidArgumentException
*/
function testWriteBadObject() {
$this->writer->write(new \StdClass());
}
function testStartElementSimple() {
$this->writer->startElement("foo");
$this->writer->endElement();
$output = <<
HI;
$this->assertEquals($output, $this->writer->outputMemory());
}
function testCallback() {
$this->compare([
'{http://sabredav.org/ns}root' => function(Writer $writer) {
$writer->text('deferred writer');
},
], <<deferred writer
HI
);
}
/**
* @expectedException \InvalidArgumentException
*/
function testResource() {
$this->compare([
'{http://sabredav.org/ns}root' => fopen('php://memory', 'r'),
], <<deferred writer
HI
);
}
function testClassMap() {
$obj = (object)[
'key1' => 'value1',
'key2' => 'value2',
];
$this->writer->classMap['stdClass'] = function(Writer $writer, $value) {
foreach (get_object_vars($value) as $key => $val) {
$writer->writeElement('{http://sabredav.org/ns}' . $key, $val);
}
};
$this->compare([
'{http://sabredav.org/ns}root' => $obj
], <<value1value2
HI
);
}
}
sabre-xml-1.4.0/tests/bootstrap.php 0000664 0000000 0000000 00000000505 12660207703 0017301 0 ustar 00root root 0000000 0000000
sabre.io codesniffer ruleset
sabre-xml-1.4.0/tests/phpunit.xml.dist 0000664 0000000 0000000 00000000623 12660207703 0017727 0 ustar 00root root 0000000 0000000 Sabre/../lib/