File indexing completed on 2024-12-22 05:36:21
0001 <?php 0002 0003 /** 0004 * Represents a measurable length, with a string numeric magnitude 0005 * and a unit. This object is immutable. 0006 */ 0007 class HTMLPurifier_Length 0008 { 0009 0010 /** 0011 * String numeric magnitude. 0012 * @type string 0013 */ 0014 protected $n; 0015 0016 /** 0017 * String unit. False is permitted if $n = 0. 0018 * @type string|bool 0019 */ 0020 protected $unit; 0021 0022 /** 0023 * Whether or not this length is valid. Null if not calculated yet. 0024 * @type bool 0025 */ 0026 protected $isValid; 0027 0028 /** 0029 * Array Lookup array of units recognized by CSS 2.1 0030 * @type array 0031 */ 0032 protected static $allowedUnits = array( 0033 'em' => true, 'ex' => true, 'px' => true, 'in' => true, 0034 'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true 0035 ); 0036 0037 /** 0038 * @param string $n Magnitude 0039 * @param bool|string $u Unit 0040 */ 0041 public function __construct($n = '0', $u = false) 0042 { 0043 $this->n = (string) $n; 0044 $this->unit = $u !== false ? (string) $u : false; 0045 } 0046 0047 /** 0048 * @param string $s Unit string, like '2em' or '3.4in' 0049 * @return HTMLPurifier_Length 0050 * @warning Does not perform validation. 0051 */ 0052 public static function make($s) 0053 { 0054 if ($s instanceof HTMLPurifier_Length) { 0055 return $s; 0056 } 0057 $n_length = strspn($s, '1234567890.+-'); 0058 $n = substr($s, 0, $n_length); 0059 $unit = substr($s, $n_length); 0060 if ($unit === '') { 0061 $unit = false; 0062 } 0063 return new HTMLPurifier_Length($n, $unit); 0064 } 0065 0066 /** 0067 * Validates the number and unit. 0068 * @return bool 0069 */ 0070 protected function validate() 0071 { 0072 // Special case: 0073 if ($this->n === '+0' || $this->n === '-0') { 0074 $this->n = '0'; 0075 } 0076 if ($this->n === '0' && $this->unit === false) { 0077 return true; 0078 } 0079 if (!ctype_lower($this->unit)) { 0080 $this->unit = strtolower($this->unit); 0081 } 0082 if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) { 0083 return false; 0084 } 0085 // Hack: 0086 $def = new HTMLPurifier_AttrDef_CSS_Number(); 0087 $result = $def->validate($this->n, false, false); 0088 if ($result === false) { 0089 return false; 0090 } 0091 $this->n = $result; 0092 return true; 0093 } 0094 0095 /** 0096 * Returns string representation of number. 0097 * @return string 0098 */ 0099 public function toString() 0100 { 0101 if (!$this->isValid()) { 0102 return false; 0103 } 0104 return $this->n . $this->unit; 0105 } 0106 0107 /** 0108 * Retrieves string numeric magnitude. 0109 * @return string 0110 */ 0111 public function getN() 0112 { 0113 return $this->n; 0114 } 0115 0116 /** 0117 * Retrieves string unit. 0118 * @return string 0119 */ 0120 public function getUnit() 0121 { 0122 return $this->unit; 0123 } 0124 0125 /** 0126 * Returns true if this length unit is valid. 0127 * @return bool 0128 */ 0129 public function isValid() 0130 { 0131 if ($this->isValid === null) { 0132 $this->isValid = $this->validate(); 0133 } 0134 return $this->isValid; 0135 } 0136 0137 /** 0138 * Compares two lengths, and returns 1 if greater, -1 if less and 0 if equal. 0139 * @param HTMLPurifier_Length $l 0140 * @return int 0141 * @warning If both values are too large or small, this calculation will 0142 * not work properly 0143 */ 0144 public function compareTo($l) 0145 { 0146 if ($l === false) { 0147 return false; 0148 } 0149 if ($l->unit !== $this->unit) { 0150 $converter = new HTMLPurifier_UnitConverter(); 0151 $l = $converter->convert($l, $this->unit); 0152 if ($l === false) { 0153 return false; 0154 } 0155 } 0156 return $this->n - $l->n; 0157 } 0158 } 0159 0160 // vim: et sw=4 sts=4