This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Openbuildings\Spiderling; |
||
4 | |||
5 | /** |
||
6 | * Node - represents HTML Dom node |
||
7 | * |
||
8 | * @package Openbuildings\Spiderling |
||
9 | * @author Ivan Kerin |
||
10 | * @copyright (c) 2013 OpenBuildings Ltd. |
||
11 | * @license http://spdx.org/licenses/BSD-3-Clause |
||
12 | */ |
||
13 | class Node { |
||
14 | |||
15 | const DEFAULT_WAIT_TIME = 2000; |
||
16 | |||
17 | /** |
||
18 | * The driver for traversing this node and its children |
||
19 | * @var Driver |
||
20 | */ |
||
21 | protected $_driver; |
||
22 | |||
23 | /** |
||
24 | * The parent node, NULL if root |
||
25 | * @var Node |
||
26 | */ |
||
27 | protected $_parent; |
||
28 | |||
29 | /** |
||
30 | * The id for the current node, NULL if root |
||
31 | * @var string |
||
32 | */ |
||
33 | protected $_id = NULL; |
||
34 | |||
35 | /** |
||
36 | * The time find operation will wait for the node to appear, in milliseconds |
||
37 | * @var integer |
||
38 | */ |
||
39 | protected $_next_wait_time; |
||
40 | |||
41 | /** |
||
42 | * All methods not for this node will be proxied through this |
||
43 | * @var object |
||
44 | */ |
||
45 | protected $_extension; |
||
46 | |||
47 | 38 | function __construct(Driver $driver = NULL, Node $parent = NULL, $id = NULL) |
|
0 ignored issues
–
show
|
|||
48 | { |
||
49 | 38 | $this->_driver = $driver; |
|
50 | 38 | $this->_parent = $parent; |
|
51 | 38 | $this->_id = $id; |
|
52 | |||
53 | 38 | if ($parent AND $parent->_extension) |
|
54 | { |
||
55 | 1 | $this->_extension = $parent->_extension; |
|
56 | } |
||
57 | 38 | } |
|
58 | |||
59 | /** |
||
60 | * Getter, get the current driver object |
||
61 | * @return Driver |
||
62 | */ |
||
63 | 22 | public function driver() |
|
64 | { |
||
65 | 22 | return $this->_driver; |
|
66 | } |
||
67 | |||
68 | /** |
||
69 | * Getter / Setter for the extension object |
||
70 | * @param mixed $extension |
||
71 | * @return mixed|$this |
||
72 | */ |
||
73 | 2 | public function extension($extension = NULL) |
|
74 | { |
||
75 | 2 | if ($extension !== NULL) |
|
76 | { |
||
77 | 1 | $this->_extension = $extension; |
|
78 | 1 | return $this; |
|
79 | } |
||
80 | 2 | return $this->_extension; |
|
81 | } |
||
82 | |||
83 | /** |
||
84 | * Getter - get the parent node |
||
85 | * @return Node |
||
86 | */ |
||
87 | 1 | public function parent() |
|
88 | { |
||
89 | 1 | return $this->_parent; |
|
90 | } |
||
91 | |||
92 | /** |
||
93 | * Setter this method is used to populate a node with a new id |
||
94 | * @param string $id |
||
95 | * @return Node $this |
||
96 | */ |
||
97 | 14 | public function load_new_id($id) |
|
98 | { |
||
99 | 14 | $this->_id = $id; |
|
100 | 14 | return $this; |
|
101 | } |
||
102 | |||
103 | /** |
||
104 | * Setter / Getter of the next wait time |
||
105 | * @param integer $next_wait_time milliseconds |
||
106 | * @return integer|Node |
||
107 | */ |
||
108 | 12 | public function next_wait_time($next_wait_time = NULL) |
|
109 | { |
||
110 | 12 | if ($next_wait_time !== NULL) |
|
111 | { |
||
112 | 1 | $this->_next_wait_time = $next_wait_time; |
|
113 | 1 | return $this; |
|
114 | } |
||
115 | |||
116 | 12 | if ($this->_next_wait_time === NULL AND $this->_driver) |
|
117 | { |
||
118 | 12 | $this->_next_wait_time = $this->_driver->default_wait_time; |
|
119 | } |
||
120 | |||
121 | 12 | return $this->_next_wait_time; |
|
122 | } |
||
123 | |||
124 | /** |
||
125 | * Wait milliseconds |
||
126 | * @param integer $milliseconds |
||
127 | * @return Node $this |
||
128 | */ |
||
129 | 1 | public function wait($milliseconds = 1000) |
|
130 | { |
||
131 | 1 | usleep($milliseconds * 1000); |
|
132 | |||
133 | 1 | return $this; |
|
134 | } |
||
135 | |||
136 | /** |
||
137 | * The DOMDocument or DOMElement representation of the current tag |
||
138 | * @return DOMDocument|DOMElement |
||
139 | */ |
||
140 | 9 | public function dom() |
|
141 | { |
||
142 | 9 | return $this->driver()->dom($this->id()); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Openbuildings\Spiderling\Driver as the method dom() does only exist in the following sub-classes of Openbuildings\Spiderling\Driver : Openbuildings\Spiderling\Driver_Kohana , Openbuildings\Spiderling\Driver_Simple , Openbuildings\Spiderling\Driver_SimpleXML . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
143 | } |
||
144 | |||
145 | /** |
||
146 | * GETTERS |
||
147 | * =========================================== |
||
148 | */ |
||
149 | |||
150 | /** |
||
151 | * is this the main html page? |
||
152 | * @return boolean |
||
153 | */ |
||
154 | 1 | public function is_root() |
|
155 | { |
||
156 | 1 | return ! (bool) $this->_id; |
|
157 | } |
||
158 | |||
159 | /** |
||
160 | * The current internal ID, unique to this page |
||
161 | * @return mixed |
||
162 | */ |
||
163 | 15 | public function id() |
|
164 | { |
||
165 | 15 | return $this->_id; |
|
166 | } |
||
167 | |||
168 | /** |
||
169 | * The html source of the current tag |
||
170 | * @return string |
||
171 | */ |
||
172 | 2 | public function html() |
|
173 | { |
||
174 | 2 | return $this->driver()->html($this->id()); |
|
175 | } |
||
176 | |||
177 | /** |
||
178 | * The html source of the current tag |
||
179 | * @return string |
||
180 | */ |
||
181 | 1 | public function __toString() |
|
182 | { |
||
183 | 1 | return (string) $this->html(); |
|
184 | } |
||
185 | |||
186 | /** |
||
187 | * The tag name of the current tag (body, div, input) |
||
188 | * @return string |
||
189 | */ |
||
190 | 2 | public function tag_name() |
|
191 | { |
||
192 | 2 | return $this->driver()->tag_name($this->id()); |
|
193 | } |
||
194 | |||
195 | /** |
||
196 | * Attribute of the current tag |
||
197 | * @param string $name the name of the attribute |
||
198 | * @return string |
||
199 | */ |
||
200 | 3 | public function attribute($name) |
|
201 | { |
||
202 | 3 | return $this->driver()->attribute($this->id(), $name); |
|
203 | } |
||
204 | |||
205 | /** |
||
206 | * The text content of the current tag (similar to javascript's innerText) |
||
207 | * @return string |
||
208 | */ |
||
209 | 2 | public function text() |
|
210 | { |
||
211 | 2 | return $this->driver()->text($this->id()); |
|
212 | } |
||
213 | |||
214 | /** |
||
215 | * Is this element visible? |
||
216 | * @return boolean |
||
217 | */ |
||
218 | 1 | public function is_visible() |
|
219 | { |
||
220 | 1 | return $this->driver()->is_visible($this->id()); |
|
221 | } |
||
222 | |||
223 | /** |
||
224 | * Is this option element selected? |
||
225 | * @return boolean |
||
226 | */ |
||
227 | 1 | public function is_selected() |
|
228 | { |
||
229 | 1 | return $this->driver()->is_selected($this->id()); |
|
230 | } |
||
231 | |||
232 | /** |
||
233 | * Is this checkbox checked? |
||
234 | * @return boolean |
||
235 | */ |
||
236 | 1 | public function is_checked() |
|
237 | { |
||
238 | 1 | return $this->driver()->is_checked($this->id()); |
|
239 | } |
||
240 | |||
241 | /** |
||
242 | * Get the value of the current form field |
||
243 | * @return string |
||
244 | */ |
||
245 | 3 | public function value() |
|
246 | { |
||
247 | 3 | return $this->driver()->value($this->id()); |
|
248 | } |
||
249 | |||
250 | |||
251 | /** |
||
252 | * SETTERS |
||
253 | * =========================================== |
||
254 | */ |
||
255 | |||
256 | /** |
||
257 | * Set the value for the current form field |
||
258 | * @param mixed $value |
||
259 | * @return Node $this |
||
260 | */ |
||
261 | 3 | public function set($value) |
|
262 | { |
||
263 | 3 | $this->driver()->set($this->id(), $value); |
|
264 | 3 | return $this; |
|
265 | } |
||
266 | |||
267 | /** |
||
268 | * Append to the current value - useful for textarea / input fields |
||
269 | * @param string $value |
||
270 | * @return Node $this |
||
271 | */ |
||
272 | 1 | public function append($value) |
|
273 | { |
||
274 | 1 | $current_value = $this->driver()->value($this->id()); |
|
275 | |||
276 | 1 | $this->driver()->set($this->id(), $current_value.$value); |
|
277 | |||
278 | 1 | return $this; |
|
279 | } |
||
280 | |||
281 | /** |
||
282 | * Click on the current html tag, either a button or a link |
||
283 | * @return Node $this |
||
284 | */ |
||
285 | 2 | public function click() |
|
286 | { |
||
287 | 2 | $this->driver()->click($this->id()); |
|
288 | 2 | return $this; |
|
289 | } |
||
290 | |||
291 | /** |
||
292 | * Select an option for the current select tag |
||
293 | * @return Node $this |
||
294 | */ |
||
295 | 3 | public function select_option() |
|
296 | { |
||
297 | 3 | $this->driver()->select_option($this->id(), TRUE); |
|
298 | 3 | return $this; |
|
299 | } |
||
300 | |||
301 | /** |
||
302 | * Unselect an option for the current select tag |
||
303 | * @return Node $this |
||
304 | */ |
||
305 | 2 | public function unselect_option() |
|
306 | { |
||
307 | 2 | $this->driver()->select_option($this->id(), FALSE); |
|
308 | 2 | return $this; |
|
309 | } |
||
310 | |||
311 | /** |
||
312 | * Hover over the current tag with the mouse |
||
313 | * @param integer $x offset inside the tag |
||
314 | * @param integer $y offset inside the tag |
||
315 | * @return Node $this |
||
316 | */ |
||
317 | 1 | public function hover($x = NULL, $y = NULL) |
|
318 | { |
||
319 | 1 | $this->driver()->move_to($this->id(), $x, $y); |
|
320 | 1 | return $this; |
|
321 | } |
||
322 | |||
323 | /** |
||
324 | * Simulate drop file events on the current element |
||
325 | * @param array|string $files local file filename or an array of filenames |
||
326 | * @return Node $this |
||
327 | */ |
||
328 | 1 | public function drop_files($files) |
|
329 | { |
||
330 | 1 | $this->driver()->drop_files($this->id(), $files); |
|
0 ignored issues
–
show
The method
drop_files() does not seem to exist on object<Openbuildings\Spiderling\Driver> .
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. ![]() |
|||
331 | 1 | return $this; |
|
332 | } |
||
333 | |||
334 | |||
335 | /** |
||
336 | * ACTIONS |
||
337 | * ======================================= |
||
338 | */ |
||
339 | |||
340 | /** |
||
341 | * Click on a specifc tag child of the current tag |
||
342 | * @param string|array $selector |
||
343 | * @param array $filters |
||
344 | * @return Node $this |
||
345 | */ |
||
346 | 1 | public function click_on($selector, array $filters = array()) |
|
347 | { |
||
348 | 1 | $this->find($selector, $filters)->click(); |
|
349 | 1 | return $this; |
|
350 | } |
||
351 | |||
352 | /** |
||
353 | * Click on a specifc link child of the current tag |
||
354 | * @param string|array $selector |
||
355 | * @param array $filters |
||
356 | * @return Node $this |
||
357 | */ |
||
358 | 1 | public function click_link($selector, array $filters = array()) |
|
359 | { |
||
360 | 1 | $this->find_link($selector, $filters)->click(); |
|
361 | 1 | return $this; |
|
362 | } |
||
363 | |||
364 | /** |
||
365 | * Click on a specifc button child of the current tag |
||
366 | * @param string|array $selector |
||
367 | * @param array $filters |
||
368 | * @return Node $this |
||
369 | */ |
||
370 | 1 | public function click_button($selector, array $filters = array()) |
|
371 | { |
||
372 | 1 | $this->find_button($selector, $filters)->click(); |
|
373 | 1 | return $this; |
|
374 | } |
||
375 | |||
376 | /** |
||
377 | * Set the value of the specific form field inside the current tag |
||
378 | * @param string|array $selector |
||
379 | * @param mixed $with the value to be set |
||
380 | * @param array $filters |
||
381 | * @return Node this |
||
382 | */ |
||
383 | 1 | public function fill_in($selector, $with, array $filters = array()) |
|
384 | { |
||
385 | 1 | $field = $this->find_field($selector, $filters); |
|
386 | |||
387 | 1 | if ( ! in_array($field->tag_name(), array('input', 'textarea'))) |
|
388 | throw new Exception('Element of type ":type" cannot be filled in! Only input and textarea elements can.'); |
||
389 | |||
390 | 1 | $field->set($with); |
|
391 | |||
392 | 1 | return $this; |
|
393 | } |
||
394 | |||
395 | /** |
||
396 | * Choose a spesific radio tag inside the current tag |
||
397 | * @param string|array $selector |
||
398 | * @param array $filters |
||
399 | * @return Node $this |
||
400 | */ |
||
401 | 1 | public function choose($selector, array $filters = array()) |
|
402 | { |
||
403 | 1 | $this->find_field($selector, $filters)->set(TRUE); |
|
404 | 1 | return $this; |
|
405 | } |
||
406 | |||
407 | /** |
||
408 | * Check a spesific checkbox input tag inside the current tag |
||
409 | * @param string|array $selector |
||
410 | * @param array $filters |
||
411 | * @return Node $this |
||
412 | */ |
||
413 | 1 | public function check($selector, array $filters = array()) |
|
414 | { |
||
415 | 1 | $this->find_field($selector, $filters)->set(TRUE); |
|
416 | 1 | return $this; |
|
417 | } |
||
418 | |||
419 | /** |
||
420 | * Uncheck a spesific checkbox input tag inside the current tag |
||
421 | * @param string|array $selector |
||
422 | * @param array $filters |
||
423 | * @return Node $this |
||
424 | */ |
||
425 | 1 | public function uncheck($selector, array $filters = array()) |
|
426 | { |
||
427 | 1 | $this->find_field($selector, $filters)->set(FALSE); |
|
428 | 1 | return $this; |
|
429 | } |
||
430 | |||
431 | /** |
||
432 | * Attach a file to a spesific file input tag inside the current tag |
||
433 | * @param string|array $selector |
||
434 | * @param string $file the filename for the file |
||
435 | * @param array $filters |
||
436 | * @return Node $this |
||
437 | */ |
||
438 | 1 | public function attach_file($selector, $file, array $filters = array()) |
|
439 | { |
||
440 | 1 | $this->find_field($selector, $filters)->set($file); |
|
441 | 1 | return $this; |
|
442 | } |
||
443 | |||
444 | /** |
||
445 | * Select an option of a spesific select tag inside the current tag |
||
446 | * |
||
447 | * To select the option the second parameter can be either a string of the option text |
||
448 | * or a filter to be applied on the options e.g. array('value' => 10) |
||
449 | * |
||
450 | * @param string|array $selector |
||
451 | * @param array $filters |
||
452 | * @param array|string $option_filters |
||
453 | * @return Node $this |
||
454 | */ |
||
455 | 1 | public function select($selector, $option_filters, array $filters = array()) |
|
456 | { |
||
457 | 1 | if ( ! is_array($option_filters)) |
|
458 | { |
||
459 | 1 | $option_filters = array('text' => $option_filters); |
|
460 | } |
||
461 | |||
462 | $this |
||
463 | 1 | ->find_field($selector, $filters) |
|
464 | 1 | ->find('option', $option_filters) |
|
465 | 1 | ->select_option(); |
|
466 | |||
467 | 1 | return $this; |
|
468 | } |
||
469 | |||
470 | /** |
||
471 | * Unselect an option of a spesific select tag inside the current tag |
||
472 | * |
||
473 | * To select the option the second parameter can be either a string of the option text |
||
474 | * or a filter to be applied on the options e.g. array('value' => 10) |
||
475 | * |
||
476 | * @param string|array $selector |
||
477 | * @param array $filters |
||
478 | * @param array|string $option_filters |
||
479 | * @return Node $this |
||
480 | */ |
||
481 | 1 | public function unselect($selector, $option_filters, array $filters = array()) |
|
0 ignored issues
–
show
|
|||
482 | { |
||
483 | 1 | if ( ! is_array($option_filters)) |
|
484 | { |
||
485 | 1 | $option_filters = array('value' => $option_filters); |
|
486 | } |
||
487 | |||
488 | $this |
||
489 | 1 | ->find_field($selector) |
|
490 | 1 | ->find('option', $option_filters) |
|
491 | 1 | ->unselect_option(); |
|
492 | 1 | return $this; |
|
493 | } |
||
494 | |||
495 | /** |
||
496 | * Confirm a javascript alert/confirm dialog box |
||
497 | * |
||
498 | * @param boolean|string $confirm alert/confirm - use boolean for inputs use string |
||
499 | * @return Node $this |
||
500 | */ |
||
501 | 1 | public function confirm($confirm) |
|
502 | { |
||
503 | 1 | $this->driver()->confirm($confirm); |
|
0 ignored issues
–
show
It seems like
$confirm defined by parameter $confirm on line 501 can also be of type string ; however, Openbuildings\Spiderling\Driver::confirm() does only seem to accept boolean , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
504 | 1 | return $this; |
|
505 | } |
||
506 | |||
507 | /** |
||
508 | * Execute arbitrary javascript on the page and get the result |
||
509 | * |
||
510 | * @param string $script |
||
511 | * @return mixed |
||
512 | */ |
||
513 | 1 | public function execute($script, $callback = NULL) |
|
514 | { |
||
515 | 1 | $result = $this->driver()->execute($this->id(), $script); |
|
516 | 1 | if ($callback) |
|
517 | { |
||
518 | 1 | call_user_func($callback, $result, $this); |
|
519 | 1 | return $this; |
|
520 | } |
||
521 | else |
||
522 | { |
||
523 | 1 | return $result; |
|
524 | } |
||
525 | } |
||
526 | |||
527 | /** |
||
528 | * Perform a screenshot of the current into the given file |
||
529 | * @param string $file |
||
530 | * @return Node $this |
||
531 | */ |
||
532 | 1 | public function screenshot($file) |
|
533 | { |
||
534 | 1 | $this->driver()->screenshot($file); |
|
535 | 1 | return $this; |
|
536 | } |
||
537 | |||
538 | /** |
||
539 | * Hover the mouse over a specific tag child of the current tag |
||
540 | * @param string|array $selector |
||
541 | * @param array $filters |
||
542 | * @return Node $this |
||
543 | */ |
||
544 | 1 | public function hover_on($selector, array $filters = array()) |
|
545 | { |
||
546 | 1 | $this->find($selector, $filters)->hover(); |
|
547 | 1 | return $this; |
|
548 | } |
||
549 | |||
550 | /** |
||
551 | * Hover the mouse over a specific link child of the current tag |
||
552 | * @param string|array $selector |
||
553 | * @param array $filters |
||
554 | * @return Node $this |
||
555 | */ |
||
556 | 1 | public function hover_link($selector, array $filters = array()) |
|
557 | { |
||
558 | 1 | $this->find_link($selector, $filters)->hover(); |
|
559 | 1 | return $this; |
|
560 | } |
||
561 | |||
562 | /** |
||
563 | * Hover the mouse over a specific field child of the current tag |
||
564 | * @param string|array $selector |
||
565 | * @param array $filters |
||
566 | * @return Node $this |
||
567 | */ |
||
568 | 1 | public function hover_field($selector, array $filters = array()) |
|
569 | { |
||
570 | 1 | $this->find_field($selector, $filters)->hover(); |
|
571 | 1 | return $this; |
|
572 | } |
||
573 | |||
574 | /** |
||
575 | * Hover the mouse over a specific button child of the current tag |
||
576 | * @param string|array $selector |
||
577 | * @param array $filters |
||
578 | * @return Node $this |
||
579 | */ |
||
580 | 1 | public function hover_button($selector, array $filters = array()) |
|
581 | { |
||
582 | 1 | $this->find_button($selector, $filters)->hover(); |
|
583 | 1 | return $this; |
|
584 | } |
||
585 | |||
586 | /** |
||
587 | * FINDERS |
||
588 | * ===================================================== |
||
589 | */ |
||
590 | |||
591 | /** |
||
592 | * Find an html form field child of the current tag |
||
593 | * @param string|array $selector |
||
594 | * @param array $filters |
||
595 | * @return Node $this |
||
596 | */ |
||
597 | 5 | public function find_field($selector, array $filters = array()) |
|
598 | { |
||
599 | 5 | return $this->find(array('field', $selector, $filters)); |
|
600 | } |
||
601 | |||
602 | /** |
||
603 | * Find an html form field child of the current tag |
||
604 | * @param string|array $selector |
||
605 | * @param array $filters |
||
606 | * @return Node $this |
||
607 | */ |
||
608 | 4 | public function find_link($selector, array $filters = array()) |
|
609 | { |
||
610 | 4 | return $this->find(array('link', $selector, $filters)); |
|
611 | } |
||
612 | |||
613 | /** |
||
614 | * Find an html button tag child of the current tag |
||
615 | * @param string|array $selector |
||
616 | * @param array $filters |
||
617 | * @return Node $this |
||
618 | */ |
||
619 | 4 | public function find_button($selector, array $filters = array()) |
|
620 | { |
||
621 | 4 | return $this->find(array('button', $selector, $filters)); |
|
622 | } |
||
623 | |||
624 | /** |
||
625 | * Find an html tag child of the current tag |
||
626 | * This is the basic find method that is used by all the other finders. |
||
627 | * To work with ajax requests it waits a bit (defualt 2 seconds) for the content to appear on the page |
||
628 | * before throwing an Functest_Exception_Notfound exception |
||
629 | * |
||
630 | * @param string|array $selector |
||
631 | * @param array $filters |
||
632 | * @throws Functest_Exception_Notfound If element not found |
||
633 | * @return Node $this |
||
634 | */ |
||
635 | 10 | public function find($selector, array $filters = array()) |
|
636 | { |
||
637 | 10 | $locator = self::get_locator($selector, $filters); |
|
638 | 10 | $self = $this; |
|
639 | |||
640 | $node = Attempt::make(function() use ($self, $locator){ |
||
641 | 10 | return $self->all($locator)->first(); |
|
642 | 10 | }, $this->next_wait_time()); |
|
0 ignored issues
–
show
It seems like
$this->next_wait_time() targeting Openbuildings\Spiderling\Node::next_wait_time() can also be of type this<Openbuildings\Spiderling\Node> ; however, Openbuildings\Spiderling\Attempt::make() does only seem to accept integer , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
643 | |||
644 | 10 | $this->_next_wait_time = NULL; |
|
645 | |||
646 | 10 | if ($node == NULL) |
|
647 | 2 | throw new Exception_Notfound($locator, $this->driver()); |
|
648 | |||
649 | 10 | return $node; |
|
650 | } |
||
651 | |||
652 | /** |
||
653 | * Oposite to the find method() |
||
654 | * |
||
655 | * @param string|array $selector |
||
656 | * @param array $filters |
||
657 | * @throws Functest_Exception_Found If element is found on the page |
||
658 | * @return Node $this |
||
659 | */ |
||
660 | 1 | public function not_present($selector, array $filters = array()) |
|
661 | { |
||
662 | 1 | $locator = self::get_locator($selector, $filters); |
|
663 | 1 | $self = $this; |
|
664 | |||
665 | $not_found = Attempt::make(function() use ($self, $locator){ |
||
666 | 1 | return ! $self->all($locator)->first(); |
|
667 | 1 | }, $this->next_wait_time()); |
|
0 ignored issues
–
show
It seems like
$this->next_wait_time() targeting Openbuildings\Spiderling\Node::next_wait_time() can also be of type this<Openbuildings\Spiderling\Node> ; however, Openbuildings\Spiderling\Attempt::make() does only seem to accept integer , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
668 | |||
669 | 1 | $this->_next_wait_time = NULL; |
|
670 | |||
671 | 1 | if ( ! $not_found) |
|
672 | 1 | throw new Exception_Found($locator, $this->driver()); |
|
673 | |||
674 | 1 | return TRUE; |
|
675 | } |
||
676 | |||
677 | /** |
||
678 | * Returns the parent element |
||
679 | * |
||
680 | * @return Node parent |
||
681 | */ |
||
682 | 1 | public function end() |
|
683 | { |
||
684 | 1 | return $this->_parent; |
|
685 | } |
||
686 | |||
687 | /** |
||
688 | * Find a list of elements represented by the selector / filter |
||
689 | * |
||
690 | * @param string|array $selector |
||
691 | * @param array $filters |
||
692 | * @return Nodelist |
||
693 | */ |
||
694 | 18 | public function all($selector, array $filters = array()) |
|
695 | { |
||
696 | 18 | $locator = self::get_locator($selector, $filters); |
|
697 | |||
698 | 18 | return new Nodelist($this->driver(), $locator, $this); |
|
699 | } |
||
700 | |||
701 | /** |
||
702 | * Shortcuts for creating locators (from arrays or nested arrays) |
||
703 | * @param string|Locator|array $selector |
||
704 | * @param array $filters |
||
705 | * @return Locator |
||
706 | */ |
||
707 | 27 | public static function get_locator($selector, array $filters = array()) |
|
708 | { |
||
709 | 27 | if ($selector instanceof Locator) |
|
710 | 11 | return $selector; |
|
711 | |||
712 | 27 | $type = NULL; |
|
713 | |||
714 | 27 | if (is_array($selector)) |
|
715 | { |
||
716 | // Manage nested selectors |
||
717 | 13 | if (is_array($selector[1])) |
|
718 | { |
||
719 | 1 | $selector = $selector[1]; |
|
720 | } |
||
721 | |||
722 | 13 | $type = $selector[0]; |
|
723 | 13 | $filters = isset($selector[2]) ? $selector[2] : array(); |
|
724 | 13 | $selector = $selector[1]; |
|
725 | } |
||
726 | |||
727 | 27 | return new Locator($type, $selector, $filters); |
|
728 | } |
||
729 | |||
730 | /** |
||
731 | * Pass all other methods to the extension if it is set. That way you can add additional methods |
||
732 | * @param string $method |
||
733 | * @param array $arguments |
||
734 | * @return Node $this |
||
735 | */ |
||
736 | 1 | public function __call($method, $arguments) |
|
737 | { |
||
738 | 1 | if ( ! $this->extension() OR ! method_exists($this->extension(), $method)) |
|
739 | throw new Exception_Methodmissing('Method :method does not exist on this node or node extension', array(':method' => $method)); |
||
740 | |||
741 | 1 | array_unshift($arguments, $this); |
|
742 | |||
743 | 1 | call_user_func_array(array($this->extension(), $method), $arguments); |
|
744 | |||
745 | 1 | return $this; |
|
746 | } |
||
747 | } |
||
748 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.