]>
Commit | Line | Data |
---|---|---|
010efc9b AD |
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 | { | |
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 | if ($s instanceof HTMLPurifier_Length) return $s; | |
48 | $n_length = strspn($s, '1234567890.+-'); | |
49 | $n = substr($s, 0, $n_length); | |
50 | $unit = substr($s, $n_length); | |
51 | if ($unit === '') $unit = false; | |
52 | return new HTMLPurifier_Length($n, $unit); | |
53 | } | |
54 | ||
55 | /** | |
56 | * Validates the number and unit. | |
57 | */ | |
58 | protected function validate() { | |
59 | // Special case: | |
60 | if ($this->n === '+0' || $this->n === '-0') $this->n = '0'; | |
61 | if ($this->n === '0' && $this->unit === false) return true; | |
62 | if (!ctype_lower($this->unit)) $this->unit = strtolower($this->unit); | |
63 | if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) return false; | |
64 | // Hack: | |
65 | $def = new HTMLPurifier_AttrDef_CSS_Number(); | |
66 | $result = $def->validate($this->n, false, false); | |
67 | if ($result === false) return false; | |
68 | $this->n = $result; | |
69 | return true; | |
70 | } | |
71 | ||
72 | /** | |
73 | * Returns string representation of number. | |
74 | */ | |
75 | public function toString() { | |
76 | if (!$this->isValid()) return false; | |
77 | return $this->n . $this->unit; | |
78 | } | |
79 | ||
80 | /** | |
81 | * Retrieves string numeric magnitude. | |
82 | */ | |
83 | public function getN() {return $this->n;} | |
84 | ||
85 | /** | |
86 | * Retrieves string unit. | |
87 | */ | |
88 | public function getUnit() {return $this->unit;} | |
89 | ||
90 | /** | |
91 | * Returns true if this length unit is valid. | |
92 | */ | |
93 | public function isValid() { | |
94 | if ($this->isValid === null) $this->isValid = $this->validate(); | |
95 | 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 | if ($l === false) return false; | |
105 | if ($l->unit !== $this->unit) { | |
106 | $converter = new HTMLPurifier_UnitConverter(); | |
107 | $l = $converter->convert($l, $this->unit); | |
108 | if ($l === false) return false; | |
109 | } | |
110 | return $this->n - $l->n; | |
111 | } | |
112 | ||
113 | } | |
114 | ||
115 | // vim: et sw=4 sts=4 |