Refactor VarParser and VarParser_Flexible to use template method, factoring out commo...
[htmlpurifier.git] / library / HTMLPurifier / VarParser.php
blobbb0313f1617ac87df2c81a0338c595b8f63ec3b2
1 <?php
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
10 /**
11 * Lookup table of allowed types.
13 static public $types = array(
14 'string' => true,
15 'istring' => true,
16 'text' => true,
17 'itext' => true,
18 'int' => true,
19 'float' => true,
20 'bool' => true,
21 'lookup' => true,
22 'list' => true,
23 'hash' => true,
24 'mixed' => true
27 /**
28 * Validate a variable according to type. Throws
29 * HTMLPurifier_VarParserException if invalid.
30 * It may return NULL as a valid type if $allow_null is true.
32 * @param $var Variable to validate
33 * @param $type Type of variable, see HTMLPurifier_VarParser->types
34 * @param $allow_null Whether or not to permit null as a value
35 * @return Validated and type-coerced variable
37 final public function parse($var, $type, $allow_null = false) {
38 if (!isset(HTMLPurifier_VarParser::$types[$type])) {
39 throw new HTMLPurifier_VarParserException("Invalid type $type");
41 $var = $this->parseImplementation($var, $type, $allow_null);
42 if ($allow_null && $var === null) return null;
43 // These are basic checks, to make sure nothing horribly wrong
44 // happened in our implementations.
45 switch ($type) {
46 case 'string':
47 case 'istring':
48 case 'text':
49 case 'itext':
50 if (!is_string($var)) break;
51 if ($type[0] == 'i') $var = strtolower($var);
52 return $var;
53 case 'int':
54 if (!is_int($var)) break;
55 return $var;
56 case 'float':
57 if (!is_float($var)) break;
58 return $var;
59 case 'bool':
60 if (!is_bool($var)) break;
61 return $var;
62 case 'lookup':
63 case 'list':
64 case 'hash':
65 if (!is_array($var)) break;
66 if ($type === 'lookup') {
67 foreach ($var as $k) if ($k !== true) $this->error('Lookup table contains value other than true');
68 } elseif ($type === 'list') {
69 $keys = array_keys($var);
70 if (array_keys($keys) !== $keys) $this->error('Indices for list are not uniform');
72 return $var;
73 case 'mixed':
74 return $var;
75 default:
76 $this->errorInconsistent(__CLASS__, $type);
78 $this->errorGeneric($var, $type);
81 /**
82 * Actually implements the parsing. Base implementation is to not
83 * do anything to $var. Subclasses should overload this!
85 protected function parseImplementation($var, $type, $allow_null) {
86 return $var;
89 /**
90 * Throws an exception.
92 protected function error($msg) {
93 throw new HTMLPurifier_VarParserException($msg);
96 /**
97 * Throws an inconsistency exception.
98 * @note This should not ever be called. It would be called if we
99 * extend the allowed values of HTMLPurifier_VarParser without
100 * updating subclasses.
102 protected function errorInconsistent($class, $type) {
103 throw new HTMLPurifier_Exception("Inconsistency in $class: $type not implemented");
107 * Generic error for if a type didn't work.
109 protected function errorGeneric($var, $type) {
110 $vtype = gettype($var);
111 $this->error("Expected type $type, got $vtype");