Done XML formatter

modifié:         core/lib/Thelia/Core/FileFormat/Formatting/Formatter/XMLFormatter.php
	modifié:         core/lib/Thelia/Tests/FileFormat/Formatting/Formatter/XMLFormatterTest.php
This commit is contained in:
Benjamin Perche
2014-07-18 12:32:36 +02:00
parent 32d8d2051d
commit 00ba277daa
2 changed files with 181 additions and 47 deletions

View File

@@ -11,6 +11,7 @@
/*************************************************************************************/
namespace Thelia\Core\FileFormat\Formatting\Formatter;
use Symfony\Component\DependencyInjection\SimpleXMLElement;
use Thelia\Core\FileFormat\Formatter\Exception\BadFormattedStringException;
use Thelia\Core\FileFormat\Formatting\AbstractFormatter;
use Thelia\Core\FileFormat\Formatting\FormatterData;
@@ -24,8 +25,8 @@ use Thelia\Core\FileFormat\FormatType;
class XMLFormatter extends AbstractFormatter
{
public $root = "data";
public $nodeName = "node";
public $rowName = "row";
public $nodeName = "entry";
/**
* @return string
@@ -83,7 +84,7 @@ class XMLFormatter extends AbstractFormatter
foreach ($arrayData as $key=>$entry) {
if (is_array($entry)) {
$node = $container->appendChild(new \DOMElement($this->nodeName));
$node = $container->appendChild(new \DOMElement($this->rowName));
$this->recursiveBuild($entry, $node);
} else {
$node = new \DOMElement($this->nodeName);
@@ -109,7 +110,7 @@ class XMLFormatter extends AbstractFormatter
$newNode = $node->appendChild(new \DOMElement($key));
$this->recursiveBuild($entry, $newNode);
} else {
$inputNode = new \DOMElement($this->rowName);
$inputNode = new \DOMElement($this->nodeName);
$node->appendChild($inputNode);
/** @var \DOMElement $lastChild */
@@ -128,9 +129,58 @@ class XMLFormatter extends AbstractFormatter
* a FormatterData object.
*/
public function decode($rawData)
{
$raw = $this->rawDecode($rawData);
return (new FormatterData())->setData($this->recursiveDecode($raw));
}
public function recursiveDecode(array &$data, array &$parent = null)
{
$row = [];
foreach ($data as $name => &$child) {
if (is_array($child)) {
$data = $this->recursiveDecode($child, $data);
}
if ($name === "name" || $name === "value") {
$row[$name] = $this->getValue($name, $data);
}
if (count($row) == 2) {
reset($parent);
if (is_int($key = key($parent))) {
$parent[$row["name"]] = $row["value"];
unset($parent[$key]);
} else {
$data[$row["name"]] = $row["value"];
}
$row=[];
}
}
return $parent === null ? $data : $parent;
}
public function getValue($name, array &$data) {
$value = $data[$name];
unset ($data[$name]);
return $value;
}
/**
* @param $rawData
* @return array
* @throws \Thelia\Core\FileFormat\Formatter\Exception\BadFormattedStringException
*/
public function rawDecode($rawData)
{
try {
$xml = new \SimpleXMLElement($rawData);
$xml = new SimpleXMLElement($rawData);
} catch (\Exception $e) {
$errorMessage = $this->translator->trans(
"You tried to load a bad formatted XML"
@@ -145,16 +195,40 @@ class XMLFormatter extends AbstractFormatter
);
}
$array = json_decode(json_encode($xml),true);
$array = [];
if (isset($array[$this->nodeName])) {
$array += $array[$this->nodeName];
unset($array[$this->nodeName]);
foreach ($xml->children() as $child) {
$this->recursiveRawDecode($array, $child);
}
$data = new FormatterData();
return $array;
}
return $data->setData($array);
protected function recursiveRawDecode(array &$data, \SimpleXMLElement $node)
{
if ($node->count()) {
if (!array_key_exists($node->getName(), $data)) {
$data[$node->getName()] = [];
}
$row = &$data[$node->getName()];
foreach ($node->children() as $child) {
$this->recursiveRawDecode($row, $child);
}
} else {
$newRow = array();
/** @var SimpleXMLElement $attribute */
foreach ($node->attributes() as $attribute) {
$newRow[$attribute->getName()] = $node->getAttributeAsPhp($attribute->getName());
}
if ($node->getName() === $this->nodeName) {
$data[] = $newRow;
} else {
$data[$node->getName()] = $newRow;
}
}
}
public function getHandledType()

View File

@@ -62,8 +62,15 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase
);
$dom = new \DOMDocument("1.0");
$dom->appendChild(new \DOMElement("data"))
->appendChild(new \DOMElement("foo", "bar"));
/** @var \DOMElement $node */
$node =$dom->appendChild(new \DOMElement($this->formatter->root))
->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "foo");
$node->setAttribute("value", "bar");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
@@ -76,7 +83,6 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase
public function testComplexEncode()
{
$data = new FormatterData();
$this->formatter->nodeName = "baz";
$data->setData(
[
@@ -97,18 +103,29 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase
);
$dom = new \DOMDocument("1.0");
$base = $dom->appendChild(new \DOMElement("data"));
$base->appendChild(new \DOMElement("foo", "bar"));
$base = $dom->appendChild(new \DOMElement($this->formatter->root));
/** @var \DOMElement $node */
$node = $base->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "foo");
$node->setAttribute("value", "bar");
$baz = $base->appendChild(new \DOMElement("baz"));
$baz->appendChild(new \DOMElement("name", "banana"));
$baz->appendChild(new \DOMElement("type", "fruit"));
$baz = $base->appendChild(new \DOMElement($this->formatter->rowName));
$node = $baz->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "name");
$node->setAttribute("value", "banana");
$node = $baz->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "type");
$node->setAttribute("value", "fruit");
$baz = $base->appendChild(new \DOMElement("baz"));
$baz = $base->appendChild(new \DOMElement($this->formatter->rowName));
$orange = $baz->appendChild(new \DOMElement("orange"));
$orange->appendChild(new \DOMElement("type","fruit"));
$node = $orange->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name","type");
$node->setAttribute("value","fruit");
$banana = $baz->appendChild(new \DOMElement("banana"));
$banana->appendChild(new \DOMElement("like", "Yes"));
$node = $banana->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "like");
$node->setAttribute("value", "Yes");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
@@ -122,8 +139,12 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase
public function testSimpleDecode()
{
$dom = new \DOMDocument("1.0");
$dom->appendChild(new \DOMElement("data"))
->appendChild(new \DOMElement("foo", "bar"));
$node =$dom->appendChild(new \DOMElement($this->formatter->root))
->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "foo");
$node->setAttribute("value", "bar");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
@@ -131,6 +152,8 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase
$data = $this->formatter->decode($raw);
var_dump($data->getData());
$this->assertEquals(["foo" => "bar"], $data->getData());
}
@@ -138,39 +161,76 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase
{
$expectedData =
[
"foo" => "bar",
[
"name" => "banana",
"type" => "fruit",
"name" => "foo",
"value" => "bar",
],
"row" => [
[
"name" => "fruit",
"value" => "banana",
],
[
"name" => "type",
"value" => "fruit",
],
"orange"=> [
[
"name" => "type",
"value" => "fruit",
]
],
"banana"=> [
[
"name" => "like",
"value" => "Yes",
]
]
]
];
$dom = new \DOMDocument("1.0");
$base = $dom->appendChild(new \DOMElement($this->formatter->root));
/** @var \DOMElement $node */
$node = $base->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "foo");
$node->setAttribute("value", "bar");
$baz = $base->appendChild(new \DOMElement($this->formatter->rowName));
$node = $baz->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "fruit");
$node->setAttribute("value", "banana");
$node = $baz->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "type");
$node->setAttribute("value", "fruit");
$baz = $base->appendChild(new \DOMElement($this->formatter->rowName));
$orange = $baz->appendChild(new \DOMElement("orange"));
$node = $orange->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name","type");
$node->setAttribute("value","fruit");
$banana = $baz->appendChild(new \DOMElement("banana"));
$node = $banana->appendChild(new \DOMElement($this->formatter->nodeName));
$node->setAttribute("name", "like");
$node->setAttribute("value", "Yes");
$data = $this->formatter->rawDecode($dom->saveXML());
$this->assertEquals($expectedData, $data);
$expectedData = [
"foo" => "bar",
"row" => [
"fruit" => "banana",
"type" => "fruit",
"orange"=>[
"type" => "fruit"
],
"banana"=>[
"like" => "Yes"
]
]
],
];
$dom = new \DOMDocument("1.0");
$base = $dom->appendChild(new \DOMElement("data"));
$base->appendChild(new \DOMElement("foo", "bar"));
$baz = $base->appendChild(new \DOMElement("baz"));
$baz->appendChild(new \DOMElement("name", "banana"));
$baz->appendChild(new \DOMElement("type", "fruit"));
$baz = $base->appendChild(new \DOMElement("baz"));
$orange = $baz->appendChild(new \DOMElement("orange"));
$orange->appendChild(new \DOMElement("type","fruit"));
$banana = $baz->appendChild(new \DOMElement("banana"));
$banana->appendChild(new \DOMElement("like", "Yes"));
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$this->formatter->nodeName = "baz";
$data = $this->formatter->decode($dom->saveXML());
$this->assertEquals($expectedData, $data->getData());