AdvancedHtmlBase::__call()   D
last analyzed

Complexity

Conditions 48
Paths 50

Size

Total Lines 126
Code Lines 82

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 46
CRAP Score 242.9288

Importance

Changes 0
Metric Value
cc 48
eloc 82
c 0
b 0
f 0
nc 50
nop 2
dl 0
loc 126
ccs 46
cts 82
cp 0.561
crap 242.9288
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Bavix\AdvancedHtmlDom;
4
5
class AdvancedHtmlBase
6
{
7
8
    /**
9
     * @var
10
     */
11
    public $doc;
12
13
    /**
14
     * @var
15
     */
16
    public $dom;
17
18
    /**
19
     * @var
20
     */
21
    public $node;
22
23
    /**
24
     * @var bool
25
     */
26
    public $is_text = false;
27
28
    /**
29
     * @see https://github.com/monkeysuffrage/advanced_html_dom/issues/19
30
     */
31 4
    public function __destruct()
32
    {
33 4
        $this->doc = $this->dom = $this->node = null;
34 4
        unset($this->doc, $this->dom, $this->node);
35 4
        Cleanup::all();
36 4
    }
37
38
    /**
39
     * @return string
40
     */
41
    public function __toString()
42
    {
43
        return (string)$this->html();
44
    }
45
46
    /**
47
     * @return mixed
48
     */
49 3
    public function html()
50
    {
51 3
        return $this->doc->dom->saveXML($this->node);
52
    }
53
54
    /**
55
     * @return $this
56
     */
57
    public function remove()
58
    {
59
        $this->node->parentNode->removeChild($this->node);
60
61
        return $this;
62
    }
63
64
    /**
65
     * @return Str
66
     */
67
    public function str()
68
    {
69
        return new Str($this->text);
0 ignored issues
show
Bug Best Practice introduced by
The property text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __get, consider adding a @property annotation.
Loading history...
70
    }
71
72
    /**
73
     * @param $re
74
     *
75
     * @return bool
76
     */
77
    public function match($re)
78
    {
79
        $str = new Str($this->text);
0 ignored issues
show
Bug Best Practice introduced by
The property text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __get, consider adding a @property annotation.
Loading history...
80
81
        return $str->match($re);
82
    }
83
84
    /**
85
     * @param $re
86
     *
87
     * @return mixed
88
     */
89
    public function scan($re)
90
    {
91
        $str = new Str($this->text);
0 ignored issues
show
Bug Best Practice introduced by
The property text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __get, consider adding a @property annotation.
Loading history...
92
93
        return $str->scan($re);
94
    }
95
96
    /**
97
     * @param $str
98
     *
99
     * @return string
100
     */
101
    public function clean($str)
102
    {
103
        return $this->trim(\preg_replace('/\s+/', ' ', $str));
104
    }
105
106
    /**
107
     * @param $str
108
     *
109
     * @return string
110
     */
111
    public function trim($str)
112
    {
113
        return \trim($str);
114
    }
115
116
    /**
117
     * @param $key
118
     * @param $args
119
     *
120
     * @return AHTMLNode[]|AHTMLNodeList|null
121
     */
122 6
    public function __call($key, $args)
123
    {
124 6
        $key = \strtolower(\str_replace('_', '', $key));
125
        switch ($key) {
126 6
            case 'innertext':
127 1
                return ($this->is_text || !$this->children->length) ? $this->text() : $this->find('./text()|./*')->outertext;
0 ignored issues
show
Bug Best Practice introduced by
The property length does not exist on Bavix\AdvancedHtmlDom\AHTMLNodeList. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property outertext does not exist on Bavix\AdvancedHtmlDom\AHTMLNodeList. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property children does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __get, consider adding a @property annotation.
Loading history...
128 6
            case 'plaintext':
129
                return $this->text();
130 6
            case 'outertext':
131 6
            case 'html':
132 6
            case 'save':
133
                return $this->html();
134 6
            case 'innerhtml':
135
                $ret = '';
136
                foreach ($this->node->childNodes as $child) {
137
                    $ret .= $this->doc->dom->saveHTML($child);
138
                }
139
140
                return $ret;
141
142 6
            case 'tag':
143 1
                return $this->node->nodeName;
144 6
            case 'next':
145
                return $this->at('./following-sibling::*[1]|./following-sibling::text()[1]|./following-sibling::comment()[1]');
0 ignored issues
show
Bug introduced by
The method at() does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

145
                return $this->/** @scrutinizer ignore-call */ at('./following-sibling::*[1]|./following-sibling::text()[1]|./following-sibling::comment()[1]');
Loading history...
146
147 6
            case 'index':
148
                return $this->search('./preceding-sibling::*')->length + 1;
0 ignored issues
show
Bug introduced by
The method search() does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

148
                return $this->/** @scrutinizer ignore-call */ search('./preceding-sibling::*')->length + 1;
Loading history...
149
150
            /*
151
            DOMNode::insertBefore — Adds a new child
152
            */
153
154
            // simple-html-dom junk methods
155 6
            case 'clear':
156
                return;
157
158
            // search functions
159 6
            case 'at':
160 3
            case 'getelementbytagname':
161 6
                return $this->find($args[0], 0);
162
163 3
            case 'search':
164 3
            case 'getelementsbytagname':
165 1
                return isset($args[1]) ? $this->find($args[0], $args[1]) : $this->find($args[0]);
166
167 3
            case 'getelementbyid':
168
                return $this->find('#' . $args[0], 0);
169 3
            case 'getelementsbyid':
170
                return isset($args[1]) ? $this->find('#' . $args[0], $args[1]) : $this->find('#' . $args[0]);
171
172
            // attributes
173 3
            case 'hasattribute':
174
                return !$this->is_text && $this->node->hasAttribute($args[0]);
175
176 3
            case 'getattribute':
177
                $arg = $args[0];
178
179
                return $this->$arg;
180 3
            case 'setattribute':
181
                $arg0 = $args[0];
182
                $arg1 = $args[1];
183
184
                return $this->$arg0 = $arg1;
185 3
            case 'removeattribute':
186
                $arg = $args[0];
187
188
                return $this->$arg = null;
189
190
            // wrap
191 3
            case 'wrap':
192
                return $this->replace('<' . $args[0] . '>' . $this . '</' . $args[0] . '>');
0 ignored issues
show
Bug introduced by
The method replace() does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

192
                return $this->/** @scrutinizer ignore-call */ replace('<' . $args[0] . '>' . $this . '</' . $args[0] . '>');
Loading history...
193 3
            case 'unwrap':
194
                return $this->parent->replace($this);
0 ignored issues
show
Bug Best Practice introduced by
The property parent does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __get, consider adding a @property annotation.
Loading history...
195
196 3
            case 'str':
197
                return new Str($this->text);
0 ignored issues
show
Bug Best Practice introduced by
The property text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase. Since you implemented __get, consider adding a @property annotation.
Loading history...
198
199
            // heirarchy
200 3
            case 'firstchild':
201
                return $this->at('> *');
202 3
            case 'lastchild':
203
                return $this->at('> *:last');
204 3
            case 'nextsibling':
205
                return $this->at('+ *');
206 3
            case 'prevsibling':
207
                return $this->at('./preceding-sibling::*[1]');
208 3
            case 'parent':
209
                return $this->at('./..');
210 3
            case 'children':
211 3
            case 'childnodes':
212 1
                $nl = $this->search('./*');
213
214 1
                return isset($args[0]) ? $nl[$args[0]] : $nl;
215 2
            case 'child': // including text/comment nodes
216
                $nl = $this->search('./*|./text()|./comment()');
217
218
                return isset($args[0]) ? $nl[$args[0]] : $nl;
219
220
        }
221
222
        // $doc->spans[x]
223 2
        if (\preg_match(TAGS_REGEX, $key, $m)) {
224
            return $this->find($m[1]);
225
        }
226 2
        if (\preg_match(TAG_REGEX, $key, $m)) {
227
            return $this->find($m[1], 0);
228
        }
229
230 2
        if (\preg_match('/(clean|trim|str)(.*)/', $key, $m) && isset($m[2])) {
231
            list($arg0, $arg1, $arg2) = $m;
232
233
            return $this->$arg1($this->$arg2);
234
        }
235
236 2
        if (\in_array($key, ['dom', 'node', 'doc'])) {
237
            return null;
238
        }
239
240 2
        if (!\preg_match(ATTRIBUTE_REGEX, $key, $m)) {
241
            \trigger_error('Unknown method or property: ' . $key, E_USER_WARNING);
242
        }
243 2
        if (!$this->node || $this->is_text) {
244
            return null;
245
        }
246
247 2
        return $this->node->getAttribute($key);
248
    }
249
250
    /**
251
     * @return mixed
252
     */
253 2
    public function text()
254
    {
255 2
        return $this->node->nodeValue;
256
    }
257
258
    // magic methods
259
260
    /**
261
     * @param      $css
262
     * @param null $index
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $index is correct as it would always require null to be passed?
Loading history...
263
     *
264
     * @return array|AHTMLNode|AHTMLNodeList
265
     */
266 6
    public function find($css, $index = null)
267
    {
268 6
        $xpath = CSS::xpath_for($css);
269
270 6
        if (!isset($this->doc, $this->doc->xpath)) {
271
            return null;
272
        }
273
274 6
        if (null === $index) {
0 ignored issues
show
introduced by
The condition null === $index is always true.
Loading history...
275 5
            return new AHTMLNodeList($this->doc->xpath->query($xpath, $this->node), $this->doc);
276
        }
277
278 6
        $nl = $this->doc->xpath->query($xpath, $this->node);
279 6
        if ($index < 0) {
280
            $index = $nl->length + $index;
281
        }
282 6
        $node = $nl->item($index);
283
284 6
        return $node ? new AHTMLNode($node, $this->doc) : null;
285
    }
286
287
    /**
288
     * @param $key
289
     *
290
     * @return mixed
291
     */
292 4
    public function __get($key)
293
    {
294 4
        return $this->$key();
295
    }
296
297
    /**
298
     * @param $name
299
     * @param $value
300
     */
301
    public function __set($name, $value)
302
    {
303
        throw new \InvalidArgumentException(__METHOD__);
304
    }
305
306
    /**
307
     * @param $name
308
     *
309
     * @return bool
310
     */
311
    public function __isset($name)
312
    {
313
        return true;
314
    }
315
}
316