Passed
Push — master ( 535426...920989 )
by Dominik
01:49
created

XmlTransformer::dataToNodes()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 17
cts 17
cp 1
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 19
nc 6
nop 3
crap 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Serialization\Transformer;
6
7
use Doctrine\Common\Inflector\Inflector;
8
9
final class XmlTransformer implements TransformerInterface
10
{
11
    /**
12
     * @var bool
13
     */
14
    private $formatOutput;
15
16
    /**
17
     * @var int
18
     */
19
    private $options;
20
21
    /**
22
     * @param bool $formatOutput
23
     * @param int  $options
24
     */
25 1
    public function __construct(bool $formatOutput = false, int $options = LIBXML_NOEMPTYTAG)
26
    {
27 1
        $this->formatOutput = $formatOutput;
28 1
        $this->options = $options;
29 1
    }
30
31
    /**
32
     * @param array $data
33
     *
34
     * @return string
35
     */
36 1
    public function transform(array $data): string
37
    {
38 1
        $document = new \DOMDocument('1.0', 'UTF-8');
39 1
        $document->formatOutput = $this->formatOutput;
40
41 1
        $responseNode = $document->createElement('response');
42
43 1
        $document->appendChild($responseNode);
44
45 1
        $this->dataToNodes($document, $responseNode, $data);
46
47 1
        return trim($document->saveXML(null, $this->options));
48
    }
49
50
    /**
51
     * @param \DOMDocument $document
52
     * @param \DOMNode     $listNode
53
     * @param array        $data
54
     */
55 1
    private function dataToNodes(\DOMDocument $document, \DOMNode $listNode, array $data)
56
    {
57 1
        foreach ($data as $key => $value) {
58 1
            if (is_array($value)) {
59 1
                $childNode = $document->createElement(is_int($key) ? Inflector::singularize($listNode->nodeName) : $key);
60 1
                $this->dataToNodes($document, $childNode, $value);
61
            } else {
62 1
                if (is_string($value)) {
63 1
                    if (strpos($value, '<') !== false || strpos($value, '&') !== false) {
64 1
                        $childNode = $document->createElement($key);
65 1
                        $childNode->appendChild($document->createCDATASection($value));
66
                    } else {
67 1
                        $childNode = $document->createElement($key, $value);
68
                    }
69 1
                    $childNode->setAttribute('type', 'string');
70 1
                } elseif (null === $value) {
71 1
                    $childNode = $document->createElement($key);
72
                } else {
73 1
                    $childNode = $document->createElement($key, $this->getValueAsString($value));
74 1
                    $childNode->setAttribute('type', $this->getType($value));
75
                }
76
            }
77
78 1
            $listNode->appendChild($childNode);
79
        }
80 1
    }
81
82
    /**
83
     * @param bool|float|int $value
84
     *
85
     * @return string|null
86
     *
87
     * @throws \InvalidArgumentException
88
     */
89 1
    private function getValueAsString($value): string
90
    {
91 1
        if (is_bool($value)) {
92 1
            return $value ? 'true' : 'false';
93
        }
94
95 1
        if (is_float($value) || is_int($value)) {
96 1
            return (string) $value;
97
        }
98
99
        throw new \InvalidArgumentException(sprintf('Unsupported data type: %s', gettype($value)));
100
    }
101
102
    /**
103
     * @param bool|float|int|string $value
104
     *
105
     * @return null|string
106
     */
107 1
    private function getType($value): string
108
    {
109 1
        if (is_bool($value)) {
110 1
            return 'boolean';
111
        }
112
113 1
        if (is_float($value)) {
114 1
            return 'float';
115
        }
116
117 1
        if (is_int($value)) {
118 1
            return 'integer';
119
        }
120
121
        if (is_string($value)) {
122
            return 'string';
123
        }
124
125
        throw new \InvalidArgumentException(sprintf('Unsupported data type: %s', gettype($value)));
126
    }
127
}
128