Completed
Push — master ( a046ab...1a416e )
by Бабичев
02:17
created

AdvancedHtmlBase   F

Complexity

Total Complexity 66

Size/Duplication

Total Lines 319
Duplicated Lines 0 %

Test Coverage

Coverage 49.6%

Importance

Changes 0
Metric Value
dl 0
loc 319
ccs 62
cts 125
cp 0.496
rs 3.1913
c 0
b 0
f 0
wmc 66

15 Methods

Rating   Name   Duplication   Size   Complexity  
A match() 0 5 1
B find() 0 22 5
A __set() 0 3 1
A remove() 0 5 1
D __call() 0 133 48
A str() 0 3 1
A __isset() 0 3 1
A scan() 0 5 1
A text() 0 3 1
A clean() 0 3 1
A __get() 0 3 1
A trim() 0 3 1
A __toString() 0 3 1
A html() 0 3 1
A __destruct() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like AdvancedHtmlBase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdvancedHtmlBase, and based on these observations, apply Extract Interface, too.

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 2
    public function __destruct()
32
    {
33 2
        $this->doc = $this->dom = $this->node = null;
34 2
        unset($this->doc, $this->dom, $this->node);
35 2
        Cleanup::all();
36 2
    }
37
38
    /**
39
     * @return mixed
40
     */
41 1
    public function text()
42
    {
43 1
        return $this->node->nodeValue;
44
    }
45
46
    /**
47
     * @return mixed
48
     */
49 3
    public function html()
50
    {
51 3
        return $this->doc->dom->saveHTML($this->node);
52
    }
53
54
    /**
55
     * @return string
56
     */
57
    public function __toString()
58
    {
59
        return (string)$this->html();
60
    }
61
62
    /**
63
     * @return $this
64
     */
65
    public function remove()
66
    {
67
        $this->node->parentNode->removeChild($this->node);
68
69
        return $this;
70
    }
71
72
    /**
73
     * @return Str
74
     */
75
    public function str()
76
    {
77
        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...
78
    }
79
80
    /**
81
     * @param $re
82
     *
83
     * @return bool
84
     */
85
    public function match($re)
86
    {
87
        $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...
88
89
        return $str->match($re);
90
    }
91
92
    /**
93
     * @param $re
94
     *
95
     * @return mixed
96
     */
97
    public function scan($re)
98
    {
99
        $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...
100
101
        return $str->scan($re);
102
    }
103
104
    /**
105
     * @param $str
106
     *
107
     * @return string
108
     */
109
    public function clean($str)
110
    {
111
        return $this->trim(\preg_replace('/\s+/', ' ', $str));
112
    }
113
114
    /**
115
     * @param $str
116
     *
117
     * @return string
118
     */
119
    public function trim($str)
120
    {
121
        return \trim($str);
122
    }
123
124
    /**
125
     * @param      $css
126
     * @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...
127
     *
128
     * @return array|AHTMLNode|AHTMLNodeList
129
     */
130 4
    public function find($css, $index = null)
131
    {
132 4
        $xpath = CSS::xpath_for($css);
133
134 4
        if (!isset($this->doc, $this->doc->xpath))
135
        {
136
            return null;
137
        }
138
139 4
        if (null === $index)
140
        {
141 3
            return new AHTMLNodeList($this->doc->xpath->query($xpath, $this->node), $this->doc);
142
        }
143
144 4
        $nl = $this->doc->xpath->query($xpath, $this->node);
145 4
        if ($index < 0)
146
        {
147
            $index = $nl->length + $index;
148
        }
149 4
        $node = $nl->item($index);
150
151 4
        return $node ? new AHTMLNode($node, $this->doc) : null;
152
    }
153
154
    // magic methods
155
156
    /**
157
     * @param $key
158
     * @param $args
159
     *
160
     * @return AHTMLNode[]|AHTMLNodeList|null
161
     */
162 4
    public function __call($key, $args)
163
    {
164 4
        $key = \strtolower(\str_replace('_', '', $key));
165
        switch ($key)
166
        {
167 4
            case 'innertext':
168
                return ($this->is_text || !$this->children->length) ? $this->text() : $this->find('./text()|./*')->outertext;
0 ignored issues
show
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...
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...
169 4
            case 'plaintext':
170
                return $this->text();
171 4
            case 'outertext':
172 4
            case 'html':
173 4
            case 'save':
174
                return $this->html();
175 4
            case 'innerhtml':
176
                $ret = '';
177
                foreach ($this->node->childNodes as $child)
178
                {
179
                    $ret .= $this->doc->dom->saveHTML($child);
180
                }
181
182
                return $ret;
183
184 4
            case 'tag':
185 1
                return $this->node->nodeName;
186 4
            case 'next':
187
                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

187
                return $this->/** @scrutinizer ignore-call */ at('./following-sibling::*[1]|./following-sibling::text()[1]|./following-sibling::comment()[1]');
Loading history...
188
189 4
            case 'index':
190
                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

190
                return $this->/** @scrutinizer ignore-call */ search('./preceding-sibling::*')->length + 1;
Loading history...
191
192
            /*
193
            DOMNode::insertBefore — Adds a new child
194
            */
195
196
            // simple-html-dom junk methods
197 4
            case 'clear':
198
                return;
199
200
            // search functions
201 4
            case 'at':
202 1
            case 'getelementbytagname':
203 4
                return $this->find($args[0], 0);
204
205 1
            case 'search':
206 1
            case 'getelementsbytagname':
207
                return isset($args[1]) ? $this->find($args[0], $args[1]) : $this->find($args[0]);
208
209 1
            case 'getelementbyid':
210
                return $this->find('#' . $args[0], 0);
211 1
            case 'getelementsbyid':
212
                return isset($args[1]) ? $this->find('#' . $args[0], $args[1]) : $this->find('#' . $args[0]);
213
214
            // attributes
215 1
            case 'hasattribute':
216
                return !$this->is_text && $this->node->hasAttribute($args[0]);
217
218 1
            case 'getattribute':
219
                $arg = $args[0];
220
221
                return $this->$arg;
222 1
            case 'setattribute':
223
                $arg0 = $args[0];
224
                $arg1 = $args[1];
225
226
                return $this->$arg0 = $arg1;
227 1
            case 'removeattribute':
228
                $arg = $args[0];
229
230
                return $this->$arg = null;
231
232
            // wrap
233 1
            case 'wrap':
234
                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

234
                return $this->/** @scrutinizer ignore-call */ replace('<' . $args[0] . '>' . $this . '</' . $args[0] . '>');
Loading history...
235 1
            case 'unwrap':
236
                return $this->parent->replace($this);
0 ignored issues
show
Bug introduced by
The method replace() does not exist on Bavix\AdvancedHtmlDom\AHTMLNodeList. 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

236
                return $this->parent->/** @scrutinizer ignore-call */ replace($this);
Loading history...
Bug introduced by
The method replace() does not exist on null. ( Ignorable by Annotation )

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

236
                return $this->parent->/** @scrutinizer ignore-call */ replace($this);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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...
237
238 1
            case 'str':
239
                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...
240
241
            // heirarchy
242 1
            case 'firstchild':
243
                return $this->at('> *');
244 1
            case 'lastchild':
245
                return $this->at('> *:last');
246 1
            case 'nextsibling':
247
                return $this->at('+ *');
248 1
            case 'prevsibling':
249
                return $this->at('./preceding-sibling::*[1]');
250 1
            case 'parent':
251
                return $this->at('./..');
252 1
            case 'children':
253 1
            case 'childnodes':
254
                $nl = $this->search('./*');
255
256
                return isset($args[0]) ? $nl[$args[0]] : $nl;
257 1
            case 'child': // including text/comment nodes
258
                $nl = $this->search('./*|./text()|./comment()');
259
260
                return isset($args[0]) ? $nl[$args[0]] : $nl;
261
262
        }
263
264
        // $doc->spans[x]
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
265 1
        if (\preg_match(TAGS_REGEX, $key, $m))
266
        {
267
            return $this->find($m[1]);
268
        }
269 1
        if (\preg_match(TAG_REGEX, $key, $m))
270
        {
271
            return $this->find($m[1], 0);
272
        }
273
274 1
        if (\preg_match('/(clean|trim|str)(.*)/', $key, $m) && isset($m[2]))
275
        {
276
            list($arg0, $arg1, $arg2) = $m;
277
278
            return $this->$arg1($this->$arg2);
279
        }
280
281 1
        if (\in_array($key, ['dom','node','doc'])) {
282
            return null;
283
        }
284
285 1
        if (!\preg_match(ATTRIBUTE_REGEX, $key, $m))
286
        {
287
            \trigger_error('Unknown method or property: ' . $key, E_USER_WARNING);
288
        }
289 1
        if (!$this->node || $this->is_text)
290
        {
291
            return null;
292
        }
293
294 1
        return $this->node->getAttribute($key);
295
    }
296
297
    /**
298
     * @param $key
299
     *
300
     * @return mixed
301
     */
302 2
    public function __get($key)
303
    {
304 2
        return $this->$key();
305
    }
306
307
    /**
308
     * @param $name
309
     * @param $value
310
     */
311
    public function __set($name, $value)
312
    {
313
        throw new \InvalidArgumentException(__METHOD__);
314
    }
315
316
    /**
317
     * @param $name
318
     *
319
     * @return bool
320
     */
321
    public function __isset($name)
322
    {
323
        return true;
324
    }
325
}
326