Issues (731)

Security Analysis    no request data  

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

  Cross-Site Scripting
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
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
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.

gan_selector_html.php (77 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
0 ignored issues
show
File has mixed line endings; this may cause incorrect results
Loading history...
2
/**
3
 * @author Niels A.D.
4
 * @author Todd Burry <[email protected]>
5
 * @copyright 2010 Niels A.D., 2014 Todd Burry
6
 * @license http://opensource.org/licenses/LGPL-2.1 LGPL-2.1
7
 * @package pQuery
8
 */
9
10
namespace pQuery;
11
12
/**
13
 * Tokenizes a css selector query
14
 */
15
class CSSQueryTokenizer extends TokenizerBase {
16
17
	/**
18
	 * Opening bracket token, used for "["
19
	 */
20
	const TOK_BRACKET_OPEN = 100;
21
	/**
22
	 * Closing bracket token, used for "]"
23
	 */
24
	const TOK_BRACKET_CLOSE = 101;
25
	/**
26
	 * Opening brace token, used for "("
27
	 */
28
	const TOK_BRACE_OPEN = 102;
29
	/**
30
	 * Closing brace token, used for ")"
31
	 */
32
	const TOK_BRACE_CLOSE = 103;
33
	/**
34
	 * String token
35
	 */
36
	const TOK_STRING = 104;
37
	/**
38
	 * Colon token, used for ":"
39
	 */
40
	const TOK_COLON = 105;
41
	/**
42
	 * Comma token, used for ","
43
	 */
44
	const TOK_COMMA = 106;
45
	/**
46
	 * "Not" token, used for "!"
47
	 */
48
	const TOK_NOT = 107;
49
50
	/**
51
	 * "All" token, used for "*" in query
52
	 */
53
	const TOK_ALL = 108;
54
	/**
55
	 * Pipe token, used for "|"
56
	 */
57
	const TOK_PIPE = 109;
58
	/**
59
	 * Plus token, used for "+"
60
	 */
61
	const TOK_PLUS = 110;
62
	/**
63
	 * "Sibling" token, used for "~" in query
64
	 */
65
	const TOK_SIBLING = 111;
66
	/**
67
	 * Class token, used for "." in query
68
	 */
69
	const TOK_CLASS = 112;
70
	/**
71
	 * ID token, used for "#" in query
72
	 */
73
	const TOK_ID = 113;
74
	/**
75
	 * Child token, used for ">" in query
76
	 */
77
	const TOK_CHILD = 114;
78
79
	/**
80
	 * Attribute compare prefix token, used for "|="
81
	 */
82
	const TOK_COMPARE_PREFIX = 115;
83
	/**
84
	 * Attribute contains token, used for "*="
85
	 */
86
	const TOK_COMPARE_CONTAINS = 116;
87
	/**
88
	 * Attribute contains word token, used for "~="
89
	 */
90
	const TOK_COMPARE_CONTAINS_WORD = 117;
91
	/**
92
	 * Attribute compare end token, used for "$="
93
	 */
94
	const TOK_COMPARE_ENDS = 118;
95
	/**
96
	 * Attribute equals token, used for "="
97
	 */
98
	const TOK_COMPARE_EQUALS = 119;
99
	/**
100
	 * Attribute not equal token, used for "!="
101
	 */
102
	const TOK_COMPARE_NOT_EQUAL = 120;
103
	/**
104
	 * Attribute compare bigger than token, used for ">="
105
	 */
106
	const TOK_COMPARE_BIGGER_THAN = 121;
107
	/**
108
	 * Attribute compare smaller than token, used for "<="
109
	 */
110
	const TOK_COMPARE_SMALLER_THAN = 122;
111
	/**
112
	 * Attribute compare with regex, used for "%="
113
	 */
114
	const TOK_COMPARE_REGEX = 123;
115
	/**
116
	 * Attribute compare start token, used for "^="
117
	 */
118
	const TOK_COMPARE_STARTS = 124;
119
120
	/**
121
	 * Sets query identifiers
122
	 * @see TokenizerBase::$identifiers
123
	 * @access private
124
	 */
125
	var $identifiers = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_-?';
0 ignored issues
show
The visibility should be declared for property $identifiers.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
126
127
	/**
128
	 * Map characters to match their tokens
129
	 * @see TokenizerBase::$custom_char_map
130
	 * @access private
131
	 */
132
	var $custom_char_map = array(
0 ignored issues
show
The visibility should be declared for property $custom_char_map.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
133
		'.' => self::TOK_CLASS,
134
		'#' => self::TOK_ID,
135
		',' => self::TOK_COMMA,
136
		'>' => 'parse_gt',//self::TOK_CHILD,
137
138
		'+' => self::TOK_PLUS,
139
		'~' => 'parse_sibling',
140
141
		'|' => 'parse_pipe',
142
		'*' => 'parse_star',
143
		'$' => 'parse_compare',
144
		'=' => self::TOK_COMPARE_EQUALS,
145
		'!' => 'parse_not',
146
		'%' => 'parse_compare',
147
		'^' => 'parse_compare',
148
		'<' => 'parse_compare',
149
150
		'"' => 'parse_string',
151
		"'" => 'parse_string',
152
		'(' => self::TOK_BRACE_OPEN,
153
		')' => self::TOK_BRACE_CLOSE,
154
		'[' => self::TOK_BRACKET_OPEN,
155
		']' => self::TOK_BRACKET_CLOSE,
156
		':' => self::TOK_COLON
157
	);
158
159
	/**
160
	 * Parse ">" character
161
	 * @internal Could be {@link TOK_CHILD} or {@link TOK_COMPARE_BIGGER_THAN}
162
	 * @return int
163
	 */
164
	protected function parse_gt() {
165
		if ((($this->pos + 1) < $this->size) && ($this->doc[$this->pos + 1] === '=')) {
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
166
			++$this->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
167
			return ($this->token = self::TOK_COMPARE_BIGGER_THAN);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
168
		} else {
169
			return ($this->token = self::TOK_CHILD);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
170
		}
171
	}
172
173
	/**
174
	 * Parse "~" character
175
	 * @internal Could be {@link TOK_SIBLING} or {@link TOK_COMPARE_CONTAINS_WORD}
176
	 * @return int
177
	 */
178
	protected function parse_sibling() {
179
		if ((($this->pos + 1) < $this->size) && ($this->doc[$this->pos + 1] === '=')) {
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
180
			++$this->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
181
			return ($this->token = self::TOK_COMPARE_CONTAINS_WORD);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
182
		} else {
183
			return ($this->token = self::TOK_SIBLING);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
184
		}
185
	}
186
187
	/**
188
	 * Parse "|" character
189
	 * @internal Could be {@link TOK_PIPE} or {@link TOK_COMPARE_PREFIX}
190
	 * @return int
191
	 */
192 1
	protected function parse_pipe() {
193 1
		if ((($this->pos + 1) < $this->size) && ($this->doc[$this->pos + 1] === '=')) {
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
194 1
			++$this->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
195 1
			return ($this->token = self::TOK_COMPARE_PREFIX);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
196
		} else {
197
			return ($this->token = self::TOK_PIPE);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
198
		}
199
	}
200
201
	/**
202
	 * Parse "*" character
203
	 * @internal Could be {@link TOK_ALL} or {@link TOK_COMPARE_CONTAINS}
204
	 * @return int
205
	 */
206 2
	protected function parse_star() {
207 2
		if ((($this->pos + 1) < $this->size) && ($this->doc[$this->pos + 1] === '=')) {
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
208
			++$this->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
209
			return ($this->token = self::TOK_COMPARE_CONTAINS);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
210
		} else {
211 2
			return ($this->token = self::TOK_ALL);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
212
		}
213
	}
214
215
	/**
216
	 * Parse "!" character
217
	 * @internal Could be {@link TOK_NOT} or {@link TOK_COMPARE_NOT_EQUAL}
218
	 * @return int
219
	 */
220
	protected function parse_not() {
221
		if ((($this->pos + 1) < $this->size) && ($this->doc[$this->pos + 1] === '=')) {
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
222
			++$this->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
223
			return ($this->token = self::TOK_COMPARE_NOT_EQUAL);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
224
		} else {
225
			return ($this->token = self::TOK_NOT);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
226
		}
227
	}
228
229
	/**
230
	 * Parse several compare characters
231
	 * @return int
232
	 */
233
	protected function parse_compare() {
234
		if ((($this->pos + 1) < $this->size) && ($this->doc[$this->pos + 1] === '=')) {
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
235
			switch($this->doc[$this->pos++]) {
0 ignored issues
show
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
236
				case '$':
237
					return ($this->token = self::TOK_COMPARE_ENDS);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
238
				case '%':
239
					return ($this->token = self::TOK_COMPARE_REGEX);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
240
				case '^':
241
					return ($this->token = self::TOK_COMPARE_STARTS);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
242
				case '<':
243
					return ($this->token = self::TOK_COMPARE_SMALLER_THAN);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
244
			}
245
		}
246
		return false;
247
	}
248
249
	/**
250
	 * Parse strings (" and ')
251
	 * @return int
252
	 */
253 5
	protected function parse_string() {
254 5
		$char = $this->doc[$this->pos];
0 ignored issues
show
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
255
256 5
		while (true) {
257 5
			if ($this->next_search($char.'\\', false) !== self::TOK_NULL) {
258 5
				if($this->doc[$this->pos] === $char) {
0 ignored issues
show
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
259 5
					break;
260
				} else {
261
					++$this->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
262
				}
263
			} else {
264
				$this->pos = $this->size - 1;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
The property size cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
265
				break;
266
			}
267
		}
268
269 5
		return ($this->token = self::TOK_STRING);
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
270
	}
271
272
}
273
274
/**
275
 * Performs a css select query on HTML nodes
276
 */
277
class HtmlSelector {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
278
279
	/**
280
	 * Parser object
281
	 * @internal If string, then it will create a new instance as parser
282
	 * @var CSSQueryTokenizer
283
	 */
284
	var $parser = 'pQuery\\CSSQueryTokenizer';
0 ignored issues
show
The visibility should be declared for property $parser.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
285
286
	/**
287
	 * Target of queries
288
	 * @var DomNode
289
	 */
290
	var $root = null;
0 ignored issues
show
The visibility should be declared for property $root.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
291
292
	/**
293
	 * Last performed query, result in {@link $result}
294
	 * @var string
295
	 */
296
	var $query = '';
0 ignored issues
show
The visibility should be declared for property $query.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
297
298
	/**
299
	 * Array of matching nodes
300
	 * @var array
301
	 */
302
	var $result = array();
0 ignored issues
show
The visibility should be declared for property $result.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
303
304
	/**
305
	 * Include root in search, if false the only child nodes are evaluated
306
	 * @var bool
307
	 */
308
	var $search_root = false;
0 ignored issues
show
The visibility should be declared for property $search_root.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
309
310
	/**
311
	 * Search recursively
312
	 * @var bool
313
	 */
314
	var $search_recursive = true;
0 ignored issues
show
The visibility should be declared for property $search_recursive.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
315
316
	/**
317
	 * Extra function map for custom filters
318
	 * @var array
319
	 * @internal array('root' => 'filter_root') will cause the
320
	 * selector to call $this->filter_root at :root
321
	 * @see DomNode::$filter_map
322
	 */
323
	var $custom_filter_map = array();
0 ignored issues
show
The visibility should be declared for property $custom_filter_map.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
324
325
	/**
326
	 * Class constructor
327
	 * @param DomNode $root {@link $root}
328
	 * @param string $query
329
	 * @param bool $search_root {@link $search_root}
330
	 * @param bool $search_recursive {@link $search_recursive}
331
	 * @param CSSQueryTokenizer $parser If null, then default class will be used
332
	 */
333 37
	function __construct($root, $query = '*', $search_root = false, $search_recursive = true, $parser = null) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
334 37
		if ($parser === null) {
335 37
			$parser = new $this->parser();
336 37
		}
337 37
		$this->parser = $parser;
338 37
		$this->root =& $root;
339
340 37
		$this->search_root = $search_root;
341 37
		$this->search_recursive = $search_recursive;
342
343 37
		$this->select($query);
344 37
	}
345
346
	#php4 PHP4 class constructor compatibility
347
	#function HtmlSelector($root, $query = '*', $search_root = false, $search_recursive = true, $parser = null) {return $this->__construct($root, $query, $search_root, $search_recursive, $parser);}
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...
348
	#php4e
349
350
	/**
351
	 * toString method, returns {@link $query}
352
	 * @return string
353
	 * @access private
354
	 */
355
	function __toString() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
356
		return $this->query;
357
	}
358
359
	/**
360
	 * Class magic invoke method, performs {@link select()}
361
	 * @return array
362
	 * @access private
363
	 */
364
	function __invoke($query = '*') {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
365
		return $this->select($query);
366
	}
367
368
	/**
369
	 * Perform query
370
	 * @param string $query
371
	 * @return array False on failure
372
	 */
373 37
	function select($query = '*') {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
374 37
		$this->parser->setDoc($query);
375 37
		$this->query = $query;
376 37
		return (($this->parse()) ? $this->result : false);
377
	}
378
379
	/**
380
	 * Trigger error
381
	 * @param string $error
382
	 * @internal %pos% and %tok% will be replace in string with position and token(string)
383
	 * @access private
384
	 */
385
	protected function error($error) {
386
		$error = htmlentities(str_replace(
387
			array('%tok%', '%pos%'),
388
			array($this->parser->getTokenString(), (int) $this->parser->getPos()),
389
			$error
390
		));
391
392
		trigger_error($error);
393
	}
394
395
	/**
396
	 * Get identifier (parse identifier or string)
397
	 * @param bool $do_error Error on failure
398
	 * @return string False on failure
399
	 * @access private
400
	 */
401 36
	protected function parse_getIdentifier($do_error = true) {
402 36
		$p =& $this->parser;
403 36
		$tok = $p->token;
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
404
405 36
		if ($tok === CSSQueryTokenizer::TOK_IDENTIFIER) {
406 36
			return $p->getTokenString();
407 17
		} elseif($tok === CSSQueryTokenizer::TOK_STRING) {
408 5
			return str_replace(array('\\\'', '\\"', '\\\\'), array('\'', '"', '\\'), $p->getTokenString(1, -1));
409 17
		} elseif ($do_error) {
410
			$this->error('Expected identifier at %pos%!');
411
		}
412 17
		return false;
413
	}
414
415
	/**
416
	 * Get query conditions (tag, attribute and filter conditions)
417
	 * @return array False on failure
418
	 * @see DomNode::match()
419
	 * @access private
420
	 */
421 37
	protected function parse_conditions() {
422 37
		$p =& $this->parser;
423 37
		$tok = $p->token;
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
424
425 37
		if ($tok === CSSQueryTokenizer::TOK_NULL) {
426
			$this->error('Invalid search pattern(1): Empty string!');
427
			return false;
428
		}
429 37
		$conditions_all = array();
430
431
		//Tags
432 37
		while ($tok !== CSSQueryTokenizer::TOK_NULL) {
433 37
			$conditions = array('tags' => array(), 'attributes' => array());
434
435 37
			if ($tok === CSSQueryTokenizer::TOK_ALL) {
436 2
				$tok = $p->next();
437 2
				if (($tok === CSSQueryTokenizer::TOK_PIPE) && ($tok = $p->next()) && ($tok !== CSSQueryTokenizer::TOK_ALL)) {
438
					if (($tag = $this->parse_getIdentifier()) === false) {
439
						return false;
440
					}
441
					$conditions['tags'][] = array(
442
						'tag' => $tag,
443
						'compare' => 'name'
444
					);
445
					$tok = $p->next_no_whitespace();
446
				} else {
447 2
					$conditions['tags'][''] = array(
448 2
						'tag' => '',
449
						'match' => false
450 2
					);
451 2
					if ($tok === CSSQueryTokenizer::TOK_ALL) {
452
						$tok = $p->next_no_whitespace();
453
					}
454
				}
455 37
			} elseif ($tok === CSSQueryTokenizer::TOK_PIPE) {
456
				$tok = $p->next();
457
				if ($tok === CSSQueryTokenizer::TOK_ALL) {
458
					$conditions['tags'][] = array(
459
						'tag' => '',
460
						'compare' => 'namespace',
461
					);
462
				} elseif (($tag = $this->parse_getIdentifier()) !== false) {
463
					$conditions['tags'][] = array(
464
						'tag' => $tag,
465
						'compare' => 'total',
466
					);
467
				} else {
468
					return false;
469
				}
470
				$tok = $p->next_no_whitespace();
471 36
			} elseif ($tok === CSSQueryTokenizer::TOK_BRACE_OPEN) {
472
				$tok = $p->next_no_whitespace();
473
				$last_mode = 'or';
474
475
				while (true) {
476
					$match = true;
477
					$compare = 'total';
478
479
					if ($tok === CSSQueryTokenizer::TOK_NOT) {
480
						$match = false;
481
						$tok = $p->next_no_whitespace();
482
					}
483
484
					if ($tok === CSSQueryTokenizer::TOK_ALL) {
485
						$tok = $p->next();
486
						if ($tok === CSSQueryTokenizer::TOK_PIPE) {
487
							$this->next();
0 ignored issues
show
The method next() does not seem to exist on object<pQuery\HtmlSelector>.

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

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

Loading history...
488
							$compare = 'name';
489
							if (($tag = $this->parse_getIdentifier()) === false) {
490
								return false;
491
							}
492
						}
493
					} elseif ($tok === CSSQueryTokenizer::TOK_PIPE) {
494
						$tok = $p->next();
495
						if ($tok === CSSQueryTokenizer::TOK_ALL) {
496
							$tag = '';
497
							$compare = 'namespace';
498
						} elseif (($tag = $this->parse_getIdentifier()) === false) {
499
							return false;
500
						}
501
						$tok = $p->next_no_whitespace();
502
					} else {
503
						if (($tag = $this->parse_getIdentifier()) === false) {
504
							return false;
505
						}
506
						$tok = $p->next();
507
						if ($tok === CSSQueryTokenizer::TOK_PIPE) {
508
							$tok = $p->next();
509
510
							if ($tok === CSSQueryTokenizer::TOK_ALL) {
511
								$compare = 'namespace';
512
							} elseif (($tag_name = $this->parse_getIdentifier()) !== false) {
513
								$tag = $tag.':'.$tag_name;
514
							} else {
515
								return false;
516
							}
517
518
							$tok = $p->next_no_whitespace();
519
						}
520
					}
521
					if ($tok === CSSQueryTokenizer::TOK_WHITESPACE) {
522
						$tok = $p->next_no_whitespace();
523
					}
524
525
					$conditions['tags'][] = array(
526
						'tag' => $tag,
0 ignored issues
show
The variable $tag 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...
527
						'match' => $match,
528
						'operator' => $last_mode,
529
						'compare' => $compare
530
					);
531
					switch($tok) {
532
						case CSSQueryTokenizer::TOK_COMMA:
533
							$tok = $p->next_no_whitespace();
534
							$last_mode = 'or';
535
							continue 2;
536
						case CSSQueryTokenizer::TOK_PLUS:
537
							$tok = $p->next_no_whitespace();
538
							$last_mode = 'and';
539
							continue 2;
540
						case CSSQueryTokenizer::TOK_BRACE_CLOSE:
541
							$tok = $p->next();
542
							break 2;
543
						default:
544
							$this->error('Expected closing brace or comma at pos %pos%!');
545
							return false;
546
					}
547
				}
548 36
			} elseif (($tag = $this->parse_getIdentifier(false)) !== false) {
549 22
				$tok = $p->next();
550 22
				if ($tok === CSSQueryTokenizer::TOK_PIPE) {
551
					$tok = $p->next();
552
553
					if ($tok === CSSQueryTokenizer::TOK_ALL) {
554
						$conditions['tags'][] = array(
555
							'tag' => $tag,
556
							'compare' => 'namespace'
557
						);
558
					} elseif (($tag_name = $this->parse_getIdentifier()) !== false) {
559
						$tag = $tag.':'.$tag_name;
560
						$conditions['tags'][] = array(
561
							'tag' => $tag,
562
							'match' => true
563
						);
564
					} else {
565
						return false;
566
					}
567
568
					$tok = $p->next();
569 22
                } elseif ($tag === 'text' && $tok === CSSQueryTokenizer::TOK_BRACE_OPEN) {
570 1
                    $pos = $p->getPos();
571 1
                    $tok = $p->next();
572 1
                    if ($tok === CSSQueryTokenizer::TOK_BRACE_CLOSE) {
573 1
                        $conditions['tags'][] = array(
574 1
                            'tag' => '~text~',
575
                            'match' => true
576 1
                        );
577 1
                        $p->next();
578 1
                    } else {
579
                        $p->setPos($pos);
580
                    }
581 1
				} else {
582 21
					$conditions['tags'][] = array(
583 21
						'tag' => $tag,
584
						'match' => true
585 21
					);
586
				}
587 22
			} else {
588 17
				unset($conditions['tags']);
589
			}
590
591
			//Class
592 37
			$last_mode = 'or';
593 37
			if ($tok === CSSQueryTokenizer::TOK_CLASS) {
594 12
				$p->next();
595 12
				if (($class = $this->parse_getIdentifier()) === false) {
596
					return false;
597
				}
598
599 12
				$conditions['attributes'][] = array(
600 12
					'attribute' => 'class',
601 12
					'operator_value' => 'contains_word',
602 12
					'value' => $class,
603
					'operator_result' => $last_mode
604 12
				);
605 12
				$last_mode = 'and';
606 12
				$tok = $p->next();
607 12
			}
608
609
			//ID
610 37
			if ($tok === CSSQueryTokenizer::TOK_ID) {
611 1
				$p->next();
612 1
				if (($id = $this->parse_getIdentifier()) === false) {
613
					return false;
614
				}
615
616 1
				$conditions['attributes'][] = array(
617 1
					'attribute' => 'id',
618 1
					'operator_value' => 'equals',
619 1
					'value' => $id,
620
					'operator_result' => $last_mode
621 1
				);
622 1
				$last_mode = 'and';
623 1
				$tok = $p->next();
624 1
			}
625
626
			//Attributes
627 37
			if ($tok === CSSQueryTokenizer::TOK_BRACKET_OPEN) {
628 6
				$tok = $p->next_no_whitespace();
629
630 6
				while (true) {
631 6
					$match = true;
632 6
					$compare = 'total';
633 6
					if ($tok === CSSQueryTokenizer::TOK_NOT) {
634
						$match = false;
635
						$tok = $p->next_no_whitespace();
636
					}
637
638 6
					if ($tok === CSSQueryTokenizer::TOK_ALL) {
639
						$tok = $p->next();
640
						if ($tok === CSSQueryTokenizer::TOK_PIPE) {
641
							$tok = $p->next();
0 ignored issues
show
$tok 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...
642
							if (($attribute = $this->parse_getIdentifier()) === false) {
643
								return false;
644
							}
645
							$compare = 'name';
646
							$tok = $p->next();
647
						} else {
648
							$this->error('Expected pipe at pos %pos%!');
649
							return false;
650
						}
651 6
					} elseif ($tok === CSSQueryTokenizer::TOK_PIPE) {
652
						$tok = $p->next();
0 ignored issues
show
$tok 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...
653
						if (($tag = $this->parse_getIdentifier()) === false) {
654
							return false;
655
						}
656
						$tok = $p->next_no_whitespace();
657 6
					} elseif (($attribute = $this->parse_getIdentifier()) !== false) {
658 6
						$tok = $p->next();
659 6
						if ($tok === CSSQueryTokenizer::TOK_PIPE) {
660
							$tok = $p->next();
0 ignored issues
show
$tok 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...
661
662
							if (($attribute_name = $this->parse_getIdentifier()) !== false) {
663
								$attribute = $attribute.':'.$attribute_name;
664
							} else {
665
								return false;
666
							}
667
668
							$tok = $p->next();
669
						}
670 6
					} else {
671
						return false;
672
					}
673 6
					if ($tok === CSSQueryTokenizer::TOK_WHITESPACE) {
674
						$tok = $p->next_no_whitespace();
675
					}
676
677 6
					$operator_value = '';
678 6
					$val = '';
679
					switch($tok) {
680 6
						case CSSQueryTokenizer::TOK_COMPARE_PREFIX:
681 6
						case CSSQueryTokenizer::TOK_COMPARE_CONTAINS:
682 6
						case CSSQueryTokenizer::TOK_COMPARE_CONTAINS_WORD:
683 6
						case CSSQueryTokenizer::TOK_COMPARE_ENDS:
684 6
						case CSSQueryTokenizer::TOK_COMPARE_EQUALS:
685 6
						case CSSQueryTokenizer::TOK_COMPARE_NOT_EQUAL:
686 6
						case CSSQueryTokenizer::TOK_COMPARE_REGEX:
687 6
						case CSSQueryTokenizer::TOK_COMPARE_STARTS:
688 6
						case CSSQueryTokenizer::TOK_COMPARE_BIGGER_THAN:
689 6
						case CSSQueryTokenizer::TOK_COMPARE_SMALLER_THAN:
690 6
							$operator_value = $p->getTokenString(($tok === CSSQueryTokenizer::TOK_COMPARE_EQUALS) ? 0 : -1);
691 6
							$p->next_no_whitespace();
692
693 6
							if (($val = $this->parse_getIdentifier()) === false) {
694
								return false;
695
							}
696
697 6
							$tok = $p->next_no_whitespace();
698 6
							break;
699
					}
700
701 6
					if ($operator_value && $val) {
702 6
						$conditions['attributes'][] = array(
703 6
							'attribute' => $attribute,
0 ignored issues
show
The variable $attribute 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...
704 6
							'operator_value' => $operator_value,
705 6
							'value' => $val,
706 6
							'match' => $match,
707 6
							'operator_result' => $last_mode,
708
							'compare' => $compare
709 6
						);
710 6
					} else {
711
						$conditions['attributes'][] = array(
712
							'attribute' => $attribute,
713
							'value' => $match,
714
							'operator_result' => $last_mode,
715
							'compare' => $compare
716
						);
717
					}
718
719
					switch($tok) {
720 6
						case CSSQueryTokenizer::TOK_COMMA:
721
							$tok = $p->next_no_whitespace();
722
							$last_mode = 'or';
723
							continue 2;
724 6
						case CSSQueryTokenizer::TOK_PLUS:
725
							$tok = $p->next_no_whitespace();
726
							$last_mode = 'and';
727
							continue 2;
728 6
						case CSSQueryTokenizer::TOK_BRACKET_CLOSE:
729 6
							$tok = $p->next();
730 6
							break 2;
731
						default:
732
							$this->error('Expected closing bracket or comma at pos %pos%!');
733
							return false;
734
					}
735
				}
736 6
			}
737
738 37
			if (count($conditions['attributes']) < 1) {
739 23
				unset($conditions['attributes']);
740 23
			}
741
742 37
			while($tok === CSSQueryTokenizer::TOK_COLON) {
743 3
				if (count($conditions) < 1) {
744 2
					$conditions['tags'] = array(array(
745 2
						'tag' => '',
746
						'match' => false
747 2
					));
748 2
				}
749
750 3
				$tok = $p->next();
0 ignored issues
show
$tok 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...
751 3
				if (($filter = $this->parse_getIdentifier()) === false) {
752
					return false;
753
				}
754
755 3
				if (($tok = $p->next()) === CSSQueryTokenizer::TOK_BRACE_OPEN) {
756
					$start = $p->pos;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
757
					$count = 1;
758
					while ((($tok = $p->next()) !== CSSQueryTokenizer::TOK_NULL) && !(($tok === CSSQueryTokenizer::TOK_BRACE_CLOSE) && (--$count === 0))) {
759
						if ($tok === CSSQueryTokenizer::TOK_BRACE_OPEN) {
760
							++$count;
761
						}
762
					}
763
764
765
					if ($tok !== CSSQueryTokenizer::TOK_BRACE_CLOSE) {
766
						$this->error('Expected closing brace at pos %pos%!');
767
						return false;
768
					}
769
					$len = $p->pos - 1 - $start;
0 ignored issues
show
The property pos cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
770
					$params = (($len > 0) ? substr($p->doc, $start + 1, $len) : '');
0 ignored issues
show
The property doc cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
771
					$tok = $p->next();
772
				} else {
773 3
					$params = '';
774
				}
775
776 3
				$conditions['filters'][] = array('filter' => $filter, 'params' => $params);
777 3
			}
778 37
			if (count($conditions) < 1) {
779
				$this->error('Invalid search pattern(2): No conditions found!');
780
				return false;
781
			}
782 37
			$conditions_all[] = $conditions;
783
784 37
			if ($tok === CSSQueryTokenizer::TOK_WHITESPACE) {
785
				$tok = $p->next_no_whitespace();
786
			}
787
788 37
			if ($tok === CSSQueryTokenizer::TOK_COMMA) {
789 2
				$tok = $p->next_no_whitespace();
790 2
				continue;
791
			} else {
792 37
				break;
793
			}
794
		}
795
796 37
		return $conditions_all;
797
	}
798
799
800
	/**
801
	 * Evaluate root node using custom callback
802
	 * @param array $conditions {@link parse_conditions()}
803
	 * @param bool|int $recursive
804
	 * @param bool $check_root
805
	 * @return array
806
	 * @access private
807
	 */
808 37
	protected function parse_callback($conditions, $recursive = true, $check_root = false) {
809 37
		return ($this->result = $this->root->getChildrenByMatch(
810 37
			$conditions,
811 37
			$recursive,
812 37
			$check_root,
813 37
			$this->custom_filter_map
814 37
		));
815
	}
816
817
	/**
818
	 * Parse first bit of query, only root node has to be evaluated now
819
	 * @param bool|int $recursive
820
	 * @return bool
821
	 * @internal Result of query is set in {@link $result}
822
	 * @access private
823
	 */
824 37
	protected function parse_single($recursive = true) {
825 37
		if (($c = $this->parse_conditions()) === false) {
826
			return false;
827
		}
828
829 37
		$this->parse_callback($c, $recursive, $this->search_root);
830 37
		return true;
831
	}
832
833
	/**
834
	 * Evaluate sibling nodes
835
	 * @return bool
836
	 * @internal Result of query is set in {@link $result}
837
	 * @access private
838
	 */
839
	protected function parse_adjacent() {
840
		$tmp = $this->result;
841
		$this->result = array();
842
		if (($c = $this->parse_conditions()) === false) {
843
			return false;
844
		}
845
846
		foreach($tmp as $t) {
847
			if (($sibling = $t->getNextSibling()) !== false) {
848
				if ($sibling->match($c, true, $this->custom_filter_map)) {
849
					$this->result[] = $sibling;
850
				}
851
			}
852
		}
853
854
		return true;
855
	}
856
857
	/**
858
	 * Evaluate {@link $result}
859
	 * @param bool $parent Evaluate parent nodes
860
	 * @param bool|int $recursive
861
	 * @return bool
862
	 * @internal Result of query is set in {@link $result}
863
	 * @access private
864
	 */
865
	protected function parse_result($parent = false, $recursive = true) {
866
		$tmp = $this->result;
867
		$tmp_res = array();
868
		if (($c = $this->parse_conditions()) === false) {
869
			return false;
870
		}
871
872
		foreach(array_keys($tmp) as $t) {
873
			$this->root = (($parent) ? $tmp[$t]->parent : $tmp[$t]);
874
			$this->parse_callback($c, $recursive);
875
			foreach(array_keys($this->result) as $r) {
876
				if (!in_array($this->result[$r], $tmp_res, true)) {
877
					$tmp_res[] = $this->result[$r];
878
				}
879
			}
880
		}
881
		$this->result = $tmp_res;
882
		return true;
883
	}
884
885
	/**
886
	 * Parse full query
887
	 * @return bool
888
	 * @internal Result of query is set in {@link $result}
889
	 * @access private
890
	 */
891 37
	protected function parse() {
892 37
		$p =& $this->parser;
893 37
		$p->setPos(0);
894 37
		$this->result = array();
895
896 37
		if (!$this->parse_single()) {
897
			return false;
898
		}
899
900 37
		while (count($this->result) > 0) {
901 37
			switch($p->token) {
0 ignored issues
show
The property token cannot be accessed from this context as it is declared private in class pQuery\TokenizerBase.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
902 37
				case CSSQueryTokenizer::TOK_CHILD:
903
					$this->parser->next_no_whitespace();
904
					if (!$this->parse_result(false, 1)) {
905
						return false;
906
					}
907
					break;
908
909 37
				case CSSQueryTokenizer::TOK_SIBLING:
910
					$this->parser->next_no_whitespace();
911
					if (!$this->parse_result(true, 1)) {
912
						return false;
913
					}
914
					break;
915
916 37
				case CSSQueryTokenizer::TOK_PLUS:
917
					$this->parser->next_no_whitespace();
918
					if (!$this->parse_adjacent()) {
919
						return false;
920
					}
921
					break;
922
923 37
				case CSSQueryTokenizer::TOK_ALL:
924 37
				case CSSQueryTokenizer::TOK_IDENTIFIER:
925 37
				case CSSQueryTokenizer::TOK_STRING:
926 37
				case CSSQueryTokenizer::TOK_BRACE_OPEN:
927 37
				case CSSQueryTokenizer::TOK_BRACKET_OPEN:
928 37
				case CSSQueryTokenizer::TOK_ID:
929 37
				case CSSQueryTokenizer::TOK_CLASS:
930 37
				case CSSQueryTokenizer::TOK_COLON:
931
					if (!$this->parse_result()) {
932
						return false;
933
					}
934
					break;
935
936 37
				case CSSQueryTokenizer::TOK_NULL:
937 37
					break 2;
938
939
				default:
940
					$this->error('Invalid search pattern(3): No result modifier found!');
941
					return false;
942
			}
943
		}
944
945 37
		return true;
946
	}
947
}
948
949
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
950