Passed
Push — master ( aed6dd...0bdd13 )
by Andrew
03:37 queued 01:31
created

XMLReaderElement::filterNamespace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
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
        $namespace = [];
40
        preg_match_all('/{(.*?)}/', $data['name'], $namespace);
41
42
        if (count($namespace) === 2) {
43
            $this->namespace = $namespace[1][0];
44
            $this->name      = str_replace($namespace[0][0], '', $data['name']);
45
        } else {
46
            $this->name      = $data['name'];
47
        }
48
49
        $this->attributes = (object) $this->convertAttributes($data['attributes']);
50
        if (is_array($data['value']) && !array_key_exists('name', $data['value']) && array_key_exists('name', current($data['value']))) {
51
            $this->value = [];
52
            foreach ($data['value'] as $value) {
53
                $this->value[] = (new XMLReaderElement())->parse($value);
54
            }
55
            return $this;
56
        }
57
58
        if (!is_array($data['value']) || !array_key_exists('name', $data['value'])) {
59
            $this->value = $this->convertValue($data['value']);
60
            return $this;
61
        }
62
63
        $this->value = (new XMLReaderElement())->parse($data['value']);
64
65
        return $this;
66
    }
67
68
    protected function convertAttributes($attributes)
69
    {
70
        foreach($attributes as $k=>$attribute)
71
        {
72
            $attributes[$k] = $this->convertValue($attribute);
73
        }
74
75
        return $attributes;
76
    }
77
78
    protected function convertValue($value) {
79
        if (is_string($value))
80
        {
81
            if ($this->isBool($value))
82
            {
83
                return filter_var($value, FILTER_VALIDATE_BOOLEAN);
84
            }
85
86
            if ($this->isInteger($value))
87
            {
88
                return (int) $value;
89
            }
90
        }
91
        return $value;
92
    }
93
94
    /* Very specific type of integer checking to ensure
95
    that we have a number value, and not one that has been
96
    mistakenly casted by PHP. Examples below.
97
98
    var_dump(isInteger(23));    //bool(true)
99
    var_dump(isInteger("23"));  //bool(true)
100
    var_dump(isInteger(23.5));  //bool(false)
101
    var_dump(isInteger(NULL));  //bool(false)
102
    var_dump(isInteger(""));    //bool(false)
103
    */
104
    protected function isInteger($input)
105
    {
106
        return(ctype_digit(strval($input)));
107
    }
108
109
    /* Very specific type of boolean checking to ensure
110
    that we have a bool value, and not one that has been
111
    mistakenly casted by PHP. Examples below.
112
113
    var_dump(isBool(true));     //bool(true)
114
    var_dump(isBool("false"));  //bool(true)
115
    var_dump(isBool(0));        //bool(false)
116
    var_dump(isBool(NULL));     //bool(false)
117
    var_dump(isBool(""));       //bool(false)
118
    */
119
    protected function isBool($input)
120
    {
121
        return in_array(strtolower($input), ['true', 'false']) !== false;
122
    }
123
124
    public function children()
125
    {
126
        if ($this->value instanceof XMLReaderElement) {
127
            return [$this->value];
128
        }
129
130
        if (is_array($this->value)) {
131
            $results = [];
132
            foreach($this->value as $value) {
133
                if ($value instanceof XMLReaderElement &&
134
                                $this->namespace === $value->namespace) {
135
                    $results[] = $value;
136
                }
137
            }
138
            return $results;
139
        }
140
141
        return [];
142
    }
143
144
    public function findFirst($search)
145
    {
146
        return current($this->find($search));
147
    }
148
149
    public function find($search) {
150
151
        $results = [];
152
153
        if ($this->name == $search)
154
            $results[] = $this;
155
156
        foreach($this->children() as $child) {
157
            $results = array_merge($results, $child->find($search));
158
        }
159
160
        if ($search[0] == '@') {
161
            $search = substr($search, 1);
162
            if (property_exists($this->attributes, $search))
163
                $results[] = $this->attributes->$search;
164
        }
165
166
        return $results;
167
    }
168
169
    public function __get($name)
170
    {
171
        if (is_array($this->value))
172
        {
173
            foreach($this->value as $value)
174
            {
175
                if ($value instanceof XMLReaderElement && $value->name == $name)
176
                    return $value;
177
            }
178
        }
179
180
        return $this->$name;
181
    }
182
183
    public function __debugInfo() {
184
185
        $arr = ['name' => $this->name];
186
187
        if (!empty($this->namespace)) {
188
            $arr['namespace'] = $this->namespace;
189
        }
190
191
        if (!empty($this->attributes)) {
192
            $arr += ['attributes' => $this->attributes];
193
        }
194
195
        if (!empty($this->children())) {
196
            $names = [];
197
            foreach($this->children() as $child) {
198
                $names[] = $child->name;
199
            }
200
201
            $arr += ['children' => implode(',', $names)];
202
        } else {
203
            $arr += ['value' => $this->value];
204
        }
205
206
        return $arr;
207
    }
208
}
209