XmlTransformer::outputStrategy()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
rs 9.4286
cc 2
eloc 14
nc 2
nop 1
1
<?php
2
/**
3
 * Author: Nil Portugués Calderó <[email protected]>
4
 * Date: 25/12/15
5
 * Time: 22:27.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace NilPortugues\Api\Hal;
12
13
use DOMDocument;
14
use SimpleXMLElement;
15
16
/**
17
 * This Transformer follows the JSON+HAL specification.
18
 *
19
 * @link http://stateless.co/hal_specification.html
20
 */
21
class XmlTransformer extends JsonTransformer implements HalTransformer
22
{
23
    /**
24
     * @var array
25
     */
26
    private $linkKeys = [
27
        JsonTransformer::LINKS_HREF,
28
        JsonTransformer::LINKS_HREF_LANG_KEY,
29
        JsonTransformer::LINKS_TITLE_KEY,
30
        JsonTransformer::LINKS_TYPE_KEY,
31
    ];
32
33
    /**
34
     * @param mixed $data
35
     *
36
     * @return string
37
     */
38
    protected function outputStrategy(array &$data)
39
    {
40
        $xmlData = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><resource></resource>');
41
        $this->arrayToXml($data, $xmlData);
42
        if (!empty($data[JsonTransformer::LINKS_KEY][JsonTransformer::SELF_LINK][JsonTransformer::LINKS_HREF])) {
43
            $xmlData->addAttribute(
44
                JsonTransformer::LINKS_HREF,
45
                $data[JsonTransformer::LINKS_KEY][JsonTransformer::SELF_LINK][JsonTransformer::LINKS_HREF]
46
            );
47
        }
48
49
        $xml = $xmlData->asXML();
50
        $xmlDoc = new DOMDocument();
51
        $xmlDoc->loadXML($xml);
52
        $xmlDoc->preserveWhiteSpace = false;
53
        $xmlDoc->formatOutput = true;
54
        $xmlDoc->substituteEntities = false;
55
56
        return rtrim(html_entity_decode($xmlDoc->saveXML()), "\n");
57
    }
58
59
    /**
60
     * Converts an array to XML using SimpleXMLElement.
61
     *
62
     * @param array            $data
63
     * @param SimpleXMLElement $xmlData
64
     */
65
    private function arrayToXml(array &$data, SimpleXMLElement $xmlData)
66
    {
67
        foreach ($data as $key => $value) {
68
            $key = ltrim($key, '_');
69
70
            if (\is_array($value)) {
71
                if (\is_numeric($key)) {
72
                    $key = 'resource';
73
                }
74
75
                if (false === empty($value[JsonTransformer::LINKS_HREF])) {
76
                    $subnode = $xmlData->addChild('link');
77
                    $subnode->addAttribute('rel', $key);
78
79
                    foreach ($this->linkKeys as $linkKey) {
80
                        if (!empty($value[$linkKey])) {
81
                            $subnode->addAttribute($linkKey, $value[$linkKey]);
82
                        }
83
                    }
84
                } else {
85
                    if (!empty($value[JsonTransformer::LINKS_KEY][JsonTransformer::SELF_LINK][JsonTransformer::LINKS_HREF])) {
86
                        $subnode = $xmlData->addChild('resource');
87
                        $subnode->addAttribute(
88
                            JsonTransformer::LINKS_HREF,
89
                            $value[JsonTransformer::LINKS_KEY][JsonTransformer::SELF_LINK][JsonTransformer::LINKS_HREF]
90
                        );
91
92
                        if ($key !== 'resource') {
93
                            $subnode->addAttribute('rel', $key);
94
                        }
95
                    } else {
96
                        $subnode = $xmlData->addChild($key);
97
                    }
98
                }
99
100
                $this->arrayToXml($value, $subnode);
101
            } else {
102
                if ($key !== JsonTransformer::LINKS_HREF) {
103
                    if ($value === true || $value === false) {
104
                        $value = ($value)  ? 'true' : 'false';
105
                    }
106
107
                    $xmlData->addChild("$key", '<![CDATA['.html_entity_decode($value).']]>');
108
                }
109
            }
110
        }
111
    }
112
}
113