Passed
Push — master ( 0bdd13...9be812 )
by Andrew
02:06
created

XMLReaderElement::parseNameSpace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
namespace Sabre\Xml;
3
4
class XMLReaderElement implements \Iterator {
5
6
    protected $namespace;
7
    protected $name;
8
    protected $attributes;
9
    protected $value;
10
11
    public function rewind()
12
    {
13
        reset($this->value);
14
    }
15
16
    public function current()
17
    {
18
        return current($this->value);
19
    }
20
21
    public function key()
22
    {
23
        return key($this->value);
24
    }
25
26
    public function next()
27
    {
28
        return next($this->value);
29
    }
30
31
    public function valid()
32
    {
33
        $key = key($this->value);
34
        return ($key !== NULL && $key !== FALSE);
35
    }
36
37
    public function parse($data)
38
    {
39
        $this->parseNameSpace($data);
40
        $this->attributes = (object) $this->convertAttributes($data['attributes']);
41
42
        if ($this->isElementArray($data['value'])) {
43
            $this->value = [];
44
45
            foreach ($data['value'] as $value) {
46
                $this->value[] = (new XMLReaderElement())->parse($value);
47
            }
48
        } elseif ($this->isElementValue($data['value'])) {
49
            $this->value = $this->convertValue($data['value']);
50
        } else {
51
            $this->value = (new XMLReaderElement())->parse($data['value']);
52
        }
53
54
        return $this;
55
    }
56
57
    protected function isElementArray($value) {
58
        return is_array($value) && !array_key_exists('name', $value) && array_key_exists('name', current($value));
59
    }
60
61
    protected function isElementValue($value) {
62
        return !is_array($value) || !array_key_exists('name', $value);
63
    }
64
65
    protected function parseNameSpace($data) {
66
        $namespace = [];
67
        preg_match_all('/{(.*?)}/', $data['name'], $namespace);
68
69
        if (count($namespace) === 2) {
70
            $this->namespace = $namespace[1][0];
71
            $this->name      = str_replace($namespace[0][0], '', $data['name']);
72
        } else {
73
            $this->name      = $data['name'];
74
        }
75
    }
76
77
    protected function parseAttributes($data) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
78
79
    }
80
81
    protected function convertAttributes($attributes)
82
    {
83
        foreach($attributes as $k=>$attribute)
84
        {
85
            $attributes[$k] = $this->convertValue($attribute);
86
        }
87
88
        return $attributes;
89
    }
90
91
    protected function convertValue($value) {
92
        if (is_string($value))
93
        {
94
            if ($this->isBool($value))
95
            {
96
                return filter_var($value, FILTER_VALIDATE_BOOLEAN);
97
            }
98
99
            if ($this->isInteger($value))
100
            {
101
                return (int) $value;
102
            }
103
        }
104
        return $value;
105
    }
106
107
    /* Very specific type of integer checking to ensure
108
    that we have a number value, and not one that has been
109
    mistakenly casted by PHP. Examples below.
110
111
    var_dump(isInteger(23));    //bool(true)
112
    var_dump(isInteger("23"));  //bool(true)
113
    var_dump(isInteger(23.5));  //bool(false)
114
    var_dump(isInteger(NULL));  //bool(false)
115
    var_dump(isInteger(""));    //bool(false)
116
    */
117
    protected function isInteger($input)
118
    {
119
        return(ctype_digit(strval($input)));
120
    }
121
122
    /* Very specific type of boolean checking to ensure
123
    that we have a bool value, and not one that has been
124
    mistakenly casted by PHP. Examples below.
125
126
    var_dump(isBool(true));     //bool(true)
127
    var_dump(isBool("false"));  //bool(true)
128
    var_dump(isBool(0));        //bool(false)
129
    var_dump(isBool(NULL));     //bool(false)
130
    var_dump(isBool(""));       //bool(false)
131
    */
132
    protected function isBool($input)
133
    {
134
        return in_array(strtolower($input), ['true', 'false']) !== false;
135
    }
136
137
    public function children()
138
    {
139
        if ($this->value instanceof XMLReaderElement) {
140
            return [$this->value];
141
        }
142
143
        if (is_array($this->value)) {
144
            $results = [];
145
            foreach($this->value as $value) {
146
                if ($value instanceof XMLReaderElement &&
147
                                $this->namespace === $value->namespace) {
148
                    $results[] = $value;
149
                }
150
            }
151
            return $results;
152
        }
153
154
        return [];
155
    }
156
157
    public function findFirst($search)
158
    {
159
        return current($this->find($search));
160
    }
161
162
    public function find($search) {
163
164
        $results = [];
165
166
        if ($this->name == $search)
167
            $results[] = $this;
168
169
        foreach($this->children() as $child) {
170
            $results = array_merge($results, $child->find($search));
171
        }
172
173
        if ($search[0] == '@') {
174
            $search = substr($search, 1);
175
            if (property_exists($this->attributes, $search))
176
                $results[] = $this->attributes->$search;
177
        }
178
179
        return $results;
180
    }
181
182
    public function __get($name)
183
    {
184
        if (is_array($this->value))
185
        {
186
            foreach($this->value as $value)
187
            {
188
                if ($value instanceof XMLReaderElement && $value->name == $name)
189
                    return $value;
190
            }
191
        }
192
193
        return $this->$name;
194
    }
195
196
    public function __debugInfo() {
197
198
        $arr = ['name' => $this->name];
199
200
        if (!empty($this->namespace)) {
201
            $arr['namespace'] = $this->namespace;
202
        }
203
204
        if (!empty($this->attributes)) {
205
            $arr += ['attributes' => $this->attributes];
206
        }
207
208
        if (!empty($this->children())) {
209
            $names = [];
210
            foreach($this->children() as $child) {
211
                $names[] = $child->name;
212
            }
213
214
            $arr += ['children' => implode(',', $names)];
215
        } else {
216
            $arr += ['value' => $this->value];
217
        }
218
219
        return $arr;
220
    }
221
}
222