HTMLPurifier 4.4.0
/home/ezyang/Dev/htmlpurifier/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
Go to the documentation of this file.
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