PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / libs / HTML / Common2.php
matomo / app / libs / HTML Last commit date
QuickForm2 6 years ago Common2.php 6 years ago QuickForm2.php 6 years ago
Common2.php
489 lines
1 <?php
2 /**
3 * HTML_Common2: port of HTML_Common package to PHP5
4 *
5 * PHP version 5
6 *
7 * LICENSE:
8 *
9 * Copyright (c) 2004-2009, Alexey Borzov <avb@php.net>
10 *
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * * The names of the authors may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
26 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
33 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * @category HTML
38 * @package HTML_Common2
39 * @author Alexey Borzov <avb@php.net>
40 * @license http://opensource.org/licenses/bsd-license.php New BSD License
41 * @version CVS: $Id: Common2.php 295050 2010-02-14 05:01:19Z clockwerx $
42 * @link http://pear.php.net/package/HTML_Common2
43 */
44
45 /**
46 * Base class for HTML classes
47 *
48 * Implements methods for working with HTML attributes, parsing and generating
49 * attribute strings. Port of HTML_Common class for PHP4 originally written by
50 * Adam Daniel with contributions from numerous other developers.
51 *
52 * @category HTML
53 * @package HTML_Common2
54 * @author Alexey Borzov <avb@php.net>
55 * @version Release: @package_version@
56 */
57 abstract class HTML_Common2
58 {
59 /**
60 * Associative array of attributes
61 * @var array
62 */
63 protected $attributes = array();
64
65 /**
66 * List of attribites changes to which will be announced via onAttributeChange()
67 * method rather than performed by HTML_Common2 class itself
68 * @var array
69 * @see onAttributeChange()
70 */
71 protected $watchedAttributes = array();
72
73 /**
74 * Indentation level of the element
75 * @var int
76 */
77 private $_indentLevel = 0;
78
79 /**
80 * Comment associated with the element
81 * @var string
82 */
83 private $_comment = null;
84
85 /**
86 * Global options for all elements generated by subclasses of HTML_Common2
87 *
88 * Preset options are
89 * - 'charset': charset parameter used in htmlspecialchars() calls,
90 * defaults to 'ISO-8859-1'
91 * - 'indent': string used to indent HTML elements, defaults to "\11"
92 * - 'linebreak': string used to indicate linebreak, defaults to "\12"
93 *
94 * @var array
95 */
96 private static $_options = array(
97 'charset' => 'ISO-8859-1',
98 'indent' => "\11",
99 'linebreak' => "\12"
100 );
101
102 /**
103 * Sets global option(s)
104 *
105 * @param string|array Option name or array ('option name' => 'option value')
106 * @param mixed Option value, if first argument is not an array
107 */
108 public static function setOption($nameOrOptions, $value = null)
109 {
110 if (is_array($nameOrOptions)) {
111 foreach ($nameOrOptions as $k => $v) {
112 self::setOption($k, $v);
113 }
114 } else {
115 $linebreaks = array('win' => "\15\12", 'unix' => "\12", 'mac' => "\15");
116 if ('linebreak' == $nameOrOptions && isset($linebreaks[$value])) {
117 $value = $linebreaks[$value];
118 }
119 self::$_options[$nameOrOptions] = $value;
120 }
121 }
122
123 /**
124 * Returns global option(s)
125 *
126 * @param string Option name
127 * @return mixed Option value, null if option does not exist,
128 * array of all options if $name is not given
129 */
130 public static function getOption($name = null)
131 {
132 if (null === $name) {
133 return self::$_options;
134 } else {
135 return isset(self::$_options[$name])? self::$_options[$name]: null;
136 }
137 }
138
139 /**
140 * Parses the HTML attributes given as string
141 *
142 * @param string HTML attribute string
143 * @return array An associative aray of attributes
144 */
145 protected static function parseAttributes($attrString)
146 {
147 $attributes = array();
148 if (preg_match_all(
149 "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
150 "([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/",
151 $attrString,
152 $regs
153 )) {
154 for ($i = 0; $i < count($regs[1]); $i++) {
155 $name = trim($regs[1][$i]);
156 $check = trim($regs[0][$i]);
157 $value = trim($regs[7][$i]);
158 if ($name == $check) {
159 $attributes[strtolower($name)] = strtolower($name);
160 } else {
161 if (!empty($value) && ($value[0] == '\'' || $value[0] == '"')) {
162 $value = substr($value, 1, -1);
163 }
164 $attributes[strtolower($name)] = $value;
165 }
166 }
167 }
168 return $attributes;
169 }
170
171 /**
172 * Creates a valid attribute array from either a string or an array
173 *
174 * @param mixed Array of attributes or HTML attribute string
175 * @return array An associative aray of attributes
176 */
177 protected static function prepareAttributes($attributes)
178 {
179 $prepared = array();
180 if (is_string($attributes)) {
181 return self::parseAttributes($attributes);
182
183 } elseif (is_array($attributes)) {
184 foreach ($attributes as $key => $value) {
185 if (is_int($key)) {
186 $key = strtolower($value);
187 $prepared[$key] = $key;
188 } else {
189 $prepared[strtolower($key)] = (string)$value;
190 }
191 }
192 }
193 return $prepared;
194 }
195
196 /**
197 * Removes an attribute from an attribute array
198 *
199 * @param array Attribute array
200 * @param string Name of attribute to remove
201 */
202 protected static function removeAttributeArray(&$attributes, $name)
203 {
204 unset($attributes[strtolower($name)]);
205 }
206
207 /**
208 * Creates HTML attribute string from array
209 *
210 * @param array Attribute array
211 * @return string Attribute string
212 */
213 protected static function getAttributesString($attributes)
214 {
215 $str = '';
216 if (is_array($attributes)) {
217 $charset = self::getOption('charset');
218 foreach ($attributes as $key => $value) {
219 $str .= ' ' . $key . '="' . htmlspecialchars($value, ENT_QUOTES, $charset) . '"';
220 }
221 }
222 return $str;
223 }
224
225 /**
226 * Class constructor, sets default attributes
227 *
228 * @param mixed Array of attribute 'name' => 'value' pairs or HTML attribute string
229 */
230 public function __construct($attributes = null)
231 {
232 $this->mergeAttributes($attributes);
233 }
234
235 /**
236 * Sets the value of the attribute
237 *
238 * @param string Attribute name
239 * @param string Attribute value (will be set to $name if omitted)
240 * @return HTML_Common2
241 */
242 public function setAttribute($name, $value = null)
243 {
244 $name = strtolower($name);
245 if (is_null($value)) {
246 $value = $name;
247 }
248 if (in_array($name, $this->watchedAttributes)) {
249 $this->onAttributeChange($name, $value);
250 } else {
251 $this->attributes[$name] = (string)$value;
252 }
253 return $this;
254 }
255
256 /**
257 * Returns the value of an attribute
258 *
259 * @param string Attribute name
260 * @return string Attribute value, null if attribute does not exist
261 */
262 public function getAttribute($name)
263 {
264 $name = strtolower($name);
265 return isset($this->attributes[$name])? $this->attributes[$name]: null;
266 }
267
268 /**
269 * Sets the attributes
270 *
271 * @param mixed Array of attribute 'name' => 'value' pairs or HTML attribute string
272 * @return HTML_Common2
273 */
274 public function setAttributes($attributes)
275 {
276 $attributes = self::prepareAttributes($attributes);
277 $watched = array();
278 foreach ($this->watchedAttributes as $watchedKey) {
279 if (isset($attributes[$watchedKey])) {
280 $this->setAttribute($watchedKey, $attributes[$watchedKey]);
281 unset($attributes[$watchedKey]);
282 } else {
283 $this->removeAttribute($watchedKey);
284 }
285 if (isset($this->attributes[$watchedKey])) {
286 $watched[$watchedKey] = $this->attributes[$watchedKey];
287 }
288 }
289 $this->attributes = array_merge($watched, $attributes);
290 return $this;
291 }
292
293 /**
294 * Returns the attribute array or string
295 *
296 * @param bool Whether to return attributes as string
297 * @return mixed Either an array or string of attributes
298 */
299 public function getAttributes($asString = false)
300 {
301 if ($asString) {
302 return self::getAttributesString($this->attributes);
303 } else {
304 return $this->attributes;
305 }
306 }
307
308 /**
309 * Merges the existing attributes with the new ones
310 *
311 * @param mixed Array of attribute 'name' => 'value' pairs or HTML attribute string
312 * @return HTML_Common2
313 */
314 public function mergeAttributes($attributes)
315 {
316 $attributes = self::prepareAttributes($attributes);
317 foreach ($this->watchedAttributes as $watchedKey) {
318 if (isset($attributes[$watchedKey])) {
319 $this->onAttributeChange($watchedKey, $attributes[$watchedKey]);
320 unset($attributes[$watchedKey]);
321 }
322 }
323 $this->attributes = array_merge($this->attributes, $attributes);
324 return $this;
325 }
326
327 /**
328 * Removes an attribute
329 *
330 * @param string Name of attribute to remove
331 * @return HTML_Common2
332 */
333 public function removeAttribute($attribute)
334 {
335 if (in_array(strtolower($attribute), $this->watchedAttributes)) {
336 $this->onAttributeChange(strtolower($attribute), null);
337 } else {
338 self::removeAttributeArray($this->attributes, $attribute);
339 }
340 return $this;
341 }
342
343 /**
344 * Sets the indentation level
345 *
346 * @param int
347 * @return HTML_Common2
348 */
349 public function setIndentLevel($level)
350 {
351 $level = intval($level);
352 if (0 <= $level) {
353 $this->_indentLevel = $level;
354 }
355 return $this;
356 }
357
358 /**
359 * Gets the indentation level
360 *
361 * @return int
362 */
363 public function getIndentLevel()
364 {
365 return $this->_indentLevel;
366 }
367
368 /**
369 * Returns the string to indent the element
370 *
371 * @return string
372 */
373 protected function getIndent()
374 {
375 return str_repeat(self::getOption('indent'), $this->getIndentLevel());
376 }
377
378 /**
379 * Sets the comment for the element
380 *
381 * @param string
382 * @return HTML_Common2
383 */
384 public function setComment($comment)
385 {
386 $this->_comment = $comment;
387 return $this;
388 }
389
390 /**
391 * Returns the comment associated with the element
392 *
393 * @return string
394 */
395 public function getComment()
396 {
397 return $this->_comment;
398 }
399
400 /**
401 * Checks whether the element has given CSS class
402 *
403 * @param string Class name
404 * @return bool
405 */
406 public function hasClass($class)
407 {
408 $regex = '/(^|\s)' . preg_quote($class, '/') . '(\s|$)/';
409 return (bool)preg_match($regex, $this->getAttribute('class'));
410 }
411
412 /**
413 * Adds the given CSS class(es) to the element
414 *
415 * @param string|array Class name, multiple class names separated by
416 * whitespace, array of class names
417 * @return HTML_Common2
418 */
419 public function addClass($class)
420 {
421 if (!is_array($class)) {
422 $class = preg_split('/\s+/', $class, null, PREG_SPLIT_NO_EMPTY);
423 }
424 $curClass = preg_split('/\s+/', $this->getAttribute('class'),
425 null, PREG_SPLIT_NO_EMPTY);
426 foreach ($class as $c) {
427 if (!in_array($c, $curClass)) {
428 $curClass[] = $c;
429 }
430 }
431 $this->setAttribute('class', implode(' ', $curClass));
432
433 return $this;
434 }
435
436 /**
437 * Removes the given CSS class(es) from the element
438 *
439 * @param string|array Class name, multiple class names separated by
440 * whitespace, array of class names
441 * @return HTML_Common2
442 */
443 public function removeClass($class)
444 {
445 if (!is_array($class)) {
446 $class = preg_split('/\s+/', $class, null, PREG_SPLIT_NO_EMPTY);
447 }
448 $curClass = array_diff(
449 preg_split('/\s+/', $this->getAttribute('class'),
450 null, PREG_SPLIT_NO_EMPTY),
451 $class
452 );
453 if (0 == count($curClass)) {
454 $this->removeAttribute('class');
455 } else {
456 $this->setAttribute('class', implode(' ', $curClass));
457 }
458 return $this;
459 }
460
461 /**
462 * Returns the HTML representation of the element
463 *
464 * This magic method allows using the instances of HTML_Common2 in string
465 * contexts
466 *
467 * @return string
468 */
469 abstract public function __toString();
470
471 /**
472 * Called if trying to change an attribute with name in $watchedAttributes
473 *
474 * This method is called for each attribute whose name is in the
475 * $watchedAttributes array and which is being changed by setAttribute(),
476 * setAttributes() or mergeAttributes() or removed via removeAttribute().
477 * Note that the operation for the attribute is not carried on after calling
478 * this method, it is the responsibility of this method to change or remove
479 * (or not) the attribute.
480 *
481 * @param string Attribute name
482 * @param string Attribute value, null if attribute is being removed
483 */
484 protected function onAttributeChange($name, $value = null)
485 {
486 }
487 }
488 ?>
489