Skip to content

Commit

Permalink
Add detection for toArray() method in Xml
Browse files Browse the repository at this point in the history
If values or parameters have `toArray()` use that method to convert the
value into an array. This lets ORM\ResultSet and ORM\Query objects to
interoperate with Xml. It also defines a simple duck type that userland
code can use.
  • Loading branch information
markstory committed May 21, 2014
1 parent a3404fa commit 699ce32
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
18 changes: 11 additions & 7 deletions src/Utility/Xml.php
@@ -1,9 +1,5 @@
<?php
/**
* XML handling for Cake.
*
* The methods in these classes enable the datasources that use XML to work.
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
Expand All @@ -18,6 +14,7 @@
*/
namespace Cake\Utility;

use Cake\Collection\Collection;
use Cake\Core\Configure;
use Cake\Network\Error\SocketException;
use Cake\Network\Http\Client;
Expand Down Expand Up @@ -94,7 +91,7 @@ public static function build($input, array $options = []) {
$options += $defaults;

if (is_array($input) || is_object($input)) {
return static::fromArray((array)$input, $options);
return static::fromArray($input, $options);
} elseif (strpos($input, '<') !== false) {
return static::_loadXml($input, $options);
} elseif (file_exists($input)) {
Expand Down Expand Up @@ -183,12 +180,15 @@ protected static function _loadXml($input, $options) {
*
* `<root><tag id="1" value="defect">description</tag></root>`
*
* @param array $input Array with data
* @param array|\Cake\Collection\Collection $input Array with data or a collection instance.
* @param string|array $options The options to use
* @return \SimpleXMLElement|\DOMDocument SimpleXMLElement or DOMDocument
* @throws \Cake\Utility\Error\XmlException
*/
public static function fromArray(array $input, $options = array()) {
public static function fromArray($input, $options = array()) {
if (method_exists($input, 'toArray')) {
$input = $input->toArray();
}
if (!is_array($input) || count($input) !== 1) {
throw new Error\XmlException('Invalid input.');
}
Expand Down Expand Up @@ -238,6 +238,10 @@ protected static function _fromArray($dom, $node, &$data, $format) {
}
foreach ($data as $key => $value) {
if (is_string($key)) {
if (method_exists($value, 'toArray')) {
$value = $value->toArray();
}

if (!is_array($value)) {
if (is_bool($value)) {
$value = (int)$value;
Expand Down
24 changes: 22 additions & 2 deletions tests/TestCase/Utility/XmlTest.php
@@ -1,7 +1,5 @@
<?php
/**
* XmlTest file
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
Expand All @@ -16,6 +14,7 @@
*/
namespace Cake\Test\TestCase\Utility;

use Cake\Collection\Collection;
use Cake\Core\Configure;
use Cake\TestSuite\TestCase;
use Cake\Utility\Error\XmlException;
Expand Down Expand Up @@ -111,6 +110,27 @@ public function testBuild() {
$this->assertNotRegExp('/encoding/', $obj->saveXML());
}

/**
* Test build() with a Collection instance.
*
* @return void
*/
public function testBuildCollection() {
$xml = new Collection(['tag' => 'value']);
$obj = Xml::build($xml);

$this->assertEquals('tag', $obj->getName());
$this->assertEquals('value', (string)$obj);

$xml = new Collection([
'response' => [
'users' => new Collection(['leonardo', 'raphael'])
]
]);
$obj = Xml::build($xml);
$this->assertContains('<users>leonardo</users>', $obj->saveXML());
}

/**
* data provider function for testBuildInvalidData
*
Expand Down

0 comments on commit 699ce32

Please sign in to comment.