Completed
Push — master ( 0f1798...3080ff )
by Dominik
02:20
created

XmlTransformer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 1
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
        $this->dataToNodes($document, $document, $data);
42
43 1
        return trim($document->saveXML(null, $this->options));
44
    }
45
46
    /**
47
     * @param \DOMDocument $document
48
     * @param \DOMNode     $listNode
49
     * @param array        $data
50
     */
51 1
    private function dataToNodes(\DOMDocument $document, \DOMNode $listNode, array $data)
52
    {
53 1
        foreach ($data as $key => $value) {
54 1
            if (is_array($value)) {
55 1
                $childNode = $document->createElement(is_int($key) ? Inflector::singularize($listNode->nodeName) : $key);
56 1
                $this->dataToNodes($document, $childNode, $value);
57
            } else {
58 1
                if (is_string($value)) {
59 1
                    $childNode = $document->createElement($key);
60 1
                    $childNode->appendChild($document->createCDATASection($value));
61 1
                    $childNode->setAttribute('type', 'string');
62 1
                } elseif (null === $value) {
63 1
                    $childNode = $document->createElement($key);
64
                } else {
65 1
                    $childNode = $document->createElement($key, $this->getValueAsString($value));
66 1
                    $childNode->setAttribute('type', $this->getType($value));
67
                }
68
            }
69
70 1
            $listNode->appendChild($childNode);
71
        }
72 1
    }
73
74
    /**
75
     * @param bool|float|int $value
76
     *
77
     * @return string|null
78
     *
79
     * @throws \InvalidArgumentException
80
     */
81 1
    private function getValueAsString($value): string
82
    {
83 1
        if (is_bool($value)) {
84 1
            return $value ? 'true' : 'false';
85
        }
86
87 1
        if (is_float($value) || is_int($value)) {
88 1
            return (string) $value;
89
        }
90
91
        throw new \InvalidArgumentException(sprintf('Unsupported data type: %s', gettype($value)));
92
    }
93
94
    /**
95
     * @param bool|float|int|string $value
96
     *
97
     * @return null|string
98
     */
99 1
    private function getType($value): string
100
    {
101 1
        if (is_bool($value)) {
102 1
            return 'boolean';
103
        }
104
105 1
        if (is_float($value)) {
106 1
            return 'float';
107
        }
108
109 1
        if (is_int($value)) {
110 1
            return 'integer';
111
        }
112
113
        if (is_string($value)) {
114
            return 'string';
115
        }
116
117
        throw new \InvalidArgumentException(sprintf('Unsupported data type: %s', gettype($value)));
118
    }
119
}
120