DomNode::index()   B
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 27
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 19.1203
Metric Value
dl 0
loc 27
ccs 4
cts 14
cp 0.2857
rs 8.439
cc 6
eloc 13
nc 7
nop 1
crap 19.1203
1
<?php
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
 * Holds (x)html/xml tag information like tag name, attributes,
14
 * parent, children, self close, etc.
15
 *
16
 */
17
class DomNode implements IQuery {
18
19
	/**
20
	 * Element Node, used for regular elements
21
	 */
22
	const NODE_ELEMENT = 0;
23
	/**
24
	 * Text Node
25
	 */
26
	const NODE_TEXT = 1;
27
	/**
28
	 * Comment Node
29
	 */
30
	const NODE_COMMENT = 2;
31
	/**
32
	 * Conditional Node (<![if]> <![endif])
33
	 */
34
	const NODE_CONDITIONAL = 3;
35
	/**
36
	 * CDATA Node (<![CDATA[]]>
37
	 */
38
	const NODE_CDATA = 4;
39
	/**
40
	 * Doctype Node
41
	 */
42
	const NODE_DOCTYPE = 5;
43
	/**
44
	 * XML Node, used for tags that start with ?, like <?xml and <?php
45
	 */
46
	const NODE_XML = 6;
47
	/**
48
	 * ASP Node
49
	 */
50
	const NODE_ASP = 7;
51
52
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
53
	#static $NODE_TYPE = self::NODE_ELEMENT;
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...
54
	#php4e
55
	#php5
56
	/**
57
	 * Node type of class
58
	 */
59
	const NODE_TYPE = self::NODE_ELEMENT;
60
	#php5e
61
62
63
	/**
64
	 * Name of the selector class
65
	 * @var string
66
	 * @see select()
67
	 */
68
	var $selectClass = 'pQuery\\HtmlSelector';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $selectClass.

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...
69
	/**
70
	 * Name of the parser class
71
	 * @var string
72
	 * @see setOuterText()
73
	 * @see setInnerText()
74
	 */
75
	var $parserClass = 'pQuery\\Html5Parser';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $parserClass.

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...
76
77
	/**
78
	 * Name of the class used for {@link addChild()}
79
	 * @var string
80
	 */
81
	var $childClass = __CLASS__;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass.

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...
82
	/**
83
	 * Name of the class used for {@link addText()}
84
	 * @var string
85
	 */
86
	var $childClass_Text = 'pQuery\\TextNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_Text.

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...
87
	/**
88
	 * Name of the class used for {@link addComment()}
89
	 * @var string
90
	 */
91
	var $childClass_Comment = 'pQuery\\CommentNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_Comment.

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...
92
	/**
93
	 * Name of the class used for {@link addContional()}
94
	 * @var string
95
	 */
96
	var $childClass_Conditional = 'pQuery\\ConditionalTagNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_Conditional.

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...
97
	/**
98
	 * Name of the class used for {@link addCDATA()}
99
	 * @var string
100
	 */
101
	var $childClass_CDATA = 'pQuery\\CdataNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_CDATA.

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...
102
	/**
103
	 * Name of the class used for {@link addDoctype()}
104
	 * @var string
105
	 */
106
	var $childClass_Doctype = 'pQuery\\DoctypeNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_Doctype.

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...
107
	/**
108
	 * Name of the class used for {@link addXML()}
109
	 * @var string
110
	 */
111
	var $childClass_XML = 'pQuery\\XmlNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_XML.

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...
112
	/**
113
	 * Name of the class used for {@link addASP()}
114
	 * @var string
115
	 */
116
	var $childClass_ASP = 'pQuery\\AspEmbeddedNode';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $childClass_ASP.

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...
117
118
	/**
119
	 * Parent node, null if none
120
	 * @var DomNode
121
	 * @see changeParent()
122
	 */
123
	var $parent = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $parent.

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...
124
125
	/**
126
	 * Attributes of node
127
	 * @var array
128
	 * @internal array('attribute' => 'value')
129
	 * @internal Public for faster access!
130
	 * @see getAttribute()
131
	 * @see setAttribute()
132
	 * @access private
133
	 */
134
	var $attributes = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $attributes.

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...
135
136
	/**
137
	 * Namespace info for attributes
138
	 * @var array
139
	 * @internal array('tag' => array(array('ns', 'tag', 'ns:tag', index)))
140
	 * @internal Public for easy outside modifications!
141
	 * @see findAttribute()
142
	 * @access private
143
	 */
144
	var $attributes_ns = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $attributes_ns.

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...
145
146
	/**
147
	 * Array of child nodes
148
	 * @var array
149
	 * @internal Public for faster access!
150
	 * @see childCount()
151
	 * @see getChild()
152
	 * @see addChild()
153
	 * @see deleteChild()
154
	 * @access private
155
	 */
156
	var $children = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $children.

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...
157
158
	/**
159
	 * Full tag name (including namespace)
160
	 * @var string
161
	 * @see getTagName()
162
	 * @see getNamespace()
163
	 */
164
	var $tag = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag.

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...
165
166
	/**
167
	 * Namespace info for tag
168
	 * @var array
169
	 * @internal array('namespace', 'tag')
170
	 * @internal Public for easy outside modifications!
171
	 * @access private
172
	 */
173
	var $tag_ns = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag_ns.

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...
174
175
	/**
176
	 * Is node a self closing node? No closing tag if true.
177
	 * @var bool
178
	 */
179
	var $self_close = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $self_close.

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...
180
181
	/**
182
	 * If self close, then this will be used to close the tag
183
	 * @var string
184
	 * @see $self_close
185
	 */
186
	var $self_close_str = ' /';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $self_close_str.

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...
187
188
	/**
189
	 * Use short tags for attributes? If true, then attributes
190
	 * with values equal to the attribute name will not output
191
	 * the value, e.g. selected="selected" will be selected.
192
	 * @var bool
193
	 */
194
	var $attribute_shorttag = true;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $attribute_shorttag.

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...
195
196
	/**
197
	 * Function map used for the selector filter
198
	 * @var array
199
	 * @internal array('root' => 'filter_root') will cause the
200
	 * selector to call $this->filter_root at :root
201
	 * @access private
202
	 */
203
	var $filter_map = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $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...
204
		'root' => 'filter_root',
205
		'nth-child' => 'filter_nchild',
206
		'eq' => 'filter_nchild', //jquery (naming) compatibility
207
		'gt' => 'filter_gt',
208
		'lt' => 'filter_lt',
209
		'nth-last-child' => 'filter_nlastchild',
210
		'nth-of-type' => 'filter_ntype',
211
		'nth-last-of-type' => 'filter_nlastype',
212
		'odd' => 'filter_odd',
213
		'even' => 'filter_even',
214
		'every' => 'filter_every',
215
		'first-child' => 'filter_first',
216
		'last-child' => 'filter_last',
217
		'first-of-type' => 'filter_firsttype',
218
		'last-of-type' => 'filter_lasttype',
219
		'only-child' => 'filter_onlychild',
220
		'only-of-type' => 'filter_onlytype',
221
		'empty' => 'filter_empty',
222
		'not-empty' => 'filter_notempty',
223
		'has-text' => 'filter_hastext',
224
		'no-text' => 'filter_notext',
225
		'lang' => 'filter_lang',
226
		'contains' => 'filter_contains',
227
		'has' => 'filter_has',
228
		'not' => 'filter_not',
229
		'element' => 'filter_element',
230
		'text' => 'filter_text',
231
		'comment' => 'filter_comment',
232
        'checked' => 'filter_checked',
233
        'selected' => 'filter_selected',
234
	);
235
236
	/**
237
	 * Class constructor
238
	 * @param string|array $tag Name of the tag, or array with taginfo (array(
239
	 *	'tag_name' => 'tag',
240
	 *	'self_close' => false,
241
	 *	'attributes' => array('attribute' => 'value')))
242
	 * @param DomNode $parent Parent of node, null if none
243
	 */
244 37
	function __construct($tag, $parent) {
0 ignored issues
show
Best Practice introduced by
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...
245 37
		$this->parent = $parent;
246
247 37
		if (is_string($tag)) {
248 37
			$this->tag = $tag;
249 37
		} else {
250 37
			$this->tag = $tag['tag_name'];
251 37
			$this->self_close = $tag['self_close'];
252 37
			$this->attributes = $tag['attributes'];
253
		}
254 37
	}
255
256
	#php4 PHP4 class constructor compatibility
257
	#function DomNode($tag, $parent) {return $this->__construct($tag, $parent);}
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% 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...
258
	#php4e
259
260
	/**
261
	 * Class destructor
262
	 * @access private
263
	 */
264 15
	function __destruct() {
0 ignored issues
show
Best Practice introduced by
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...
265 15
		$this->delete();
266 15
	}
267
268
	/**
269
	 * Class toString, outputs {@link $tag}
270
	 * @return string
271
	 * @access private
272
	 */
273
	function __toString() {
0 ignored issues
show
Best Practice introduced by
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...
274
		return (($this->tag === '~root~') ? $this->toString(true, true, 1) : $this->tag);
275
	}
276
277
	/**
278
	 * Class magic get method, outputs {@link getAttribute()}
279
	 * @return string
280
	 * @access private
281
	 */
282 4
	function __get($attribute) {
0 ignored issues
show
Best Practice introduced by
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...
283 4
		return $this->getAttribute($attribute);
284
	}
285
286
	/**
287
	 * Class magic set method, performs {@link setAttribute()}
288
	 * @access private
289
	 */
290 4
	function __set($attribute, $value) {
0 ignored issues
show
Best Practice introduced by
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...
291 4
		$this->setAttribute($attribute, $value);
292 4
	}
293
294
	/**
295
	 * Class magic isset method, returns {@link hasAttribute()}
296
	 * @return bool
297
	 * @access private
298
	 */
299
	function __isset($attribute) {
0 ignored issues
show
Best Practice introduced by
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...
300
		return $this->hasAttribute($attribute);
301
	}
302
303
	/**
304
	 * Class magic unset method, performs {@link deleteAttribute()}
305
	 * @access private
306
	 */
307 1
	function __unset($attribute) {
0 ignored issues
show
Best Practice introduced by
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...
308 1
		return $this->deleteAttribute($attribute);
309
	}
310
311
	/**
312
	 * Class magic invoke method, performs {@link query()}.
313
     * @param string $query The css query to run on the nodes.
314
	 * @return \pQuery
315
	 */
316 3
	function __invoke($query = '*') {
0 ignored issues
show
Best Practice introduced by
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...
317 3
		return $this->query($query);
318
	}
319
320
	/**
321
	 * Returns place in document
322
	 * @return string
323
	 */
324
	 function dumpLocation() {
0 ignored issues
show
Best Practice introduced by
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...
325
		return (($this->parent) ? (($p = $this->parent->dumpLocation()) ? $p.' > ' : '').$this->tag.'('.$this->typeIndex().')' : '');
326
	 }
327
328
	/**
329
	 * Returns all the attributes and their values
330
	 * @return string
331
	 * @access private
332
	 */
333 20
	protected function toString_attributes() {
334 20
		$s = '';
335 20
		foreach($this->attributes as $a => $v) {
336 17
			$s .= ' '.$a;
337 17
			if ((!$this->attribute_shorttag) || ($v !== $a)) {
338 17
				$quote = (strpos($v, '"') === false) ? '"' : "'";
339 17
				$s .= '='.$quote.$v.$quote;
340 17
			}
341 20
		}
342 20
		return $s;
343
	}
344
345
	/**
346
	 * Returns the content of the node (child tags and text)
347
	 * @param bool $attributes Print attributes of child tags
348
	 * @param bool|int $recursive How many sublevels of childtags to print. True for all.
349
	 * @param bool $content_only Only print text, false will print tags too.
350
	 * @return string
351
	 * @access private
352
	 */
353 23
	protected function toString_content($attributes = true, $recursive = true, $content_only = false) {
354 23
		$s = '';
355 23
		foreach($this->children as $c) {
356 23
			$s .= $c->toString($attributes, $recursive, $content_only);
357 23
		}
358 23
		return $s;
359
	}
360
361
	/**
362
	 * Returns the node as string
363
	 * @param bool $attributes Print attributes (of child tags)
364
	 * @param bool|int $recursive How many sub-levels of child tags to print. True for all.
365
	 * @param bool|int $content_only Only print text, false will print tags too.
366
	 * @return string
367
	 */
368 23
	function toString($attributes = true, $recursive = true, $content_only = false) {
0 ignored issues
show
Best Practice introduced by
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...
369 23
		if ($content_only) {
370 23
			if (is_int($content_only)) {
371 21
				--$content_only;
372 21
			}
373 23
			return $this->toString_content($attributes, $recursive, $content_only);
0 ignored issues
show
Bug introduced by
It seems like $content_only can also be of type integer; however, pQuery\DomNode::toString_content() does only seem to accept boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
374
		}
375
376 20
		$s = '<'.$this->tag;
377 20
		if ($attributes) {
378 20
			$s .= $this->toString_attributes();
379 20
		}
380 20
		if ($this->self_close) {
381
			$s .= $this->self_close_str.'>';
382
		} else {
383 20
			$s .= '>';
384 20
			if($recursive) {
385 20
				$s .= $this->toString_content($attributes);
386 20
			}
387 20
			$s .= '</'.$this->tag.'>';
388
		}
389 20
		return $s;
390
	}
391
392
	/**
393
	 * Similar to JavaScript outerText, will return full (html formatted) node
394
	 * @return string
395
	 */
396
	function getOuterText() {
0 ignored issues
show
Best Practice introduced by
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...
397
		return html_entity_decode($this->toString(), ENT_QUOTES);
398
	}
399
400
	/**
401
	 * Similar to JavaScript outerText, will replace node (and child nodes) with new text
402
	 * @param string $text
403
	 * @param HtmlParserBase $parser Null to auto create instance
404
	 * @return bool|array True on succeed, array with errors on failure
405
	 */
406
	function setOuterText($text, $parser = null) {
0 ignored issues
show
Best Practice introduced by
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...
407
		if (trim($text)) {
408
			$index = $this->index();
409
			if ($parser === null) {
410
				$parser = new $this->parserClass();
411
			}
412
			$parser->setDoc($text);
413
			$parser->parse_all();
414
			$parser->root->moveChildren($this->parent, $index);
415
		}
416
		$this->delete();
417
		return (($parser && $parser->errors) ? $parser->errors : true);
418
	}
419
420
	/**
421
	 * Return html code of node
422
	 * @internal jquery (naming) compatibility
423
     * @param string|null $value The value to set or null to get the value.
424
	 * @see toString()
425
	 * @return string
426
	 */
427 20
	function html($value = null) {
0 ignored issues
show
Best Practice introduced by
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...
428 20
      if ($value !== null) {
429 1
         $this->setInnerText($value);
430 1
      }
431 20
		return $this->getInnerText();
432
	}
433
434
	/**
435
	 * Similar to JavaScript innerText, will return (html formatted) content
436
	 * @return string
437
	 */
438 21
	function getInnerText() {
0 ignored issues
show
Best Practice introduced by
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...
439 21
		return html_entity_decode($this->toString(true, true, 1), ENT_QUOTES);
440
	}
441
442
	/**
443
	 * Similar to JavaScript innerText, will replace child nodes with new text
444
	 * @param string $text
445
	 * @param HtmlParserBase $parser Null to auto create instance
446
	 * @return bool|array True on succeed, array with errors on failure
447
	 */
448 2
	function setInnerText($text, $parser = null) {
0 ignored issues
show
Best Practice introduced by
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...
449 2
		$this->clear();
450 2
		if (trim($text)) {
451 2
			if ($parser === null) {
452 2
				$parser = new $this->parserClass();
453 2
			}
454 2
			$parser->root =& $this;
455 2
			$parser->setDoc($text);
456 2
			$parser->parse_all();
457 2
		}
458 2
		return (($parser && $parser->errors) ? $parser->errors : true);
459
	}
460
461
	/**
462
	 * Similar to JavaScript plainText, will return text in node (and subnodes)
463
	 * @return string
464
	 */
465 2
	function getPlainText() {
0 ignored issues
show
Best Practice introduced by
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...
466 2
		return preg_replace('`\s+`', ' ', html_entity_decode($this->toString(true, true, true), ENT_QUOTES));
467
	}
468
469
	/**
470
	 * Return plaintext taking document encoding into account
471
	 * @return string
472
	 */
473
	function getPlainTextUTF8() {
0 ignored issues
show
Best Practice introduced by
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...
474
		$txt = $this->toString(true, true, true);
475
		$enc = $this->getEncoding();
476
		if ($enc !== false) {
477
			$txt = mb_convert_encoding($txt, 'UTF-8', $enc);
478
		}
479
		return preg_replace('`\s+`', ' ', html_entity_decode($txt, ENT_QUOTES, 'UTF-8'));
480
	}
481
482
	/**
483
	 * Similar to JavaScript plainText, will replace child nodes with new text (literal)
484
	 * @param string $text
485
	 */
486 1
	function setPlainText($text) {
0 ignored issues
show
Best Practice introduced by
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...
487 1
		$this->clear();
488 1
		if (trim($text)) {
489 1
			$this->addText(htmlentities($text, ENT_QUOTES));
490 1
		}
491 1
	}
492
493
	/**
494
	 * Delete node from parent and clear node
495
	 */
496 15
	function delete() {
0 ignored issues
show
Best Practice introduced by
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...
497 15
		if (($p = $this->parent) !== null) {
498 4
			$this->parent = null;
499 4
			$p->deleteChild($this);
500 4
		} else {
501 15
			$this->clear();
502
		}
503 15
	}
504
505
	/**
506
	 * Detach node from parent
507
	 * @param bool $move_children_up Only detach current node and replace it with child nodes
508
	 * @internal jquery (naming) compatibility
509
	 * @see delete()
510
	 */
511 1
	function detach($move_children_up = false) {
0 ignored issues
show
Best Practice introduced by
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...
512 1
		if (($p = $this->parent) !== null) {
513 1
			$index = $this->index();
514 1
			$this->parent = null;
515
516 1
			if ($move_children_up) {
517 1
				$this->moveChildren($p, $index);
518 1
			}
519 1
			$p->deleteChild($this, true);
520 1
		}
521 1
	}
522
523
	/**
524
	 * Deletes all child nodes from node
525
	 */
526 15
	function clear() {
0 ignored issues
show
Best Practice introduced by
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...
527 15
		foreach($this->children as $c) {
528 8
			$c->parent = null;
529 8
			$c->delete();
530 15
		}
531 15
		$this->children = array();
532 15
	}
533
534
	/**
535
	 * Get top parent
536
	 * @return DomNode Root, null if node has no parent
537
	 */
538
	function getRoot() {
0 ignored issues
show
Best Practice introduced by
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...
539
		$r = $this->parent;
540
		$n = ($r === null) ? null : $r->parent;
541
		while ($n !== null) {
542
			$r = $n;
543
			$n = $r->parent;
544
		}
545
546
		return $r;
547
	}
548
549
	/**
550
	 * Change parent
551
	 * @param null|DomNode $to New parent, null if none
552
	 * @param false|int $index Add child to parent if not present at index, false to not add, negative to count from end, null to append
553
	 */
554
	#php4
555
	#function changeParent($to, &$index) {
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...
556
	#php4e
557
	#php5
558 10
	function changeParent($to, &$index = null) {
0 ignored issues
show
Best Practice introduced by
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...
559
	#php5e
560 10
		if ($this->parent !== null) {
561 10
			$this->parent->deleteChild($this, true);
562 10
		}
563 10
		$this->parent = $to;
564 10
		if ($index !== false) {
565 10
			$new_index = $this->index();
566 10
			if (!(is_int($new_index) && ($new_index >= 0))) {
567 10
				$this->parent->addChild($this, $index);
568 10
			}
569 10
		}
570 10
	}
571
572
	/**
573
	 * Find out if node has (a certain) parent
574
	 * @param DomNode|string $tag Match against parent, string to match tag, object to fully match node, null to return if node has parent
575
	 * @param bool $recursive
576
	 * @return bool
577
	 */
578
	function hasParent($tag = null, $recursive = false) {
0 ignored issues
show
Best Practice introduced by
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...
579
		if ($this->parent !== null) {
580
			if ($tag === null) {
581
				return true;
582
			} elseif (is_string($tag)) {
583
				return (($this->parent->tag === $tag) || ($recursive && $this->parent->hasParent($tag)));
584
			} elseif (is_object($tag)) {
585
				return (($this->parent === $tag) || ($recursive && $this->parent->hasParent($tag)));
586
			}
587
		}
588
589
		return false;
590
	}
591
592
	/**
593
	 * Find out if node is parent of a certain tag
594
	 * @param DomNode|string $tag Match against parent, string to match tag, object to fully match node
595
	 * @param bool $recursive
596
	 * @return bool
597
	 * @see hasParent()
598
	 */
599
	function isParent($tag, $recursive = false) {
0 ignored issues
show
Best Practice introduced by
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...
600
		return ($this->hasParent($tag, $recursive) === ($tag !== null));
601
	}
602
603
	/**
604
	 * Find out if node is text
605
	 * @return bool
606
	 */
607
	function isText() {
0 ignored issues
show
Best Practice introduced by
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...
608
		return false;
609
	}
610
611
	/**
612
	 * Find out if node is comment
613
	 * @return bool
614
	 */
615
	function isComment() {
0 ignored issues
show
Best Practice introduced by
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...
616
		return false;
617
	}
618
619
	/**
620
	 * Find out if node is text or comment node
621
	 * @return bool
622
	 */
623
	function isTextOrComment() {
0 ignored issues
show
Best Practice introduced by
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...
624
		return false;
625
	}
626
627
	/**
628
	 * Move node to other node
629
	 * @param DomNode $to New parent, null if none
630
	 * @param int $new_index Add child to parent at index if not present, null to not add, negative to count from end
631
	 * @internal Performs {@link changeParent()}
632
	 */
633
	#php4
634
	#function move($to, &$new_index) {
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...
635
	#php4e
636
	#php5
637
	function move($to, &$new_index = -1) {
0 ignored issues
show
Best Practice introduced by
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...
638
	#php5e
639
		$this->changeParent($to, $new_index);
640
	}
641
642
	/**
643
	 * Move child nodes to other node
644
	 * @param DomNode $to New parent, null if none
645
	 * @param int $new_index Add child to new node at index if not present, null to not add, negative to count from end
646
	 * @param int $start Index from child node where to start wrapping, 0 for first element
647
	 * @param int $end Index from child node where to end wrapping, -1 for last element
648
	 */
649
	#php4
650
	#function moveChildren($to, &$new_index, $start = 0, $end = -1) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
651
	#php4e
652
	#php5
653 2
	function moveChildren($to, &$new_index = -1, $start = 0, $end = -1) {
0 ignored issues
show
Best Practice introduced by
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...
654
	#php5e
655 2
		if ($end < 0) {
656 1
			$end += count($this->children);
657 1
		}
658 2
		for ($i = $start; $i <= $end; $i++) {
659 2
			$this->children[$start]->changeParent($to, $new_index);
660 2
		}
661 2
	}
662
663
	/**
664
	 * Index of node in parent
665
	 * @param bool $count_all True to count all tags, false to ignore text and comments
666
	 * @return int -1 if not found
667
	 */
668 10
	function index($count_all = true) {
0 ignored issues
show
Best Practice introduced by
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...
669 10
		if (!$this->parent) {
670
			return -1;
671 10
		} elseif ($count_all) {
672 10
			return $this->parent->findChild($this);
673
		} else{
674
			$index = -1;
675
			//foreach($this->parent->children as &$c) {
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...
676
			//	if (!$c->isTextOrComment()) {
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...
677
			//		++$index;
678
			//	}
679
			//	if ($c === $this) {
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...
680
			//		return $index;
681
			//	}
682
			//}
683
684
			foreach(array_keys($this->parent->children) as $k) {
685
				if (!$this->parent->children[$k]->isTextOrComment()) {
686
					++$index;
687
				}
688
				if ($this->parent->children[$k] === $this) {
689
					return $index;
690
				}
691
			}
692
			return -1;
693
		}
694
	}
695
696
	/**
697
	 * Change index of node in parent
698
	 * @param int $index New index
699
	 */
700
	function setIndex($index) {
0 ignored issues
show
Best Practice introduced by
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...
701
		if ($this->parent) {
702
			if ($index > $this->index()) {
703
				--$index;
704
			}
705
			$this->delete();
706
			$this->parent->addChild($this, $index);
707
		}
708
	}
709
710
	/**
711
	 * Index of all similar nodes in parent
712
	 * @return int -1 if not found
713
	 */
714
	function typeIndex() {
0 ignored issues
show
Best Practice introduced by
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...
715
		if (!$this->parent) {
716
			return -1;
717
		} else {
718
			$index = -1;
719
			//foreach($this->parent->children as &$c) {
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...
720
			//	if (strcasecmp($this->tag, $c->tag) === 0) {
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...
721
			//		++$index;
722
			//	}
723
			//	if ($c === $this) {
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...
724
			//		return $index;
725
			//	}
726
			//}
727
728
			foreach(array_keys($this->parent->children) as $k) {
729
				if (strcasecmp($this->tag, $this->parent->children[$k]->tag) === 0) {
730
					++$index;
731
				}
732
				if ($this->parent->children[$k] === $this) {
733
					return $index;
734
				}
735
			}
736
			return -1;
737
		}
738
	}
739
740
	/**
741
	 * Calculate indent of node (number of parent tags - 1)
742
	 * @return int
743
	 */
744
	function indent() {
0 ignored issues
show
Best Practice introduced by
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...
745
		return (($this->parent) ? $this->parent->indent() + 1 : -1);
746
	}
747
748
	/**
749
	 * Get sibling node
750
	 * @param int $offset Offset from current node
751
	 * @return DomNode Null if not found
752
	 */
753
	function getSibling($offset = 1) {
0 ignored issues
show
Best Practice introduced by
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...
754
		$index = $this->index() + $offset;
755
		if (($index >= 0) && ($index < $this->parent->childCount())) {
756
			return $this->parent->getChild($index);
757
		} else {
758
			return null;
759
		}
760
	}
761
762
	/**
763
	 * Get node next to current
764
	 * @param bool $skip_text_comments
765
	 * @return DomNode Null if not found
766
	 * @see getSibling()
767
	 * @see getPreviousSibling()
768
	 */
769
	function getNextSibling($skip_text_comments = true) {
0 ignored issues
show
Best Practice introduced by
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...
770
		$offset = 1;
771
		while (($n = $this->getSibling($offset)) !== null) {
772
			if ($skip_text_comments && ($n->tag[0] === '~')) {
773
				++$offset;
774
			} else {
775
				break;
776
			}
777
		}
778
779
		return $n;
780
	}
781
782
	/**
783
	 * Get node previous to current
784
	 * @param bool $skip_text_comments
785
	 * @return DomNode Null if not found
786
	 * @see getSibling()
787
	 * @see getNextSibling()
788
	 */
789
	function getPreviousSibling($skip_text_comments = true) {
0 ignored issues
show
Best Practice introduced by
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...
790
		$offset = -1;
791
		while (($n = $this->getSibling($offset)) !== null) {
792
			if ($skip_text_comments && ($n->tag[0] === '~')) {
793
				--$offset;
794
			} else {
795
				break;
796
			}
797
		}
798
799
		return $n;
800
	}
801
802
	/**
803
	 * Get namespace of node
804
	 * @return string
805
	 * @see setNamespace()
806
	 */
807 2
	function getNamespace() {
0 ignored issues
show
Best Practice introduced by
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...
808 2
		if ($this->tag_ns === null) {
809 2
			$a = explode(':', $this->tag, 2);
810 2
			if (empty($a[1])) {
811 2
				$this->tag_ns = array('', $a[0]);
812 2
			} else {
813
				$this->tag_ns = array($a[0], $a[1]);
814
			}
815 2
		}
816
817 2
		return $this->tag_ns[0];
818
	}
819
820
	/**
821
	 * Set namespace of node
822
	 * @param string $ns
823
	 * @see getNamespace()
824
	 */
825
	function setNamespace($ns) {
0 ignored issues
show
Best Practice introduced by
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...
826
		if ($this->getNamespace() !== $ns) {
827
			$this->tag_ns[0] = $ns;
828
			$this->tag = $ns.':'.$this->tag_ns[1];
829
		}
830
	}
831
832
	/**
833
	 * Get tagname of node (without namespace)
834
	 * @return string
835
	 * @see setTag()
836
	 */
837 2
	function getTag() {
0 ignored issues
show
Best Practice introduced by
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...
838 2
		if ($this->tag_ns === null) {
839 2
			$this->getNamespace();
840 2
		}
841
842 2
		return $this->tag_ns[1];
843
	}
844
845
	/**
846
	 * Set tag (with or without namespace)
847
	 * @param string $tag
848
	 * @param bool $with_ns Does $tag include namespace?
849
	 * @see getTag()
850
	 */
851 2
	function setTag($tag, $with_ns = false) {
0 ignored issues
show
Best Practice introduced by
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...
852 2
		$with_ns = $with_ns || (strpos($tag, ':') !== false);
853 2
		if ($with_ns) {
854
			$this->tag = $tag;
855
			$this->tag_ns = 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 $tag_ns.

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...
856 2
		} elseif ($this->getTag() !== $tag) {
857 2
			$this->tag_ns[1] = $tag;
858 2
			$this->tag = (($this->tag_ns[0]) ? $this->tag_ns[0].':' : '').$tag;
859 2
		}
860 2
	}
861
862
	/**
863
	 * Try to determine the encoding of the current tag
864
	 * @return string|bool False if encoding could not be found
865
	 */
866
	function getEncoding() {
0 ignored issues
show
Best Practice introduced by
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...
867
		$root = $this->getRoot();
868
		if ($root !== null) {
869
			if ($enc = $root->select('meta[charset]', 0, true, true)) {
870
				return $enc->getAttribute("charset");
871
			} elseif ($enc = $root->select('"?xml"[encoding]', 0, true, true)) {
872
				return $enc->getAttribute("encoding");
0 ignored issues
show
Bug introduced by
The method getAttribute cannot be called on $enc (of type array<integer,object<pQuery\DomNode>>).

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...
873
			} elseif ($enc = $root->select('meta[content*="charset="]', 0, true, true)) {
874
				$enc = $enc->getAttribute("content");
0 ignored issues
show
Bug introduced by
The method getAttribute cannot be called on $enc (of type array<integer,object<pQuery\DomNode>>).

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...
875
				return substr($enc, strpos($enc, "charset=")+8);
876
			}
877
		}
878
879
		return false;
880
	}
881
882
	/**
883
	 * Number of children in node
884
	 * @param bool $ignore_text_comments Ignore text/comments with calculation
885
	 * @return int
886
	 */
887 37
	function childCount($ignore_text_comments = false) {
0 ignored issues
show
Best Practice introduced by
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...
888 37
		if (!$ignore_text_comments) {
889 37
			return count($this->children);
890
		} else{
891
			$count = 0;
892
			//foreach($this->children as &$c) {
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...
893
			//	if (!$c->isTextOrComment()) {
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...
894
			//		++$count;
895
			//	}
896
			//}
897
898
			foreach(array_keys($this->children) as $k) {
899
				if (!$this->children[$k]->isTextOrComment()) {
900
					++$count;
901
				}
902
			}
903
			return $count;
904
		}
905
	}
906
907
	/**
908
	 * Find node in children
909
	 * @param DomNode $child
910
	 * @return int False if not found
911
	 */
912 12
	function findChild($child) {
0 ignored issues
show
Best Practice introduced by
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...
913 12
		return array_search($child, $this->children, true);
914
	}
915
916
	/**
917
	 * Checks if node has another node as child
918
	 * @param DomNode $child
919
	 * @return bool
920
	 */
921
	function hasChild($child) {
0 ignored issues
show
Best Practice introduced by
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...
922
		return ((bool) findChild($child));
923
	}
924
925
	/**
926
	 * Get childnode
927
	 * @param int|DomNode $child Index, negative to count from end
928
	 * @param bool $ignore_text_comments Ignore text/comments with index calculation
929
	 * @return DomNode
930
	 */
931
	function &getChild($child, $ignore_text_comments = false) {
932
		if (!is_int($child)) {
933
			$child = $this->findChild($child);
934
		} elseif ($child < 0) {
935
			$child += $this->childCount($ignore_text_comments);
936
		}
937
938
		if ($ignore_text_comments) {
939
			$count = 0;
940
			$last = null;
941
			//foreach($this->children as &$c) {
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...
942
			//	if (!$c->isTextOrComment()) {
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...
943
			//		if ($count++ === $child) {
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...
944
			//			return $c;
945
			//		}
946
			//		$last = $c;
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...
947
			//	}
948
			//}
949
950
			foreach(array_keys($this->children) as $k) {
951
				if (!$this->children[$k]->isTextOrComment()) {
952
					if ($count++ === $child) {
953
						return $this->children[$k];
954
					}
955
					$last = $this->children[$k];
956
				}
957
			}
958
			return (($child > $count) ? $last : null);
959
		} else {
960
			return $this->children[$child];
961
		}
962
	}
963
964
	/**
965
	 * Add child node
966
	 * @param string|DomNode $tag Tag name or object
967
	 * @param int $offset Position to insert node, negative to count from end, null to append
968
	 * @return DomNode Added node
969
	 */
970
	#php4
971
	#function &addChild($tag, &$offset) {
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...
972
	#php4e
973
	#php5
974 37
	function &addChild($tag, &$offset = null) {
975
	#php5e
976 37
        if (is_array($tag)) {
977 37
            $tag = new $this->childClass($tag, $this);
978 37
        } elseif (is_string($tag)) {
979 3
            $nodes = $this->createNodes($tag);
980 3
            $tag = array_shift($nodes);
981
982 3
            if ($tag && $tag->parent !== $this) {
983 2
                $index = false;
984 2
                $tag->changeParent($this, $index);
985 2
            }
986 37
		} elseif (is_object($tag) && $tag->parent !== $this) {
987
			$index = false; //Needs to be passed by ref
988
			$tag->changeParent($this, $index);
989
		}
990
991 37
		if (is_int($offset) && ($offset < count($this->children)) && ($offset !== -1)) {
992 8
			if ($offset < 0) {
993
				$offset += count($this->children);
994
			}
995 8
			array_splice($this->children, $offset++, 0, array(&$tag));
996 8
		} else {
997 37
			$this->children[] =& $tag;
998
		}
999
1000 37
		return $tag;
1001
	}
1002
1003
	/**
1004
	 * First child node
1005
	 * @param bool $ignore_text_comments Ignore text/comments with index calculation
1006
	 * @return DomNode
1007
	 */
1008
	function &firstChild($ignore_text_comments = false) {
1009
		return $this->getChild(0, $ignore_text_comments);
1010
	}
1011
1012
	/**
1013
	 * Last child node
1014
	 * @param bool $ignore_text_comments Ignore text/comments with index calculation
1015
	 * @return DomNode
1016
	 */
1017
	function &lastChild($ignore_text_comments = false) {
1018
		return $this->getChild(-1, $ignore_text_comments);
1019
	}
1020
1021
	/**
1022
	 * Insert childnode
1023
	 * @param string|DomNode $tag Tagname or object
1024
	 * @param int $offset Position to insert node, negative to count from end, null to append
0 ignored issues
show
Bug introduced by
There is no parameter named $offset. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1025
	 * @return DomNode Added node
1026
	 * @see addChild();
1027
	 */
1028
	function &insertChild($tag, $index) {
1029
		return $this->addChild($tag, $index);
1030
	}
1031
1032
	/**
1033
	 * Add text node
1034
	 * @param string $text
1035
	 * @param int $offset Position to insert node, negative to count from end, null to append
1036
	 * @return DomNode Added node
1037
	 * @see addChild();
1038
	 */
1039
	#php4
1040
	#function &addText($text, &$offset) {
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...
1041
	#php4e
1042
	#php5
1043 37
	function &addText($text, &$offset = null) {
1044
	#php5e
1045 37
		return $this->addChild(new $this->childClass_Text($this, $text), $offset);
1046
	}
1047
1048
	/**
1049
	 * Add comment node
1050
	 * @param string $text
1051
	 * @param int $offset Position to insert node, negative to count from end, null to append
1052
	 * @return DomNode Added node
1053
	 * @see addChild();
1054
	 */
1055
	#php4
1056
	#function &addComment($text, &$offset) {
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...
1057
	#php4e
1058
	#php5
1059 9
	function &addComment($text, &$offset = null) {
1060
	#php5e
1061 9
		return $this->addChild(new $this->childClass_Comment($this, $text), $offset);
1062
	}
1063
1064
	/**
1065
	 * Add conditional node
1066
	 * @param string $condition
1067
	 * @param bool True for <!--[if, false for <![if
1068
	 * @param int $offset Position to insert node, negative to count from end, null to append
1069
	 * @return DomNode Added node
1070
	 * @see addChild();
1071
	 */
1072
	#php4
1073
	#function &addConditional($condition, $hidden = true, &$offset) {
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...
1074
	#php4e
1075
	#php5
1076
	function &addConditional($condition, $hidden = true, &$offset = null) {
1077
	#php5e
1078
		return $this->addChild(new $this->childClass_Conditional($this, $condition, $hidden), $offset);
1079
	}
1080
1081
	/**
1082
	 * Add CDATA node
1083
	 * @param string $text
1084
	 * @param int $offset Position to insert node, negative to count from end, null to append
1085
	 * @return DomNode Added node
1086
	 * @see addChild();
1087
	 */
1088
	#php4
1089
	#function &addCDATA($text, &$offset) {
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...
1090
	#php4e
1091
	#php5
1092
	function &addCDATA($text, &$offset = null) {
1093
	#php5e
1094
		return $this->addChild(new $this->childClass_CDATA($this, $text), $offset);
1095
	}
1096
1097
	/**
1098
	 * Add doctype node
1099
	 * @param string $dtd
1100
	 * @param int $offset Position to insert node, negative to count from end, null to append
1101
	 * @return DomNode Added node
1102
	 * @see addChild();
1103
	 */
1104
	#php4
1105
	#function &addDoctype($dtd, &$offset) {
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...
1106
	#php4e
1107
	#php5
1108 9
	function &addDoctype($dtd, &$offset = null) {
1109
	#php5e
1110 9
		return $this->addChild(new $this->childClass_Doctype($this, $dtd), $offset);
1111
	}
1112
1113
	/**
1114
	 * Add xml node
1115
	 * @param string $tag Tag name after "?", e.g. "php" or "xml"
1116
	 * @param string $text
1117
	 * @param array $attributes Array of attributes (array('attribute' => 'value'))
1118
	 * @param int $offset Position to insert node, negative to count from end, null to append
1119
	 * @return DomNode Added node
1120
	 * @see addChild();
1121
	 */
1122
	#php4
1123
	#function &addXML($tag = 'xml', $text = '', $attributes = array(), &$offset) {
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...
1124
	#php4e
1125
	#php5
1126
	function &addXML($tag = 'xml', $text = '', $attributes = array(), &$offset = null) {
1127
	#php5e
1128
		return $this->addChild(new $this->childClass_XML($this, $tag, $text, $attributes), $offset);
1129
	}
1130
1131
	/**
1132
	 * Add ASP node
1133
	 * @param string $tag Tag name after "%"
1134
	 * @param string $text
1135
	 * @param array $attributes Array of attributes (array('attribute' => 'value'))
1136
	 * @param int $offset Position to insert node, negative to count from end, null to append
1137
	 * @return DomNode Added node
1138
	 * @see addChild();
1139
	 */
1140
	#php4
1141
	#function &addASP($tag = '', $text = '', $attributes = array(), &$offset) {
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...
1142
	#php4e
1143
	#php5
1144
	function &addASP($tag = '', $text = '', $attributes = array(), &$offset = null) {
1145
	#php5e
1146
		return $this->addChild(new $this->childClass_ASP($this, $tag, $text, $attributes), $offset);
1147
	}
1148
1149
	/**
1150
	 * Delete a child node
1151
	 * @param int|DomNode $child Child(index) to delete, negative to count from end
1152
	 * @param bool $soft_delete False to call {@link delete()} from child
1153
	 */
1154 12
	function deleteChild($child, $soft_delete = false) {
0 ignored issues
show
Best Practice introduced by
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...
1155 12
		if (is_object($child)) {
1156 12
			$child = $this->findChild($child);
1157 12
		} elseif ($child < 0) {
1158
			$child += count($this->children);
1159
		}
1160
1161 12
		if (!$soft_delete) {
1162 4
			$this->children[$child]->delete();
1163 4
		}
1164 12
		unset($this->children[$child]);
1165
1166
		//Rebuild indices
1167 12
		$tmp = array();
1168
1169
		//foreach($this->children as &$c) {
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...
1170
		//	$tmp[] =& $c;
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...
1171
		//}
1172 12
		foreach(array_keys($this->children) as $k) {
1173 12
			$tmp[] =& $this->children[$k];
1174 12
		}
1175 12
		$this->children = $tmp;
1176 12
	}
1177
1178
	/**
1179
	 * Wrap node
1180
	 * @param string|DomNode $node Wrapping node, string to create new element node
1181
	 * @param int $wrap_index Index to insert current node in wrapping node, -1 to append
1182
	 * @param int $node_index Index to insert wrapping node, null to keep at same position
1183
	 * @return DomNode Wrapping node
1184
	 */
1185 2
	function wrap($node, $wrap_index = -1, $node_index = null) {
0 ignored issues
show
Best Practice introduced by
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...
1186 2
		if ($node_index === null) {
1187 2
			$node_index = $this->index();
1188 2
		}
1189
1190 2
		if (!is_object($node)) {
1191 2
			$node = $this->parent->addChild($node, $node_index);
1192 2
		} elseif ($node->parent !== $this->parent) {
1193
			$node->changeParent($this->parent, $node_index);
1194
		}
1195
1196 2
		$this->changeParent($node, $wrap_index);
1197 2
		return $node;
1198
	}
1199
1200
	/**
1201
	 * Wrap child nodes
1202
	 * @param string|DomNode $node Wrapping node, string to create new element node
1203
	 * @param int $start Index from child node where to start wrapping, 0 for first element
1204
	 * @param int $end Index from child node where to end wrapping, -1 for last element
1205
	 * @param int $wrap_index Index to insert in wrapping node, -1 to append
1206
	 * @param int $node_index Index to insert current node, null to keep at same position
1207
	 * @return DomNode Wrapping node
1208
	 */
1209 1
	function wrapInner($node, $start = 0, $end = -1, $wrap_index = -1, $node_index = null) {
0 ignored issues
show
Best Practice introduced by
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...
1210 1
		if ($end < 0) {
1211 1
			$end += count($this->children);
1212 1
		}
1213 1
		if ($node_index === null) {
1214 1
			$node_index = $end + 1;
1215 1
		}
1216
1217 1
		if (!is_object($node)) {
1218 1
			$node = $this->addChild($node, $node_index);
1219 1
		} elseif ($node->parent !== $this) {
1220
			$node->changeParent($this->parent, $node_index);
1221
		}
1222
1223 1
		$this->moveChildren($node, $wrap_index, $start, $end);
1224 1
		return $node;
1225
	}
1226
1227
	/**
1228
	 * Number of attributes
1229
	 * @return int
1230
	 */
1231
	function attributeCount() {
0 ignored issues
show
Best Practice introduced by
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...
1232
		return count($this->attributes);
1233
	}
1234
1235
	/**
1236
	 * Find attribute using namespace, name or both
1237
	 * @param string|int $attr Negative int to count from end
1238
	 * @param string $compare "namespace", "name" or "total"
1239
	 * @param bool $case_sensitive Compare with case sensitivity
1240
	 * @return array array('ns', 'attr', 'ns:attr', index)
1241
	 * @access private
1242
	 */
1243 27
	protected function findAttribute($attr, $compare = 'total', $case_sensitive = false) {
1244 27
		if (is_int($attr)) {
1245
			if ($attr < 0) {
1246
				$attr += count($this->attributes);
1247
			}
1248
			$keys = array_keys($this->attributes);
1249
			return $this->findAttribute($keys[$attr], 'total', true);
1250 27
		} else if ($compare === 'total') {
1251 27
			$b = explode(':', $attr, 2);
1252 27
			if ($case_sensitive) {
1253
				$t =& $this->attributes;
1254
			} else {
1255 27
				$t = array_change_key_case($this->attributes);
1256 27
				$attr = strtolower($attr);
1257
			}
1258
1259 27
			if (isset($t[$attr])) {
1260 26
				$index = 0;
1261 26
				foreach($this->attributes as $a => $v) {
1262 26
					if (($v === $t[$attr]) && (strcasecmp($a, $attr) === 0)) {
1263 26
						$attr = $a;
1264 26
						$b = explode(':', $attr, 2);
1265 26
						break;
1266
					}
1267 6
					++$index;
1268 26
				}
1269
1270 26
				if (empty($b[1])) {
1271 26
					return array(array('', $b[0], $attr, $index));
1272
				} else {
1273
					return array(array($b[0], $b[1], $attr, $index));
1274
				}
1275
			} else {
1276 22
				return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by pQuery\DomNode::findAttribute of type array.

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...
1277
			}
1278
		} else {
1279
			if ($this->attributes_ns === null) {
1280
				$index = 0;
1281
				foreach($this->attributes as $a => $v) {
1282
					$b = explode(':', $a, 2);
1283
					if (empty($b[1])) {
1284
						$this->attributes_ns[$b[0]][] = array('', $b[0], $a, $index);
1285
					} else {
1286
						$this->attributes_ns[$b[1]][] = array($b[0], $b[1], $a, $index);
1287
					}
1288
					++$index;
1289
				}
1290
			}
1291
1292
			if ($case_sensitive) {
1293
				$t =& $this->attributes_ns;
1294
			} else {
1295
				$t = array_change_key_case($this->attributes_ns);
1296
				$attr = strtolower($attr);
1297
			}
1298
1299
			if ($compare === 'namespace') {
1300
				$res = array();
1301
				foreach($t as $ar) {
1302
					foreach($ar as $a) {
1303
						if ($a[0] === $attr) {
1304
							$res[] = $a;
1305
						}
1306
					}
1307
				}
1308
				return $res;
1309
			} elseif ($compare === 'name') {
1310
				return ((isset($t[$attr])) ? $t[$attr] : false);
1311
			} else {
1312
				trigger_error('Unknown comparison mode');
1313
			}
1314
		}
1315
	}
1316
1317
	/**
1318
	 * Checks if node has attribute
1319
	 * @param string|int$attr Negative int to count from end
1320
	 * @param string $compare Find node using "namespace", "name" or "total"
1321
	 * @param bool $case_sensitive Compare with case sensitivity
1322
	 * @return bool
1323
	 */
1324
	function hasAttribute($attr, $compare = 'total', $case_sensitive = false) {
0 ignored issues
show
Best Practice introduced by
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...
1325
		return ((bool) $this->findAttribute($attr, $compare, $case_sensitive));
1326
	}
1327
1328
	/**
1329
	 * Gets namespace of attribute(s)
1330
	 * @param string|int $attr Negative int to count from end
1331
	 * @param string $compare Find node using "namespace", "name" or "total"
1332
	 * @param bool $case_sensitive Compare with case sensitivity
1333
	 * @return string|array False if not found
1334
	 */
1335
	function getAttributeNS($attr, $compare = 'name', $case_sensitive = false) {
0 ignored issues
show
Best Practice introduced by
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...
1336
		$f = $this->findAttribute($attr, $compare, $case_sensitive);
1337
		if (is_array($f) && $f) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $f 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...
1338
			if (count($f) === 1) {
1339
				return $this->attributes[$f[0][0]];
1340
			} else {
1341
				$res = array();
1342
				foreach($f as $a) {
1343
					$res[] = $a[0];
1344
				}
1345
				return $res;
1346
			}
1347
		} else {
1348
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by pQuery\DomNode::getAttributeNS of type string|array.

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...
1349
		}
1350
	}
1351
1352
	/**
1353
	 * Sets namespace of attribute(s)
1354
	 * @param string|int $attr Negative int to count from end
1355
	 * @param string $namespace
1356
	 * @param string $compare Find node using "namespace", "name" or "total"
1357
	 * @param bool $case_sensitive Compare with case sensitivity
1358
	 * @return bool
1359
	 */
1360
	function setAttributeNS($attr, $namespace, $compare = 'name', $case_sensitive = false) {
0 ignored issues
show
Best Practice introduced by
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...
1361
		$f = $this->findAttribute($attr, $compare, $case_sensitive);
1362
		if (is_array($f) && $f) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $f 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...
1363
			if ($namespace) {
1364
				$namespace .= ':';
1365
			}
1366
			foreach($f as $a) {
1367
				$val = $this->attributes[$a[2]];
1368
				unset($this->attributes[$a[2]]);
1369
				$this->attributes[$namespace.$a[1]] = $val;
1370
			}
1371
			$this->attributes_ns = 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 $attributes_ns.

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...
1372
			return true;
1373
		} else {
1374
			return false;
1375
		}
1376
	}
1377
1378
	/**
1379
	 * Gets value(s) of attribute(s)
1380
	 * @param string|int $attr Negative int to count from end
1381
	 * @param string $compare Find node using "namespace", "name" or "total"
1382
	 * @param bool $case_sensitive Compare with case sensitivity
1383
	 * @return string|array
1384
	 */
1385 12
	function getAttribute($attr, $compare = 'total', $case_sensitive = false) {
0 ignored issues
show
Best Practice introduced by
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...
1386 12
		$f = $this->findAttribute($attr, $compare, $case_sensitive);
1387 12
		if (is_array($f) && $f){
0 ignored issues
show
Bug Best Practice introduced by
The expression $f 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...
1388 12
			if (count($f) === 1) {
1389 12
				return $this->attributes[$f[0][2]];
1390
			} else {
1391
				$res = array();
1392
				foreach($f as $a) {
1393
					$res[] = $this->attributes[$a[2]];
1394
				}
1395
				return $res;
1396
			}
1397
		} else {
1398 8
			return null;
1399
		}
1400
	}
1401
1402
	/**
1403
	 * Sets value(s) of attribute(s)
1404
	 * @param string|int $attr Negative int to count from end
1405
	 * @param string $compare Find node using "namespace", "name" or "total"
1406
	 * @param bool $case_sensitive Compare with case sensitivity
1407
	 */
1408 9
	function setAttribute($attr, $val, $compare = 'total', $case_sensitive = false) {
0 ignored issues
show
Best Practice introduced by
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...
1409 9
		if ($val === null) {
1410
			return $this->deleteAttribute($attr, $compare, $case_sensitive);
1411
		}
1412
1413 9
		$f = $this->findAttribute($attr, $compare, $case_sensitive);
1414 9
		if (is_array($f) && $f) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $f 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...
1415 6
			foreach($f as $a) {
1416 6
				$this->attributes[$a[2]] = (string) $val;
1417 6
			}
1418 6
		} else {
1419 6
			$this->attributes[$attr] = (string) $val;
1420
		}
1421 9
	}
1422
1423
	/**
1424
	 * Add new attribute
1425
	 * @param string $attr
1426
	 * @param string $val
1427
	 */
1428
	function addAttribute($attr, $val) {
0 ignored issues
show
Best Practice introduced by
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...
1429
		$this->setAttribute($attr, $val, 'total', true);
1430
	}
1431
1432
	/**
1433
	 * Delete attribute(s)
1434
	 * @param string|int $attr Negative int to count from end
1435
	 * @param string $compare Find node using "namespace", "name" or "total"
1436
	 * @param bool $case_sensitive Compare with case sensitivity
1437
	 */
1438 5
	function deleteAttribute($attr, $compare = 'total', $case_sensitive = false) {
0 ignored issues
show
Best Practice introduced by
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...
1439 5
		$f = $this->findAttribute($attr, $compare, $case_sensitive);
1440 5
		if (is_array($f) && $f) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $f 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...
1441 5
			foreach($f as $a) {
1442 5
				unset($this->attributes[$a[2]]);
1443 5
				if ($this->attributes_ns !== null) {
1444
					unset($this->attributes_ns[$a[1]]);
1445
				}
1446 5
			}
1447 5
		}
1448 5
	}
1449
1450
	/**
1451
	 * Determine if node has a certain class
1452
	 * @param string $className
1453
	 * @return bool
1454
	 */
1455 2
	function hasClass($className) {
0 ignored issues
show
Best Practice introduced by
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...
1456 2
		return ($className && preg_match('`\b'.preg_quote($className).'\b`si', $this->class));
0 ignored issues
show
Documentation introduced by
The property class does not exist on object<pQuery\DomNode>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1457
	}
1458
1459
	/**
1460
	 * Add new class(es)
1461
	 * @param string|array $className
1462
	 */
1463 4
	function addClass($className) {
0 ignored issues
show
Best Practice introduced by
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...
1464 4
		if (!is_array($className)) {
1465 4
			$className = array($className);
1466 4
		}
1467 4
		$class = $this->class;
0 ignored issues
show
Documentation introduced by
The property class does not exist on object<pQuery\DomNode>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1468 4
		foreach ($className as $c) {
1469 4
			if (!(preg_match('`\b'.preg_quote($c).'\b`si', $class) > 0)) {
1470 4
				$class .= ' '.$c;
1471 4
			}
1472 4
		}
1473 4
		 $this->class = trim($class);
0 ignored issues
show
Documentation introduced by
The property class does not exist on object<pQuery\DomNode>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1474 4
	}
1475
1476
	/**
1477
	 * Remove clas(ses)
1478
	 * @param string|array $className
1479
	 */
1480 2
	function removeClass($className) {
0 ignored issues
show
Best Practice introduced by
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...
1481 2
		if (!is_array($className)) {
1482 2
			$className = array($className);
1483 2
		}
1484 2
		$class = $this->class;
0 ignored issues
show
Documentation introduced by
The property class does not exist on object<pQuery\DomNode>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1485 2
		foreach ($className as $c) {
1486 2
			$class = preg_replace('`\b'.preg_quote($c).'\b`si', '', $class);
1487 2
		}
1488 2
		if ($class) {
1489 2
			$this->class = $class;
0 ignored issues
show
Documentation introduced by
The property class does not exist on object<pQuery\DomNode>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1490 2
		} else {
1491 1
			unset($this->class);
1492
		}
1493 2
	}
1494
1495
	/**
1496
	 * Finds children using a callback function
1497
	 * @param callable $callback Function($node) that returns a bool
1498
	 * @param bool|int $recursive Check recursively
1499
	 * @param bool $check_self Include this node in search?
1500
	 * @return array
1501
	 */
1502
	function getChildrenByCallback($callback, $recursive = true, $check_self = false) {
0 ignored issues
show
Best Practice introduced by
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...
1503
		$count = $this->childCount();
1504
		if ($check_self && $callback($this)) {
1505
			$res = array($this);
1506
		} else {
1507
			$res = array();
1508
		}
1509
1510
		if ($count > 0) {
1511
			if (is_int($recursive)) {
1512
				$recursive = (($recursive > 1) ? $recursive - 1 : false);
1513
			}
1514
1515
			for ($i = 0; $i < $count; $i++) {
1516
				if ($callback($this->children[$i])) {
1517
					$res[] = $this->children[$i];
1518
				}
1519
				if ($recursive) {
1520
					$res = array_merge($res, $this->children[$i]->getChildrenByCallback($callback, $recursive));
1521
				}
1522
			}
1523
		}
1524
1525
		return $res;
1526
	}
1527
1528
	/**
1529
	 * Finds children using the {$link match()} function
1530
	 * @param $conditions See {$link match()}
1531
	 * @param $custom_filters See {$link match()}
1532
	 * @param bool|int $recursive Check recursively
1533
	 * @param bool $check_self Include this node in search?
1534
	 * @return array
1535
	 */
1536 37
	function getChildrenByMatch($conditions, $recursive = true, $check_self = false, $custom_filters = array()) {
0 ignored issues
show
Best Practice introduced by
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...
1537 37
		$count = $this->childCount();
1538 37
		if ($check_self && $this->match($conditions, true, $custom_filters)) {
1539
			$res = array($this);
1540
		} else {
1541 37
			$res = array();
1542
		}
1543
1544 37
		if ($count > 0) {
1545 37
			if (is_int($recursive)) {
1546
				$recursive = (($recursive > 1) ? $recursive - 1 : false);
1547
			}
1548
1549 37
			for ($i = 0; $i < $count; $i++) {
1550 37
				if ($this->children[$i]->match($conditions, true, $custom_filters)) {
1551 37
					$res[] = $this->children[$i];
1552 37
				}
1553 37
				if ($recursive) {
1554 37
					$res = array_merge($res, $this->children[$i]->getChildrenByMatch($conditions, $recursive, false, $custom_filters));
1555 37
				}
1556 37
			}
1557 37
		}
1558
1559 37
		return $res;
1560
	}
1561
1562
	/**
1563
	 * Checks if tag matches certain conditions
1564
	 * @param array $tags array('tag1', 'tag2') or array(array(
1565
	 *	'tag' => 'tag1',
1566
	 *	'operator' => 'or'/'and',
1567
	 *	'compare' => 'total'/'namespace'/'name',
1568
	 * 	'case_sensitive' => true))
1569
	 * @return bool
1570
	 * @internal Used by selector class
1571
	 * @see match()
1572
	 * @access private
1573
	 */
1574 23
	protected function match_tags($tags) {
1575 23
		$res = false;
1576
1577 23
		foreach($tags as $tag => $match) {
1578 23
			if (!is_array($match)) {
1579
				$match = array(
1580
					'match' => $match,
1581
					'operator' => 'or',
1582
					'compare' => 'total',
1583
					'case_sensitive' => false
1584
				);
1585
			} else {
1586 23
				if (is_int($tag)) {
1587 22
					$tag = $match['tag'];
1588 22
				}
1589 23
				if (!isset($match['match'])) {
1590
					$match['match'] = true;
1591
				}
1592 23
				if (!isset($match['operator'])) {
1593 23
					$match['operator'] = 'or';
1594 23
				}
1595 23
				if (!isset($match['compare'])) {
1596 23
					$match['compare'] = 'total';
1597 23
				}
1598 23
				if (!isset($match['case_sensitive'])) {
1599 23
					$match['case_sensitive'] = false;
1600 23
				}
1601
			}
1602
1603 23
			if (($match['operator'] === 'and') && (!$res)) {
1604
				return false;
1605 23
			} elseif (!($res && ($match['operator'] === 'or'))) {
1606 23
				if ($match['compare'] === 'total') {
1607 23
					$a = $this->tag;
1608 23
				} elseif ($match['compare'] === 'namespace') {
1609
					$a = $this->getNamespace();
1610
				} elseif ($match['compare'] === 'name') {
1611
					$a = $this->getTag();
1612
				}
1613
1614 23
				if ($match['case_sensitive']) {
1615
					$res = (($a === $tag) === $match['match']);
0 ignored issues
show
Bug introduced by
The variable $a 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...
1616
				} else {
1617 23
					$res = ((strcasecmp($a, $tag) === 0) === $match['match']);
1618
				}
1619 23
			}
1620 23
		}
1621
1622 23
		return $res;
1623
	}
1624
1625
	/**
1626
	 * Checks if attributes match certain conditions
1627
	 * @param array $attributes array('attr' => 'val') or array(array(
1628
	 *	'operator_value' => 'equals'/'='/'contains_regex'/etc
1629
	 *	'attribute' => 'attr',
1630
	 *	'value' => 'val',
1631
	 *	'match' => true,
1632
	 *	'operator_result' => 'or'/'and',
1633
	 *	'compare' => 'total'/'namespace'/'name',
1634
	 *	'case_sensitive' => true))
1635
	 * @return bool
1636
	 * @internal Used by selector class
1637
	 * @see match()
1638
	 * @access private
1639
	 */
1640 19
	protected function match_attributes($attributes) {
1641 19
		$res = false;
1642
1643 19
		foreach($attributes as $attribute => $match) {
1644 19
			if (!is_array($match)) {
1645
				$match = array(
1646
					'operator_value' => 'equals',
1647
					'value' => $match,
1648
					'match' => true,
1649
					'operator_result' => 'or',
1650
					'compare' => 'total',
1651
					'case_sensitive' => false
1652
				);
1653
			} else {
1654 19
				if (is_int($attribute)) {
1655 19
					$attribute = $match['attribute'];
1656 19
				}
1657 19
				if (!isset($match['match'])) {
1658 13
					$match['match'] = true;
1659 13
				}
1660 19
				if (!isset($match['operator_result'])) {
1661
					$match['operator_result'] = 'or';
1662
				}
1663 19
				if (!isset($match['compare'])) {
1664 13
					$match['compare'] = 'total';
1665 13
				}
1666 19
				if (!isset($match['case_sensitive'])) {
1667 19
					$match['case_sensitive'] = false;
1668 19
				}
1669
			}
1670
1671 19
			if (is_string($match['value']) && (!$match['case_sensitive'])) {
1672 19
				$match['value'] = strtolower($match['value']);
1673 19
			}
1674
1675 19
			if (($match['operator_result'] === 'and') && (!$res)) {
1676
				return false;
1677 19
			} elseif (!($res && ($match['operator_result'] === 'or'))) {
1678 19
				$possibles = $this->findAttribute($attribute, $match['compare'], $match['case_sensitive']);
1679
1680 19
				$has = (is_array($possibles) && $possibles);
0 ignored issues
show
Bug Best Practice introduced by
The expression $possibles 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...
1681 19
				$res = (($match['value'] === $has) || (($match['match'] === false) && ($has === $match['match'])));
1682
1683 19
				if ((!$res) && $has && is_string($match['value'])) {
1684 19
					foreach($possibles as $a) {
1685 19
						$val = $this->attributes[$a[2]];
1686 19
						if (is_string($val) && (!$match['case_sensitive'])) {
1687 19
							$val = strtolower($val);
1688 19
						}
1689
1690 19
						switch($match['operator_value']) {
1691 19
							case '%=':
1692 19
							case 'contains_regex':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1693
								$res = ((preg_match('`'.$match['value'].'`s', $val) > 0) === $match['match']);
1694
								if ($res) break 1; else break 2;
1695
1696 19
							case '|=':
1697 19
							case 'contains_prefix':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1698 1
								$res = ((preg_match('`\b'.preg_quote($match['value']).'[\-\s]`s', $val) > 0) === $match['match']);
1699 1
								if ($res) break 1; else break 2;
1700
1701 18
							case '~=':
1702 18
							case 'contains_word':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1703 12
								$res = ((preg_match('`\s'.preg_quote($match['value']).'\s`s', " $val ") > 0) === $match['match']);
1704 12
								if ($res) break 1; else break 2;
1705
1706 6
							case '*=':
1707 6
							case 'contains':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1708
								$res = ((strpos($val, $match['value']) !== false) === $match['match']);
1709
								if ($res) break 1; else break 2;
1710
1711 6
							case '$=':
1712 6
							case 'ends_with':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1713
								$res = ((substr($val, -strlen($match['value'])) === $match['value']) === $match['match']);
1714
								if ($res) break 1; else break 2;
1715
1716 6
							case '^=':
1717 6
							case 'starts_with':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1718
								$res = ((substr($val, 0, strlen($match['value'])) === $match['value']) === $match['match']);
1719
								if ($res) break 1; else break 2;
1720
1721 6
							case '!=':
1722 6
							case 'not_equal':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1723
								$res = (($val !== $match['value']) === $match['match']);
1724
								if ($res) break 1; else break 2;
1725
1726 6
							case '=':
1727 6
							case 'equals':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1728 6
								$res = (($val === $match['value']) === $match['match']);
1729 6
								if ($res) break 1; else break 2;
1730
1731
							case '>=':
1732
							case 'bigger_than':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1733
								$res = (($val >= $match['value']) === $match['match']);
1734
								if ($res) break 1; else break 2;
1735
1736
							case '<=':
1737
							case 'smaller_than':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1738
								$res = (($val >= $match['value']) === $match['match']);
1739
								if ($res) break 1; else break 2;
1740
1741
							default:
1742
								trigger_error('Unknown operator "'.$match['operator_value'].'" to match attributes!');
1743
								return false;
1744 19
						}
1745 19
					}
1746 19
				}
1747 19
			}
1748 19
		}
1749
1750 19
		return $res;
1751
	}
1752
1753
	/**
1754
	 * Checks if node matches certain filters
1755
	 * @param array $tags array(array(
0 ignored issues
show
Bug introduced by
There is no parameter named $tags. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1756
	 *	'filter' => 'last-child',
1757
	 *	'params' => '123'))
1758
	 * @param array $custom_filters Custom map next to {@link $filter_map}
1759
	 * @return bool
1760
	 * @internal Used by selector class
1761
	 * @see match()
1762
	 * @access private
1763
	 */
1764 3
	protected function match_filters($conditions, $custom_filters = array()) {
1765 3
		foreach($conditions as $c) {
1766 3
			$c['filter'] = strtolower($c['filter']);
1767 3
			if (isset($this->filter_map[$c['filter']])) {
1768 3
				if (!$this->{$this->filter_map[$c['filter']]}($c['params'])) {
1769 3
					return false;
1770
				}
1771 3
			} elseif (isset($custom_filters[$c['filter']])) {
1772
				if (!call_user_func($custom_filters[$c['filter']], $this, $c['params'])) {
1773
					return false;
1774
				}
1775
			} else {
1776
				trigger_error('Unknown filter "'.$c['filter'].'"!');
1777
				return false;
1778
			}
1779 3
		}
1780
1781 3
		return true;
1782
	}
1783
1784
	/**
1785
	 * Checks if node matches certain conditions
1786
	 * @param array $tags array('tags' => array(tag_conditions), 'attributes' => array(attr_conditions), 'filters' => array(filter_conditions))
0 ignored issues
show
Bug introduced by
There is no parameter named $tags. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1787
	 * @param array $match Should conditions evaluate to true?
1788
	 * @param array $custom_filters Custom map next to {@link $filter_map}
1789
	 * @return bool
1790
	 * @internal Used by selector class
1791
	 * @see match_tags();
1792
	 * @see match_attributes();
1793
	 * @see match_filters();
1794
	 * @access private
1795
	 */
1796 37
	function match($conditions, $match = true, $custom_filters = array()) {
0 ignored issues
show
Best Practice introduced by
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...
1797 37
		$t = isset($conditions['tags']);
1798 37
		$a = isset($conditions['attributes']);
1799 37
		$f = isset($conditions['filters']);
1800
1801 37
		if (!($t || $a || $f)) {
1802 37
			if (is_array($conditions) && $conditions) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $conditions 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...
1803 37
				foreach($conditions as $c) {
1804 37
					if ($this->match($c, $match)) {
1805 37
						return true;
1806
					}
1807 36
				}
1808 36
			}
1809
1810 36
			return false;
1811
		} else {
1812 37
			if (($t && (!$this->match_tags($conditions['tags']))) === $match) {
1813 22
				return false;
1814
			}
1815
1816 37
			if (($a && (!$this->match_attributes($conditions['attributes']))) === $match) {
1817 19
				return false;
1818
			}
1819
1820 37
			if (($f && (!$this->match_filters($conditions['filters'], $custom_filters))) === $match) {
1821 3
				return false;
1822
			}
1823
1824 37
			return true;
1825
		}
1826
	}
1827
1828
	/**
1829
	 * Finds children that match a certain attribute
1830
	 * @param string $attribute
1831
	 * @param string $value
1832
	 * @param string $mode Compare mode, "equals", "|=", "contains_regex", etc.
1833
	 * @param string $compare "total"/"namespace"/"name"
1834
	 * @param bool|int $recursive
1835
	 * @return array
1836
	 */
1837
	function getChildrenByAttribute($attribute, $value, $mode = 'equals', $compare = 'total', $recursive = true) {
0 ignored issues
show
Best Practice introduced by
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...
1838
		if ($this->childCount() < 1) {
1839
			return array();
1840
		}
1841
1842
		$mode = explode(' ', strtolower($mode));
1843
		$match = ((isset($mode[1]) && ($mode[1] === 'not')) ? 'false' : 'true');
1844
1845
		return $this->getChildrenByMatch(
1846
			array(
1847
				'attributes' => array(
1848
					$attribute => array(
1849
						'operator_value' => $mode[0],
1850
						'value' => $value,
1851
						'match' => $match,
1852
						'compare' => $compare
1853
					)
1854
				)
1855
			),
1856
			$recursive
1857
		);
1858
	}
1859
1860
	/**
1861
	 * Finds children that match a certain tag
1862
	 * @param string $tag
1863
	 * @param string $compare "total"/"namespace"/"name"
1864
	 * @param bool|int $recursive
1865
	 * @return array
1866
	 */
1867
	function getChildrenByTag($tag, $compare = 'total', $recursive = true) {
0 ignored issues
show
Best Practice introduced by
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...
1868
		if ($this->childCount() < 1) {
1869
			return array();
1870
		}
1871
1872
		$tag = explode(' ', strtolower($tag));
1873
		$match = ((isset($tag[1]) && ($tag[1] === 'not')) ? 'false' : 'true');
1874
1875
		return $this->getChildrenByMatch(
1876
			array(
1877
				'tags' => array(
1878
					$tag[0] => array(
1879
						'match' => $match,
1880
						'compare' => $compare
1881
					)
1882
				)
1883
			),
1884
			$recursive
1885
		);
1886
	}
1887
1888
	/**
1889
	 * Finds all children using ID attribute
1890
	 * @param string $id
1891
	 * @param bool|int $recursive
1892
	 * @return array
1893
	 */
1894
	function getChildrenByID($id, $recursive = true) {
0 ignored issues
show
Best Practice introduced by
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...
1895
		return $this->getChildrenByAttribute('id', $id, 'equals', 'total', $recursive);
1896
	}
1897
1898
	/**
1899
	 * Finds all children using class attribute
1900
	 * @param string $class
1901
	 * @param bool|int $recursive
1902
	 * @return array
1903
	 */
1904
	function getChildrenByClass($class, $recursive = true) {
0 ignored issues
show
Best Practice introduced by
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...
1905
		return $this->getChildrenByAttribute('class', $class, 'equals', 'total', $recursive);
1906
	}
1907
1908
	/**
1909
	 * Finds all children using name attribute
1910
	 * @param string $name
1911
	 * @param bool|int $recursive
1912
	 * @return array
1913
	 */
1914
	function getChildrenByName($name, $recursive = true) {
0 ignored issues
show
Best Practice introduced by
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...
1915
		return $this->getChildrenByAttribute('name', $name, 'equals', 'total', $recursive);
1916
	}
1917
1918
    /**
1919
     * Performs a css query on the node.
1920
     * @param string $query
1921
     * @return IQuery Returns the matching nodes from the query.
1922
     */
1923 36
    public function query($query = '*') {
1924 36
        $select = $this->select($query);
1925 36
        $result = new \pQuery((array)$select);
1926 36
        return $result;
1927
    }
1928
1929
	/**
1930
	 * Performs css query on node
1931
	 * @param string $query
1932
	 * @param int|bool $index True to return node instead of array if only 1 match,
1933
	 * false to return array, int to return match at index, negative int to count from end
1934
	 * @param bool|int $recursive
1935
	 * @param bool $check_self Include this node in search or only search child nodes
1936
	 * @return DomNode[]|DomNode Returns an array of matching {@link DomNode} objects
1937
     *  or a single {@link DomNode} if `$index` is not false.
1938
	 */
1939 37
	function select($query = '*', $index = false, $recursive = true, $check_self = false) {
0 ignored issues
show
Best Practice introduced by
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...
1940 37
		$s = new $this->selectClass($this, $query, $check_self, $recursive);
1941 37
		$res = $s->result;
1942 37
		unset($s);
1943 37
		if (is_array($res) && ($index === true) && (count($res) === 1)) {
1944
			return $res[0];
1945 37
		} elseif (is_int($index) && is_array($res)) {
1946
			if ($index < 0) {
1947
				$index += count($res);
1948
			}
1949
			return ($index < count($res)) ? $res[$index] : null;
1950
        } else {
1951 37
			return $res;
1952
		}
1953
	}
1954
1955
	/**
1956
	 * Checks if node matches css query filter ":root"
1957
	 * @return bool
1958
	 * @see match()
1959
	 * @access private
1960
	 */
1961
	protected function filter_root() {
1962
		return (strtolower($this->tag) === 'html');
1963
	}
1964
1965
	/**
1966
	 * Checks if node matches css query filter ":nth-child(n)"
1967
	 * @param string $n 1-based index
1968
	 * @return bool
1969
	 * @see match()
1970
	 * @access private
1971
	 */
1972
	protected function filter_nchild($n) {
1973
		return ($this->index(false)+1 === (int) $n);
1974
	}
1975
1976
	/**
1977
	 * Checks if node matches css query filter ":gt(n)"
1978
	 * @param string $n 0-based index
1979
	 * @return bool
1980
	 * @see match()
1981
	 * @access private
1982
	 */
1983
	protected function filter_gt($n) {
1984
		return ($this->index(false) > (int) $n);
1985
	}
1986
1987
	/**
1988
	 * Checks if node matches css query filter ":lt(n)"
1989
	 * @param string $n 0-based index
1990
	 * @return bool
1991
	 * @see match()
1992
	 * @access private
1993
	 */
1994
	protected function filter_lt($n) {
1995
		return ($this->index(false) < (int) $n);
1996
	}
1997
1998
	/**
1999
	 * Checks if node matches css query filter ":nth-last-child(n)"
2000
	 * @param string $n 1-based index
2001
	 * @return bool
2002
	 * @see match()
2003
	 * @access private
2004
	 */
2005
	protected function filter_nlastchild($n) {
2006
		if ($this->parent === null) {
2007
			return false;
2008
		} else {
2009
			return ($this->parent->childCount(true) - $this->index(false) === (int) $n);
2010
		}
2011
	}
2012
2013
	/**
2014
	 * Checks if node matches css query filter ":nth-of-type(n)"
2015
	 * @param string $n 1-based index
2016
	 * @return bool
2017
	 * @see match()
2018
	 * @access private
2019
	 */
2020
	protected function filter_ntype($n) {
2021
		return ($this->typeIndex()+1 === (int) $n);
2022
	}
2023
2024
	/**
2025
	 * Checks if node matches css query filter ":nth-last-of-type(n)"
2026
	 * @param string $n 1-based index
2027
	 * @return bool
2028
	 * @see match()
2029
	 * @access private
2030
	 */
2031
	protected function filter_nlastype($n) {
2032
		if ($this->parent === null) {
2033
			return false;
2034
		} else {
2035
			return (count($this->parent->getChildrenByTag($this->tag, 'total', false)) - $this->typeIndex() === (int) $n);
2036
		}
2037
	}
2038
2039
	/**
2040
	 * Checks if node matches css query filter ":odd"
2041
	 * @return bool
2042
	 * @see match()
2043
	 * @access private
2044
	 */
2045
	protected function filter_odd() {
2046
		return (($this->index(false) & 1) === 1);
2047
	}
2048
2049
	/**
2050
	 * Checks if node matches css query filter ":even"
2051
	 * @return bool
2052
	 * @see match()
2053
	 * @access private
2054
	 */
2055
	protected function filter_even() {
2056
		return (($this->index(false) & 1) === 0);
2057
	}
2058
2059
	/**
2060
	 * Checks if node matches css query filter ":every(n)"
2061
	 * @return bool
2062
	 * @see match()
2063
	 * @access private
2064
	 */
2065
	protected function filter_every($n) {
2066
		return (($this->index(false) % (int) $n) === 0);
2067
	}
2068
2069
	/**
2070
	 * Checks if node matches css query filter ":first"
2071
	 * @return bool
2072
	 * @see match()
2073
	 * @access private
2074
	 */
2075
	protected function filter_first() {
2076
		return ($this->index(false) === 0);
2077
	}
2078
2079
	/**
2080
	 * Checks if node matches css query filter ":last"
2081
	 * @return bool
2082
	 * @see match()
2083
	 * @access private
2084
	 */
2085
	protected function filter_last() {
2086
		if ($this->parent === null) {
2087
			return false;
2088
		} else {
2089
			return ($this->parent->childCount(true) - 1 === $this->index(false));
2090
		}
2091
	}
2092
2093
	/**
2094
	 * Checks if node matches css query filter ":first-of-type"
2095
	 * @return bool
2096
	 * @see match()
2097
	 * @access private
2098
	 */
2099
	protected function filter_firsttype() {
2100
		return ($this->typeIndex() === 0);
2101
	}
2102
2103
	/**
2104
	 * Checks if node matches css query filter ":last-of-type"
2105
	 * @return bool
2106
	 * @see match()
2107
	 * @access private
2108
	 */
2109
	protected function filter_lasttype() {
2110
		if ($this->parent === null) {
2111
			return false;
2112
		} else {
2113
			return (count($this->parent->getChildrenByTag($this->tag, 'total', false)) - 1 === $this->typeIndex());
2114
		}
2115
	}
2116
2117
	/**
2118
	 * Checks if node matches css query filter ":only-child"
2119
	 * @return bool
2120
	 * @see match()
2121
	 * @access private
2122
	 */
2123
	protected function filter_onlychild() {
2124
		if ($this->parent === null) {
2125
			return false;
2126
		} else {
2127
			return ($this->parent->childCount(true) === 1);
2128
		}
2129
	}
2130
2131
	/**
2132
	 * Checks if node matches css query filter ":only-of-type"
2133
	 * @return bool
2134
	 * @see match()
2135
	 * @access private
2136
	 */
2137
	protected function filter_onlytype() {
2138
		if ($this->parent === null) {
2139
			return false;
2140
		} else {
2141
			return (count($this->parent->getChildrenByTag($this->tag, 'total', false)) === 1);
2142
		}
2143
	}
2144
2145
	/**
2146
	 * Checks if node matches css query filter ":empty"
2147
	 * @return bool
2148
	 * @see match()
2149
	 * @access private
2150
	 */
2151
	protected function filter_empty() {
2152
		return ($this->childCount() === 0);
2153
	}
2154
2155
	/**
2156
	 * Checks if node matches css query filter ":not-empty"
2157
	 * @return bool
2158
	 * @see match()
2159
	 * @access private
2160
	 */
2161
	protected function filter_notempty() {
2162
		return ($this->childCount() !== 0);
2163
	}
2164
2165
	/**
2166
	 * Checks if node matches css query filter ":has-text"
2167
	 * @return bool
2168
	 * @see match()
2169
	 * @access private
2170
	 */
2171
	protected function filter_hastext() {
2172
		return ($this->getPlainText() !== '');
2173
	}
2174
2175
	/**
2176
	 * Checks if node matches css query filter ":no-text"
2177
	 * @return bool
2178
	 * @see match()
2179
	 * @access private
2180
	 */
2181
	protected function filter_notext() {
2182
		return ($this->getPlainText() === '');
2183
	}
2184
2185
	/**
2186
	 * Checks if node matches css query filter ":lang(s)"
2187
	 * @param string $lang
2188
	 * @return bool
2189
	 * @see match()
2190
	 * @access private
2191
	 */
2192
	protected function filter_lang($lang) {
2193
		return ($this->lang === $lang);
0 ignored issues
show
Documentation introduced by
The property lang does not exist on object<pQuery\DomNode>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2194
	}
2195
2196
	/**
2197
	 * Checks if node matches css query filter ":contains(s)"
2198
	 * @param string $text
2199
	 * @return bool
2200
	 * @see match()
2201
	 * @access private
2202
	 */
2203
	protected function filter_contains($text) {
2204
		return (strpos($this->getPlainTextUTF8(), $text) !== false);
2205
	}
2206
2207
	/**
2208
	 * Checks if node matches css query filter ":has(s)"
2209
	 * @param string $selector
2210
	 * @return bool
2211
	 * @see match()
2212
	 * @access private
2213
	 */
2214
	protected function filter_has($selector) {
2215
		$s = $this->select((string) $selector, false);
2216
		return (is_array($s) && (count($s) > 0));
2217
	}
2218
2219
	/**
2220
	 * Checks if node matches css query filter ":not(s)"
2221
	 * @param string $selector
2222
	 * @return bool
2223
	 * @see match()
2224
	 * @access private
2225
	 */
2226
	protected function filter_not($selector) {
2227
		$s = $this->select((string) $selector, false, true, true);
2228
		return ((!is_array($s)) || (array_search($this, $s, true) === false));
2229
	}
2230
2231
	/**
2232
	 * Checks if node matches css query filter ":element"
2233
	 * @return bool
2234
	 * @see match()
2235
	 * @access private
2236
	 */
2237
	protected function filter_element() {
2238
		return true;
2239
	}
2240
2241
	/**
2242
	 * Checks if node matches css query filter ":text"
2243
	 * @return bool
2244
	 * @see match()
2245
	 * @access private
2246
	 */
2247
	protected function filter_text() {
2248
		return false;
2249
	}
2250
2251
    /**
2252
     * Checks if a node matches css query filter ":checked"
2253
     * @return bool
2254
     * @see match()
2255
     */
2256 1
    protected function filter_checked() {
2257 1
        $attr = $this->getAttribute('checked');
2258 1
        if (is_array($attr))
2259 1
            $attr = reset($attr);
2260 1
        return strcasecmp($attr, 'checked') === 0;
2261
    }
2262
2263
	/**
2264
	 * Checks if node matches css query filter ":comment"
2265
	 * @return bool
2266
	 * @see match()
2267
	 * @access private
2268
	 */
2269
	protected function filter_comment() {
2270
		return false;
2271
	}
2272
2273
    /**
2274
     * Checks if a node matches css query filter ":selected"
2275
     * @return bool
2276
     * @see match()
2277
     */
2278 2
    protected function filter_selected() {
2279 2
        $attr = $this->getAttribute('selected');
2280 2
        if (is_array($attr))
2281 2
            $attr = reset($attr);
2282
2283 2
        return strcasecmp($attr, 'selected') === 0;
2284
    }
2285
2286 1
    public function after($content) {
2287 1
        $offset = $this->index() + 1;
2288 1
        $parent = $this->parent;
2289 1
        $nodes = $this->createNodes($content);
2290
2291 1
        foreach ($nodes as $node) {
2292 1
            $node->changeParent($parent, $offset);
2293 1
        }
2294 1
        return $this;
2295
    }
2296
2297
2298
    /**
2299
     * Create a {@link DomNode} from its string representation.
2300
     * @param string|DomNode $content
2301
     * @return DomNode
2302
     */
2303 2
    protected function createNode($content) {
2304 2
        $nodes = $this->createNodes($content);
2305 2
        return reset($nodes);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression reset($nodes); of type pQuery\DomNode|false adds false to the return on line 2305 which is incompatible with the return type documented by pQuery\DomNode::createNode of type pQuery\DomNode. It seems like you forgot to handle an error condition.
Loading history...
2306
    }
2307
2308
    /**
2309
     * Create an array of {@link DomNode} objects from their string representation.
2310
     * @param string|DomNode $content
2311
     * @return DomNode[]
2312
     */
2313 9
    protected function createNodes($content) {
2314 9
        if (is_string($content)) {
2315 9
            if (strpos($content, ' ') === false) {
2316 1
                $nodes = array(new $this->childClass($content, $this));
2317 1
            } else {
2318 8
                $node = new $this->parserClass($content);
2319 8
                $nodes = $node->root->children;
2320
            }
2321 9
        } else {
2322
            $nodes = (array)$content;
2323
        }
2324 9
        return $nodes;
2325
    }
2326
2327 1
    public function append($content) {
2328 1
        $nodes = $this->createNodes($content);
2329 1
        foreach ($nodes as $node) {
2330 1
            $node->changeParent($this);
2331 1
        }
2332 1
        return $this;
2333
    }
2334
2335 9
    public function attr($name, $value = null) {
2336 9
        if ($value === null)
2337 9
            return $this->getAttribute($name);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getAttribute($name); of type string|array adds the type array to the return on line 2337 which is incompatible with the return type declared by the interface pQuery\IQuery::attr of type string|pQuery\IQuery.
Loading history...
2338
2339 4
        $this->setAttribute($name, $value);
2340 4
        return $this;
2341
    }
2342
2343 1
   public function before($content) {
2344 1
      $offset = $this->index();
2345 1
      $parent = $this->parent;
2346 1
      $nodes = $this->createNodes($content);
2347
2348 1
      foreach ($nodes as $node) {
2349 1
          $node->changeParent($parent, $offset);
2350 1
      }
2351
2352 1
      return $this;
2353
   }
2354
2355
   public function count() {
2356
       return 1;
2357
   }
2358
2359
//   public function css($name, $value = null) {
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...
2360
//
2361
//   }
2362
2363 1
   public function prepend($content = null) {
2364 1
      $offset = 0;
2365 1
      $parent = $this;
2366 1
      $nodes = $this->createNodes($content);
2367
2368 1
      foreach ($nodes as $node) {
2369 1
          $node->changeParent($parent, $offset);
2370 1
      }
2371
2372 1
      return $this;
2373
   }
2374
2375 4
    public function prop($name, $value = null) {
2376 4
        switch (strtolower($name)) {
2377 4
            case 'checked':
2378 4
            case 'disabled':
2379 4
            case 'selected':
2380 3
                if ($value !== null) {
2381 2
                    if ($value) {
2382 1
                        $this->attr($name, $name);
2383 1
                    } else {
2384 1
                        $this->removeAttr($name);
2385
                    }
2386 2
                    return $this;
2387
                }
2388 3
                return $this->attr($name) == $name;
2389 1
            case 'tagname':
2390 1
                return $this->tagName($value);
0 ignored issues
show
Bug introduced by
It seems like $value defined by parameter $value on line 2375 can also be of type string; however, pQuery\DomNode::tagName() does only seem to accept object<pQuery\type>|null, 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...
2391
        }
2392
        // The property is not supported, degrade gracefully
2393
        if ($value === null)
2394
            return $this;
2395
        else
2396
            return null;
2397
    }
2398
2399 4
   public function remove($selector = null) {
2400 4
      if ($selector == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $selector of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
2401 3
         $this->delete();
2402 3
      } else {
2403 1
         $nodes = (array)$this->select($selector);
2404 1
         foreach ($nodes as $node) {
2405 1
            $node->delete();
2406 1
         }
2407
      }
2408 4
   }
2409
2410 3
   public function removeAttr($name) {
2411 3
      $this->deleteAttribute($name);
2412
2413 3
      return $this;
2414
   }
2415
2416 2
   function replaceWith($content) {
0 ignored issues
show
Best Practice introduced by
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...
2417 2
        $node_index = $this->index();
2418
2419
        // Add the new node.
2420 2
        $node = $this->createNode($content);
2421 2
        $node->changeParent($this->parent, $node_index);
2422
2423
        // Remove this node.
2424 2
        $this->remove();
2425
2426 2
		return $node;
2427
	}
2428
2429
    /**
2430
     * @param type $value
2431
     * @return string|DomNode
2432
     */
2433 2
    public function tagName($value = null) {
2434 2
        if ($value !== null) {
2435 2
            $this->setTag($value);
2436 2
            return $this;
2437
        }
2438 1
        return $this->getTag();
2439
    }
2440
2441 2
   public function text($value = null) {
2442 2
      if ($value === null)
2443 2
         return $this->getPlainText();
2444
2445 1
      $this->setPlainText($value);
2446 1
      return $this;
2447
   }
2448
2449 1
   public function toggleClass($classname, $switch = null) {
2450 1
      if ($switch === true) {
2451 1
         $this->addClass($classname);
2452 1
      } elseif ($switch === false) {
2453 1
         $this->removeClass($classname);
2454 1
      } else {
2455 1
         if ($this->hasClass($classname))
2456 1
            $this->removeClass($classname);
2457
         else
2458 1
            $this->addClass($classname);
2459
      }
2460 1
      return $this;
2461
   }
2462
2463 1
   public function unwrap() {
2464 1
      $this->parent->detach(true);
2465 1
      return $this;
2466
   }
2467
2468 5
    public function val($value = null) {
2469 5
        switch (strtolower($this->tag)) {
2470 5
            case 'select':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
2471 2
                if ($value === null) {
2472
                    // Return the value of a selected child.
2473 2
                    return $this->query('option:selected')->attr('value');
2474
                } else {
2475
                    // Select the option with the right value and deselect the others.
2476 1
                    foreach ($this->query('option') as $option) {
2477 1
                        if ($option->attr('value') == $value) {
2478 1
                            $option->attr('selected', 'selected');
2479 1
                        } else {
2480 1
                            $option->removeAttr('selected');
2481
                        }
2482 1
                    }
2483 1
                    return $this;
2484
                }
2485 3
            case 'textarea':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
2486 1
                if ($value === null) {
2487
                    // Return the contents of the textarea.
2488 1
                    return $this->getInnerText();
2489
                } else {
2490
                    // Set the contents of the textarea.
2491 1
                    $this->setInnerText($value);
2492 1
                    return $this;
2493
                }
2494 2
            case 'input':
2495 2
                switch (strtolower($this->getAttribute('type'))) {
2496 2
                    case 'checkbox':
2497 1
                        if ($value === null)
2498 1
                            return $this->prop('checked') ? $this->getAttribute('value') : null;
2499
                        else {
2500 1
                            if (!$value) {
2501 1
                                $this->deleteAttribute('checked');
2502 1
                            } else {
2503 1
                                $this->setAttribute('value', $value);
2504 1
                                $this->setAttribute('checked', 'checked');
2505
                            }
2506 1
                            return $this;
2507
                        }
2508 1
                }
2509 1
        }
2510
2511
        // Other node types can just get/set the value attribute.
2512 1
        if ($value !== null) {
2513 1
           $this->setAttribute('value', $value);
2514 1
           return $this;
2515
        }
2516 1
        return $this->getAttribute('value');
2517
    }
2518
2519
}
2520
2521
/**
2522
 * Node subclass for text
2523
 */
2524
class TextNode extends DomNode {
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...
2525
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2526
	#static $NODE_TYPE = self::NODE_TEXT;
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...
2527
	#php4e
2528
	#php5
2529
	const NODE_TYPE = self::NODE_TEXT;
2530
	#php5e
2531
	var $tag = '~text~';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag.

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...
2532
2533
	/**
2534
	 * @var string
2535
	 */
2536
	var $text = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $text.

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...
2537
2538
	/**
2539
	 * Class constructor
2540
	 * @param DomNode $parent
2541
	 * @param string $text
2542
	 */
2543 37
	function __construct($parent, $text = '') {
0 ignored issues
show
Best Practice introduced by
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...
2544 37
		$this->parent = $parent;
0 ignored issues
show
Documentation introduced by
The property $parent is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2545 37
		$this->text = $text;
2546 37
	}
2547
2548
	#php4 PHP4 class constructor compatibility
2549
	#function TextNode($parent, $text = '') {return $this->__construct($parent, $text);}
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...
2550
	#php4e
2551
2552
	function isText() {return true;}
0 ignored issues
show
Best Practice introduced by
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...
2553
	function isTextOrComment() {return true;}
0 ignored issues
show
Best Practice introduced by
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...
2554
	protected function filter_element() {return false;}
2555
	protected function filter_text() {return true;}
2556
	function toString_attributes() {return '';}
0 ignored issues
show
Best Practice introduced by
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...
2557
	function toString_content($attributes = true, $recursive = true, $content_only = false) {return $this->text;}
0 ignored issues
show
Best Practice introduced by
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...
2558
	function toString($attributes = true, $recursive = true, $content_only = false) {return $this->text;}
0 ignored issues
show
Best Practice introduced by
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...
2559
2560
    /**
2561
     * {@inheritdoc}
2562
     */
2563 1
    public function text($value = null) {
2564 1
        if ($value !== null) {
2565 1
            $this->text = $value;
2566 1
            return $this;
2567
        }
2568 1
        return $this->text;
2569
    }
2570
2571
    /**
2572
     * {@inheritdoc}
2573
     */
2574 1
    public function html($value = null) {
2575 1
        if ($value !== null) {
2576
            $this->text = $value;
2577
            return $this;
2578
        }
2579 1
        return $this->text;
2580
    }
2581
}
2582
2583
/**
2584
 * Node subclass for comments
2585
 */
2586
class CommentNode extends DomNode {
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...
2587
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2588
	#static $NODE_TYPE = self::NODE_COMMENT;
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...
2589
	#php4e
2590
	#php5
2591
	const NODE_TYPE = self::NODE_COMMENT;
2592
	#php5e
2593
	var $tag = '~comment~';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag.

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...
2594
2595
	/**
2596
	 * @var string
2597
	 */
2598
	var $text = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $text.

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...
2599
2600
	/**
2601
	 * Class constructor
2602
	 * @param DomNode $parent
2603
	 * @param string $text
2604
	 */
2605 9
	function __construct($parent, $text = '') {
0 ignored issues
show
Best Practice introduced by
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...
2606 9
		$this->parent = $parent;
0 ignored issues
show
Documentation introduced by
The property $parent is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2607 9
		$this->text = $text;
2608 9
	}
2609
2610
	#php4 PHP4 class constructor compatibility
2611
	#function CommentNode($parent, $text = '') {return $this->__construct($parent, $text);}
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...
2612
	#php4e
2613
2614
	function isComment() {return true;}
0 ignored issues
show
Best Practice introduced by
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...
2615
	function isTextOrComment() {return true;}
0 ignored issues
show
Best Practice introduced by
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...
2616
	protected function filter_element() {return false;}
2617
	protected function filter_comment() {return true;}
2618
	function toString_attributes() {return '';}
0 ignored issues
show
Best Practice introduced by
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...
2619
	function toString_content($attributes = true, $recursive = true, $content_only = false) {return $this->text;}
0 ignored issues
show
Best Practice introduced by
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...
2620
	function toString($attributes = true, $recursive = true, $content_only = false) {return '<!--'.$this->text.'-->';}
0 ignored issues
show
Best Practice introduced by
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...
2621
}
2622
2623
/**
2624
 * Node subclass for conditional tags
2625
 */
2626
class ConditionalTagNode extends DomNode {
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...
2627
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2628
	#static $NODE_TYPE = self::NODE_CONDITIONAL;
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...
2629
	#php4e
2630
	#php5
2631
	const NODE_TYPE = self::NODE_CONDITIONAL;
2632
	#php5e
2633
	var $tag = '~conditional~';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag.

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...
2634
2635
	/**
2636
	 * @var string
2637
	 */
2638
	var $condition = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $condition.

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...
2639
2640
	/**
2641
	 * Class constructor
2642
	 * @param DomNode $parent
2643
	 * @param string $condition e.g. "if IE"
2644
	 * @param bool $hidden <!--[if if true, <![if if false
2645
	 */
2646
	function __construct($parent, $condition = '', $hidden = true) {
0 ignored issues
show
Best Practice introduced by
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...
2647
		$this->parent = $parent;
0 ignored issues
show
Documentation introduced by
The property $parent is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2648
		$this->hidden = $hidden;
0 ignored issues
show
Documentation introduced by
The property hidden does not exist on object<pQuery\ConditionalTagNode>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2649
		$this->condition = $condition;
2650
	}
2651
2652
	#php4 PHP4 class constructor compatibility
2653
	#function ConditionalTagNode($parent, $condition = '', $hidden = true) {return $this->__construct($parent, $condition, $hidden);}
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% 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...
2654
	#php4e
2655
2656
	protected function filter_element() {return false;}
2657
	function toString_attributes() {return '';}
0 ignored issues
show
Best Practice introduced by
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...
2658
	function toString($attributes = true, $recursive = true, $content_only = false) {
0 ignored issues
show
Best Practice introduced by
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...
2659
		if ($content_only) {
2660
			if (is_int($content_only)) {
2661
				--$content_only;
2662
			}
2663
			return $this->toString_content($attributes, $recursive, $content_only);
0 ignored issues
show
Bug introduced by
It seems like $content_only defined by --$content_only on line 2661 can also be of type integer; however, pQuery\DomNode::toString_content() does only seem to accept boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2664
		}
2665
2666
		$s = '<!'.(($this->hidden) ? '--' : '').'['.$this->condition.']>';
0 ignored issues
show
Documentation introduced by
The property hidden does not exist on object<pQuery\ConditionalTagNode>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2667
		if($recursive) {
2668
			$s .= $this->toString_content($attributes);
2669
		}
2670
		$s .= '<![endif]'.(($this->hidden) ? '--' : '').'>';
0 ignored issues
show
Documentation introduced by
The property hidden does not exist on object<pQuery\ConditionalTagNode>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2671
		return $s;
2672
	}
2673
}
2674
2675
/**
2676
 * Node subclass for CDATA tags
2677
 */
2678
class CdataNode extends DomNode {
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...
2679
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2680
	#static $NODE_TYPE = self::NODE_CDATA;
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...
2681
	#php4e
2682
	#php5
2683
	const NODE_TYPE = self::NODE_CDATA;
2684
	#php5e
2685
	var $tag = '~cdata~';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag.

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...
2686
2687
	/**
2688
	 * @var string
2689
	 */
2690
	var $text = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $text.

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...
2691
2692
	/**
2693
	 * Class constructor
2694
	 * @param DomNode $parent
2695
	 * @param string $text
2696
	 */
2697
	function __construct($parent, $text = '') {
0 ignored issues
show
Best Practice introduced by
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...
2698
		$this->parent = $parent;
0 ignored issues
show
Documentation introduced by
The property $parent is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2699
		$this->text = $text;
2700
	}
2701
2702
	#php4 PHP4 class constructor compatibility
2703
	#function CdataNode($parent, $text = '') {return $this->__construct($parent, $text);}
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...
2704
	#php4e
2705
2706
	protected function filter_element() {return false;}
2707
	function toString_attributes() {return '';}
0 ignored issues
show
Best Practice introduced by
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...
2708
	function toString_content($attributes = true, $recursive = true, $content_only = false) {return $this->text;}
0 ignored issues
show
Best Practice introduced by
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...
2709
	function toString($attributes = true, $recursive = true, $content_only = false) {return '<![CDATA['.$this->text.']]>';}
0 ignored issues
show
Best Practice introduced by
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...
2710
}
2711
2712
/**
2713
 * Node subclass for doctype tags
2714
 */
2715
class DoctypeNode extends DomNode {
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...
2716
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2717
	#static $NODE_TYPE = self::NODE_DOCTYPE;
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...
2718
	#php4e
2719
	#php5
2720
	const NODE_TYPE = self::NODE_DOCTYPE;
2721
	#php5e
2722
	var $tag = '!DOCTYPE';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag.

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...
2723
2724
	/**
2725
	 * @var string
2726
	 */
2727
	var $dtd = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $dtd.

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...
2728
2729
	/**
2730
	 * Class constructor
2731
	 * @param DomNode $parent
2732
	 * @param string $dtd
2733
	 */
2734 9
	function __construct($parent, $dtd = '') {
0 ignored issues
show
Best Practice introduced by
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...
2735 9
		$this->parent = $parent;
0 ignored issues
show
Documentation introduced by
The property $parent is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2736 9
		$this->dtd = $dtd;
2737 9
	}
2738
2739
	#php4 PHP4 class constructor compatibility
2740
	#function DoctypeNode($parent, $dtd = '') {return $this->__construct($parent, $dtd);}
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...
2741
	#php4e
2742
2743
	protected function filter_element() {return false;}
2744
	function toString_attributes() {return '';}
0 ignored issues
show
Best Practice introduced by
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...
2745
	function toString_content($attributes = true, $recursive = true, $content_only = false) {return $this->text;}
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<pQuery\DoctypeNode>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Best Practice introduced by
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...
2746
	function toString($attributes = true, $recursive = true, $content_only = false) {return '<'.$this->tag.' '.$this->dtd.'>';}
0 ignored issues
show
Best Practice introduced by
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...
2747
}
2748
2749
/**
2750
 * Node subclass for embedded tags like xml, php and asp
2751
 */
2752
class EmbeddedNode extends DomNode {
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...
2753
2754
	/**
2755
	 * @var string
2756
	 * @internal specific char for tags, like ? for php and % for asp
2757
	 * @access private
2758
	 */
2759
	var $tag_char = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $tag_char.

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...
2760
2761
	/**
2762
	 * @var string
2763
	 */
2764
	var $text = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $text.

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...
2765
2766
	/**
2767
	 * Class constructor
2768
	 * @param DomNode $parent
2769
	 * @param string $tag_char {@link $tag_char}
2770
	 * @param string $tag {@link $tag}
2771
	 * @param string $text
2772
	 * @param array $attributes array('attr' => 'val')
2773
	 */
2774
	function __construct($parent, $tag_char = '', $tag = '', $text = '', $attributes = array()) {
0 ignored issues
show
Best Practice introduced by
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...
2775
		$this->parent = $parent;
0 ignored issues
show
Documentation introduced by
The property $parent is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2776
		$this->tag_char = $tag_char;
2777
		if ($tag[0] !== $this->tag_char) {
2778
			$tag = $this->tag_char.$tag;
2779
		}
2780
		$this->tag = $tag;
0 ignored issues
show
Documentation introduced by
The property $tag is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2781
		$this->text = $text;
2782
		$this->attributes = $attributes;
0 ignored issues
show
Documentation introduced by
The property $attributes is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2783
		$this->self_close_str = $tag_char;
0 ignored issues
show
Documentation introduced by
The property $self_close_str is declared private in pQuery\DomNode. Since you implemented __set(), maybe consider adding a @property or @property-write annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2784
	}
2785
2786
	#php4 PHP4 class constructor compatibility
2787
	#function EmbeddedNode($parent, $tag_char = '', $tag = '', $text = '', $attributes = array()) {return $this->__construct($parent, $tag_char, $tag, $text, $attributes);}
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...
2788
	#php4e
2789
2790
	protected function filter_element() {return false;}
2791
	function toString($attributes = true, $recursive = true, $content_only = false) {
0 ignored issues
show
Best Practice introduced by
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...
2792
		$s = '<'.$this->tag;
0 ignored issues
show
Documentation introduced by
The property $tag is declared private in pQuery\DomNode. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2793
		if ($attributes) {
2794
			$s .= $this->toString_attributes();
2795
		}
2796
		$s .= $this->text.$this->self_close_str.'>';
0 ignored issues
show
Documentation introduced by
The property $self_close_str is declared private in pQuery\DomNode. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
2797
		return $s;
2798
	}
2799
}
2800
2801
/**
2802
 * Node subclass for "?" tags, like php and xml
2803
 */
2804
class XmlNode extends EmbeddedNode {
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...
2805
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2806
	#static $NODE_TYPE = self::NODE_XML;
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...
2807
	#php4e
2808
	#php5
2809
	const NODE_TYPE = self::NODE_XML;
2810
	#php5e
2811
2812
	/**
2813
	 * Class constructor
2814
	 * @param DomNode $parent
2815
	 * @param string $tag {@link $tag}
2816
	 * @param string $text
2817
	 * @param array $attributes array('attr' => 'val')
2818
	 */
2819
	function __construct($parent, $tag = 'xml', $text = '', $attributes = array()) {
0 ignored issues
show
Best Practice introduced by
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...
2820
		return parent::__construct($parent, '?', $tag, $text, $attributes);
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
2821
	}
2822
2823
	#php4 PHP4 class constructor compatibility
2824
	#function XmlNode($parent, $tag = 'xml', $text = '', $attributes = array()) {return $this->__construct($parent, $tag, $text, $attributes);}
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...
2825
	#php4e
2826
}
2827
2828
/**
2829
 * Node subclass for asp tags
2830
 */
2831
class AspEmbeddedNode extends EmbeddedNode {
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...
2832
	#php4 Compatibility with PHP4, this gets changed to a regular var in release tool
2833
	#static $NODE_TYPE = self::NODE_ASP;
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...
2834
	#php4e
2835
	#php5
2836
	const NODE_TYPE = self::NODE_ASP;
2837
	#php5e
2838
2839
	/**
2840
	 * Class constructor
2841
	 * @param DomNode $parent
2842
	 * @param string $tag {@link $tag}
2843
	 * @param string $text
2844
	 * @param array $attributes array('attr' => 'val')
2845
	 */
2846
	function __construct($parent, $tag = '', $text = '', $attributes = array()) {
0 ignored issues
show
Best Practice introduced by
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...
2847
		return parent::__construct($parent, '%', $tag, $text, $attributes);
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
2848
	}
2849
2850
	#php4 PHP4 class constructor compatibility
2851
	#function AspEmbeddedNode($parent, $tag = '', $text = '', $attributes = array()) {return $this->__construct($parent, $tag, $text, $attributes);}
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...
2852
	#php4e
2853
}
2854
2855
?>
0 ignored issues
show
Best Practice introduced by
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...