From 00ba277daa90ef53b34e59bdc5ecffbc4f4994a1 Mon Sep 17 00:00:00 2001 From: Benjamin Perche Date: Fri, 18 Jul 2014 12:32:36 +0200 Subject: [PATCH] =?UTF-8?q?Done=20XML=20formatter=20=09modifi=C3=A9:=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20core/lib/Thelia/Core/FileFormat/Formatting?= =?UTF-8?q?/Formatter/XMLFormatter.php=20=09modifi=C3=A9:=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20core/lib/Thelia/Tests/FileFormat/Formatting/Formatt?= =?UTF-8?q?er/XMLFormatterTest.php?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Formatting/Formatter/XMLFormatter.php | 94 ++++++++++-- .../Formatting/Formatter/XMLFormatterTest.php | 134 +++++++++++++----- 2 files changed, 181 insertions(+), 47 deletions(-) diff --git a/core/lib/Thelia/Core/FileFormat/Formatting/Formatter/XMLFormatter.php b/core/lib/Thelia/Core/FileFormat/Formatting/Formatter/XMLFormatter.php index e445e3b32..a6ce7c62c 100644 --- a/core/lib/Thelia/Core/FileFormat/Formatting/Formatter/XMLFormatter.php +++ b/core/lib/Thelia/Core/FileFormat/Formatting/Formatter/XMLFormatter.php @@ -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() diff --git a/core/lib/Thelia/Tests/FileFormat/Formatting/Formatter/XMLFormatterTest.php b/core/lib/Thelia/Tests/FileFormat/Formatting/Formatter/XMLFormatterTest.php index 2c34d6ebd..3823c0f62 100644 --- a/core/lib/Thelia/Tests/FileFormat/Formatting/Formatter/XMLFormatterTest.php +++ b/core/lib/Thelia/Tests/FileFormat/Formatting/Formatter/XMLFormatterTest.php @@ -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,46 +152,85 @@ class XMLFormatterTest extends \PHPUnit_Framework_TestCase $data = $this->formatter->decode($raw); + var_dump($data->getData()); + $this->assertEquals(["foo" => "bar"], $data->getData()); } public function testComplexDecode() { $expectedData = - [ + [ + [ + "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", - [ - "name" => "banana", + "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());