Browse Source

Merge pull request #3542 from cakephp/issue-3538

3.0 Make Xml play nice with the new ORM
José Lorenzo Rodríguez 11 years ago
parent
commit
1232fd7bf4
2 changed files with 54 additions and 56 deletions
  1. 13 7
      src/Utility/Xml.php
  2. 41 49
      tests/TestCase/Utility/XmlTest.php

+ 13 - 7
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)
  *
@@ -94,7 +90,7 @@ class Xml {
 		$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)) {
@@ -183,12 +179,15 @@ class Xml {
  *
  * `<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.');
 		}
@@ -238,6 +237,10 @@ class Xml {
 		}
 		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;
@@ -298,6 +301,9 @@ class Xml {
 	protected static function _createChild($data) {
 		extract($data);
 		$childNS = $childValue = null;
+		if (method_exists($value, 'toArray')) {
+			$value = $value->toArray();
+		}
 		if (is_array($value)) {
 			if (isset($value['@'])) {
 				$childValue = (string)$value['@'];

+ 41 - 49
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)
  *
@@ -16,7 +14,9 @@
  */
 namespace Cake\Test\TestCase\Utility;
 
+use Cake\Collection\Collection;
 use Cake\Core\Configure;
+use Cake\ORM\Entity;
 use Cake\TestSuite\TestCase;
 use Cake\Utility\Error\XmlException;
 use Cake\Utility\Xml;
@@ -112,6 +112,45 @@ class XmlTest extends TestCase {
 	}
 
 /**
+ * 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());
+	}
+
+/**
+ * Test build() with ORM\Entity instances wrapped in a Collection.
+ *
+ * @return void
+ */
+	public function testBuildOrmEntity() {
+		$user = new Entity(['username' => 'mark', 'email' => 'mark@example.com']);
+		$xml = new Collection([
+			'response' => [
+				'users' => new Collection([$user])
+			]
+		]);
+		$obj = Xml::build($xml);
+		$output = $obj->saveXML();
+		$this->assertContains('<username>mark</username>', $output);
+		$this->assertContains('<email>mark@example.com</email>', $output);
+	}
+
+/**
  * data provider function for testBuildInvalidData
  *
  * @return array
@@ -1076,53 +1115,6 @@ XML;
 	}
 
 /**
- * testWithModel method
- *
- * @return void
- */
-	public function testWithModel() {
-		$this->markTestIncomplete('Models do not work right now');
-		$this->loadFixtures('User', 'Article');
-
-		$user = new XmlUser();
-		$data = $user->read(null, 1);
-
-		$obj = Xml::build(compact('data'));
-		$expected = <<<XML
-<?xml version="1.0" encoding="UTF-8"?><data>
-<User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
-<created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
-<Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
-<published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
-<Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
-<published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
-</data>
-XML;
-		$this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
-
-		//multiple model results - without a records key it would fatal error
-		$data = $user->find('all', array('limit' => 2));
-		$data = array('records' => $data);
-		$obj = Xml::build(compact('data'));
-		$expected = <<<XML
-<?xml version="1.0" encoding="UTF-8"?><data>
-<records>
-<User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
-<created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
-<Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
-<published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
-<Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
-<published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
-</records><records><User><id>2</id><user>nate</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
-<created>2007-03-17 01:18:23</created><updated>2007-03-17 01:20:31</updated></User><Article/>
-</records>
-</data>
-XML;
-		$obj->asXML();
-		$this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
-	}
-
-/**
  * Test ampersand in text elements.
  *
  * @return void