XmlTypeDecoder::decode()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 1
cts 1
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Deserialization\Decoder;
6
7
use Chubbyphp\Deserialization\DeserializerRuntimeException;
8
9
/**
10
 * @deprecated use JsonxTypeDecoder instead
11
 */
12
final class XmlTypeDecoder implements TypeDecoderInterface
13
{
14
    public function getContentType(): string
15
    {
16
        return 'application/xml';
17 2
    }
18
19 2
    /**
20
     * @throws DeserializerRuntimeException
21
     */
22
    public function decode(string $data): array
23
    {
24
        $document = new \DOMDocument();
25
26
        if (!@$document->loadXML($data)) {
27
            throw DeserializerRuntimeException::createNotParsable($this->getContentType());
28
        }
29 3
30
        return $this->transformType($document->getElementsByTagName('object')->item(0));
31 3
    }
32
33 3
    private function transformType(\DOMElement $node): array
34 1
    {
35
        $data = [];
36
37 2
        $childNodes = [];
38
        foreach ($node->childNodes as $childNode) {
39
            if ($childNode instanceof \DOMElement) {
40
                $childNodes[] = $childNode;
41
            }
42
        }
43
44
        foreach ($childNodes as $childNode) {
45 2
            if (0 === $childNode->childNodes->length) {
46
                $data[$this->getKey($childNode)] = null;
47 2
48
                continue;
49 2
            }
50 2
51 2
            if (1 === $childNode->childNodes->length) {
52 2
                $data[$this->getKey($childNode)] = $this->getValue($childNode);
53
54
                continue;
55
            }
56 2
57 2
            if ('object' === $childNode->nodeName
58 1
                && $childNode->hasAttribute('type')
59
                && !$childNode->hasAttribute('key')
60 1
            ) {
61
                return $this->transformType($childNode);
62
            }
63 2
64 2
            $data[$this->getKey($childNode)] = $this->transformType($childNode);
65
        }
66 2
67
        if ('object' === $node->nodeName && $node->hasAttribute('type')) {
68
            $data['_type'] = $node->getAttribute('type');
69 2
        }
70 2
71 2
        return $data;
72
    }
73 1
74
    /**
75
     * @return string|int
76 2
     */
77
    private function getKey(\DOMElement $node)
78
    {
79 2
        if ($node->hasAttribute('key')) {
80 2
            return (int) $node->getAttribute('key');
81
        }
82
83 2
        $name = $node->nodeName;
84
        if (0 === strpos($name, 'meta-')) {
85
            $name = '_'.substr($name, 5);
86
        }
87
88
        return $name;
89
    }
90
91 2
    /**
92
     * @return bool|string
93 2
     */
94 2
    private function getValue(\DOMElement $node)
95
    {
96
        $value = $node->nodeValue;
97 2
98 2
        if ('boolean' === $type = $node->getAttribute('type')) {
99 1
            return 'true' === $value;
100
        }
101
102 2
        settype($value, $type);
103
104
        return $value;
105
    }
106
}
107