HTMLPurifier 4.4.0
|
00001 <?php 00002 00003 class HTMLPurifier_ConfigSchema_InterchangeBuilder 00004 { 00005 00009 protected $varParser; 00010 00011 public function __construct($varParser = null) { 00012 $this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native(); 00013 } 00014 00015 public static function buildFromDirectory($dir = null) { 00016 $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); 00017 $interchange = new HTMLPurifier_ConfigSchema_Interchange(); 00018 return $builder->buildDir($interchange, $dir); 00019 } 00020 00021 public function buildDir($interchange, $dir = null) { 00022 if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; 00023 if (file_exists($dir . '/info.ini')) { 00024 $info = parse_ini_file($dir . '/info.ini'); 00025 $interchange->name = $info['name']; 00026 } 00027 00028 $files = array(); 00029 $dh = opendir($dir); 00030 while (false !== ($file = readdir($dh))) { 00031 if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') { 00032 continue; 00033 } 00034 $files[] = $file; 00035 } 00036 closedir($dh); 00037 00038 sort($files); 00039 foreach ($files as $file) { 00040 $this->buildFile($interchange, $dir . '/' . $file); 00041 } 00042 00043 return $interchange; 00044 } 00045 00046 public function buildFile($interchange, $file) { 00047 $parser = new HTMLPurifier_StringHashParser(); 00048 $this->build( 00049 $interchange, 00050 new HTMLPurifier_StringHash( $parser->parseFile($file) ) 00051 ); 00052 } 00053 00059 public function build($interchange, $hash) { 00060 if (!$hash instanceof HTMLPurifier_StringHash) { 00061 $hash = new HTMLPurifier_StringHash($hash); 00062 } 00063 if (!isset($hash['ID'])) { 00064 throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID'); 00065 } 00066 if (strpos($hash['ID'], '.') === false) { 00067 if (count($hash) == 2 && isset($hash['DESCRIPTION'])) { 00068 $hash->offsetGet('DESCRIPTION'); // prevent complaining 00069 } else { 00070 throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace'); 00071 } 00072 } else { 00073 $this->buildDirective($interchange, $hash); 00074 } 00075 $this->_findUnused($hash); 00076 } 00077 00078 public function buildDirective($interchange, $hash) { 00079 $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive(); 00080 00081 // These are required elements: 00082 $directive->id = $this->id($hash->offsetGet('ID')); 00083 $id = $directive->id->toString(); // convenience 00084 00085 if (isset($hash['TYPE'])) { 00086 $type = explode('/', $hash->offsetGet('TYPE')); 00087 if (isset($type[1])) $directive->typeAllowsNull = true; 00088 $directive->type = $type[0]; 00089 } else { 00090 throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined"); 00091 } 00092 00093 if (isset($hash['DEFAULT'])) { 00094 try { 00095 $directive->default = $this->varParser->parse($hash->offsetGet('DEFAULT'), $directive->type, $directive->typeAllowsNull); 00096 } catch (HTMLPurifier_VarParserException $e) { 00097 throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'"); 00098 } 00099 } 00100 00101 if (isset($hash['DESCRIPTION'])) { 00102 $directive->description = $hash->offsetGet('DESCRIPTION'); 00103 } 00104 00105 if (isset($hash['ALLOWED'])) { 00106 $directive->allowed = $this->lookup($this->evalArray($hash->offsetGet('ALLOWED'))); 00107 } 00108 00109 if (isset($hash['VALUE-ALIASES'])) { 00110 $directive->valueAliases = $this->evalArray($hash->offsetGet('VALUE-ALIASES')); 00111 } 00112 00113 if (isset($hash['ALIASES'])) { 00114 $raw_aliases = trim($hash->offsetGet('ALIASES')); 00115 $aliases = preg_split('/\s*,\s*/', $raw_aliases); 00116 foreach ($aliases as $alias) { 00117 $directive->aliases[] = $this->id($alias); 00118 } 00119 } 00120 00121 if (isset($hash['VERSION'])) { 00122 $directive->version = $hash->offsetGet('VERSION'); 00123 } 00124 00125 if (isset($hash['DEPRECATED-USE'])) { 00126 $directive->deprecatedUse = $this->id($hash->offsetGet('DEPRECATED-USE')); 00127 } 00128 00129 if (isset($hash['DEPRECATED-VERSION'])) { 00130 $directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION'); 00131 } 00132 00133 if (isset($hash['EXTERNAL'])) { 00134 $directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL'))); 00135 } 00136 00137 $interchange->addDirective($directive); 00138 } 00139 00143 protected function evalArray($contents) { 00144 return eval('return array('. $contents .');'); 00145 } 00146 00150 protected function lookup($array) { 00151 $ret = array(); 00152 foreach ($array as $val) $ret[$val] = true; 00153 return $ret; 00154 } 00155 00160 protected function id($id) { 00161 return HTMLPurifier_ConfigSchema_Interchange_Id::make($id); 00162 } 00163 00169 protected function _findUnused($hash) { 00170 $accessed = $hash->getAccessed(); 00171 foreach ($hash as $k => $v) { 00172 if (!isset($accessed[$k])) { 00173 trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE); 00174 } 00175 } 00176 } 00177 00178 } 00179 00180 // vim: et sw=4 sts=4