Completed
Push — master ( 141360...6dcb9d )
by Adam
03:25
created

Xml::convert()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 15
ccs 0
cts 15
cp 0
rs 9.2
cc 4
eloc 12
nc 4
nop 2
crap 20
1
<?php
2
3
namespace BestServedCold\PhalueObjects\Format;
4
5
use BestServedCold\PhalueObjects\Format;
6
7
final class Xml extends Format
8
{
9
    public function __construct($value)
10
    {
11
        parent::__construct($value);
12
        $domDocument = new \DOMDocument('1.0', 'UTF-8');
13
        $domDocument->formatOutput = true;
14
        $domDocument->encoding = 'UTF-8';
15
        $domDocument->loadXML($this->getValue());
16
        $this->value = $domDocument;
17
    }
18
19
    public function parse()
20
    {
21
        return [$this->getValue()->documentElement->tagName =>
22
            $this->parseElement($this->value->documentElement)];
23
    }
24
25
    public function parseElement($node, $output = [])
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
26
    {
27
        switch ($node->nodeType) {
28
            case XML_CDATA_SECTION_NODE:
29
                $output['@cdata'] = trim($node->textContent);
30
                break;
31
            case XML_TEXT_NODE:
32
                return trim($node->textContent);
33
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
34
            case XML_ELEMENT_NODE:
35
                return $this->elementNode($node);
36
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
37
        }
38
39
        return $output;
40
    }
41
42
    private function elementNode($node)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
43
    {
44
        $output = $this->childNode($node);
45
        $output = $this->addChildNodes($output);
46
        return $this->attributes($node, $output);
47
    }
48
49
    private function childNode($node, $output = [])
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
50
    {
51
        foreach ($node->childNodes as $child) {
52
            $children = $this->parseElement($child);
53
54
            if (isset($child->tagName)) {
55
                $tagName = $child->tagName;
56
                $output[$tagName] = isset($output[$tagName])
57
                    ? $output[$tagName]
58
                    : [];
59
                $output[$tagName][] = $children;
60
            } elseif ($children !== '') {
61
                $output = $children;
62
            }
63
        }
64
        return $output;
65
    }
66
67
    private function loopAttributes($attributes, $array = [])
68
    {
69
        // Loop through the attributes and collect them.
70
        foreach ($attributes as $key => $node) {
71
            $array[$key] = (string) $node->value;
72
        }
73
74
        return $array;
75
    }
76
77
    private function attributes($node, $output)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
78
    {
79
        // If there are attributes.
80
        if ($node->attributes->length) {
81
            $output = is_array($output) ? $output : ['@value' => $output];
82
            $output['@attributes'] = $this->loopAttributes($node->attributes);
83
        }
84
        return $output;
85
    }
86
87
    private function addChildNodes($output)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
88
    {
89
        if (is_array($output)) {
90
            foreach ($output as $key => $value) {
91
                $output[$key] = is_array($value) && count($value) === 1
92
                    ? $value[0]
93
                    : $value;
94
            }
95
            $output = !isset($output) || empty($output) ? '' : $output;
96
        }
97
98
        return $output;
99
    }
100
}
101