4 * Parses string representations into their corresponding native PHP
5 * variable type. The base implementation does a simple type-check.
7 class HTMLPurifier_VarParser
23 * Lookup table of allowed types. Mainly for backwards compatibility, but
24 * also convenient for transforming string type names to the integer constants.
26 static public $types = array(
27 'string' => self::STRING,
28 'istring' => self::ISTRING,
30 'itext' => self::ITEXT,
32 'float' => self::FLOAT,
34 'lookup' => self::LOOKUP,
35 'list' => self::ALIST,
37 'mixed' => self::MIXED
41 * Lookup table of types that are string, and can have aliases or
42 * allowed value lists.
44 static public $stringTypes = array(
46 self::ISTRING => true,
52 * Validate a variable according to type. Throws
53 * HTMLPurifier_VarParserException if invalid.
54 * It may return NULL as a valid type if $allow_null is true.
56 * @param $var Variable to validate
57 * @param $type Type of variable, see HTMLPurifier_VarParser->types
58 * @param $allow_null Whether or not to permit null as a value
59 * @return Validated and type-coerced variable
61 final public function parse($var, $type, $allow_null = false) {
62 if (is_string($type)) {
63 if (!isset(HTMLPurifier_VarParser::$types[$type])) {
64 throw new HTMLPurifier_VarParserException("Invalid type '$type'");
66 $type = HTMLPurifier_VarParser::$types[$type];
69 $var = $this->parseImplementation($var, $type, $allow_null);
70 if ($allow_null && $var === null) return null;
71 // These are basic checks, to make sure nothing horribly wrong
72 // happened in our implementations.
78 if (!is_string($var)) break;
79 if ($type == self::ISTRING || $type == self::ITEXT) $var = strtolower($var);
82 if (!is_int($var)) break;
85 if (!is_float($var)) break;
88 if (!is_bool($var)) break;
93 if (!is_array($var)) break;
94 if ($type === self::LOOKUP) {
95 foreach ($var as $k) if ($k !== true) $this->error('Lookup table contains value other than true');
96 } elseif ($type === self::ALIST) {
97 $keys = array_keys($var);
98 if (array_keys($keys) !== $keys) $this->error('Indices for list are not uniform');
104 $this->errorInconsistent(get_class($this), $type);
106 $this->errorGeneric($var, $type);
110 * Actually implements the parsing. Base implementation is to not
111 * do anything to $var. Subclasses should overload this!
113 protected function parseImplementation($var, $type, $allow_null) {
118 * Throws an exception.
120 protected function error($msg) {
121 throw new HTMLPurifier_VarParserException($msg);
125 * Throws an inconsistency exception.
126 * @note This should not ever be called. It would be called if we
127 * extend the allowed values of HTMLPurifier_VarParser without
128 * updating subclasses.
130 protected function errorInconsistent($class, $type) {
131 throw new HTMLPurifier_Exception("Inconsistency in $class: ".HTMLPurifier_VarParser::getTypeName($type)." not implemented");
135 * Generic error for if a type didn't work.
137 protected function errorGeneric($var, $type) {
138 $vtype = gettype($var);
139 $this->error("Expected type ".HTMLPurifier_VarParser::getTypeName($type).", got $vtype");
142 static public function getTypeName($type) {
145 // Lazy load the alternative lookup table
146 $lookup = array_flip(HTMLPurifier_VarParser::$types);
148 if (!isset($lookup[$type])) return 'unknown';
149 return $lookup[$type];
154 // vim: et sw=4 sts=4