Passed
Pull Request — master (#59)
by Raúl
04:04
created

XmlHandler::_future_serializeAsXml()   B

Complexity

Conditions 8
Paths 24

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 21
c 1
b 0
f 0
nc 24
nop 3
dl 0
loc 27
rs 8.4444
1
<?php
2
/**
3
 * Mime Type: application/xml
4
 *
5
 * @author Zack Douglas <[email protected]>
6
 * @author Nathan Good <[email protected]>
7
 */
8
9
namespace Httpful\Handlers;
10
11
class XmlHandler extends MimeHandlerAdapter
12
{
13
    /**
14
     *  @var string $namespace xml namespace to use with simple_load_string
15
     */
16
    private $namespace;
17
18
    /**
19
     * @var int $libxml_opts see http://www.php.net/manual/en/libxml.constants.php
20
     */
21
    private $libxml_opts;
22
23
    /**
24
     * @param array $conf sets configuration options
25
     */
26
    public function __construct(array $conf = array())
27
    {
28
        $this->namespace =      isset($conf['namespace']) ? $conf['namespace'] : '';
29
        $this->libxml_opts =    isset($conf['libxml_opts']) ? $conf['libxml_opts'] : 0;
30
    }
31
32
    /**
33
     * @param string $body
34
     * @return mixed
35
     * @throws \Exception if unable to parse
36
     */
37
    public function parse($body)
38
    {
39
        $body = $this->stripBom($body);
40
        if (empty($body))
41
            return null;
42
        $parsed = simplexml_load_string($body, null, $this->libxml_opts, $this->namespace);
43
        if ($parsed === false)
44
            throw new \Exception("Unable to parse response as XML");
45
        return $parsed;
46
    }
47
48
    /**
49
     * @param mixed $payload
50
     * @return string
51
     * @throws \Exception if unable to serialize
52
     */
53
    public function serialize($payload)
54
    {
55
        list($_, $dom) = $this->_future_serializeAsXml($payload);
56
        return $dom->saveXml();
57
    }
58
59
    /**
60
     * @param mixed $payload
61
     * @return string
62
     * @author Ted Zellers
63
     */
64
    public function serialize_clean($payload)
65
    {
66
        $xml = new \XMLWriter;
67
        $xml->openMemory();
68
        $xml->startDocument('1.0','ISO-8859-1');
69
        $this->serialize_node($xml, $payload);
70
        return $xml->outputMemory(true);
71
    }
72
73
    /**
74
     * @param \XMLWriter $xmlw
75
     * @param mixed $node to serialize
76
     * @author Ted Zellers
77
     */
78
    public function serialize_node(&$xmlw, $node){
79
        if (!is_array($node)){
80
            $xmlw->text($node);
81
        } else {
82
            foreach ($node as $k => $v){
83
                $xmlw->startElement($k);
84
                    $this->serialize_node($xmlw, $v);
85
                $xmlw->endElement();
86
            }
87
        }
88
    }
89
90
    /**
91
     * @author Zack Douglas <[email protected]>
92
     */
93
    private function _future_serializeAsXml($value, $node = null, $dom = null)
94
    {
95
        if (!$dom) {
96
            $dom = new \DOMDocument;
97
        }
98
        if (!$node) {
99
            if (!is_object($value)) {
100
                $node = $dom->createElement('response');
101
                $dom->appendChild($node);
102
            } else {
103
                $node = $dom;
104
            }
105
        }
106
        if (is_object($value)) {
107
            $objNode = $dom->createElement(get_class($value));
108
            $node->appendChild($objNode);
109
            $this->_future_serializeObjectAsXml($value, $objNode, $dom);
110
        } else if (is_array($value)) {
111
            $arrNode = $dom->createElement('array');
112
            $node->appendChild($arrNode);
113
            $this->_future_serializeArrayAsXml($value, $arrNode, $dom);
114
        } else if (is_bool($value)) {
115
            $node->appendChild($dom->createTextNode($value?'TRUE':'FALSE'));
116
        } else {
117
            $node->appendChild($dom->createTextNode($value));
118
        }
119
        return array($node, $dom);
120
    }
121
    /**
122
     * @author Zack Douglas <[email protected]>
123
     */
124
    private function _future_serializeArrayAsXml($value, &$parent, &$dom)
125
    {
126
        foreach ($value as $k => &$v) {
127
            $n = $k;
128
            if (is_numeric($k)) {
129
                $n = "child-{$n}";
130
            }
131
            $el = $dom->createElement($n);
132
            $parent->appendChild($el);
133
            $this->_future_serializeAsXml($v, $el, $dom);
134
        }
135
        return array($parent, $dom);
136
    }
137
    /**
138
     * @author Zack Douglas <[email protected]>
139
     */
140
    private function _future_serializeObjectAsXml($value, &$parent, &$dom)
141
    {
142
        $refl = new \ReflectionObject($value);
143
        foreach ($refl->getProperties() as $pr) {
144
            if (!$pr->isPrivate()) {
145
                $el = $dom->createElement($pr->getName());
146
                $parent->appendChild($el);
147
                $this->_future_serializeAsXml($pr->getValue($value), $el, $dom);
148
            }
149
        }
150
        return array($parent, $dom);
151
    }
152
}