00001 <?php
00002
00007 class HTMLPurifier_VarParser
00008 {
00009
00010 const STRING = 1;
00011 const ISTRING = 2;
00012 const TEXT = 3;
00013 const ITEXT = 4;
00014 const INT = 5;
00015 const FLOAT = 6;
00016 const BOOL = 7;
00017 const LOOKUP = 8;
00018 const ALIST = 9;
00019 const HASH = 10;
00020 const MIXED = 11;
00021
00026 static public $types = array(
00027 'string' => self::STRING,
00028 'istring' => self::ISTRING,
00029 'text' => self::TEXT,
00030 'itext' => self::ITEXT,
00031 'int' => self::INT,
00032 'float' => self::FLOAT,
00033 'bool' => self::BOOL,
00034 'lookup' => self::LOOKUP,
00035 'list' => self::ALIST,
00036 'hash' => self::HASH,
00037 'mixed' => self::MIXED
00038 );
00039
00044 static public $stringTypes = array(
00045 self::STRING => true,
00046 self::ISTRING => true,
00047 self::TEXT => true,
00048 self::ITEXT => true,
00049 );
00050
00061 final public function parse($var, $type, $allow_null = false) {
00062 if (is_string($type)) {
00063 if (!isset(HTMLPurifier_VarParser::$types[$type])) {
00064 throw new HTMLPurifier_VarParserException("Invalid type '$type'");
00065 } else {
00066 $type = HTMLPurifier_VarParser::$types[$type];
00067 }
00068 }
00069 $var = $this->parseImplementation($var, $type, $allow_null);
00070 if ($allow_null && $var === null) return null;
00071
00072
00073 switch ($type) {
00074 case (self::STRING):
00075 case (self::ISTRING):
00076 case (self::TEXT):
00077 case (self::ITEXT):
00078 if (!is_string($var)) break;
00079 if ($type == self::ISTRING || $type == self::ITEXT) $var = strtolower($var);
00080 return $var;
00081 case (self::INT):
00082 if (!is_int($var)) break;
00083 return $var;
00084 case (self::FLOAT):
00085 if (!is_float($var)) break;
00086 return $var;
00087 case (self::BOOL):
00088 if (!is_bool($var)) break;
00089 return $var;
00090 case (self::LOOKUP):
00091 case (self::ALIST):
00092 case (self::HASH):
00093 if (!is_array($var)) break;
00094 if ($type === self::LOOKUP) {
00095 foreach ($var as $k) if ($k !== true) $this->error('Lookup table contains value other than true');
00096 } elseif ($type === self::ALIST) {
00097 $keys = array_keys($var);
00098 if (array_keys($keys) !== $keys) $this->error('Indices for list are not uniform');
00099 }
00100 return $var;
00101 case (self::MIXED):
00102 return $var;
00103 default:
00104 $this->errorInconsistent(get_class($this), $type);
00105 }
00106 $this->errorGeneric($var, $type);
00107 }
00108
00113 protected function parseImplementation($var, $type, $allow_null) {
00114 return $var;
00115 }
00116
00120 protected function error($msg) {
00121 throw new HTMLPurifier_VarParserException($msg);
00122 }
00123
00130 protected function errorInconsistent($class, $type) {
00131 throw new HTMLPurifier_Exception("Inconsistency in $class: ".HTMLPurifier_VarParser::getTypeName($type)." not implemented");
00132 }
00133
00137 protected function errorGeneric($var, $type) {
00138 $vtype = gettype($var);
00139 $this->error("Expected type ".HTMLPurifier_VarParser::getTypeName($type).", got $vtype");
00140 }
00141
00142 static public function getTypeName($type) {
00143 static $lookup;
00144 if (!$lookup) {
00145
00146 $lookup = array_flip(HTMLPurifier_VarParser::$types);
00147 }
00148 if (!isset($lookup[$type])) return 'unknown';
00149 return $lookup[$type];
00150 }
00151
00152 }