Completed
Push — master ( 02e9fb...917ed3 )
by Julián
01:24
created

Xml::simpleXML2Array()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 20
rs 9.2
cc 4
eloc 12
nc 4
nop 1
1
<?php
2
3
/*
4
 * body-parser (https://github.com/juliangut/body-parser).
5
 * PSR7 body parser middleware.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/body-parser
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
namespace Jgut\BodyParser\Decoder;
13
14
/**
15
 * XML request decoder.
16
 */
17
class Xml implements Decoder
18
{
19
    use MimeTypeTrait;
20
21
    /**
22
     * XML request decoder constructor.
23
     */
24
    public function __construct()
25
    {
26
        $this->addMimeType('application/xml');
27
        $this->addMimeType('text/xml');
28
        $this->addMimeType('application/x-xml');
29
    }
30
31
    /**
32
     * {@inheritdoc}
33
     *
34
     * @throws \RuntimeException
35
     */
36
    public function decode($rawBody)
37
    {
38
        if (trim($rawBody) === '') {
39
            return;
40
        }
41
42
        $disableEntityLoader = libxml_disable_entity_loader(true);
43
        $useInternalErrors = libxml_use_internal_errors(true);
44
45
        $parsedBody = simplexml_load_string(trim($rawBody));
46
47
        libxml_use_internal_errors($useInternalErrors);
48
        libxml_disable_entity_loader($disableEntityLoader);
49
50
        if ($parsedBody === false) {
51
            // @codeCoverageIgnoreStart
52
            $errors = array_map(
53
                function (\LibXMLError $error) {
54
                    return '"' . $error->message . '"';
55
                },
56
                libxml_get_errors()
57
            );
58
            // @codeCoverageIgnoreEnd
59
60
            libxml_clear_errors();
61
62
            throw new \RuntimeException(sprintf('XML request body parsing error: "%s"', implode(',', $errors)));
63
        }
64
65
        return $this->simpleXML2Array($parsedBody);
66
    }
67
68
    /**
69
     * Get array from SimpleXMLElement.
70
     *
71
     * @param \SimpleXMLElement $xml
72
     *
73
     * @return array
74
     */
75
    protected function simpleXML2Array(\SimpleXMLElement $xml)
76
    {
77
        $array = [];
78
79
        foreach ($xml as $element) {
80
            /* @var \SimpleXMLElement $element */
81
            $elementName = $element->getName();
82
            $elementVars = get_object_vars($element);
83
84
            if (!empty($elementVars)) {
85
                $array[$elementName] = $element instanceof \SimpleXMLElement
86
                    ? $this->simpleXML2Array($element)
87
                    : $elementVars;
88
            } else {
89
                $array[$elementName] = trim($element);
90
            }
91
        }
92
93
        return $array;
94
    }
95
}
96