Browse Source

Fixes #16285: Modified yii\web\XmlResponseFormatter to accept attributes for XML elements

3.0
Mahesh S Warrier 6 years ago committed by Alexander Makarov
parent
commit
f903fb2c0a
  1. 1
      framework/CHANGELOG.md
  2. 11
      framework/web/XmlResponseFormatter.php
  3. 2
      tests/framework/helpers/JsonTest.php
  4. 8
      tests/framework/web/JsonResponseFormatterTest.php
  5. 5
      tests/framework/web/Post.php
  6. 29
      tests/framework/web/XmlResponseFormatterTest.php

1
framework/CHANGELOG.md

@ -4,6 +4,7 @@ Yii Framework 2 Change Log
3.0.0 under development
-----------------------
- Enh #16285: Modified yii\web\XmlResponseFormatter to accept attributes for XML elements (codespede)
- Bug #16327: Fix getComposer() yii\BaseYii::createObject(null) BaseMailer (cjtterabyte)
- Bug #16065: Remove using `date.timezone` at `yii\base\Application`, use `date_default_timezone_get()` instead (sashsvamir)
- Bug #12539: `yii\filters\ContentNegotiator` now generates 406 'Not Acceptable' instead of 415 'Unsupported Media Type' on content-type negotiation fail (PowerGamer1)

11
framework/web/XmlResponseFormatter.php

@ -94,14 +94,21 @@ class XmlResponseFormatter extends Component implements ResponseFormatterInterfa
foreach ($data as $name => $value) {
if (is_int($name) && is_object($value)) {
$this->buildXml($element, $value);
} elseif (is_array($value) || is_object($value)) {
} elseif ((is_array($value) && !isset($value['xml-attributes'])) || is_object($value)) {
$child = new DOMElement($this->getValidXmlElementName($name));
$element->appendChild($child);
$this->buildXml($child, $value);
} else {
$child = new DOMElement($this->getValidXmlElementName($name));
$element->appendChild($child);
$child->appendChild(new DOMText($this->formatScalarValue($value)));
if(is_array($value) && isset($value['xml-attributes'])){
foreach($value['xml-attributes'] as $attribute => $val){
$child->setAttribute($attribute, $val);
}
$child->appendChild(new DOMText($this->formatScalarValue($value['value'])));
}else{
$child->appendChild(new DOMText($this->formatScalarValue($value)));
}
}
}
} elseif (is_object($data)) {

2
tests/framework/helpers/JsonTest.php

@ -151,7 +151,7 @@ class JsonTest extends TestCase
$postsStack->push(new Post(915, 'record1'));
$postsStack->push(new Post(456, 'record2'));
$this->assertSame('{"1":{"id":456,"title":"record2"},"0":{"id":915,"title":"record1"}}', Json::encode($postsStack));
$this->assertSame('{"1":{"id":456,"title":"record2","city":null},"0":{"id":915,"title":"record1","city":null}}', Json::encode($postsStack));
}
public function testDecode()

8
tests/framework/web/JsonResponseFormatterTest.php

@ -76,15 +76,15 @@ class JsonResponseFormatterTest extends FormatterTest
public function formatObjectDataProvider()
{
return [
[new Post(123, 'abc'), '{"id":123,"title":"abc"}'],
[new Post(123, 'abc'), '{"id":123,"title":"abc","city":null}'],
[[
new Post(123, 'abc'),
new Post(456, 'def'),
], '[{"id":123,"title":"abc"},{"id":456,"title":"def"}]'],
], '[{"id":123,"title":"abc","city":null},{"id":456,"title":"def","city":null}]'],
[[
new Post(123, '<>'),
'a' => new Post(456, 'def'),
], '{"0":{"id":123,"title":"<>"},"a":{"id":456,"title":"def"}}'],
], '{"0":{"id":123,"title":"<>","city":null},"a":{"id":456,"title":"def","city":null}}'],
];
}
@ -95,7 +95,7 @@ class JsonResponseFormatterTest extends FormatterTest
$postsStack->push(new Post(456, 'record2'));
return [
[$postsStack, '{"1":{"id":456,"title":"record2"},"0":{"id":915,"title":"record1"}}'],
[$postsStack, '{"1":{"id":456,"title":"record2","city":null},"0":{"id":915,"title":"record1","city":null}}'],
];
}

5
tests/framework/web/Post.php

@ -13,10 +13,13 @@ class Post extends BaseObject
{
public $id;
public $title;
public $city;
public function __construct($id, $title)
public function __construct($id, $title, $city = null)
{
$this->id = $id;
$this->title = $title;
if(!is_null($city))
$this->city = $city;
}
}

29
tests/framework/web/XmlResponseFormatterTest.php

@ -68,8 +68,15 @@ class XmlResponseFormatterTest extends FormatterTest
'a' => 1,
'b' => 'abc',
'c' => [2, '<>'],
'city' => [
'value' => 'New York',
'xml-attributes' => [
'type' => 'metropolitan',
'population' => '10000000'
]
],
false,
], "<response><a>1</a><b>abc</b><c><item>2</item><item>&lt;&gt;</item></c><item>false</item></response>\n"],
], "<response><a>1</a><b>abc</b><c><item>2</item><item>&lt;&gt;</item></c><city type=\"metropolitan\" population=\"10000000\">New York</city><item>false</item></response>\n"],
// Checks if empty keys and keys not valid in XML are processed.
// See https://github.com/yiisoft/yii2/pull/10346/
@ -89,12 +96,18 @@ class XmlResponseFormatterTest extends FormatterTest
$postsStack = new \SplStack();
$postsStack->push(new Post(915, 'record1'));
$expectedXmlForStack = '<Post><id>915</id><title>record1</title></Post>' .
$postsStack->push(new Post(915, 'record1', [
'value' => 'New York',
'xml-attributes' => [
'type' => 'metropolitan',
'population' => '10000000'
]
]));
$expectedXmlForStack = '<Post><id>915</id><title>record1</title><city type="metropolitan" population="10000000">New York</city></Post>' .
$expectedXmlForStack;
$postsStack->push(new Post(456, 'record2'));
$expectedXmlForStack = '<Post><id>456</id><title>record2</title></Post>' .
$expectedXmlForStack = '<Post><id>456</id><title>record2</title><city></city></Post>' .
$expectedXmlForStack;
$data = [
@ -107,15 +120,15 @@ class XmlResponseFormatterTest extends FormatterTest
public function formatObjectDataProvider()
{
return $this->addXmlHead([
[new Post(123, 'abc'), "<response><Post><id>123</id><title>abc</title></Post></response>\n"],
[new Post(123, 'abc'), "<response><Post><id>123</id><title>abc</title><city></city></Post></response>\n"],
[[
new Post(123, 'abc'),
new Post(456, 'def'),
], "<response><Post><id>123</id><title>abc</title></Post><Post><id>456</id><title>def</title></Post></response>\n"],
], "<response><Post><id>123</id><title>abc</title><city></city></Post><Post><id>456</id><title>def</title><city></city></Post></response>\n"],
[[
new Post(123, '<>'),
'a' => new Post(456, 'def'),
], "<response><Post><id>123</id><title>&lt;&gt;</title></Post><a><Post><id>456</id><title>def</title></Post></a></response>\n"],
], "<response><Post><id>123</id><title>&lt;&gt;</title><city></city></Post><a><Post><id>456</id><title>def</title><city></city></Post></a></response>\n"],
]);
}
@ -160,6 +173,6 @@ class XmlResponseFormatterTest extends FormatterTest
$this->response->data = new Post(123, 'abc');
$formatter->format($this->response);
$this->assertEquals($this->xmlHead . "<response><id>123</id><title>abc</title></response>\n", $this->response->content);
$this->assertEquals($this->xmlHead . "<response><id>123</id><title>abc</title><city></city></response>\n", $this->response->content);
}
}

Loading…
Cancel
Save