Issues (1066)

Security Analysis    7 potential vulnerabilities

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting (1)
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection (3)
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection (3)
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/PhpQueryObject.php (255 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace PhpQuery;
3
4
use Sabberworm\CSS\Parser as CssParser;
5
6
/**
7
 * Class representing PhpQuery objects.
8
 *
9
 * @author  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
10
 * @package PhpQuery
11
 * @method PhpQueryObject clone() clone()
12
 * @method PhpQueryObject empty() empty()
13
 * @property Int $length
14
 */
15
class PhpQueryObject implements \Iterator, \Countable, \ArrayAccess
16
{
17
    public $documentID = null;
18
    /**
19
     * \DOMDocument class.
20
     *
21
     * @var \DOMDocument
22
     */
23
    public $document = null;
24
    public $charset = null;
25
    /**
26
     *
27
     * @var Dom\DOMDocumentWrapper
28
     */
29
    public $documentWrapper = null;
30
    /**
31
     * XPath interface.
32
     *
33
     * @var \DOMXPath
34
     */
35
    public $xpath = null;
36
    /**
37
     * Stack of selected elements.
38
     * @TODO refactor to ->nodes
39
     * @var array
40
     */
41
    public $elements = array();
42
    /**
43
     * @access private
44
     */
45
    protected $elementsBackup = array();
46
    /**
47
     * @access private
48
     */
49
    protected $previous = null;
50
    /**
51
     * @access private
52
     * @TODO   deprecate
53
     */
54
    protected $root = array();
55
    /**
56
     * Indicated if doument is just a fragment (no <html> tag).
57
     *
58
     * Every document is realy a full document, so even documentFragments can
59
     * be queried against <html>, but getDocument(id)->htmlOuter() will return
60
     * only contents of <body>.
61
     *
62
     * @var bool
63
     */
64
    public $documentFragment = true;
65
    /**
66
     * Iterator interface helper
67
     * @access private
68
     */
69
    protected $elementsInterator = array();
70
    /**
71
     * Iterator interface helper
72
     * @access private
73
     */
74
    protected $valid = false;
75
    /**
76
     * Iterator interface helper
77
     * @access private
78
     */
79
    protected $current = null;
80
81
    /**
82
     * Indicates whether CSS has been parsed or not. We only parse CSS if needed.
83
     * @access private
84
     */
85
    protected $cssIsParsed = array();
86
    /**
87
     * A collection of complete CSS selector strings.
88
     * @access private;
89
     */
90
    protected $cssString = array();
91
    /**
92
     * Enter description here...
93
     *
94
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
95
     */
96
97
    protected $attribute_css_mapping = array(
98
        'bgcolor' => 'background-color',
99
        'text'    => 'color',
100
        'width'   => 'width',
101
        'height'  => 'height'
102
    );
103
104
    public function __construct($documentID)
105
    {
106
        //		if ($documentID instanceof self)
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
107
        //			var_dump($documentID->getDocumentID());
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
108
        $id = $documentID instanceof self ? $documentID->getDocumentID()
109
            : $documentID;
110
        //		var_dump($id);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
111
        if (!isset(PhpQuery::$documents[$id])) {
112
            //			var_dump(PhpQuery::$documents);
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% 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...
113
            throw new \Exception("Document with ID '{$id}' isn't loaded. Use PhpQuery::newDocument(\$html) or PhpQuery::newDocumentFile(\$file) first.");
114
        }
115
        $this->documentID       = $id;
116
        $this->documentWrapper  = & PhpQuery::$documents[$id];
117
        $this->document         = & $this->documentWrapper->document;
118
        $this->xpath            = & $this->documentWrapper->xpath;
119
        $this->charset          = & $this->documentWrapper->charset;
120
        $this->documentFragment = & $this->documentWrapper->isDocumentFragment;
121
        // TODO check $this->DOM->documentElement;
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% 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...
122
        //		$this->root = $this->document->documentElement;
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
123
        $this->root = & $this->documentWrapper->root;
124
        //		$this->toRoot();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
125
        $this->elements = array(
126
            $this->root
127
        );
128
    }
129
130
    /**
131
     *
132
     * @access private
133
     * @param $attr
134
     * @return \PhpQuery\PhpQueryObject|\PhpQuery\QueryTemplatesParse|\PhpQuery\QueryTemplatesSource|\PhpQuery\QueryTemplatesSourceQuery
135
     */
136
    public function __get($attr)
137
    {
138
        switch ($attr) {
139
            // FIXME doesnt work at all ?
140
            case 'length':
141
                return $this->size();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->size(); (integer) is incompatible with the return type documented by PhpQuery\PhpQueryObject::__get of type PhpQuery\PhpQueryObject|...eryTemplatesSourceQuery.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
142
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
143
            default:
144
                return $this->$attr;
145
        }
146
    }
147
148
    /**
149
     * Saves actual object to $var by reference.
150
     * Useful when need to break chain.
151
     * @param PhpQueryObject $var
152
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
153
     */
154
    public function toReference(&$var)
155
    {
156
        return $var = $this;
157
    }
158
159
    public function documentFragment($state = null)
160
    {
161
        if ($state) {
162
            PhpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state;
163
            return $this;
164
        }
165
        return $this->documentFragment;
166
    }
167
168
    /**
169
     * @access private
170
     * @TODO   documentWrapper
171
     */
172
    protected function isRoot($node)
173
    {
174
        //		return $node instanceof \DOMDocument || $node->tagName == 'html';
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
175
        return $node instanceof \DOMDocument
176
        || ($node instanceof \DOMElement && $node->tagName == 'html')
177
        || $this->root->isSameNode($node);
0 ignored issues
show
The method isSameNode cannot be called on $this->root (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
178
    }
179
180
    /**
181
     * @access private
182
     */
183
    protected function stackIsRoot()
184
    {
185
        return $this->size() == 1 && $this->isRoot($this->elements[0]);
186
    }
187
188
    /**
189
     * Enter description here...
190
     * NON JQUERY METHOD
191
     *
192
     * Watch out, it doesn't creates new instance, can be reverted with end().
193
     *
194
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
195
     */
196
    public function toRoot()
197
    {
198
        $this->elements = array(
199
            $this->root
200
        );
201
        return $this;
202
        //		return $this->newInstance(array($this->root));
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% 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...
203
    }
204
205
    /**
206
     * Saves object's DocumentID to $var by reference.
207
     * <code>
208
     * $myDocumentId;
209
     * PhpQuery::newDocument('<div/>')
210
     *     ->getDocumentIDRef($myDocumentId)
211
     *     ->find('div')->...
212
     * </code>
213
     *
214
     * @param $documentID
215
     * @internal param string $domId
216
     * @see      PhpQuery::newDocument
217
     * @see      PhpQuery::newDocumentFile
218
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
219
     */
220
    public function getDocumentIDRef(&$documentID)
221
    {
222
        $documentID = $this->getDocumentID();
223
        return $this;
224
    }
225
226
    /**
227
     * Returns object with stack set to document root.
228
     *
229
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
230
     */
231
    public function getDocument()
232
    {
233
        return PhpQuery::getDocument($this->getDocumentID());
234
    }
235
236
    /**
237
     *
238
     * @return \DOMDocument
239
     */
240
    public function getDOMDocument()
241
    {
242
        return $this->document;
243
    }
244
245
    /**
246
     * Get object's Document ID.
247
     *
248
     * @return string
249
     */
250
    public function getDocumentID()
251
    {
252
        return $this->documentID;
253
    }
254
255
    /**
256
     * Unloads whole document from memory.
257
     * CAUTION! None further operations will be possible on this document.
258
     * All objects refering to it will be useless.
259
     *
260
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
261
     */
262
    public function unloadDocument()
263
    {
264
        PhpQuery::unloadDocuments($this->getDocumentID());
265
    }
266
267
    public function isHTML()
268
    {
269
        return $this->documentWrapper->isHTML;
270
    }
271
272
    public function isXHTML()
273
    {
274
        return $this->documentWrapper->isXHTML;
275
    }
276
277
    public function isXML()
278
    {
279
        return $this->documentWrapper->isXML;
280
    }
281
282
    /**
283
     * Enter description here...
284
     *
285
     * @link http://docs.jquery.com/Ajax/serialize
286
     * @return string
287
     */
288
    public function serialize()
289
    {
290
        return PhpQuery::param($this->serializeArray());
291
    }
292
293
    /**
294
     * Enter description here...
295
     *
296
     * @link http://docs.jquery.com/Ajax/serializeArray
297
     * @return array
298
     */
299
    public function serializeArray($submit = null)
300
    {
301
        $source = $this->filter('form, input, select, textarea')->find('input, select, textarea')->andSelf()->not(
302
            'form'
303
        );
304
        $return = array();
305
        //		$source->dumpDie();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
306
        foreach ($source as $input) {
307
            $input = PhpQuery::pq($input);
308
            if ($input->is('[disabled]')) {
309
                continue;
310
            }
311
            if (!$input->is('[name]')) {
312
                continue;
313
            }
314
            if ($input->is('[type=checkbox]') && !$input->is('[checked]')) {
315
                continue;
316
            }
317
            // jquery diff
318
            if ($submit && $input->is('[type=submit]')) {
319
                if ($submit instanceof \DOMElement
320
                    && !$input->elements[0]->isSameNode($submit)
321
                ) {
322
                    continue;
323
                } else {
324
                    if (is_string($submit) && $input->attr('name') != $submit) {
325
                        continue;
326
                    }
327
                }
328
            }
329
            $return[] = array(
330
                'name'  => $input->attr('name'),
331
                'value' => $input->val(),
332
            );
333
        }
334
        return $return;
335
    }
336
337
    /**
338
     * @access private
339
     */
340
    protected function debug($in)
341
    {
342
        if (!PhpQuery::$debug) {
343
            return;
344
        }
345
        print('<pre>');
346
        print_r($in);
347
        // file debug
348
        //		file_put_contents(dirname(__FILE__).'/PhpQuery.log', print_r($in, true)."\n", FILE_APPEND);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
349
        // quite handy debug trace
350
        //		if ( is_array($in))
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
351
        //			print_r(array_slice(debug_backtrace(), 3));
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
352
        print("</pre>\n");
353
    }
354
355
    /**
356
     * @access private
357
     */
358
    protected function isRegexp($pattern)
359
    {
360
        return in_array(
361
            $pattern[mb_strlen($pattern) - 1],
362
            array(
363
                '^',
364
                '*',
365
                '$'
366
            )
367
        );
368
    }
369
370
    /**
371
     * Determines if $char is really a char.
372
     *
373
     * @param string $char
374
     * @return bool
375
     * @todo   rewrite me to charcode range ! ;)
376
     * @access private
377
     */
378
    protected function isChar($char)
379
    {
380
        return extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_eregi('\w', $char)
381
            : preg_match('@\w@', $char);
382
    }
383
384
    /**
385
     * @access private
386
     */
387
    protected function parseSelector($query)
388
    {
389
        // clean spaces
390
        // TODO include this inside parsing ?
391
        $query   = trim(preg_replace('@\s+@', ' ', preg_replace('@\s*(>|\\+|~)\s*@', '\\1', (string) $query)));
392
        $queries = array(
393
            array()
394
        );
395
        if (!$query) {
396
            return $queries;
397
        }
398
        $return       = & $queries[0];
399
        $specialChars = array(
400
            '>',
401
            ' '
402
        );
403
        //		$specialCharsMapping = array('/' => '>');
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...
404
        $specialCharsMapping = array();
405
        $strlen              = mb_strlen($query);
406
        $classChars          = array(
407
            '.',
408
            '-'
409
        );
410
        $pseudoChars         = array(
411
            '-'
412
        );
413
        $tagChars            = array(
414
            '*',
415
            '|',
416
            '-'
417
        );
418
        // split multibyte string
419
        // http://code.google.com/p/phpquery/issues/detail?id=76
420
        $_query = array();
421
        for ($i = 0; $i < $strlen; $i++) {
422
            $_query[] = mb_substr($query, $i, 1);
423
        }
424
        $query = $_query;
425
        // it works, but i dont like it...
426
        $i = 0;
427
        while ($i < $strlen) {
428
            $c   = $query[$i];
429
            $tmp = '';
430
            // TAG
431
            if ($this->isChar($c) || in_array($c, $tagChars)) {
432 View Code Duplication
                while (isset($query[$i])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
433
                    && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) {
434
                    $tmp .= $query[$i];
435
                    $i++;
436
                }
437
                $return[] = $tmp;
438
                // IDs
439
            } else if ($c == '#') {
440
                $i++;
441 View Code Duplication
                while (isset($query[$i])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
442
                    && ($this->isChar($query[$i]) || $query[$i] == '-')) {
443
                    $tmp .= $query[$i];
444
                    $i++;
445
                }
446
                $return[] = '#' . $tmp;
447
                // SPECIAL CHARS
448
            } else if (in_array($c, $specialChars)) {
449
                $return[] = $c;
450
                $i++;
451
                // MAPPED SPECIAL MULTICHARS
452
                //			} else if ( $c.$query[$i+1] == '//') {
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
453
                //				$return[] = ' ';
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
454
                //				$i = $i+2;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
455
                // MAPPED SPECIAL CHARS
456
            } else if (isset($specialCharsMapping[$c])) {
457
                $return[] = $specialCharsMapping[$c];
458
                $i++;
459
                // COMMA
460
            } else if ($c == ',') {
461
                $queries[] = array();
462
                $return    = & $queries[count($queries) - 1];
463
                $i++;
464
                while (isset($query[$i]) && $query[$i] == ' ') {
465
                    $i++;
466
                }
467
                // CLASSES
468
            } else if ($c == '.') {
469 View Code Duplication
                while (isset($query[$i])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
470
                    && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) {
471
                    $tmp .= $query[$i];
472
                    $i++;
473
                }
474
                $return[] = $tmp;
475
                // ~ General Sibling Selector
476
            } else if ($c == '~') {
477
                $spaceAllowed = true;
478
                $tmp .= $query[$i++];
479 View Code Duplication
                while (isset($query[$i])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
480
                    && ($this->isChar($query[$i]) || in_array($query[$i], $classChars)
481
                        || $query[$i] == '*' || ($query[$i] == ' ' && $spaceAllowed))) {
482
                    if ($query[$i] != ' ') {
483
                        $spaceAllowed = false;
484
                    }
485
                    $tmp .= $query[$i];
486
                    $i++;
487
                }
488
                $return[] = $tmp;
489
                // + Adjacent sibling selectors
490
            } else {
491
                if ($c == '+') {
492
                    $spaceAllowed = true;
493
                    $tmp .= $query[$i++];
494 View Code Duplication
                    while (isset($query[$i])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
495
                        && ($this->isChar($query[$i]) || in_array($query[$i], $classChars)
496
                            || $query[$i] == '*' || ($spaceAllowed && $query[$i] == ' '))) {
497
                        if ($query[$i] != ' ') {
498
                            $spaceAllowed = false;
499
                        }
500
                        $tmp .= $query[$i];
501
                        $i++;
502
                    }
503
                    $return[] = $tmp;
504
                    // ATTRS
505
                } else {
506
                    if ($c == '[') {
507
                        $stack = 1;
508
                        $tmp .= $c;
509 View Code Duplication
                        while (isset($query[++$i])) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
510
                            $tmp .= $query[$i];
511
                            if ($query[$i] == '[') {
512
                                $stack++;
513
                            } else {
514
                                if ($query[$i] == ']') {
515
                                    $stack--;
516
                                    if (!$stack) {
517
                                        break;
518
                                    }
519
                                }
520
                            }
521
                        }
522
                        $return[] = $tmp;
523
                        $i++;
524
                        // PSEUDO CLASSES
525
                    } else {
526
                        if ($c == ':') {
527
                            $stack = 1;
0 ignored issues
show
$stack is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
528
                            $tmp .= $query[$i++];
529 View Code Duplication
                            while (isset($query[$i])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
530
                                && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) {
531
                                $tmp .= $query[$i];
532
                                $i++;
533
                            }
534
                            // with arguments ?
535
                            if (isset($query[$i]) && $query[$i] == '(') {
536
                                $tmp .= $query[$i];
537
                                $stack = 1;
538 View Code Duplication
                                while (isset($query[++$i])) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
539
                                    $tmp .= $query[$i];
540
                                    if ($query[$i] == '(') {
541
                                        $stack++;
542
                                    } else {
543
                                        if ($query[$i] == ')') {
544
                                            $stack--;
545
                                            if (!$stack) {
546
                                                break;
547
                                            }
548
                                        }
549
                                    }
550
                                }
551
                                $return[] = $tmp;
552
                                $i++;
553
                            } else {
554
                                $return[] = $tmp;
555
                            }
556
                        } else {
557
                            $i++;
558
                        }
559
                    }
560
                }
561
            }
562
        }
563
        foreach ($queries as $k => $q) {
564
            if (isset($q[0])) {
565
                if (isset($q[0][0]) && $q[0][0] == ':')
566
                    array_unshift($queries[$k], '*');
567
                if ($q[0] != '>')
568
                    array_unshift($queries[$k], ' ');
569
            }
570
        }
571
        return $queries;
572
    }
573
574
    /**
575
     * Return matched DOM nodes.
576
     *
577
     * @param int $index
578
     * @return array|\DOMElement Single \DOMElement or array of \DOMElement.
579
     */
580
    public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
581
    {
582
        $return = isset($index) ? (isset($this->elements[$index]) ? $this->elements[$index]
583
            : null) : $this->elements;
584
        // pass thou callbacks
585
        $args = func_get_args();
586
        $args = array_slice($args, 1);
587 View Code Duplication
        foreach ($args as $callback) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
588
            if (is_array($return))
589
                foreach ($return as $k => $v)
590
                    $return[$k] = PhpQuery::callbackRun(
591
                        $callback,
592
                        array(
593
                            $v
594
                        )
595
                    );
596
            else
597
                $return = PhpQuery::callbackRun(
598
                    $callback,
599
                    array(
600
                        $return
601
                    )
602
                );
603
        }
604
        return $return;
605
    }
606
607
    /**
608
     * Return matched DOM nodes.
609
     * jQuery difference.
610
     *
611
     * @param int  $index
612
     * @param null $callback1
613
     * @param null $callback2
614
     * @param null $callback3
615
     * @return array|string Returns string if $index != null
616
     * @todo implement callbacks
617
     * @todo return only arrays ?
618
     * @todo maybe other name...
619
     */
620
    public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
621
    {
622
        if ($index)
0 ignored issues
show
Bug Best Practice introduced by
The expression $index of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
623
            $return = $this->eq($index)->text();
624
        else {
625
            $return = array();
626 View Code Duplication
            for ($i = 0; $i < $this->size(); $i++) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
627
                $return[] = $this->eq($i)->text();
628
            }
629
        }
630
        // pass thou callbacks
631
        $args = func_get_args();
632
        $args = array_slice($args, 1);
633
        foreach ($args as $callback) {
634
            $return = PhpQuery::callbackRun(
635
                $callback,
636
                array(
637
                    $return
638
                )
639
            );
640
        }
641
        return $return;
642
    }
643
644
    /**
645
     * Return matched DOM nodes.
646
     * jQuery difference.
647
     *
648
     * @param int  $index
649
     * @param null $callback1
650
     * @param null $callback2
651
     * @param null $callback3
652
     * @return array|string Returns string if $index != null
653
     * @todo implement callbacks
654
     * @todo return only arrays ?
655
     * @todo maybe other name...
656
     */
657
    public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
658
    {
659
        if ($index)
0 ignored issues
show
Bug Best Practice introduced by
The expression $index of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
660
            $return = $this->eq($index)->text();
661
        else {
662
            $return = array();
663 View Code Duplication
            for ($i = 0; $i < $this->size(); $i++) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
664
                $return[] = $this->eq($i)->text();
665
            }
666
            // pass thou callbacks
667
            $args = func_get_args();
668
            $args = array_slice($args, 1);
669
        }
670 View Code Duplication
        foreach ($args as $callback) {
0 ignored issues
show
The variable $args does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
671
            if (is_array($return))
672
                foreach ($return as $k => $v)
673
                    $return[$k] = PhpQuery::callbackRun(
674
                        $callback,
675
                        array(
676
                            $v
677
                        )
678
                    );
679
            else
680
                $return = PhpQuery::callbackRun(
681
                    $callback,
682
                    array(
683
                        $return
684
                    )
685
                );
686
        }
687
        return $return;
688
    }
689
690
    /**
691
     * Returns new instance of actual class.
692
     *
693
     * @param array $newStack Optional. Will replace old stack with new and move old one to history.c
694
     * @return \PhpQuery\PhpQueryObject
695
     */
696
    public function newInstance($newStack = null)
697
    {
698
        $class = get_class($this);
699
        // support inheritance by passing old object to overloaded constructor
700
        $new           = $class != 'PhpQuery' ? new $class($this, $this->getDocumentID())
701
            : new PhpQueryObject($this->getDocumentID());
702
        $new->previous = $this;
703
        if (is_null($newStack)) {
704
            $new->elements = $this->elements;
705
            if ($this->elementsBackup)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->elementsBackup of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
706
                $this->elements = $this->elementsBackup;
707
        } else if (is_string($newStack)) {
708
            $new->elements = PhpQuery::pq($newStack, $this->getDocumentID())->stack();
709
        } else {
710
            $new->elements = $newStack;
711
        }
712
        return $new;
713
    }
714
715
    /**
716
     * Enter description here...
717
     *
718
     * In the future, when PHP will support XLS 2.0, then we would do that this way:
719
     * contains(tokenize(@class, '\s'), "something")
720
     * @param string $class
721
     * @param string $node
722
     * @return boolean
723
     * @access private
724
     */
725
    protected function matchClasses($class, $node)
726
    {
727
        // multi-class
728
        if (mb_strpos($class, '.', 1)) {
729
            $classes          = explode('.', substr($class, 1));
730
            $classesCount     = count($classes);
731
            $nodeClasses      = explode(' ', $node->getAttribute('class'));
0 ignored issues
show
The method getAttribute cannot be called on $node (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
732
            $nodeClassesCount = count($nodeClasses);
733
            if ($classesCount > $nodeClassesCount)
734
                return false;
735
            $diff = count(array_diff($classes, $nodeClasses));
736
            if (!$diff)
737
                return true;
738
            // single-class
739
        } else {
740
            return in_array(
741
            // strip leading dot from class name
742
                substr($class, 1),
743
                // get classes for element as array
744
                explode(' ', $node->getAttribute('class'))
0 ignored issues
show
The method getAttribute cannot be called on $node (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
745
            );
746
        }
747
    }
748
749
    /**
750
     * @access private
751
     */
752
    protected function runQuery($XQuery, $selector = null, $compare = null)
753
    {
754
        if ($compare && !method_exists($this, $compare))
755
            return false;
756
        $stack = array();
757
        if (!$this->elements)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->elements of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
758
            $this->debug('Stack empty, skipping...');
759
        //		var_dump($this->elements[0]->nodeType);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
760
        // element, document
761
        foreach ($this->stack(
762
                     array(
763
                         1,
764
                         9,
765
                         13
766
                     )
767
                 ) as $k => $stackNode) {
768
            $detachAfter = false;
769
            // to work on detached nodes we need temporary place them somewhere
770
            // thats because context xpath queries sucks ;]
771
            $testNode = $stackNode;
772
            while ($testNode) {
773
                if (!$testNode->parentNode && !$this->isRoot($testNode)) {
774
                    $this->root->appendChild($testNode);
0 ignored issues
show
The method appendChild cannot be called on $this->root (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
775
                    $detachAfter = $testNode;
776
                    break;
777
                }
778
                $testNode = isset($testNode->parentNode) ? $testNode->parentNode : null;
779
            }
780
            // XXX tmp ?
781
            $xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html')
782
                : $this->getNodeXpath($stackNode);
783
            // FIXME pseudoclasses-only query, support XML
784
            $query = $XQuery == '//' && $xpath == '/html[1]' ? '//*'
785
                : $xpath . $XQuery;
786
            $this->debug("XPATH: {$query}");
787
            // run query, get elements
788
            $nodes = $this->xpath->query($query);
789
            $this->debug("QUERY FETCHED");
790
            if (!$nodes->length)
791
                $this->debug('Nothing found');
792
            $debug = array();
793
            foreach ($nodes as $node) {
794
                $matched = false;
795
                if ($compare) {
796
                    PhpQuery::$debug ? $this->debug(
797
                        "Found: " . $this->whois($node)
798
                        . ", comparing with {$compare}()"
799
                    ) : null;
800
                    $PhpQueryDebug   = PhpQuery::$debug;
801
                    PhpQuery::$debug = false;
802
                    // TODO ??? use PhpQuery::callbackRun()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
803
                    if (call_user_func_array(
804
                        array(
805
                            $this,
806
                            $compare
807
                        ),
808
                        array(
809
                            $selector,
810
                            $node
811
                        )
812
                    )
813
                    )
814
                        $matched = true;
815
                    PhpQuery::$debug = $PhpQueryDebug;
816
                } else {
817
                    $matched = true;
818
                }
819
                if ($matched) {
820
                    if (PhpQuery::$debug)
821
                        $debug[] = $this->whois($node);
822
                    $stack[] = $node;
823
                }
824
            }
825
            if (PhpQuery::$debug) {
826
                $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug));
827
            }
828
            if ($detachAfter)
829
                $this->root->removeChild($detachAfter);
0 ignored issues
show
The method removeChild cannot be called on $this->root (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
830
        }
831
        $this->elements = $stack;
832
    }
833
834
    /**
835
     * Enter description here...
836
     *
837
     * @param      $selectors
838
     * @param null $context
839
     * @param bool $noHistory
840
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
841
     */
842
    public function find($selectors, $context = null, $noHistory = false)
843
    {
844
        if (!$noHistory)
845
            // backup last stack /for end()/
846
            $this->elementsBackup = $this->elements;
847
        // allow to define context
848
        // TODO combine code below with PhpQuery::pq() context guessing code
849
        //   as generic function
850
        if (isset($context)) {
851
            if (!is_array($context) && $context instanceof \DOMElement) {
852
                $this->elements = array(
853
                    $context
854
                );
855
            } elseif (is_array($context)) {
856
                $this->elements = array();
857
                foreach ($context as $c)
858
                    if ($c instanceof \DOMElement)
859
                        $this->elements[] = $c;
860
            } elseif ($context instanceof PhpQueryObject) {
861
                $this->elements = $context->elements;
862
            }
863
        }
864
865
        $queries = $this->parseSelector($selectors);
866
867
        $this->debug(
868
            array(
869
                'FIND',
870
                $selectors,
871
                $queries
872
            )
873
        );
874
        $XQuery = '';
875
        // remember stack state because of multi-queries
876
        $oldStack = $this->elements;
877
        // here we will be keeping found elements
878
        $stack = array();
879
        foreach ($queries as $selector) {
880
            $this->elements  = $oldStack;
881
            $delimiterBefore = false;
882
            foreach ($selector as $s) {
883
                // TAG
884
                $isTag = extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s)
885
                    || $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*';
886
                if ($isTag) {
887
                    if ($this->isXML()) {
888
                        // namespace support
889
                        if (mb_strpos($s, '|') !== false) {
890
                            $ns = $tag = null;
891
                            list($ns, $tag) = explode('|', $s);
892
                            $XQuery .= "$ns:$tag";
893
                        } else if ($s == '*') {
894
                            $XQuery .= "*";
895
                        } else {
896
                            $XQuery .= "*[local-name()='$s']";
897
                        }
898
                    } else {
899
                        $XQuery .= $s;
900
                    }
901
                    // ID
902
                } else if ($s[0] == '#') {
903
                    if ($delimiterBefore)
904
                        $XQuery .= '*';
905
                    $XQuery .= "[@id='" . substr($s, 1) . "']";
906
                    // ATTRIBUTES
907
                } else if ($s[0] == '[') {
908
                    if ($delimiterBefore)
909
                        $XQuery .= '*';
910
                    // strip side brackets
911
                    $attr    = trim($s, '][');
912
                    $execute = false;
913
                    // attr with specifed value
914
                    if (mb_strpos($s, '=')) {
915
                        $value = null;
916
                        list($attr, $value) = explode('=', $attr);
917
                        $value = trim($value, "'\"");
918
                        if ($this->isRegexp($attr)) {
919
                            // cut regexp character
920
                            $attr    = substr($attr, 0, -1);
921
                            $execute = true;
922
                            $XQuery .= "[@{$attr}]";
923
                        } else {
924
                            $XQuery .= "[@{$attr}='{$value}']";
925
                        }
926
                        // attr without specified value
927
                    } else {
928
                        $XQuery .= "[@{$attr}]";
929
                    }
930
                    if ($execute) {
931
                        $this->runQuery($XQuery, $s, 'is');
932
                        $XQuery = '';
933
                        if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
934
                            break;
935
                    }
936
                    // CLASSES
937
                } else if ($s[0] == '.') {
938
                    // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]");
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
939
                    // thx wizDom ;)
940
                    if ($delimiterBefore)
941
                        $XQuery .= '*';
942
                    $XQuery .= '[@class]';
943
                    $this->runQuery($XQuery, $s, 'matchClasses');
944
                    $XQuery = '';
945
                    if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
946
                        break;
947
                    // ~ General Sibling Selector
948
                } else if ($s[0] == '~') {
949
                    $this->runQuery($XQuery);
950
                    $XQuery         = '';
951
                    $this->elements = $this->siblings(substr($s, 1))->elements;
952
                    if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
953
                        break;
954
                    // + Adjacent sibling selectors
955
                } else if ($s[0] == '+') {
956
                    // TODO /following-sibling::
957
                    $this->runQuery($XQuery);
958
                    $XQuery         = '';
959
                    $subSelector    = substr($s, 1);
960
                    $subElements    = $this->elements;
961
                    $this->elements = array();
962
                    foreach ($subElements as $node) {
963
                        // search first \DOMElement sibling
964
                        $test = $node->nextSibling;
965
                        while ($test && !($test instanceof \DOMElement))
966
                            $test = $test->nextSibling;
967
                        if ($test && $this->is($subSelector, $test))
968
                            $this->elements[] = $test;
969
                    }
970
                    if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
971
                        break;
972
                    // PSEUDO CLASSES
973
                } else if ($s[0] == ':') {
974
                    // TODO optimization for :first :last
975
                    if ($XQuery) {
976
                        $this->runQuery($XQuery);
977
                        $XQuery = '';
978
                    }
979
                    if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
980
                        break;
981
                    $this->pseudoClasses($s);
982
                    if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
983
                        break;
984
                    // DIRECT DESCENDANDS
985
                } else if ($s == '>') {
986
                    $XQuery .= '/';
987
                    $delimiterBefore = 2;
988
                    // ALL DESCENDANDS
989
                } else if ($s == ' ') {
990
                    $XQuery .= '//';
991
                    $delimiterBefore = 2;
992
                    // ERRORS
993
                } else {
994
                    PhpQuery::debug("Unrecognized token '$s'");
995
                }
996
                $delimiterBefore = $delimiterBefore === 2;
997
            }
998
            // run query if any
999
            if ($XQuery && $XQuery != '//') {
1000
                $this->runQuery($XQuery);
1001
                $XQuery = '';
1002
            }
1003
            foreach ($this->elements as $node)
1004
                if (!$this->elementsContainsNode($node, $stack))
1005
                    $stack[] = $node;
1006
        }
1007
        $this->elements = $stack;
1008
        return $this->newInstance();
1009
    }
1010
1011
    /**
1012
     * @todo   create API for classes with pseudoselectors
1013
     * @access private
1014
     */
1015
    protected function pseudoClasses($class)
1016
    {
1017
        // TODO clean args parsing ?
1018
        $class    = ltrim($class, ':');
1019
        $haveArgs = mb_strpos($class, '(');
1020
        if ($haveArgs !== false) {
1021
            $args  = substr($class, $haveArgs + 1, -1);
1022
            $class = substr($class, 0, $haveArgs);
1023
        }
1024
        switch ($class) {
1025
            case 'even':
1026
            case 'odd':
1027
                $stack = array();
1028
                foreach ($this->elements as $i => $node) {
1029
                    if ($class == 'even' && ($i % 2) == 0)
1030
                        $stack[] = $node;
1031
                    else if ($class == 'odd' && $i % 2)
1032
                        $stack[] = $node;
1033
                }
1034
                $this->elements = $stack;
1035
                break;
1036
            case 'eq':
1037
                $k              = intval($args);
0 ignored issues
show
The variable $args does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1038
                $this->elements = isset($this->elements[$k]) ? array(
1039
                    $this->elements[$k]
1040
                ) : array();
1041
                break;
1042
            case 'gt':
1043
                $this->elements = array_slice($this->elements, $args + 1);
1044
                break;
1045
            case 'lt':
1046
                $this->elements = array_slice($this->elements, 0, $args + 1);
1047
                break;
1048
            case 'first':
1049
                if (isset($this->elements[0]))
1050
                    $this->elements = array(
1051
                        $this->elements[0]
1052
                    );
1053
                break;
1054
            case 'last':
1055
                if ($this->elements)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->elements of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1056
                    $this->elements = array(
1057
                        $this->elements[count($this->elements) - 1]
1058
                    );
1059
                break;
1060
            /*case 'parent':
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1061
          $stack = array();
1062
          foreach($this->elements as $node) {
1063
              if ( $node->childNodes->length )
1064
                  $stack[] = $node;
1065
          }
1066
          $this->elements = $stack;
1067
          break;*/
1068
            case 'contains':
1069
                $text  = trim($args, "\"'");
1070
                $stack = array();
1071
                foreach ($this->elements as $node) {
1072
                    if (mb_stripos($node->textContent, $text) === false)
1073
                        continue;
1074
                    $stack[] = $node;
1075
                }
1076
                $this->elements = $stack;
1077
                break;
1078
            case 'not':
1079
                $selector       = self::unQuote($args);
1080
                $this->elements = $this->not($selector)->stack();
1081
                break;
1082
            case 'slice':
1083
                // TODO jQuery difference ?
1084
                $args  = explode(',', str_replace(', ', ',', trim($args, "\"'")));
1085
                $start = $args[0];
1086
                $end   = isset($args[1]) ? $args[1] : null;
1087
                if ($end > 0)
1088
                    $end = $end - $start;
1089
                $this->elements = array_slice($this->elements, $start, $end);
1090
                break;
1091
            case 'has':
1092
                $selector = trim($args, "\"'");
1093
                $stack    = array();
1094
                foreach ($this->stack(1) as $el) {
1095
                    if ($this->find($selector, $el, true)->length)
1096
                        $stack[] = $el;
1097
                }
1098
                $this->elements = $stack;
1099
                break;
1100
            case 'submit':
1101
            case 'reset':
1102
                $this->elements = PhpQuery::merge(
1103
                    $this->map(
0 ignored issues
show
It seems like $this->map(array($this, ..., new \CallbackParam()) targeting PhpQuery\PhpQueryObject::map() can also be of type object<PhpQuery\PhpQueryObject>; however, PhpQuery\PhpQuery::merge() does only seem to accept array, 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.

Loading history...
1104
                        array(
1105
                            $this,
1106
                            'is'
1107
                        ),
1108
                        "input[type=$class]",
1109
                        new \CallbackParam()
1110
                    ),
1111
                    $this->map(
0 ignored issues
show
It seems like $this->map(array($this, ..., new \CallbackParam()) targeting PhpQuery\PhpQueryObject::map() can also be of type object<PhpQuery\PhpQueryObject>; however, PhpQuery\PhpQuery::merge() does only seem to accept array, 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.

Loading history...
1112
                        array(
1113
                            $this,
1114
                            'is'
1115
                        ),
1116
                        "button[type=$class]",
1117
                        new \CallbackParam()
1118
                    )
1119
                );
1120
                break;
1121
            //				$stack = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1122
            //				foreach($this->elements as $node)
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% 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...
1123
            //					if ($node->is('input[type=submit]') || $node->is('button[type=submit]'))
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
1124
            //						$stack[] = $el;
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1125
            //				$this->elements = $stack;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
1126
            case 'input':
1127
                $this->elements = $this->map(
1128
                    array(
1129
                        $this,
1130
                        'is'
1131
                    ),
1132
                    'input',
1133
                    new \CallbackParam()
1134
                )->elements;
1135
                break;
1136
            case 'password':
1137
            case 'checkbox':
1138
            case 'radio':
1139
            case 'hidden':
1140
            case 'image':
1141 View Code Duplication
            case 'file':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1142
                $this->elements = $this->map(
1143
                    array(
1144
                        $this,
1145
                        'is'
1146
                    ),
1147
                    "input[type=$class]",
1148
                    new \CallbackParam()
1149
                )->elements;
1150
                break;
1151
            case 'parent':
1152
                $this->elements = $this->map(
1153
                    create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1154
                        '$node',
1155
                        '
1156
						return $node instanceof \DOMElement && $node->childNodes->length
1157
							? $node : null;'
1158
                    )
1159
                )->elements;
1160
                break;
1161
            case 'empty':
1162
                $this->elements = $this->map(
1163
                    create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1164
                        '$node',
1165
                        '
1166
						return $node instanceof \DOMElement && $node->childNodes->length
1167
							? null : $node;'
1168
                    )
1169
                )->elements;
1170
                break;
1171
            case 'disabled':
1172
            case 'selected':
1173 View Code Duplication
            case 'checked':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1174
                $this->elements = $this->map(
1175
                    array(
1176
                        $this,
1177
                        'is'
1178
                    ),
1179
                    "[$class]",
1180
                    new \CallbackParam()
1181
                )->elements;
1182
                break;
1183
            case 'enabled':
1184
                $this->elements = $this->map(
1185
                    create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1186
                        '$node',
1187
                        '
1188
						return pq($node)->not(":disabled") ? $node : null;'
1189
                    )
1190
                )->elements;
1191
                break;
1192
            case 'header':
1193
                $this->elements = $this->map(
1194
                    create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1195
                        '$node',
1196
                        '$isHeader = isset($node->tagName) && in_array($node->tagName, array(
1197
							"h1", "h2", "h3", "h4", "h5", "h6", "h7"
1198
						));
1199
						return $isHeader
1200
							? $node
1201
							: null;'
1202
                    )
1203
                )->elements;
1204
                //				$this->elements = $this->map(
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% 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...
1205
                //					create_function('$node', '$node = pq($node);
1206
                //						return $node->is("h1")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1207
                //							|| $node->is("h2")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1208
                //							|| $node->is("h3")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1209
                //							|| $node->is("h4")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1210
                //							|| $node->is("h5")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1211
                //							|| $node->is("h6")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1212
                //							|| $node->is("h7")
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
1213
                //							? $node
1214
                //							: null;')
1215
                //				)->elements;
1216
                break;
1217
            case 'only-child':
1218
                $this->elements = $this->map(
1219
                    create_function('$node', 'return pq($node)->siblings()->size() == 0 ? $node : null;')
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1220
                )->elements;
1221
                break;
1222
            case 'first-child':
1223
                $this->elements = $this->map(
1224
                    create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;')
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1225
                )->elements;
1226
                break;
1227
            case 'last-child':
1228
                $this->elements = $this->map(
1229
                    create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;')
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1230
                )->elements;
1231
                break;
1232
            case 'nth-child':
1233
                $param = trim($args, "\"'");
1234
                if (!$param)
1235
                    break;
1236
                // nth-child(n+b) to nth-child(1n+b)
1237
                if ($param{0} == 'n')
1238
                    $param = '1' . $param;
1239
                // :nth-child(index/even/odd/equation)
1240
                if ($param == 'even' || $param == 'odd')
1241
                    $mapped = $this->map(
1242
                        create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1243
                            '$node, $param',
1244
                            '$index = pq($node)->prevAll()->size()+1;
1245
							if ($param == "even" && ($index%2) == 0)
1246
								return $node;
1247
							else if ($param == "odd" && $index%2 == 1)
1248
								return $node;
1249
							else
1250
								return null;'
1251
                        ),
1252
                        new \CallbackParam(),
1253
                        $param
1254
                    );
1255
                else if (mb_strlen($param) > 1
1256
                    && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1
1257
                )
1258
                    // an+b
1259
                    $mapped = $this->map(
1260
                        create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1261
                            '$node, $param',
1262
                            '$prevs = pq($node)->prevAll()->size();
1263
							$index = 1+$prevs;
1264
1265
							preg_match("/^(\d*)n([-+]?)(\d*)/", $param, $matches);
1266
							$a = intval($matches[1]);
1267
							$b = intval($matches[3]);
1268
							if( $matches[2] === "-" ) {
1269
							    $b = -$b;
1270
							}
1271
1272
							if ($a > 0) {
1273
								return ($index-$b)%$a == 0
1274
									? $node
1275
									: null;
1276
								PhpQuery::debug($a."*".floor($index/$a)."+$b-1 == ".($a*floor($index/$a)+$b-1)." ?= $prevs");
1277
								return $a*floor($index/$a)+$b-1 == $prevs
1278
										? $node
1279
										: null;
1280
							} else if ($a == 0)
1281
								return $index == $b
1282
										? $node
1283
										: null;
1284
							else
1285
								// negative value
1286
								return $index <= $b
1287
										? $node
1288
										: null;
1289
//							if (! $b)
1290
//								return $index%$a == 0
1291
//									? $node
1292
//									: null;
1293
//							else
1294
//								return ($index-$b)%$a == 0
1295
//									? $node
1296
//									: null;
1297
							'
1298
                        ),
1299
                        new \CallbackParam(),
1300
                        $param
1301
                    );
1302
                else
1303
                    // index
1304
                    $mapped = $this->map(
1305
                        create_function(
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1306
                            '$node, $index',
1307
                            '$prevs = pq($node)->prevAll()->size();
1308
							if ($prevs && $prevs == $index-1)
1309
								return $node;
1310
							else if (! $prevs && $index == 1)
1311
								return $node;
1312
							else
1313
								return null;'
1314
                        ),
1315
                        new \CallbackParam(),
1316
                        $param
1317
                    );
1318
                $this->elements = $mapped->elements;
1319
                break;
1320
            default:
1321
                $this->debug("Unknown pseudoclass '{$class}', skipping...");
1322
        }
1323
    }
1324
1325
    /**
1326
     * @access private
1327
     */
1328
    protected function __pseudoClassParam($paramsString)
0 ignored issues
show
The parameter $paramsString is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1329
    {
1330
        // TODO;
1331
    }
1332
1333
    /**
1334
     * Enter description here...
1335
     *
1336
     * @param      $selector
1337
     * @param null $nodes
1338
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1339
     */
1340
    public function is($selector, $nodes = null)
1341
    {
1342
        PhpQuery::debug(
1343
            array(
1344
                "Is:",
1345
                $selector
1346
            )
1347
        );
1348
        if (!$selector)
1349
            return false;
1350
        $oldStack    = $this->elements;
1351
        $returnArray = false;
0 ignored issues
show
$returnArray is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1352
        if ($nodes && is_array($nodes)) {
1353
            $this->elements = $nodes;
1354
        } else if ($nodes)
1355
            $this->elements = array(
1356
                $nodes
1357
            );
1358
        $this->filter($selector, true);
1359
        $stack          = $this->elements;
1360
        $this->elements = $oldStack;
1361
        if ($nodes)
1362
            return $stack ? $stack : null;
1363
        return (bool) count($stack);
1364
    }
1365
1366
    /**
1367
     * Enter description here...
1368
     * jQuery difference.
1369
     *
1370
     * Callback:
1371
     * - $index int
1372
     * - $node DOMNode
1373
     *
1374
     * @param      $callback
1375
     * @param bool $_skipHistory
1376
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1377
     * @link http://docs.jquery.com/Traversing/filter
1378
     */
1379
    public function filterCallback($callback, $_skipHistory = false)
1380
    {
1381
        if (!$_skipHistory) {
1382
            $this->elementsBackup = $this->elements;
1383
            $this->debug("Filtering by callback");
1384
        }
1385
        $newStack = array();
1386
        foreach ($this->elements as $index => $node) {
1387
            $result = PhpQuery::callbackRun(
1388
                $callback,
1389
                array(
1390
                    $index,
1391
                    $node
1392
                )
1393
            );
1394
            if (is_null($result) || (!is_null($result) && $result))
1395
                $newStack[] = $node;
1396
        }
1397
        $this->elements = $newStack;
1398
        return $_skipHistory ? $this : $this->newInstance();
1399
    }
1400
1401
    /**
1402
     * Enter description here...
1403
     *
1404
     * @param      $selectors
1405
     * @param bool $_skipHistory
1406
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1407
     * @link http://docs.jquery.com/Traversing/filter
1408
     */
1409
    public function filter($selectors, $_skipHistory = false)
1410
    {
1411
        if ($selectors instanceof \Callback OR $selectors instanceof \Closure)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
1412
            return $this->filterCallback($selectors, $_skipHistory);
1413
        if (!$_skipHistory)
1414
            $this->elementsBackup = $this->elements;
1415
        $notSimpleSelector = array(
1416
            ' ',
1417
            '>',
1418
            '~',
1419
            '+',
1420
            '/'
1421
        );
1422
        if (!is_array($selectors))
1423
            $selectors = $this->parseSelector($selectors);
1424
        if (!$_skipHistory)
1425
            $this->debug(
1426
                array(
1427
                    "Filtering:",
1428
                    $selectors
1429
                )
1430
            );
1431
        $finalStack = array();
1432
        foreach ($selectors as $selector) {
1433
            $stack = array();
1434
            if (!$selector)
1435
                break;
1436
            // avoid first space or /
1437
            if (in_array($selector[0], $notSimpleSelector))
1438
                $selector = array_slice($selector, 1);
1439
            // PER NODE selector chunks
1440
            foreach ($this->stack() as $node) {
1441
                $break = false;
1442
                foreach ($selector as $s) {
1443
                    if (!($node instanceof \DOMElement)) {
1444
                        // all besides \DOMElement
1445
                        if ($s[0] == '[') {
1446
                            $attr = trim($s, '[]');
1447
                            if (mb_strpos($attr, '=')) {
1448
                                list($attr, $val) = explode('=', $attr);
1449
                                if ($attr == 'nodeType' && $node->nodeType != $val)
1450
                                    $break = true;
1451
                            }
1452
                        } else
1453
                            $break = true;
1454
                    } else {
1455
                        // \DOMElement only
1456
                        // ID
1457
                        if ($s[0] == '#') {
1458
                            if ($node->getAttribute('id') != substr($s, 1))
1459
                                $break = true;
1460
                            // CLASSES
1461
                        } else if ($s[0] == '.') {
1462
                            if (!$this->matchClasses($s, $node))
0 ignored issues
show
$node is of type object<DOMElement>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Best Practice introduced by
The expression $this->matchClasses($s, $node) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
1463
                                $break = true;
1464
                            // ATTRS
1465
                        } else if ($s[0] == '[') {
1466
                            // strip side brackets
1467
                            $attr = trim($s, '[]');
1468
                            if (mb_strpos($attr, '=')) {
1469
                                list($attr, $val) = explode('=', $attr);
1470
                                $val = self::unQuote($val);
1471
                                if ($attr == 'nodeType') {
1472
                                    if ($val != $node->nodeType)
1473
                                        $break = true;
1474
                                } else if ($this->isRegexp($attr)) {
1475
                                    $val = extension_loaded('mbstring')
1476
                                    && PhpQuery::$mbstringSupport ? quotemeta(trim($val, '"\''))
1477
                                        : preg_quote(trim($val, '"\''), '@');
1478
                                    // switch last character
1479
                                    switch (substr($attr, -1)) {
1480
                                        // quotemeta used insted of preg_quote
1481
                                        // http://code.google.com/p/phpquery/issues/detail?id=76
1482
                                        case '^':
1483
                                            $pattern = '^' . $val;
1484
                                            break;
1485
                                        case '*':
1486
                                            $pattern = '.*' . $val . '.*';
1487
                                            break;
1488
                                        case '$':
1489
                                            $pattern = '.*' . $val . '$';
1490
                                            break;
1491
                                    }
1492
                                    // cut last character
1493
                                    $attr    = substr($attr, 0, -1);
1494
                                    $isMatch = extension_loaded('mbstring')
1495
                                    && PhpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr))
0 ignored issues
show
The variable $pattern does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1496
                                        : preg_match("@{$pattern}@", $node->getAttribute($attr));
1497
                                    if (!$isMatch)
1498
                                        $break = true;
1499
                                } else if ($node->getAttribute($attr) != $val)
1500
                                    $break = true;
1501
                            } else if (!$node->hasAttribute($attr))
1502
                                $break = true;
1503
                            // PSEUDO CLASSES
1504
                        } else if ($s[0] == ':') {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1505
                            // skip
1506
                            // TAG
1507
                        } else if (trim($s)) {
1508
                            if ($s != '*') {
1509
                                // TODO namespaces
1510
                                if (isset($node->tagName)) {
1511
                                    if ($node->tagName != $s)
1512
                                        $break = true;
1513
                                } else if ($s == 'html' && !$this->isRoot($node))
1514
                                    $break = true;
1515
                            }
1516
                            // AVOID NON-SIMPLE SELECTORS
1517
                        } else if (in_array($s, $notSimpleSelector)) {
1518
                            $break = true;
1519
                            $this->debug(
1520
                                array(
1521
                                    'Skipping non simple selector',
1522
                                    $selector
1523
                                )
1524
                            );
1525
                        }
1526
                    }
1527
                    if ($break)
1528
                        break;
1529
                }
1530
                // if element passed all chunks of selector - add it to new stack
1531
                if (!$break)
1532
                    $stack[] = $node;
1533
            }
1534
            $tmpStack       = $this->elements;
1535
            $this->elements = $stack;
1536
            // PER ALL NODES selector chunks
1537
            foreach ($selector as $s)
1538
                // PSEUDO CLASSES
1539
                if ($s[0] == ':')
1540
                    $this->pseudoClasses($s);
1541
            foreach ($this->elements as $node)
1542
                // XXX it should be merged without duplicates
1543
                // but jQuery doesnt do that
1544
                $finalStack[] = $node;
1545
            $this->elements = $tmpStack;
1546
        }
1547
        $this->elements = $finalStack;
1548
        if ($_skipHistory) {
1549
            return $this;
1550
        } else {
1551
            $this->debug("Stack length after filter(): " . count($finalStack));
1552
            return $this->newInstance();
1553
        }
1554
    }
1555
1556
    /**
1557
     *
1558
     * @param $value
1559
     * @return string
1560
     * @TODO implement in all methods using passed parameters
1561
     */
1562
    protected static function unQuote($value)
1563
    {
1564
        return $value[0] == '\'' || $value[0] == '"' ? substr($value, 1, -1)
1565
            : $value;
1566
    }
1567
1568
    /**
1569
     * Enter description here...
1570
     *
1571
     * @link http://docs.jquery.com/Ajax/load
1572
     * @param      $url
1573
     * @param null $data
1574
     * @param null $callback
1575
     * @return PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1576
     * @todo Support $selector
1577
     */
1578
    public function load($url, $data = null, $callback = null)
1579
    {
1580
        if ($data && !is_array($data)) {
1581
            $callback = $data;
1582
            $data     = null;
1583
        }
1584
        if (mb_strpos($url, ' ') !== false) {
1585
            $matches = null;
1586
            if (extension_loaded('mbstring') && PhpQuery::$mbstringSupport)
1587
                mb_ereg('^([^ ]+) (.*)$', $url, $matches);
1588
            else
1589
                preg_match('@^([^ ]+) (.*)$@', $url, $matches);
1590
            $url      = $matches[1];
1591
            $selector = $matches[2];
1592
            // FIXME this sucks, pass as callback param
1593
            $this->_loadSelector = $selector;
0 ignored issues
show
The property _loadSelector does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1594
        }
1595
        $ajax = array(
1596
            'url'      => $url,
1597
            'type'     => $data ? 'POST' : 'GET',
1598
            'data'     => $data,
1599
            'complete' => $callback,
1600
            'success'  => array(
1601
                $this,
1602
                '__loadSuccess'
1603
            )
1604
        );
1605
        PhpQuery::ajax($ajax);
1606
        return $this;
1607
    }
1608
1609
    /**
1610
     * @access private
1611
     * @param $html
1612
     */
1613
    public function __loadSuccess($html)
1614
    {
1615
        if ($this->_loadSelector) {
1616
            $html = PhpQuery::newDocument($html)->find($this->_loadSelector);
1617
            unset($this->_loadSelector);
1618
        }
1619
        foreach ($this->stack(1) as $node) {
1620
            PhpQuery::pq($node, $this->getDocumentID())->markup($html);
1621
        }
1622
    }
1623
1624
    /**
1625
     * Allows users to enter strings of CSS selectors. Useful
1626
     * when the CSS is loaded via style or @imports that PhpQuery can't load
1627
     * because it doesn't know the URL context of the request.
1628
     */
1629
    public function addCSS($string)
1630
    {
1631
        if (!isset($this->cssString[$this->getDocumentID()])) {
1632
            $this->cssString[$this->getDocumentID()] = '';
1633
        }
1634
        $this->cssString[$this->getDocumentID()] .= $string;
1635
        $this->parseCSS();
1636
    }
1637
1638
    /**
1639
     * Either sets the CSS property of an object or retrieves the
1640
     * CSS property of a proejct.
1641
     *
1642
     * @param      $property_name
1643
     * @param bool $value
1644
     * @return string of css property value
1645
     * @todo
1646
     */
1647
    public function css($property_name, $value = false)
1648
    {
1649
        if (!isset($this->cssIsParsed[$this->getDocumentID()])
1650
        || $this->cssIsParsed[$this->getDocumentID()] === false
1651
        ) {
1652
            $this->parseCSS();
1653
        }
1654
        $data = PhpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID());
1655
        if (!$value) {
1656
            if (isset($data[$property_name])) {
1657
                return $data[$property_name]['value'];
1658
            }
1659
            return null;
1660
        }
1661
        $specificity          = (isset($data[$property_name])) ? $data[$property_name]['specificity']
1662
            + 1 : 1000;
1663
        $data[$property_name] = array(
1664
            'specificity' => $specificity,
1665
            'value'       => $value
1666
        );
1667
        PhpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID());
1668
        $this->bubbleCSS(PhpQuery::pq($this->get(0), $this->getDocumentID()));
1669
1670
        if ($specificity >= 1000) {
1671
            $styles = array();
1672
            foreach ($this->data('phpquery_css') as $k => $v) {
1673
                if ($v['specificity'] >= 1000) {
1674
                    $styles[$k] = trim($k) . ':' . trim($v['value']);
1675
                }
1676
            }
1677
            ksort($styles);
1678
            if (empty($styles)) {
1679
                $this->removeAttr('style');
1680
            } elseif (PhpQuery::$enableCssShorthand) {
1681
                $parser = new \Sabberworm\CSS\Parser('{' . join(';', $styles) . '}');
1682
                $doc    = $parser->parse();
1683
                $doc->createShorthands();
1684
                $style = trim($doc->__toString(), "\n\r\t {}");
1685
            } else {
1686
                $style = join(';', $styles);
1687
            }
1688
            $this->attr('style', $style);
0 ignored issues
show
The variable $style does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1689
        }
1690
    }
1691
1692
    public function parseCSS()
1693
    {
1694
        if (!isset($this->cssString[$this->getDocumentID()])) {
1695
            $this->cssString[$this->getDocumentID()] = file_get_contents(
1696
                dirname(__FILE__)
1697
                . '/Resources/default.css'
1698
            );
1699
        }
1700
        foreach (PhpQuery::pq('style', $this->getDocumentID()) as $style) {
1701
            $this->cssString[$this->getDocumentID()] .= PhpQuery::pq($style)->text();
1702
        }
1703
1704
        $CssParser   = new CssParser($this->cssString[$this->getDocumentID()]);
1705
        $CssDocument = $CssParser->parse();
1706
        foreach ($CssDocument->getAllRuleSets() as $ruleset) {
1707
            foreach ($ruleset->getSelector() as $selector) {
1708
                $specificity = $selector->getSpecificity();
1709
                foreach (PhpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) {
1710
                    $existing = pq($el)->data('phpquery_css');
1711
                    if (PhpQuery::$enableCssShorthand) {
1712
                        $ruleset->expandShorthands();
1713
                    }
1714
                    foreach ($ruleset->getRules() as $value) {
1715
                        $rule = $value->getRule();
1716
                        if (!isset($existing[$rule])
1717
                            || $existing[$rule]['specificity'] <= $specificity
1718
                        ) {
1719
                            $value           = $value->getValue();
1720
                            $value           = (is_object($value)) ? $value->__toString() : $value;
1721
                            $existing[$rule] = array(
1722
                                'specificity' => $specificity,
1723
                                'value'       => $value
1724
                            );
1725
                        }
1726
                    }
1727
                    PhpQuery::pq($el)->data('phpquery_css', $existing);
1728
                    $this->bubbleCSS(PhpQuery::pq($el));
1729
                }
1730
            }
1731
        }
1732
        foreach (PhpQuery::pq('*', $this->getDocumentID()) as $el) {
1733
            $existing = pq($el)->data('phpquery_css');
1734
            $style    = pq($el)->attr('style');
1735
            $style    = strlen($style) ? explode(';', $style) : array();
1736
            foreach ($this->attribute_css_mapping as $map => $css_equivalent) {
1737
                if ($el->hasAttribute($map)) {
1738
                    $style[] = $css_equivalent . ':' . pq($el)->attr($map);
1739
                }
1740
            }
1741
            if (count($style)) {
1742
                $CssParser   = new CssParser('#ruleset {' . implode(';', $style) . '}');
1743
                $CssDocument = $CssParser->parse();
1744
                $ruleset     = $CssDocument->getAllRulesets();
1745
                $ruleset     = reset($ruleset);
1746
                if (PhpQuery::$enableCssShorthand) {
1747
                    $ruleset->expandShorthands();
1748
                }
1749
                foreach ($ruleset->getRules() as $value) {
1750
                    $rule = $value->getRule();
1751
                    if (!isset($existing[$rule])
1752
                        || 1000 >= $existing[$rule]['specificity']
1753
                    ) {
1754
                        $value           = $value->getValue();
1755
                        $value           = (is_object($value)) ? $value->__toString() : $value;
1756
                        $existing[$rule] = array(
1757
                            'specificity' => 1000,
1758
                            'value'       => $value
1759
                        );
1760
                    }
1761
                }
1762
                PhpQuery::pq($el)->data('phpquery_css', $existing);
1763
                $this->bubbleCSS(PhpQuery::pq($el));
1764
            }
1765
        }
1766
    }
1767
1768
    protected function bubbleCSS($element)
1769
    {
1770
        $style = $element->data('phpquery_css');
1771
        foreach ($element->children() as $element_child) {
1772
            $existing = PhpQuery::pq($element_child)->data('phpquery_css');
1773
            foreach ($style as $rule => $value) {
1774
                if (!isset($existing[$rule])
1775
                    || $value['specificity'] > $existing[$rule]['specificity']
1776
                ) {
1777
                    $existing[$rule] = $value;
1778
                }
1779
            }
1780
            PhpQuery::pq($element_child)->data('phpquery_css', $existing);
1781
            if (PhpQuery::pq($element_child)->children()->length) {
1782
                $this->bubbleCSS(PhpQuery::pq($element_child));
1783
            }
1784
        }
1785
    }
1786
1787
    /**
1788
     * @todo
1789
     *
1790
     */
1791
    public function show()
1792
    {
1793
        $display = ($this->data('phpquery_display_state')) ? $this->data('phpquery_display_state')
1794
            : 'block';
1795
        $this->css('display', $display);
0 ignored issues
show
$display is of type this<PhpQuery\PhpQueryObject>|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1796
        return $this;
1797
    }
1798
1799
    /**
1800
     * @todo
1801
     *
1802
     */
1803
    public function hide()
1804
    {
1805
        $this->data('phpquery_display_state', $this->css('display'));
1806
        $this->css('display', 'none');
0 ignored issues
show
'none' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1807
        return $this;
1808
    }
1809
1810
    /**
1811
     * Trigger a type of event on every matched element.
1812
     *
1813
     * @param                 $type
1814
     * @param array|\PhpQuery $data
1815
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1816
     * @TODO support more than event in $type (space-separated)
1817
     */
1818
    public function trigger($type, $data = array())
1819
    {
1820
        foreach ($this->elements as $node)
1821
            PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node);
0 ignored issues
show
It seems like $data defined by parameter $data on line 1818 can also be of type object<PhpQuery>; however, PhpQuery\PhpQueryEvents::trigger() does only seem to accept array, 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.

Loading history...
1822
        return $this;
1823
    }
1824
1825
    /**
1826
     * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.
1827
     *
1828
     * @param  $type
1829
     * @param  $data
1830
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1831
     * @TODO
1832
     */
1833
    public function triggerHandler($type, $data = array())
0 ignored issues
show
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1834
    {
1835
        // TODO;
1836
    }
1837
1838
    /**
1839
     * Binds a handler to one or more events (like click) for each matched element.
1840
     * Can also bind custom events.
1841
     *
1842
     * @param       $type
1843
     * @param mixed $data Optional
1844
     * @param       $callback
1845
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1846
     * @TODO support '!' (exclusive) events
1847
     * @TODO support more than event in $type (space-separated)
1848
     */
1849
    public function bind($type, $data, $callback = null)
1850
    {
1851
        // TODO check if $data is callable, not using is_callable
1852
        if (!isset($callback)) {
1853
            $callback = $data;
1854
            $data     = null;
1855
        }
1856
        foreach ($this->elements as $node)
1857
            PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback);
1858
        return $this;
1859
    }
1860
1861
    /**
1862
     * Enter description here...
1863
     *
1864
     * @param string $type
1865
     * @param        $callback
1866
     * @return unknown
1867
     * @TODO namespace events
1868
     * @TODO support more than event in $type (space-separated)
1869
     */
1870
    public function unbind($type = null, $callback = null)
1871
    {
1872
        foreach ($this->elements as $node)
1873
            PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback);
1874
        return $this;
1875
    }
1876
1877
    /**
1878
     * Enter description here...
1879
     *
1880
     * @param null $callback
1881
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1882
     */
1883
    public function change($callback = null)
1884
    {
1885
        if ($callback)
1886
            return $this->bind('change', $callback);
1887
        return $this->trigger('change');
1888
    }
1889
1890
    /**
1891
     * Enter description here...
1892
     *
1893
     * @param null $callback
1894
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1895
     */
1896
    public function submit($callback = null)
1897
    {
1898
        if ($callback)
1899
            return $this->bind('submit', $callback);
1900
        return $this->trigger('submit');
1901
    }
1902
1903
    /**
1904
     * Enter description here...
1905
     *
1906
     * @param null $callback
1907
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1908
     */
1909
    public function click($callback = null)
1910
    {
1911
        if ($callback)
1912
            return $this->bind('click', $callback);
1913
        return $this->trigger('click');
1914
    }
1915
1916
    /**
1917
     * Enter description here...
1918
     *
1919
     * @param String|PhpQuery
1920
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1921
     */
1922
    public function wrapAllOld($wrapper)
1923
    {
1924
        $wrapper = pq($wrapper)->_clone();
1925
        if (!$wrapper->length() || !$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1926
            return $this;
1927
        $wrapper->insertBefore($this->elements[0]);
1928
        $deepest = $wrapper->elements[0];
1929
        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1930
            $deepest = $deepest->firstChild;
1931
        pq($deepest)->append($this);
1932
        return $this;
1933
    }
1934
1935
    /**
1936
     * Enter description here...
1937
     *
1938
     * TODO testme...
1939
     * @param String|PhpQuery
1940
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1941
     */
1942
    public function wrapAll($wrapper)
1943
    {
1944
        if (!$this->length())
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1945
            return $this;
1946
        return PhpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(
1947
            array(
1948
                $this,
1949
                '___wrapAllCallback'
1950
            )
1951
        )->append($this);
1952
    }
1953
1954
    /**
1955
     *
1956
     * @param $node
1957
     * @return unknown_type
1958
     * @access private
1959
     */
1960
    public function ___wrapAllCallback($node)
1961
    {
1962
        $deepest = $node;
1963
        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1964
            $deepest = $deepest->firstChild;
1965
        return $deepest;
1966
    }
1967
1968
    /**
1969
     * Enter description here...
1970
     * NON JQUERY METHOD
1971
     *
1972
     * @param $codeBefore
1973
     * @param $codeAfter
1974
     * @internal param $ String|PhpQuery
1975
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1976
     */
1977
    public function wrapAllPHP($codeBefore, $codeAfter)
1978
    {
1979
        return $this->slice(0, 1)->beforePHP($codeBefore)->end()->slice(-1)->afterPHP($codeAfter)->end();
0 ignored issues
show
0 is of type integer, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1 is of type integer, but the function expects a object<PhpQuery\unknown_type>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1980
    }
1981
1982
    /**
1983
     * Enter description here...
1984
     *
1985
     * @param String|PhpQuery
1986
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1987
     */
1988
    public function wrap($wrapper)
1989
    {
1990
        foreach ($this->stack() as $node)
1991
            PhpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
1992
        return $this;
1993
    }
1994
1995
    /**
1996
     * Enter description here...
1997
     *
1998
     * @param $codeBefore
1999
     * @param $codeAfter
2000
     * @internal param $ String|PhpQuery
2001
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2002
     */
2003
    public function wrapPHP($codeBefore, $codeAfter)
2004
    {
2005
        foreach ($this->stack() as $node)
2006
            PhpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
2007
        return $this;
2008
    }
2009
2010
    /**
2011
     * Enter description here...
2012
     *
2013
     * @param String|PhpQuery
2014
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2015
     */
2016
    public function wrapInner($wrapper)
2017
    {
2018
        foreach ($this->stack() as $node)
2019
            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
2020
        return $this;
2021
    }
2022
2023
    /**
2024
     * Enter description here...
2025
     *
2026
     * @param $codeBefore
2027
     * @param $codeAfter
2028
     * @internal param $ String|PhpQuery
2029
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2030
     */
2031
    public function wrapInnerPHP($codeBefore, $codeAfter)
2032
    {
2033
        foreach ($this->stack(1) as $node)
2034
            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
2035
        return $this;
2036
    }
2037
2038
    /**
2039
     * Enter description here...
2040
     *
2041
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2042
     * @testme Support for text nodes
2043
     */
2044
    public function contents()
2045
    {
2046
        $stack = array();
2047
        foreach ($this->stack(1) as $el) {
2048
            // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56
2049
            //			if (! isset($el->childNodes))
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
2050
            //				continue;
2051
            foreach ($el->childNodes as $node) {
2052
                $stack[] = $node;
2053
            }
2054
        }
2055
        return $this->newInstance($stack);
2056
    }
2057
2058
    /**
2059
     * Enter description here...
2060
     *
2061
     * jQuery difference.
2062
     *
2063
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2064
     */
2065
    public function contentsUnwrap()
2066
    {
2067
        foreach ($this->stack(1) as $node) {
2068
            if (!$node->parentNode)
2069
                continue;
2070
            $childNodes = array();
2071
            // any modification in DOM tree breaks childNodes iteration, so cache them first
2072
            foreach ($node->childNodes as $chNode)
2073
                $childNodes[] = $chNode;
2074
            foreach ($childNodes as $chNode)
2075
                //				$node->parentNode->appendChild($chNode);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
2076
                $node->parentNode->insertBefore($chNode, $node);
2077
            $node->parentNode->removeChild($node);
2078
        }
2079
        return $this;
2080
    }
2081
2082
    /**
2083
     * Enter description here...
2084
     *
2085
     * jQuery difference.
2086
     */
2087
    public function switchWith($markup)
2088
    {
2089
        $markup  = pq($markup, $this->getDocumentID());
2090
        $content = null;
2091
        foreach ($this->stack(1) as $node) {
2092
            pq($node)->contents()->toReference($content)->end()->replaceWith($markup->clone()->append($content));
2093
        }
2094
        return $this;
2095
    }
2096
2097
    /**
2098
     * Enter description here...
2099
     *
2100
     * @param $num
2101
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2102
     */
2103
    public function eq($num)
2104
    {
2105
        $oldStack             = $this->elements;
2106
        $this->elementsBackup = $this->elements;
2107
        $this->elements       = array();
2108
        if (isset($oldStack[$num]))
2109
            $this->elements[] = $oldStack[$num];
2110
        return $this->newInstance();
2111
    }
2112
2113
    /**
2114
     * Enter description here...
2115
     *
2116
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2117
     */
2118
    public function size()
2119
    {
2120
        return count($this->elements);
2121
    }
2122
2123
    /**
2124
     * Enter description here...
2125
     *
2126
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2127
     * @deprecated Use length as attribute
2128
     */
2129
    public function length()
2130
    {
2131
        return $this->size();
2132
    }
2133
2134
    public function count()
2135
    {
2136
        return $this->size();
2137
    }
2138
2139
    /**
2140
     * Enter description here...
2141
     *
2142
     * @param int $level
2143
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2144
     * @todo $level
2145
     */
2146
    public function end($level = 1)
0 ignored issues
show
The parameter $level is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2147
    {
2148
        //		$this->elements = array_pop( $this->history );
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% 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...
2149
        //		return $this;
2150
        //		$this->previous->DOM = $this->DOM;
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
2151
        //		$this->previous->XPath = $this->XPath;
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
2152
        return $this->previous ? $this->previous : $this;
2153
    }
2154
2155
    /**
2156
     * Enter description here...
2157
     * Normal use ->clone() .
2158
     *
2159
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2160
     * @access private
2161
     */
2162
    public function _clone()
2163
    {
2164
        $newStack = array();
2165
        //pr(array('copy... ', $this->whois()));
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% 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...
2166
        //$this->dumpHistory('copy');
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% 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...
2167
        $this->elementsBackup = $this->elements;
2168
        foreach ($this->elements as $node) {
2169
            $newStack[] = $node->cloneNode(true);
2170
        }
2171
        $this->elements = $newStack;
2172
        return $this->newInstance();
2173
    }
2174
2175
    /**
2176
     * Enter description here...
2177
     *
2178
     * @param $code
2179
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2180
     */
2181
    public function replaceWithPHP($code)
2182
    {
2183
        return $this->replaceWith(PhpQuery::php($code));
2184
    }
2185
2186
    /**
2187
     * Enter description here...
2188
     *
2189
     * @param String|PhpQuery $content
2190
     * @link http://docs.jquery.com/Manipulation/replaceWith#content
2191
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2192
     */
2193
    public function replaceWith($content)
2194
    {
2195
        return $this->after($content)->remove();
2196
    }
2197
2198
    /**
2199
     * Enter description here...
2200
     *
2201
     * @param String $selector
2202
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2203
     * @todo this works ?
2204
     */
2205
    public function replaceAll($selector)
2206
    {
2207
        foreach (PhpQuery::pq($selector, $this->getDocumentID()) as $node)
2208
            PhpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
2209
        return $this;
2210
    }
2211
2212
    /**
2213
     * Enter description here...
2214
     *
2215
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2216
     */
2217
    public function remove($selector = null)
2218
    {
2219
        $loop = $selector ? $this->filter($selector)->elements : $this->elements;
2220
        foreach ($loop as $node) {
2221
            if (!$node->parentNode)
2222
                continue;
2223
            if (isset($node->tagName))
2224
                $this->debug("Removing '{$node->tagName}'");
2225
            $node->parentNode->removeChild($node);
2226
            // Mutation event
2227
            $event = new Dom\DOMEvent(array(
2228
                                      'target' => $node,
2229
                                      'type'   => 'DOMNodeRemoved'
2230
                                  ));
2231
            PhpQueryEvents::trigger(
2232
                $this->getDocumentID(),
2233
                $event->type,
2234
                array(
2235
                    $event
2236
                ),
2237
                $node
2238
            );
2239
        }
2240
        return $this;
2241
    }
2242
2243
    protected function markupEvents($newMarkup, $oldMarkup, $node)
2244
    {
2245
        if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) {
2246
            $event = new Dom\DOMEvent(array(
2247
                                      'target' => $node,
2248
                                      'type'   => 'change'
2249
                                  ));
2250
            PhpQueryEvents::trigger(
2251
                $this->getDocumentID(),
2252
                $event->type,
2253
                array(
2254
                    $event
2255
                ),
2256
                $node
2257
            );
2258
        }
2259
    }
2260
2261
    /**
2262
     * jQuey difference
2263
     *
2264
     * @param      $markup
2265
     * @param null $callback1
2266
     * @param null $callback2
2267
     * @param null $callback3
2268
     * @return unknown_type
2269
     * @TODO trigger change event for textarea
2270
     */
2271 View Code Duplication
    public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $markup is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2272
    {
2273
        $args = func_get_args();
2274
        if ($this->documentWrapper->isXML)
2275
            return call_user_func_array(
2276
                array(
2277
                    $this,
2278
                    'xml'
2279
                ),
2280
                $args
2281
            );
2282
        else
2283
            return call_user_func_array(
2284
                array(
2285
                    $this,
2286
                    'html'
2287
                ),
2288
                $args
2289
            );
2290
    }
2291
2292
    /**
2293
     * jQuey difference
2294
     *
2295
     * @param null $callback1
2296
     * @param null $callback2
2297
     * @param null $callback3
2298
     * @internal param $markup
2299
     * @return string
2300
     */
2301 View Code Duplication
    public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2302
    {
2303
        $args = func_get_args();
2304
        if ($this->documentWrapper->isXML)
2305
            return call_user_func_array(
2306
                array(
2307
                    $this,
2308
                    'xmlOuter'
2309
                ),
2310
                $args
2311
            );
2312
        else
2313
            return call_user_func_array(
2314
                array(
2315
                    $this,
2316
                    'htmlOuter'
2317
                ),
2318
                $args
2319
            );
2320
    }
2321
2322
    /**
2323
     * Enter description here...
2324
     *
2325
     * @param unknown_type $html
2326
     * @param null         $callback1
2327
     * @param null         $callback2
2328
     * @param null         $callback3
2329
     * @return string|PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2330
     * @TODO force html result
2331
     */
2332
    public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2333
    {
2334
        if (isset($html)) {
2335
            // INSERT
2336
            $nodes = $this->documentWrapper->import($html);
2337
            $this->empty();
2338
            foreach ($this->stack(1) as $alreadyAdded => $node) {
2339
                // for now, limit events for textarea
2340
                if (($this->isXHTML() || $this->isHTML())
2341
                    && $node->tagName == 'textarea'
2342
                )
2343
                    $oldHtml = pq($node, $this->getDocumentID())->markup();
2344
                foreach ($nodes as $newNode) {
2345
                    $node->appendChild(
2346
                        $alreadyAdded ? $newNode->cloneNode(true)
2347
                            : $newNode
2348
                    );
2349
                }
2350
                // for now, limit events for textarea
2351
                if (($this->isXHTML() || $this->isHTML())
2352
                    && $node->tagName == 'textarea'
2353
                )
2354
                    $this->markupEvents($html, $oldHtml, $node);
0 ignored issues
show
The variable $oldHtml does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2355
            }
2356
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (PhpQuery\PhpQueryObject) is incompatible with the return type documented by PhpQuery\PhpQueryObject::html of type string|PhpQuery\PhpQuery...eryTemplatesSourceQuery.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
2357
        } else {
2358
            // FETCH
2359
            $return = $this->documentWrapper->markup($this->elements, true);
2360
            $args   = func_get_args();
2361
            foreach (array_slice($args, 1) as $callback) {
2362
                $return = PhpQuery::callbackRun(
2363
                    $callback,
2364
                    array(
2365
                        $return
2366
                    )
2367
                );
2368
            }
2369
            return $return;
2370
        }
2371
    }
2372
2373
    /**
2374
     * @TODO force xml result
2375
     */
2376 View Code Duplication
    public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $xml is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2377
    {
2378
        $args = func_get_args();
2379
        return call_user_func_array(
2380
            array(
2381
                $this,
2382
                'html'
2383
            ),
2384
            $args
2385
        );
2386
    }
2387
2388
    /**
2389
     * Enter description here...
2390
     * @TODO force html result
2391
     *
2392
     * @param null $callback1
2393
     * @param null $callback2
2394
     * @param null $callback3
2395
     * @return String
2396
     */
2397
    public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2398
    {
2399
        $markup = $this->documentWrapper->markup($this->elements);
2400
        // pass thou callbacks
2401
        $args = func_get_args();
2402
        foreach ($args as $callback) {
2403
            $markup = PhpQuery::callbackRun(
2404
                $callback,
2405
                array(
2406
                    $markup
2407
                )
2408
            );
2409
        }
2410
        return $markup;
2411
    }
2412
2413
    /**
2414
     * @TODO force xml result
2415
     */
2416 View Code Duplication
    public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2417
    {
2418
        $args = func_get_args();
2419
        return call_user_func_array(
2420
            array(
2421
                $this,
2422
                'htmlOuter'
2423
            ),
2424
            $args
2425
        );
2426
    }
2427
2428
    public function __toString()
2429
    {
2430
        return $this->markupOuter();
2431
    }
2432
2433
    /**
2434
     * Just like html(), but returns markup with VALID (dangerous) PHP tags.
2435
     *
2436
     * @param null $code
2437
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2438
     * @todo support returning markup with PHP tags when called without param
2439
     */
2440
    public function php($code = null)
2441
    {
2442
        return $this->markupPHP($code);
2443
    }
2444
2445
    /**
2446
     * Enter description here...
2447
     *
2448
     * @param $code
2449
     * @return unknown_type
2450
     */
2451
    public function markupPHP($code = null)
2452
    {
2453
        return isset($code) ? $this->markup(PhpQuery::php($code))
0 ignored issues
show
Bug Compatibility introduced by
The expression isset($code) ? $this->ma...ToPHP($this->markup()); of type PhpQuery\unknown_type|string adds the type string to the return on line 2453 which is incompatible with the return type documented by PhpQuery\PhpQueryObject::markupPHP of type PhpQuery\unknown_type.
Loading history...
2454
            : PhpQuery::markupToPHP($this->markup());
2455
    }
2456
2457
    /**
2458
     * Enter description here...
2459
     *
2460
     * @internal param $code
2461
     * @return string PHP code
2462
     */
2463
    public function markupOuterPHP()
2464
    {
2465
        return PhpQuery::markupToPHP($this->markupOuter());
2466
    }
2467
2468
    /**
2469
     * Enter description here...
2470
     *
2471
     * @param null $selector
2472
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2473
     */
2474
    public function children($selector = null)
2475
    {
2476
        $stack = array();
2477
        foreach ($this->stack(1) as $node) {
2478
            //			foreach($node->getElementsByTagName('*') as $newNode) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
2479
            foreach ($node->childNodes as $newNode) {
2480
                if ($newNode->nodeType != 1)
2481
                    continue;
2482
                if ($selector && !$this->is($selector, $newNode))
2483
                    continue;
2484
                if ($this->elementsContainsNode($newNode, $stack))
2485
                    continue;
2486
                $stack[] = $newNode;
2487
            }
2488
        }
2489
        $this->elementsBackup = $this->elements;
2490
        $this->elements       = $stack;
2491
        return $this->newInstance();
2492
    }
2493
2494
    /**
2495
     * Enter description here...
2496
     *
2497
     * @param null $selector
2498
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2499
     */
2500
    public function ancestors($selector = null)
2501
    {
2502
        return $this->children($selector);
2503
    }
2504
2505
    /**
2506
     * Enter description here...
2507
     *
2508
     * @param $content
2509
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2510
     */
2511
    public function append($content)
2512
    {
2513
        return $this->insert($content, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2514
    }
2515
2516
    /**
2517
     * Enter description here...
2518
     *
2519
     * @param $content
2520
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2521
     */
2522
    public function appendPHP($content)
2523
    {
2524
        return $this->insert("<php><!-- {$content} --></php>", 'append');
0 ignored issues
show
'append' is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2525
    }
2526
2527
    /**
2528
     * Enter description here...
2529
     *
2530
     * @param $seletor
2531
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2532
     */
2533
    public function appendTo($seletor)
2534
    {
2535
        return $this->insert($seletor, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2536
    }
2537
2538
    /**
2539
     * Enter description here...
2540
     *
2541
     * @param $content
2542
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2543
     */
2544
    public function prepend($content)
2545
    {
2546
        return $this->insert($content, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2547
    }
2548
2549
    /**
2550
     * Enter description here...
2551
     *
2552
     * @todo accept many arguments, which are joined, arrays maybe also
2553
     * @param $content
2554
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2555
     */
2556
    public function prependPHP($content)
2557
    {
2558
        return $this->insert("<php><!-- {$content} --></php>", 'prepend');
0 ignored issues
show
'prepend' is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2559
    }
2560
2561
    /**
2562
     * Enter description here...
2563
     *
2564
     * @param $seletor
2565
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2566
     */
2567
    public function prependTo($seletor)
2568
    {
2569
        return $this->insert($seletor, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2570
    }
2571
2572
    /**
2573
     * Enter description here...
2574
     *
2575
     * @param $content
2576
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2577
     */
2578
    public function before($content)
2579
    {
2580
        return $this->insert($content, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2581
    }
2582
2583
    /**
2584
     * Enter description here...
2585
     *
2586
     * @param $content
2587
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2588
     */
2589
    public function beforePHP($content)
2590
    {
2591
        return $this->insert("<php><!-- {$content} --></php>", 'before');
0 ignored issues
show
'before' is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2592
    }
2593
2594
    /**
2595
     * Enter description here...
2596
     *
2597
     * @param String|PhpQuery
2598
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2599
     */
2600
    public function insertBefore($seletor)
2601
    {
2602
        return $this->insert($seletor, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2603
    }
2604
2605
    /**
2606
     * Enter description here...
2607
     *
2608
     * @param $content
2609
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2610
     */
2611
    public function after($content)
2612
    {
2613
        return $this->insert($content, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2614
    }
2615
2616
    /**
2617
     * Enter description here...
2618
     *
2619
     * @param $content
2620
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2621
     */
2622
    public function afterPHP($content)
2623
    {
2624
        return $this->insert("<php><!-- {$content} --></php>", 'after');
0 ignored issues
show
'after' is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2625
    }
2626
2627
    /**
2628
     * Enter description here...
2629
     *
2630
     * @param $seletor
2631
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2632
     */
2633
    public function insertAfter($seletor)
2634
    {
2635
        return $this->insert($seletor, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ is of type string, but the function expects a object<PhpQuery\unknown_type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2636
    }
2637
2638
    /**
2639
     * Internal insert method. Don't use it.
2640
     *
2641
     * @param unknown_type $target
2642
     * @param unknown_type $type
2643
     * @throws \Exception
2644
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2645
     * @access private
2646
     */
2647
    public function insert($target, $type)
2648
    {
2649
        $this->debug("Inserting data with '{$type}'");
2650
        $to = false;
2651
        switch ($type) {
2652
            case 'appendTo':
2653
            case 'prependTo':
2654
            case 'insertBefore':
2655
            case 'insertAfter':
2656
                $to = true;
2657
        }
2658
        switch (gettype($target)) {
2659
            case 'string':
2660
                $insertFrom = $insertTo = array();
0 ignored issues
show
$insertTo is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
$insertFrom is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2661
                if ($to) {
2662
                    // INSERT TO
2663
                    $insertFrom = $this->elements;
2664
                    if (PhpQuery::isMarkup($target)) {
0 ignored issues
show
Deprecated Code introduced by
The method PhpQuery\PhpQuery::isMarkup() has been deprecated.

This method has been deprecated.

Loading history...
2665
                        // $target is new markup, import it
2666
                        $insertTo = $this->documentWrapper->import($target);
2667
                        // insert into selected element
2668
                    } else {
2669
                        // $tagret is a selector
2670
                        $thisStack = $this->elements;
2671
                        $this->toRoot();
2672
                        $insertTo       = $this->find($target)->elements;
2673
                        $this->elements = $thisStack;
2674
                    }
2675
                } else {
2676
                    // INSERT FROM
2677
                    $insertTo   = $this->elements;
2678
                    $insertFrom = $this->documentWrapper->import($target);
2679
                }
2680
                break;
2681
            case 'object':
2682
                $insertFrom = $insertTo = array();
2683
                // PhpQuery
2684
                if ($target instanceof self) {
2685
                    if ($to) {
2686
                        $insertTo = $target->elements;
2687 View Code Duplication
                        if ($this->documentFragment && $this->stackIsRoot())
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2688
                            // get all body children
2689
                            //							$loop = $this->find('body > *')->elements;
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...
2690
                            // TODO test it, test it hard...
2691
                            //							$loop = $this->newInstance($this->root)->find('> *')->elements;
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
2692
                            $loop = $this->root->childNodes;
2693
                        else
2694
                            $loop = $this->elements;
2695
                        // import nodes if needed
2696
                        $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2697
                            : $target->documentWrapper->import($loop);
2698
                    } else {
2699
                        $insertTo = $this->elements;
2700
                        if ($target->documentFragment && $target->stackIsRoot())
2701
                            // get all body children
2702
                            //							$loop = $target->find('body > *')->elements;
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...
2703
                            $loop = $target->root->childNodes;
2704
                        else
2705
                            $loop = $target->elements;
2706
                        // import nodes if needed
2707
                        $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2708
                            : $this->documentWrapper->import($loop);
2709
                    }
2710
                    // DOMNODE
2711
                } elseif ($target instanceof \DOMNODE) {
2712
                    // import node if needed
2713
                    //					if ( $target->ownerDocument != $this->DOM )
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
2714
                    //						$target = $this->DOM->importNode($target, true);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
2715
                    if ($to) {
2716
                        $insertTo = array(
2717
                            $target
2718
                        );
2719 View Code Duplication
                        if ($this->documentFragment && $this->stackIsRoot())
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2720
                            // get all body children
2721
                            $loop = $this->root->childNodes;
2722
                        //							$loop = $this->find('body > *')->elements;
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...
2723
                        else
2724
                            $loop = $this->elements;
2725
                        foreach ($loop as $fromNode)
2726
                            // import nodes if needed
2727
                            $insertFrom[] = !$fromNode->ownerDocument->isSameNode(
2728
                                $target->ownerDocument
2729
                            ) ? $target->ownerDocument->importNode($fromNode, true)
2730
                                : $fromNode;
2731
                    } else {
2732
                        // import node if needed
2733
                        if (!$target->ownerDocument->isSameNode($this->document))
2734
                            $target = $this->document->importNode($target, true);
2735
                        $insertTo     = $this->elements;
2736
                        $insertFrom[] = $target;
2737
                    }
2738
                }
2739
                break;
2740
        }
2741
        PhpQuery::debug(
2742
            "From " . count($insertFrom) . "; To " . count($insertTo)
0 ignored issues
show
The variable $insertFrom does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
The variable $insertTo does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2743
            . " nodes"
2744
        );
2745
        foreach ($insertTo as $insertNumber => $toNode) {
2746
            // we need static relative elements in some cases
2747
            switch ($type) {
2748
                case 'prependTo':
2749
                case 'prepend':
2750
                    $firstChild = $toNode->firstChild;
2751
                    break;
2752
                case 'insertAfter':
2753
                case 'after':
2754
                    $nextSibling = $toNode->nextSibling;
2755
                    break;
2756
            }
2757
            foreach ($insertFrom as $fromNode) {
2758
                // clone if inserted already before
2759
                $insert = $insertNumber ? $fromNode->cloneNode(true) : $fromNode;
2760
                switch ($type) {
2761
                    case 'appendTo':
2762
                    case 'append':
2763
                        //						$toNode->insertBefore(
2764
                        //							$fromNode,
2765
                        //							$toNode->lastChild->nextSibling
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
2766
                        //						);
2767
                        $toNode->appendChild($insert);
2768
                        $eventTarget = $insert;
0 ignored issues
show
$eventTarget is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2769
                        break;
2770
                    case 'prependTo':
2771
                    case 'prepend':
2772
                        $toNode->insertBefore($insert, $firstChild);
0 ignored issues
show
The variable $firstChild does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2773
                        break;
2774
                    case 'insertBefore':
2775
                    case 'before':
2776
                        if (!$toNode->parentNode)
2777
                            throw new \Exception("No parentNode, can't do {$type}()");
2778
                        else
2779
                            $toNode->parentNode->insertBefore($insert, $toNode);
2780
                        break;
2781
                    case 'insertAfter':
2782
                    case 'after':
2783
                        if (!$toNode->parentNode)
2784
                            throw new \Exception("No parentNode, can't do {$type}()");
2785
                        else
2786
                            $toNode->parentNode->insertBefore($insert, $nextSibling);
0 ignored issues
show
The variable $nextSibling does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2787
                        break;
2788
                }
2789
                // Mutation event
2790
                $event = new Dom\DOMEvent(array(
2791
                                              'target' => $insert,
2792
                                              'type'   => 'DOMNodeInserted'
2793
                                          ));
2794
                PhpQueryEvents::trigger(
2795
                    $this->getDocumentID(),
2796
                    $event->type,
2797
                    array(
2798
                        $event
2799
                    ),
2800
                    $insert
2801
                );
2802
            }
2803
        }
2804
        return $this;
2805
    }
2806
2807
    /**
2808
     * Enter description here...
2809
     *
2810
     * @param $subject
2811
     * @return Int
2812
     */
2813
    public function index($subject)
2814
    {
2815
        $index   = -1;
2816
        $subject = $subject instanceof PhpQueryObject ? $subject->elements[0]
2817
            : $subject;
2818
        foreach ($this->newInstance() as $k => $node) {
2819
            if ($node->isSameNode($subject))
2820
                $index = $k;
2821
        }
2822
        return $index;
2823
    }
2824
2825
    /**
2826
     * Enter description here...
2827
     *
2828
     * @param unknown_type $start
2829
     * @param unknown_type $end
2830
     *
2831
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2832
     * @testme
2833
     */
2834
    public function slice($start, $end = null)
2835
    {
2836
        //		$last = count($this->elements)-1;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
2837
        //		$end = $end
2838
        //			? min($end, $last)
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
2839
        //			: $last;
2840
        //		if ($start < 0)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
2841
        //			$start = $last+$start;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
2842
        //		if ($start > $last)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
2843
        //			return array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
2844
        if ($end > 0)
2845
            $end = $end - $start;
2846
        return $this->newInstance(array_slice($this->elements, $start, $end));
2847
    }
2848
2849
    /**
2850
     * Enter description here...
2851
     *
2852
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2853
     */
2854
    public function reverse()
2855
    {
2856
        $this->elementsBackup = $this->elements;
2857
        $this->elements       = array_reverse($this->elements);
2858
        return $this->newInstance();
2859
    }
2860
2861
    /**
2862
     * Return joined text content.
2863
     * @param null $text
2864
     * @param null $callback1
2865
     * @param null $callback2
2866
     * @param null $callback3
2867
     * @return String
2868
     */
2869
    public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null)
0 ignored issues
show
The parameter $callback1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $callback3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2870
    {
2871
        if (isset($text))
2872
            return $this->html(htmlspecialchars($text));
2873
        $args   = func_get_args();
2874
        $args   = array_slice($args, 1);
2875
        $return = '';
2876
        foreach ($this->elements as $node) {
2877
            $text = $node->textContent;
2878
            if (count($this->elements) > 1 && $text)
2879
                $text .= "\n";
2880
            foreach ($args as $callback) {
2881
                $text = PhpQuery::callbackRun(
2882
                    $callback,
2883
                    array(
2884
                        $text
2885
                    )
2886
                );
2887
            }
2888
            $return .= $text;
2889
        }
2890
        return $return;
2891
    }
2892
2893
    /**
2894
     * @param null $attr
2895
     * @return The text content of each matching element, like
2896
     * text() but returns an array with one entry per matched element.
2897
     * Read only.
2898
     */
2899
    public function texts($attr = null)
0 ignored issues
show
The parameter $attr is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2900
    {
2901
        $results = array();
2902
        foreach ($this->elements as $node) {
2903
            $results[] = $node->textContent;
2904
        }
2905
        return $results;
2906
    }
2907
2908
    /**
2909
     * Enter description here...
2910
     *
2911
     * @param      $class
2912
     * @param null $file
2913
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2914
     */
2915
    public function plugin($class, $file = null)
2916
    {
2917
        PhpQuery::plugin($class, $file);
2918
        return $this;
2919
    }
2920
2921
    /**
2922
     * Deprecated, use $pq->plugin() instead.
2923
     *
2924
     * @deprecated
2925
     * @param $class
2926
     * @param $file
2927
     * @return unknown_type
2928
     */
2929
    public static function extend($class, $file = null)
2930
    {
2931
        return self::plugin($class, $file);
2932
    }
2933
2934
    /**
2935
     *
2936
     * @access private
2937
     * @param $method
2938
     * @param $args
2939
     * @throws \Exception
2940
     * @return unknown_type
2941
     */
2942
    public function __call($method, $args)
2943
    {
2944
        $aliasMethods = array(
2945
            'clone',
2946
            'empty'
2947
        );
2948
        if (isset(PhpQuery::$extendMethods[$method])) {
2949
            array_unshift($args, $this);
2950
            return PhpQuery::callbackRun(PhpQuery::$extendMethods[$method], $args);
2951
        } else if (isset(PhpQuery::$pluginsMethods[$method])) {
2952
            array_unshift($args, $this);
2953
            $class     = PhpQuery::$pluginsMethods[$method];
2954
            $realClass = "\\PhpQuery\\Plugin\\$class";
2955
            $return    = call_user_func_array(
2956
                array(
2957
                    $realClass,
2958
                    $method
2959
                ),
2960
                $args
2961
            );
2962
            // XXX deprecate ?
2963
            return is_null($return) ? $this : $return;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return is_null($return) ? $this : $return; (object|integer|double|string|array|boolean) is incompatible with the return type documented by PhpQuery\PhpQueryObject::__call of type PhpQuery\unknown_type.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
2964
        } else if (in_array($method, $aliasMethods)) {
2965
            return call_user_func_array(
2966
                array(
2967
                    $this,
2968
                    '_' . $method
2969
                ),
2970
                $args
2971
            );
2972
        } else
2973
            throw new \Exception("Method '{$method}' doesnt exist");
2974
    }
2975
2976
    /**
2977
     * Safe rename of next().
2978
     *
2979
     * Use it ONLY when need to call next() on an iterated object (in same time).
2980
     * Normaly there is no need to do such thing ;)
2981
     *
2982
     * @param null $selector
2983
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2984
     * @access private
2985
     */
2986
    public function _next($selector = null)
2987
    {
2988
        return $this->newInstance($this->getElementSiblings('nextSibling', $selector, true));
2989
    }
2990
2991
    /**
2992
     * Use prev() and next().
2993
     *
2994
     * @deprecated
2995
     * @param null $selector
2996
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2997
     * @access private
2998
     */
2999
    public function _prev($selector = null)
3000
    {
3001
        return $this->prev($selector);
3002
    }
3003
3004
    /**
3005
     * Enter description here...
3006
     *
3007
     * @param null $selector
3008
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3009
     */
3010
    public function prev($selector = null)
3011
    {
3012
        return $this->newInstance($this->getElementSiblings('previousSibling', $selector, true));
3013
    }
3014
3015
    /**
3016
     * @param null $selector
3017
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3018
     * @todo
3019
     */
3020
    public function prevAll($selector = null)
3021
    {
3022
        return $this->newInstance($this->getElementSiblings('previousSibling', $selector));
3023
    }
3024
3025
    /**
3026
     * @param null $selector
3027
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3028
     * @todo FIXME: returns source elements insted of next siblings
3029
     */
3030
    public function nextAll($selector = null)
3031
    {
3032
        return $this->newInstance($this->getElementSiblings('nextSibling', $selector));
3033
    }
3034
3035
    /**
3036
     * @access private
3037
     */
3038
    protected function getElementSiblings($direction, $selector = null, $limitToOne = false)
3039
    {
3040
        $stack = array();
3041
        $count = 0;
0 ignored issues
show
$count is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3042
        foreach ($this->stack() as $node) {
3043
            $test = $node;
3044
            while (isset($test->{$direction}) && $test->{$direction}) {
3045
                $test = $test->{$direction};
3046
                if (!$test instanceof \DOMElement)
3047
                    continue;
3048
                $stack[] = $test;
3049
                if ($limitToOne)
3050
                    break;
3051
            }
3052
        }
3053
        if ($selector) {
3054
            $stackOld       = $this->elements;
3055
            $this->elements = $stack;
3056
            $stack          = $this->filter($selector, true)->stack();
3057
            $this->elements = $stackOld;
3058
        }
3059
        return $stack;
3060
    }
3061
3062
    /**
3063
     * Enter description here...
3064
     *
3065
     * @param null $selector
3066
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3067
     */
3068
    public function siblings($selector = null)
3069
    {
3070
        $stack    = array();
3071
        $siblings = array_merge(
3072
            $this->getElementSiblings('previousSibling', $selector),
3073
            $this->getElementSiblings('nextSibling', $selector)
3074
        );
3075
        foreach ($siblings as $node) {
3076
            if (!$this->elementsContainsNode($node, $stack))
3077
                $stack[] = $node;
3078
        }
3079
        return $this->newInstance($stack);
3080
    }
3081
3082
    /**
3083
     * Enter description here...
3084
     *
3085
     * @param null $selector
3086
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3087
     */
3088
    public function not($selector = null)
3089
    {
3090
        if (is_string($selector))
3091
            PhpQuery::debug(
3092
                array(
3093
                    'not',
3094
                    $selector
3095
                )
3096
            );
3097
        else
3098
            PhpQuery::debug('not');
3099
        $stack = array();
3100
        if ($selector instanceof self || $selector instanceof \DOMNODE) {
3101
            foreach ($this->stack() as $node) {
3102
                if ($selector instanceof self) {
3103
                    $matchFound = false;
3104
                    foreach ($selector->stack() as $notNode) {
3105
                        if ($notNode->isSameNode($node))
3106
                            $matchFound = true;
3107
                    }
3108
                    if (!$matchFound)
3109
                        $stack[] = $node;
3110
                } else if ($selector instanceof \DOMNODE) {
3111
                    if (!$selector->isSameNode($node))
3112
                        $stack[] = $node;
3113
                } else {
3114
                    if (!$this->is($selector))
3115
                        $stack[] = $node;
3116
                }
3117
            }
3118
        } else {
3119
            $orgStack = $this->stack();
3120
            $matched  = $this->filter($selector, true)->stack();
3121
            //			$matched = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
3122
            //			// simulate OR in filter() instead of AND 5y
3123
            //			foreach($this->parseSelector($selector) as $s) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
3124
            //				$matched = array_merge($matched,
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
3125
            //					$this->filter(array($s))->stack()
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% 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...
3126
            //				);
3127
            //			}
3128
            foreach ($orgStack as $node)
3129
                if (!$this->elementsContainsNode($node, $matched))
3130
                    $stack[] = $node;
3131
        }
3132
        return $this->newInstance($stack);
3133
    }
3134
3135
    /**
3136
     * Enter description here...
3137
     *
3138
     * @param string|PhpQueryObject
3139
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3140
     */
3141
    public function add($selector = null)
3142
    {
3143
        if (!$selector)
3144
            return $this;
3145
        $stack                = array();
0 ignored issues
show
$stack is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3146
        $this->elementsBackup = $this->elements;
3147
        $found                = PhpQuery::pq($selector, $this->getDocumentID());
3148
        $this->merge($found->elements);
3149
        return $this->newInstance();
3150
    }
3151
3152
    /**
3153
     * @access private
3154
     */
3155
    protected function merge()
3156
    {
3157
        foreach (func_get_args() as $nodes)
3158
            foreach ($nodes as $newNode)
3159
                if (!$this->elementsContainsNode($newNode))
3160
                    $this->elements[] = $newNode;
3161
    }
3162
3163
    /**
3164
     * @access private
3165
     * TODO refactor to stackContainsNode
3166
     */
3167
    protected function elementsContainsNode($nodeToCheck, $elementsStack = null)
3168
    {
3169
        $loop = !is_null($elementsStack) ? $elementsStack : $this->elements;
3170
        foreach ($loop as $node) {
3171
            if ($node->isSameNode($nodeToCheck))
3172
                return true;
3173
        }
3174
        return false;
3175
    }
3176
3177
    /**
3178
     * Enter description here...
3179
     *
3180
     * @param null $selector
3181
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3182
     */
3183
    public function parent($selector = null)
3184
    {
3185
        $stack = array();
3186
        foreach ($this->elements as $node)
3187
            if ($node->parentNode
3188
                && !$this->elementsContainsNode($node->parentNode, $stack)
3189
            )
3190
                $stack[] = $node->parentNode;
3191
        $this->elementsBackup = $this->elements;
3192
        $this->elements       = $stack;
3193
        if ($selector)
3194
            $this->filter($selector, true);
3195
        return $this->newInstance();
3196
    }
3197
3198
    /**
3199
     * Enter description here...
3200
     *
3201
     * @param null $selector
3202
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3203
     */
3204
    public function parents($selector = null)
3205
    {
3206
        $stack = array();
3207
        if (!$this->elements)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->elements of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3208
            $this->debug('parents() - stack empty');
3209
        foreach ($this->elements as $node) {
3210
            $test = $node;
3211
            while ($test->parentNode) {
3212
                $test = $test->parentNode;
3213
                if ($this->isRoot($test))
3214
                    break;
3215
                if (!$this->elementsContainsNode($test, $stack)) {
3216
                    $stack[] = $test;
3217
                    continue;
3218
                }
3219
            }
3220
        }
3221
        $this->elementsBackup = $this->elements;
3222
        $this->elements       = $stack;
3223
        if ($selector)
3224
            $this->filter($selector, true);
3225
        return $this->newInstance();
3226
    }
3227
3228
    /**
3229
     * Internal stack iterator.
3230
     *
3231
     * @access private
3232
     * @param null $nodeTypes
3233
     * @return array {Array.<DOMNode>}
3234
     */
3235
    public function stack($nodeTypes = null)
3236
    {
3237
        if (!isset($nodeTypes))
3238
            return $this->elements;
3239
        if (!is_array($nodeTypes))
3240
            $nodeTypes = array(
3241
                $nodeTypes
3242
            );
3243
        $return = array();
3244
        foreach ($this->elements as $node) {
3245
            if (in_array($node->nodeType, $nodeTypes))
3246
                $return[] = $node;
3247
        }
3248
        return $return;
3249
    }
3250
3251
    // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes
3252
    protected function attrEvents($attr, $oldAttr, $oldValue, $node)
3253
    {
3254
        // skip events for XML documents
3255
        if (!$this->isXHTML() && !$this->isHTML())
3256
            return;
3257
        $event = null;
3258
        // identify
3259
        $isInputValue = $node->tagName == 'input'
3260
            && (in_array(
3261
                    $node->getAttribute('type'),
3262
                    array(
3263
                        'text',
3264
                        'password',
3265
                        'hidden'
3266
                    )
3267
                ) || !$node->getAttribute('type'));
3268
        $isRadio      = $node->tagName == 'input'
3269
            && $node->getAttribute('type') == 'radio';
3270
        $isCheckbox   = $node->tagName == 'input'
3271
            && $node->getAttribute('type') == 'checkbox';
3272
        $isOption     = $node->tagName == 'option';
3273
        if ($isInputValue && $attr == 'value'
3274
            && $oldValue != $node->getAttribute($attr)
3275
        ) {
3276
            $event = new Dom\DOMEvent(array(
3277
                                          'target' => $node,
3278
                                          'type'   => 'change'
3279
                                      ));
3280
        } else if (($isRadio || $isCheckbox) && $attr == 'checked'
3281
            && (
3282
                // check
3283
                (!$oldAttr && $node->hasAttribute($attr))
3284
                // un-check
3285
                || (!$node->hasAttribute($attr) && $oldAttr))
3286
        ) {
3287
            $event = new Dom\DOMEvent(array(
3288
                                          'target' => $node,
3289
                                          'type'   => 'change'
3290
                                      ));
3291
        } else if ($isOption && $node->parentNode && $attr == 'selected'
3292
            && (
3293
                // select
3294
                (!$oldAttr && $node->hasAttribute($attr))
3295
                // un-select
3296
                || (!$node->hasAttribute($attr) && $oldAttr))
3297
        ) {
3298
            $event = new Dom\DOMEvent(array(
3299
                                          'target' => $node->parentNode,
3300
                                          'type'   => 'change'
3301
                                      ));
3302
        }
3303
        if ($event) {
3304
            PhpQueryEvents::trigger(
3305
                $this->getDocumentID(),
3306
                $event->type,
3307
                array(
3308
                    $event
3309
                ),
3310
                $node
3311
            );
3312
        }
3313
    }
3314
3315
    public function attr($attr = null, $value = null)
3316
    {
3317
        foreach ($this->stack(1) as $node) {
3318
            if (!is_null($value)) {
3319
                $loop = $attr == '*' ? $this->getNodeAttrs($node)
3320
                    : array(
3321
                        $attr
3322
                    );
3323
                foreach ($loop as $a) {
3324
                    $oldValue = $node->getAttribute($a);
3325
                    $oldAttr  = $node->hasAttribute($a);
3326
                    // TODO raises an error when charset other than UTF-8
3327
                    // while document's charset is also not UTF-8
3328
                    @$node->setAttribute($a, $value);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3329
                    $this->attrEvents($a, $oldAttr, $oldValue, $node);
3330
                }
3331 View Code Duplication
            } else if ($attr == '*') {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3332
                // jQuery difference
3333
                $return = array();
3334
                foreach ($node->attributes as $n => $v)
3335
                    $return[$n] = $v->value;
3336
                return $return;
3337
            } else
3338
                return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null;
3339
        }
3340
        return is_null($value) ? '' : $this;
3341
    }
3342
3343
    /**
3344
     * @param null $attr
3345
     * @return The same attribute of each matching element, like
3346
     * attr() but returns an array with one entry per matched element.
3347
     * Read only.
3348
     */
3349
    public function attrs($attr = null)
3350
    {
3351
        $results = array();
3352
        foreach ($this->stack(1) as $node) {
3353
            $results[] = $node->hasAttribute($attr) ? $node->getAttribute($attr)
3354
                : null;
3355
        }
3356
        return $results;
3357
    }
3358
3359
    /**
3360
     * @access private
3361
     */
3362
    protected function getNodeAttrs($node)
3363
    {
3364
        $return = array();
3365
        foreach ($node->attributes as $n => $o)
3366
            $return[] = $n;
3367
        return $return;
3368
    }
3369
3370
    /**
3371
     * Enter description here...
3372
     *
3373
     * @param $attr
3374
     * @param $code
3375
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3376
     * @todo check CDATA ???
3377
     */
3378
    public function attrPHP($attr, $code)
3379
    {
3380
        if (!is_null($code)) {
3381
            $value = '<' . '?php ' . $code . ' ?' . '>';
3382
            // TODO tempolary solution
3383
            // http://code.google.com/p/phpquery/issues/detail?id=17
3384
            //			if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII')
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
3385
            //				$value	= mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES');
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% 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...
3386
        }
3387
        foreach ($this->stack(1) as $node) {
3388 View Code Duplication
            if (!is_null($code)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3389
                //				$attrNode = $this->DOM->createAttribute($attr);
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...
3390
                $node->setAttribute($attr, $value);
0 ignored issues
show
The variable $value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
3391
                //				$attrNode->value = $value;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
3392
                //				$node->appendChild($attrNode);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% 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...
3393
            } else if ($attr == '*') {
3394
                // jQuery diff
3395
                $return = array();
3396
                foreach ($node->attributes as $n => $v)
3397
                    $return[$n] = $v->value;
3398
                return $return;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $return; (array) is incompatible with the return type documented by PhpQuery\PhpQueryObject::attrPHP of type PhpQuery\PhpQueryObject|...eryTemplatesSourceQuery.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
3399
            } else
3400
                return $node->getAttribute($attr);
3401
        }
3402
        return $this;
3403
    }
3404
3405
    /**
3406
     * Enter description here...
3407
     *
3408
     * @param $attr
3409
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3410
     */
3411
    public function removeAttr($attr)
3412
    {
3413
        foreach ($this->stack(1) as $node) {
3414
            $loop = $attr == '*' ? $this->getNodeAttrs($node)
3415
                : array(
3416
                    $attr
3417
                );
3418
            foreach ($loop as $a) {
3419
                $oldValue = $node->getAttribute($a);
3420
                $node->removeAttribute($a);
3421
                $this->attrEvents($a, $oldValue, null, $node);
3422
            }
3423
        }
3424
        return $this;
3425
    }
3426
3427
    /**
3428
     * Return form element value.
3429
     *
3430
     * @param null $val
3431
     * @return String Fields value.
3432
     */
3433
    public function val($val = null)
3434
    {
3435
        if (!isset($val)) {
3436
            if ($this->eq(0)->is('select')) {
3437
                $selected = $this->eq(0)->find('option[selected=selected]');
3438
                if ($selected->is('[value]'))
3439
                    return $selected->attr('value');
3440
                else
3441
                    return $selected->text();
3442
            } else if ($this->eq(0)->is('textarea'))
3443
                return $this->eq(0)->markup();
3444
            else
3445
                return $this->eq(0)->attr('value');
3446
        } else {
3447
            $_val = null;
3448
            foreach ($this->stack(1) as $node) {
3449
                $node = pq($node, $this->getDocumentID());
3450
                if (is_array($val)
3451
                    && in_array(
3452
                        $node->attr('type'),
3453
                        array(
3454
                            'checkbox',
3455
                            'radio'
3456
                        )
3457
                    )
3458
                ) {
3459
                    $isChecked = in_array($node->attr('value'), $val)
3460
                        || in_array($node->attr('name'), $val);
3461
                    if ($isChecked)
3462
                        $node->attr('checked', 'checked');
3463
                    else
3464
                        $node->removeAttr('checked');
3465
                } else if ($node->get(0)->tagName == 'select') {
3466
                    if (!isset($_val)) {
3467
                        $_val = array();
3468
                        if (!is_array($val))
3469
                            $_val = array(
3470
                                (string) $val
3471
                            );
3472
                        else
3473
                            foreach ($val as $v)
3474
                                $_val[] = $v;
3475
                    }
3476
                    foreach ($node['option']->stack(1) as $option) {
3477
                        $option   = pq($option, $this->getDocumentID());
3478
                        $selected = false;
0 ignored issues
show
$selected is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3479
                        // XXX: workaround for string comparsion, see issue #96
3480
                        // http://code.google.com/p/phpquery/issues/detail?id=96
3481
                        $selected = is_null($option->attr('value')) ? in_array($option->markup(), $_val)
3482
                            : in_array($option->attr('value'), $_val);
3483
                        //						$optionValue = $option->attr('value');
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
3484
                        //						$optionText = $option->text();
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
3485
                        //						$optionTextLenght = mb_strlen($optionText);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
3486
                        //						foreach($_val as $v)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
3487
                        //							if ($optionValue == $v)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
3488
                        //								$selected = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
3489
                        //							else if ($optionText == $v && $optionTextLenght == mb_strlen($v))
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
3490
                        //								$selected = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
3491
                        if ($selected)
3492
                            $option->attr('selected', 'selected');
3493
                        else
3494
                            $option->removeAttr('selected');
3495
                    }
3496
                } else if ($node->get(0)->tagName == 'textarea')
3497
                    $node->markup($val);
3498
                else
3499
                    $node->attr('value', $val);
3500
            }
3501
        }
3502
        return $this;
3503
    }
3504
3505
    /**
3506
     * Enter description here...
3507
     *
3508
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3509
     */
3510
    public function andSelf()
3511
    {
3512
        if ($this->previous)
3513
            $this->elements = array_merge($this->elements, $this->previous->elements);
3514
        return $this;
3515
    }
3516
3517
    /**
3518
     * Enter description here...
3519
     *
3520
     * @param $className
3521
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3522
     */
3523
    public function addClass($className)
3524
    {
3525
        if (!$className)
3526
            return $this;
3527
        foreach ($this->stack(1) as $node) {
3528
            if (!$this->is(".$className", $node))
3529
                $node->setAttribute(
3530
                    'class',
3531
                    trim(
3532
                        $node->getAttribute('class') . ' '
3533
                        . $className
3534
                    )
3535
                );
3536
        }
3537
        return $this;
3538
    }
3539
3540
    /**
3541
     * Enter description here...
3542
     *
3543
     * @param $className
3544
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3545
     */
3546
    public function addClassPHP($className)
3547
    {
3548
        foreach ($this->stack(1) as $node) {
3549
            $classes  = $node->getAttribute('class');
3550
            $newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?'
3551
                . '>' : '<' . '?php ' . $className . ' ?' . '>';
3552
            $node->setAttribute('class', $newValue);
3553
        }
3554
        return $this;
3555
    }
3556
3557
    /**
3558
     * Enter description here...
3559
     *
3560
     * @param    string $className
3561
     * @return    bool
3562
     */
3563
    public function hasClass($className)
3564
    {
3565
        foreach ($this->stack(1) as $node) {
3566
            if ($this->is(".$className", $node))
3567
                return true;
3568
        }
3569
        return false;
3570
    }
3571
3572
    /**
3573
     * Enter description here...
3574
     *
3575
     * @param $className
3576
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3577
     */
3578
    public function removeClass($className)
3579
    {
3580
        foreach ($this->stack(1) as $node) {
3581
            $classes = explode(' ', $node->getAttribute('class'));
3582
            if (in_array($className, $classes)) {
3583
                $classes = array_diff(
3584
                    $classes,
3585
                    array(
3586
                        $className
3587
                    )
3588
                );
3589
                if ($classes)
0 ignored issues
show
Bug Best Practice introduced by
The expression $classes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3590
                    $node->setAttribute('class', implode(' ', $classes));
3591
                else
3592
                    $node->removeAttribute('class');
3593
            }
3594
        }
3595
        return $this;
3596
    }
3597
3598
    /**
3599
     * Enter description here...
3600
     *
3601
     * @param $className
3602
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3603
     */
3604
    public function toggleClass($className)
3605
    {
3606
        foreach ($this->stack(1) as $node) {
3607
            if ($this->is($node, '.' . $className))
3608
                $this->removeClass($className);
3609
            else
3610
                $this->addClass($className);
3611
        }
3612
        return $this;
3613
    }
3614
3615
    /**
3616
     * Proper name without underscore (just ->empty()) also works.
3617
     *
3618
     * Removes all child nodes from the set of matched elements.
3619
     *
3620
     * Example:
3621
     * pq("p")._empty()
3622
     *
3623
     * HTML:
3624
     * <p>Hello, <span>Person</span> <a href="#">and person</a></p>
3625
     *
3626
     * Result:
3627
     * [ <p></p> ]
3628
     *
3629
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3630
     * @access private
3631
     */
3632
    public function _empty()
3633
    {
3634
        foreach ($this->stack(1) as $node) {
3635
            // thx to 'dave at dgx dot cz'
3636
            $node->nodeValue = '';
3637
        }
3638
        return $this;
3639
    }
3640
3641
    /**
3642
     * Enter description here...
3643
     *
3644
     * @param array|string $callback Expects $node as first param, $index as second
3645
     * @param null         $param1
3646
     * @param null         $param2
3647
     * @param null         $param3
3648
     * @internal param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope)
3649
     * @internal param array $arg1 Will ba passed as third and futher args to callback.
3650
     * @internal param array $arg2 Will ba passed as fourth and futher args to callback, and so on...
3651
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3652
     */
3653
    public function each($callback, $param1 = null, $param2 = null, $param3 = null)
0 ignored issues
show
The parameter $param1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3654
    {
3655
        $paramStructure = null;
3656
        if (func_num_args() > 1) {
3657
            $paramStructure = func_get_args();
3658
            $paramStructure = array_slice($paramStructure, 1);
3659
        }
3660
        foreach ($this->elements as $v)
3661
            PhpQuery::callbackRun(
3662
                $callback,
3663
                array(
3664
                    $v
3665
                ),
3666
                $paramStructure
3667
            );
3668
        return $this;
3669
    }
3670
3671
    /**
3672
     * Run callback on actual object.
3673
     *
3674
     * @param      $callback
3675
     * @param null $param1
3676
     * @param null $param2
3677
     * @param null $param3
3678
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3679
     */
3680
    public function callback($callback, $param1 = null, $param2 = null, $param3 = null)
0 ignored issues
show
The parameter $param1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3681
    {
3682
        $params    = func_get_args();
3683
        $params[0] = $this;
3684
        PhpQuery::callbackRun($callback, $params);
3685
        return $this;
3686
    }
3687
3688
    /**
3689
     * Enter description here...
3690
     *
3691
     * @param      $callback
3692
     * @param null $param1
3693
     * @param null $param2
3694
     * @param null $param3
3695
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3696
     * @todo add $scope and $args as in each() ???
3697
     */
3698
    public function map($callback, $param1 = null, $param2 = null, $param3 = null)
0 ignored issues
show
The parameter $callback is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $param3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3699
    {
3700
        //		$stack = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
3701
        ////		foreach($this->newInstance() as $node) {
3702
        //		foreach($this->newInstance() as $node) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
3703
        //			$result = call_user_func($callback, $node);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
3704
        //			if ($result)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
3705
        //				$stack[] = $result;
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
3706
        //		}
3707
        $params = func_get_args();
3708
        array_unshift($params, $this->elements);
3709
        return $this->newInstance(
3710
            call_user_func_array(
3711
                array(
3712
                    '\\PhpQuery\\PhpQuery',
3713
                    'map'
3714
                ),
3715
                $params
3716
            )
3717
        //			PhpQuery::map($this->elements, $callback)
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
3718
        );
3719
    }
3720
3721
    /**
3722
     * Enter description here...
3723
     *
3724
     * @param <type> $key
0 ignored issues
show
The doc-type <type> could not be parsed: Unknown type name "<" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
3725
     * @param <type> $value
0 ignored issues
show
The doc-type <type> could not be parsed: Unknown type name "<" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
3726
     * @return $this
3727
     */
3728
    public function data($key, $value = null)
3729
    {
3730
        if (!isset($value)) {
3731
            // TODO? implement specific jQuery behavior od returning parent values
3732
            // is child which we look up doesn't exist
3733
            return PhpQuery::data($this->get(0), $key, $value, $this->getDocumentID());
3734
        } else {
3735
            foreach ($this as $node)
3736
                PhpQuery::data($node, $key, $value, $this->getDocumentID());
3737
            return $this;
3738
        }
3739
    }
3740
3741
    /**
3742
     * Enter description here...
3743
     *
3744
     * @param <type> $key
0 ignored issues
show
The doc-type <type> could not be parsed: Unknown type name "<" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
3745
     * @return $this
3746
     */
3747
    public function removeData($key)
3748
    {
3749
        foreach ($this as $node)
3750
            PhpQuery::removeData($node, $key, $this->getDocumentID());
3751
        return $this;
3752
    }
3753
    // INTERFACE IMPLEMENTATIONS
3754
3755
    // ITERATOR INTERFACE
3756
    /**
3757
     * @access private
3758
     */
3759
    public function rewind()
3760
    {
3761
        $this->debug('iterating foreach');
3762
        //		PhpQuery::selectDocument($this->getDocumentID());
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
3763
        $this->elementsBackup    = $this->elements;
3764
        $this->elementsInterator = $this->elements;
3765
        $this->valid             = isset($this->elements[0]) ? 1 : 0;
0 ignored issues
show
Documentation Bug introduced by
The property $valid was declared of type boolean, but isset($this->elements[0]) ? 1 : 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
3766
        // 		$this->elements = $this->valid
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% 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...
3767
        // 			? array($this->elements[0])
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% 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...
3768
        // 			: array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
3769
        $this->current = 0;
3770
    }
3771
3772
    /**
3773
     * @access private
3774
     */
3775
    public function current()
3776
    {
3777
        return $this->elementsInterator[$this->current];
3778
    }
3779
3780
    /**
3781
     * @access private
3782
     */
3783
    public function key()
3784
    {
3785
        return $this->current;
3786
    }
3787
3788
    /**
3789
     * Double-function method.
3790
     *
3791
     * First: main iterator interface method.
3792
     * Second: Returning next sibling, alias for _next().
3793
     *
3794
     * Proper functionality is choosed automagicaly.
3795
     *
3796
     * @see PhpQueryObject::_next()
3797
     * @param null $cssSelector
3798
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3799
     */
3800
    public function next($cssSelector = null)
3801
    {
3802
        //		if ($cssSelector || $this->valid)
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
3803
        //			return $this->_next($cssSelector);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
3804
        $this->valid = isset($this->elementsInterator[$this->current + 1]) ? true
3805
            : false;
3806
        if (!$this->valid && $this->elementsInterator) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->elementsInterator of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3807
            $this->elementsInterator = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $elementsInterator.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
3808
        } else if ($this->valid) {
3809
            $this->current++;
3810
        } else {
3811
            return $this->_next($cssSelector);
3812
        }
3813
    }
3814
3815
    /**
3816
     * @access private
3817
     */
3818
    public function valid()
3819
    {
3820
        return $this->valid;
3821
    }
3822
    // ITERATOR INTERFACE END
3823
    // ARRAYACCESS INTERFACE
3824
    /**
3825
     * @access private
3826
     */
3827
    public function offsetExists($offset)
3828
    {
3829
        return $this->find($offset)->size() > 0;
3830
    }
3831
3832
    /**
3833
     * @access private
3834
     */
3835
    public function offsetGet($offset)
3836
    {
3837
        return $this->find($offset);
3838
    }
3839
3840
    /**
3841
     * @access private
3842
     */
3843
    public function offsetSet($offset, $value)
3844
    {
3845
        //		$this->find($offset)->replaceWith($value);
0 ignored issues
show
Unused Code Comprehensibility introduced by
77% 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...
3846
        $this->find($offset)->html($value);
3847
    }
3848
3849
    /**
3850
     * @access private
3851
     */
3852
    public function offsetUnset($offset)
3853
    {
3854
        // empty
3855
        throw new \Exception("Can't do unset, use array interface only for calling queries and replacing HTML.");
3856
    }
3857
    // ARRAYACCESS INTERFACE END
3858
    /**
3859
     * Returns node's XPath.
3860
     *
3861
     * @param unknown_type $oneNode
3862
     * @param null         $namespace
3863
     * @return string
3864
     * @TODO   use native getNodePath is avaible
3865
     * @access private
3866
     */
3867
    protected function getNodeXpath($oneNode = null, $namespace = null)
0 ignored issues
show
The parameter $namespace is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3868
    {
3869
        $return = array();
3870
        $loop   = $oneNode ? array(
3871
            $oneNode
3872
        ) : $this->elements;
3873
        //		if ($namespace)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
3874
        //			$namespace .= ':';
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% 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...
3875
        foreach ($loop as $node) {
3876
            if ($node instanceof \DOMDocument) {
3877
                $return[] = '';
3878
                continue;
3879
            }
3880
            $xpath = array();
3881
            while (!($node instanceof \DOMDocument)) {
3882
                $i       = 1;
3883
                $sibling = $node;
3884
                while ($sibling->previousSibling) {
3885
                    $sibling   = $sibling->previousSibling;
3886
                    $isElement = $sibling instanceof \DOMElement;
3887
                    if ($isElement && $sibling->tagName == $node->tagName)
3888
                        $i++;
3889
                }
3890
                $xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]"
3891
                    : "{$node->tagName}[{$i}]";
3892
                $node    = $node->parentNode;
3893
            }
3894
            $xpath    = join('/', array_reverse($xpath));
3895
            $return[] = '/' . $xpath;
3896
        }
3897
        return $oneNode ? $return[0] : $return;
3898
    }
3899
3900
    // HELPERS
3901
    public function whois($oneNode = null)
3902
    {
3903
        $return = array();
3904
        $loop   = $oneNode ? array(
3905
            $oneNode
3906
        ) : $this->elements;
3907
        foreach ($loop as $node) {
3908
            if (isset($node->tagName)) {
3909
                $tag      = in_array(
3910
                    $node->tagName,
3911
                    array(
3912
                        'php',
3913
                        'js'
3914
                    )
3915
                ) ? strtoupper($node->tagName) : $node->tagName;
3916
                $return[] = $tag
3917
                    . ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '')
3918
                    . ($node->getAttribute('class') ? '.'
3919
                        . join('.', explode(' ', $node->getAttribute('class'))) : '')
3920
                    . ($node->getAttribute('name') ? '[name="'
3921
                        . $node->getAttribute('name') . '"]' : '')
3922
                    . ($node->getAttribute('value')
3923
                    && strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="'
3924
                        . substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15)
3925
                        . '"]' : '')
3926
                    . ($node->getAttribute('value')
3927
                    && strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]'
3928
                        : '') . ($node->getAttribute('selected') ? '[selected]' : '')
3929
                    . ($node->getAttribute('checked') ? '[checked]' : '');
3930
            } else if ($node instanceof \DOMTEXT) {
3931
                if (trim($node->textContent))
3932
                    $return[] = 'Text:'
3933
                        . substr(str_replace("\n", ' ', $node->textContent), 0, 15);
3934
            } else {
0 ignored issues
show
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
3935
3936
            }
3937
        }
3938
        return $oneNode && isset($return[0]) ? $return[0] : $return;
3939
    }
3940
3941
    /**
3942
     * Dump htmlOuter and preserve chain. Usefull for debugging.
3943
     *
3944
     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3945
     *
3946
     */
3947
    public function dump()
3948
    {
3949
        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3950
        PhpQuery::$debug = false;
3951
        //		print __FILE__.':'.__LINE__."\n";
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
3952
        var_dump($this->htmlOuter());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($this->htmlOuter()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
3953
        return $this;
3954
    }
3955
3956 View Code Duplication
    public function dumpWhois()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3957
    {
3958
        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3959
        $debug           = PhpQuery::$debug;
3960
        PhpQuery::$debug = false;
3961
        //		print __FILE__.':'.__LINE__."\n";
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
3962
        var_dump('whois', $this->whois());
0 ignored issues
show
Security Debugging Code introduced by
var_dump('whois', $this->whois()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
3963
        PhpQuery::$debug = $debug;
3964
        return $this;
3965
    }
3966
3967 View Code Duplication
    public function dumpLength()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3968
    {
3969
        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3970
        $debug           = PhpQuery::$debug;
3971
        PhpQuery::$debug = false;
3972
        //		print __FILE__.':'.__LINE__."\n";
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
3973
        var_dump('length', $this->length());
0 ignored issues
show
Security Debugging Code introduced by
var_dump('length', $this->length()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
Deprecated Code introduced by
The method PhpQuery\PhpQueryObject::length() has been deprecated with message: Use length as attribute

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
3974
        PhpQuery::$debug = $debug;
3975
        return $this;
3976
    }
3977
3978
    public function dumpTree($html = true, $title = true)
3979
    {
3980
        $output          = $title ? 'DUMP #' . (PhpQuery::$dumpCount++) . " \n" : '';
3981
        $debug           = PhpQuery::$debug;
3982
        PhpQuery::$debug = false;
3983
        foreach ($this->stack() as $node)
3984
            $output .= $this->__dumpTree($node);
3985
        PhpQuery::$debug = $debug;
3986
        print $html ? nl2br(str_replace(' ', '&nbsp;', $output)) : $output;
3987
        return $this;
3988
    }
3989
3990
    private function __dumpTree($node, $intend = 0)
3991
    {
3992
        $whois  = $this->whois($node);
3993
        $return = '';
3994
        if ($whois)
3995
            $return .= str_repeat(' - ', $intend) . $whois . "\n";
3996
        if (isset($node->childNodes))
3997
            foreach ($node->childNodes as $chNode)
3998
                $return .= $this->__dumpTree($chNode, $intend + 1);
3999
        return $return;
4000
    }
4001
4002
    /**
4003
     * Dump htmlOuter and stop script execution. Usefull for debugging.
4004
     *
4005
     */
4006
    public function dumpDie()
4007
    {
4008
        print __FILE__ . ':' . __LINE__;
4009
        var_dump($this->htmlOuter());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($this->htmlOuter()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
4010
        die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method dumpDie() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
4011
    }
4012
}
4013