50cba6910db784fee6ac8af0b38f35c9b5542f55
[yaffs-website] / vendor / ezyang / htmlpurifier / library / HTMLPurifier / VarParser.php
1 <?php
2
3 /**
4  * Parses string representations into their corresponding native PHP
5  * variable type. The base implementation does a simple type-check.
6  */
7 class HTMLPurifier_VarParser
8 {
9
10     const STRING = 1;
11     const ISTRING = 2;
12     const TEXT = 3;
13     const ITEXT = 4;
14     const INT = 5;
15     const FLOAT = 6;
16     const BOOL = 7;
17     const LOOKUP = 8;
18     const ALIST = 9;
19     const HASH = 10;
20     const MIXED = 11;
21
22     /**
23      * Lookup table of allowed types. Mainly for backwards compatibility, but
24      * also convenient for transforming string type names to the integer constants.
25      */
26     public static $types = array(
27         'string' => self::STRING,
28         'istring' => self::ISTRING,
29         'text' => self::TEXT,
30         'itext' => self::ITEXT,
31         'int' => self::INT,
32         'float' => self::FLOAT,
33         'bool' => self::BOOL,
34         'lookup' => self::LOOKUP,
35         'list' => self::ALIST,
36         'hash' => self::HASH,
37         'mixed' => self::MIXED
38     );
39
40     /**
41      * Lookup table of types that are string, and can have aliases or
42      * allowed value lists.
43      */
44     public static $stringTypes = array(
45         self::STRING => true,
46         self::ISTRING => true,
47         self::TEXT => true,
48         self::ITEXT => true,
49     );
50
51     /**
52      * Validate a variable according to type.
53      * It may return NULL as a valid type if $allow_null is true.
54      *
55      * @param mixed $var Variable to validate
56      * @param int $type Type of variable, see HTMLPurifier_VarParser->types
57      * @param bool $allow_null Whether or not to permit null as a value
58      * @return string Validated and type-coerced variable
59      * @throws HTMLPurifier_VarParserException
60      */
61     final public function parse($var, $type, $allow_null = false)
62     {
63         if (is_string($type)) {
64             if (!isset(HTMLPurifier_VarParser::$types[$type])) {
65                 throw new HTMLPurifier_VarParserException("Invalid type '$type'");
66             } else {
67                 $type = HTMLPurifier_VarParser::$types[$type];
68             }
69         }
70         $var = $this->parseImplementation($var, $type, $allow_null);
71         if ($allow_null && $var === null) {
72             return null;
73         }
74         // These are basic checks, to make sure nothing horribly wrong
75         // happened in our implementations.
76         switch ($type) {
77             case (self::STRING):
78             case (self::ISTRING):
79             case (self::TEXT):
80             case (self::ITEXT):
81                 if (!is_string($var)) {
82                     break;
83                 }
84                 if ($type == self::ISTRING || $type == self::ITEXT) {
85                     $var = strtolower($var);
86                 }
87                 return $var;
88             case (self::INT):
89                 if (!is_int($var)) {
90                     break;
91                 }
92                 return $var;
93             case (self::FLOAT):
94                 if (!is_float($var)) {
95                     break;
96                 }
97                 return $var;
98             case (self::BOOL):
99                 if (!is_bool($var)) {
100                     break;
101                 }
102                 return $var;
103             case (self::LOOKUP):
104             case (self::ALIST):
105             case (self::HASH):
106                 if (!is_array($var)) {
107                     break;
108                 }
109                 if ($type === self::LOOKUP) {
110                     foreach ($var as $k) {
111                         if ($k !== true) {
112                             $this->error('Lookup table contains value other than true');
113                         }
114                     }
115                 } elseif ($type === self::ALIST) {
116                     $keys = array_keys($var);
117                     if (array_keys($keys) !== $keys) {
118                         $this->error('Indices for list are not uniform');
119                     }
120                 }
121                 return $var;
122             case (self::MIXED):
123                 return $var;
124             default:
125                 $this->errorInconsistent(get_class($this), $type);
126         }
127         $this->errorGeneric($var, $type);
128     }
129
130     /**
131      * Actually implements the parsing. Base implementation does not
132      * do anything to $var. Subclasses should overload this!
133      * @param mixed $var
134      * @param int $type
135      * @param bool $allow_null
136      * @return string
137      */
138     protected function parseImplementation($var, $type, $allow_null)
139     {
140         return $var;
141     }
142
143     /**
144      * Throws an exception.
145      * @throws HTMLPurifier_VarParserException
146      */
147     protected function error($msg)
148     {
149         throw new HTMLPurifier_VarParserException($msg);
150     }
151
152     /**
153      * Throws an inconsistency exception.
154      * @note This should not ever be called. It would be called if we
155      *       extend the allowed values of HTMLPurifier_VarParser without
156      *       updating subclasses.
157      * @param string $class
158      * @param int $type
159      * @throws HTMLPurifier_Exception
160      */
161     protected function errorInconsistent($class, $type)
162     {
163         throw new HTMLPurifier_Exception(
164             "Inconsistency in $class: " . HTMLPurifier_VarParser::getTypeName($type) .
165             " not implemented"
166         );
167     }
168
169     /**
170      * Generic error for if a type didn't work.
171      * @param mixed $var
172      * @param int $type
173      */
174     protected function errorGeneric($var, $type)
175     {
176         $vtype = gettype($var);
177         $this->error("Expected type " . HTMLPurifier_VarParser::getTypeName($type) . ", got $vtype");
178     }
179
180     /**
181      * @param int $type
182      * @return string
183      */
184     public static function getTypeName($type)
185     {
186         static $lookup;
187         if (!$lookup) {
188             // Lazy load the alternative lookup table
189             $lookup = array_flip(HTMLPurifier_VarParser::$types);
190         }
191         if (!isset($lookup[$type])) {
192             return 'unknown';
193         }
194         return $lookup[$type];
195     }
196 }
197
198 // vim: et sw=4 sts=4