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
![]() |
|||||
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
The property
text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||
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
The property
text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||
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
The property
length does not exist on Bavix\AdvancedHtmlDom\AHTMLNodeList . Since you implemented __get , consider adding a @property annotation.
![]() The property
outertext does not exist on Bavix\AdvancedHtmlDom\AHTMLNodeList . Since you implemented __get , consider adding a @property annotation.
![]() The property
children does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||
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
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
![]() |
|||||
146 | |||||
147 | 6 | case 'index': |
|||
148 | return $this->search('./preceding-sibling::*')->length + 1; |
||||
0 ignored issues
–
show
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
![]() |
|||||
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
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
![]() |
|||||
193 | 3 | case 'unwrap': |
|||
194 | return $this->parent->replace($this); |
||||
0 ignored issues
–
show
The property
parent does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||
195 | |||||
196 | 3 | case 'str': |
|||
197 | return new Str($this->text); |
||||
0 ignored issues
–
show
The property
text does not exist on Bavix\AdvancedHtmlDom\AdvancedHtmlBase . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||
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
|
|||||
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
|
|||||
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 |