1 : <?php
2 :
3 : /**
4 : * Represents a measurable length, with a string numeric magnitude
5 : * and a unit. This object is immutable.
6 : */
7 : class HTMLPurifier_Length
8 1 : {
9 :
10 : /**
11 : * String numeric magnitude.
12 : */
13 : protected $n;
14 :
15 : /**
16 : * String unit. False is permitted if $n = 0.
17 : */
18 : protected $unit;
19 :
20 : /**
21 : * Whether or not this length is valid. Null if not calculated yet.
22 : */
23 : protected $isValid;
24 :
25 : /**
26 : * Lookup array of units recognized by CSS 2.1
27 : */
28 : protected static $allowedUnits = array(
29 : 'em' => true, 'ex' => true, 'px' => true, 'in' => true,
30 : 'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true
31 : );
32 :
33 : /**
34 : * @param number $n Magnitude
35 : * @param string $u Unit
36 : */
37 : public function __construct($n = '0', $u = false) {
38 : $this->n = (string) $n;
39 : $this->unit = $u !== false ? (string) $u : false;
40 : }
41 :
42 : /**
43 : * @param string $s Unit string, like '2em' or '3.4in'
44 : * @warning Does not perform validation.
45 : */
46 : static public function make($s) {
47 0 : if ($s instanceof HTMLPurifier_Length) return $s;
48 0 : $n_length = strspn($s, '1234567890.+-');
49 0 : $n = substr($s, 0, $n_length);
50 0 : $unit = substr($s, $n_length);
51 0 : if ($unit === '') $unit = false;
52 0 : return new HTMLPurifier_Length($n, $unit);
53 : }
54 :
55 : /**
56 : * Validates the number and unit.
57 : */
58 : protected function validate() {
59 : // Special case:
60 0 : if ($this->n === '+0' || $this->n === '-0') $this->n = '0';
61 0 : if ($this->n === '0' && $this->unit === false) return true;
62 0 : if (!ctype_lower($this->unit)) $this->unit = strtolower($this->unit);
63 0 : if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) return false;
64 : // Hack:
65 0 : $def = new HTMLPurifier_AttrDef_CSS_Number();
66 0 : $result = $def->validate($this->n, false, false);
67 0 : if ($result === false) return false;
68 0 : $this->n = $result;
69 0 : return true;
70 : }
71 :
72 : /**
73 : * Returns string representation of number.
74 : */
75 : public function toString() {
76 0 : if (!$this->isValid()) return false;
77 0 : return $this->n . $this->unit;
78 : }
79 :
80 : /**
81 : * Retrieves string numeric magnitude.
82 : */
83 0 : public function getN() {return $this->n;}
84 :
85 : /**
86 : * Retrieves string unit.
87 : */
88 0 : public function getUnit() {return $this->unit;}
89 :
90 : /**
91 : * Returns true if this length unit is valid.
92 : */
93 : public function isValid() {
94 0 : if ($this->isValid === null) $this->isValid = $this->validate();
95 0 : return $this->isValid;
96 : }
97 :
98 : /**
99 : * Compares two lengths, and returns 1 if greater, -1 if less and 0 if equal.
100 : * @warning If both values are too large or small, this calculation will
101 : * not work properly
102 : */
103 : public function compareTo($l) {
104 0 : if ($l === false) return false;
105 0 : if ($l->unit !== $this->unit) {
106 0 : $converter = new HTMLPurifier_UnitConverter();
107 0 : $l = $converter->convert($l, $this->unit);
108 0 : if ($l === false) return false;
109 0 : }
110 0 : return $this->n - $l->n;
111 : }
112 :
113 : }
|