| 1: | <?php
|
| 2: |
|
| 3: | class HTMLPurifier_ConfigSchema_InterchangeBuilder
|
| 4: | {
|
| 5: |
|
| 6: | |
| 7: | |
| 8: | |
| 9: |
|
| 10: | protected $varParser;
|
| 11: |
|
| 12: | |
| 13: | |
| 14: |
|
| 15: | public function __construct($varParser = null)
|
| 16: | {
|
| 17: | $this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native();
|
| 18: | }
|
| 19: |
|
| 20: | |
| 21: | |
| 22: | |
| 23: |
|
| 24: | public static function buildFromDirectory($dir = null)
|
| 25: | {
|
| 26: | $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
|
| 27: | $interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
| 28: | return $builder->buildDir($interchange, $dir);
|
| 29: | }
|
| 30: |
|
| 31: | |
| 32: | |
| 33: | |
| 34: | |
| 35: |
|
| 36: | public function buildDir($interchange, $dir = null)
|
| 37: | {
|
| 38: | if (!$dir) {
|
| 39: | $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema';
|
| 40: | }
|
| 41: | if (file_exists($dir . '/info.ini')) {
|
| 42: | $info = parse_ini_file($dir . '/info.ini');
|
| 43: | $interchange->name = $info['name'];
|
| 44: | }
|
| 45: |
|
| 46: | $files = array();
|
| 47: | $dh = opendir($dir);
|
| 48: | while (false !== ($file = readdir($dh))) {
|
| 49: | if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') {
|
| 50: | continue;
|
| 51: | }
|
| 52: | $files[] = $file;
|
| 53: | }
|
| 54: | closedir($dh);
|
| 55: |
|
| 56: | sort($files);
|
| 57: | foreach ($files as $file) {
|
| 58: | $this->buildFile($interchange, $dir . '/' . $file);
|
| 59: | }
|
| 60: | return $interchange;
|
| 61: | }
|
| 62: |
|
| 63: | |
| 64: | |
| 65: | |
| 66: |
|
| 67: | public function buildFile($interchange, $file)
|
| 68: | {
|
| 69: | $parser = new HTMLPurifier_StringHashParser();
|
| 70: | $this->build(
|
| 71: | $interchange,
|
| 72: | new HTMLPurifier_StringHash($parser->parseFile($file))
|
| 73: | );
|
| 74: | }
|
| 75: |
|
| 76: | |
| 77: | |
| 78: | |
| 79: | |
| 80: | |
| 81: |
|
| 82: | public function build($interchange, $hash)
|
| 83: | {
|
| 84: | if (!$hash instanceof HTMLPurifier_StringHash) {
|
| 85: | $hash = new HTMLPurifier_StringHash($hash);
|
| 86: | }
|
| 87: | if (!isset($hash['ID'])) {
|
| 88: | throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID');
|
| 89: | }
|
| 90: | if (strpos($hash['ID'], '.') === false) {
|
| 91: | if (count($hash) == 2 && isset($hash['DESCRIPTION'])) {
|
| 92: | $hash->offsetGet('DESCRIPTION');
|
| 93: | } else {
|
| 94: | throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace');
|
| 95: | }
|
| 96: | } else {
|
| 97: | $this->buildDirective($interchange, $hash);
|
| 98: | }
|
| 99: | $this->_findUnused($hash);
|
| 100: | }
|
| 101: |
|
| 102: | |
| 103: | |
| 104: | |
| 105: | |
| 106: |
|
| 107: | public function buildDirective($interchange, $hash)
|
| 108: | {
|
| 109: | $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
| 110: |
|
| 111: |
|
| 112: | $directive->id = $this->id($hash->offsetGet('ID'));
|
| 113: | $id = $directive->id->toString();
|
| 114: |
|
| 115: | if (isset($hash['TYPE'])) {
|
| 116: | $type = explode('/', $hash->offsetGet('TYPE'));
|
| 117: | if (isset($type[1])) {
|
| 118: | $directive->typeAllowsNull = true;
|
| 119: | }
|
| 120: | $directive->type = $type[0];
|
| 121: | } else {
|
| 122: | throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined");
|
| 123: | }
|
| 124: |
|
| 125: | if (isset($hash['DEFAULT'])) {
|
| 126: | try {
|
| 127: | $directive->default = $this->varParser->parse(
|
| 128: | $hash->offsetGet('DEFAULT'),
|
| 129: | $directive->type,
|
| 130: | $directive->typeAllowsNull
|
| 131: | );
|
| 132: | } catch (HTMLPurifier_VarParserException $e) {
|
| 133: | throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'");
|
| 134: | }
|
| 135: | }
|
| 136: |
|
| 137: | if (isset($hash['DESCRIPTION'])) {
|
| 138: | $directive->description = $hash->offsetGet('DESCRIPTION');
|
| 139: | }
|
| 140: |
|
| 141: | if (isset($hash['ALLOWED'])) {
|
| 142: | $directive->allowed = $this->lookup($this->evalArray($hash->offsetGet('ALLOWED')));
|
| 143: | }
|
| 144: |
|
| 145: | if (isset($hash['VALUE-ALIASES'])) {
|
| 146: | $directive->valueAliases = $this->evalArray($hash->offsetGet('VALUE-ALIASES'));
|
| 147: | }
|
| 148: |
|
| 149: | if (isset($hash['ALIASES'])) {
|
| 150: | $raw_aliases = trim($hash->offsetGet('ALIASES'));
|
| 151: | $aliases = preg_split('/\s*,\s*/', $raw_aliases);
|
| 152: | foreach ($aliases as $alias) {
|
| 153: | $directive->aliases[] = $this->id($alias);
|
| 154: | }
|
| 155: | }
|
| 156: |
|
| 157: | if (isset($hash['VERSION'])) {
|
| 158: | $directive->version = $hash->offsetGet('VERSION');
|
| 159: | }
|
| 160: |
|
| 161: | if (isset($hash['DEPRECATED-USE'])) {
|
| 162: | $directive->deprecatedUse = $this->id($hash->offsetGet('DEPRECATED-USE'));
|
| 163: | }
|
| 164: |
|
| 165: | if (isset($hash['DEPRECATED-VERSION'])) {
|
| 166: | $directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION');
|
| 167: | }
|
| 168: |
|
| 169: | if (isset($hash['EXTERNAL'])) {
|
| 170: | $directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL')));
|
| 171: | }
|
| 172: |
|
| 173: | $interchange->addDirective($directive);
|
| 174: | }
|
| 175: |
|
| 176: | |
| 177: | |
| 178: | |
| 179: |
|
| 180: | protected function evalArray($contents)
|
| 181: | {
|
| 182: | return eval('return array(' . $contents . ');');
|
| 183: | }
|
| 184: |
|
| 185: | |
| 186: | |
| 187: | |
| 188: | |
| 189: |
|
| 190: | protected function lookup($array)
|
| 191: | {
|
| 192: | $ret = array();
|
| 193: | foreach ($array as $val) {
|
| 194: | $ret[$val] = true;
|
| 195: | }
|
| 196: | return $ret;
|
| 197: | }
|
| 198: |
|
| 199: | |
| 200: | |
| 201: | |
| 202: | |
| 203: | |
| 204: |
|
| 205: | protected function id($id)
|
| 206: | {
|
| 207: | return HTMLPurifier_ConfigSchema_Interchange_Id::make($id);
|
| 208: | }
|
| 209: |
|
| 210: | |
| 211: | |
| 212: | |
| 213: | |
| 214: |
|
| 215: | protected function _findUnused($hash)
|
| 216: | {
|
| 217: | $accessed = $hash->getAccessed();
|
| 218: | foreach ($hash as $k => $v) {
|
| 219: | if (!isset($accessed[$k])) {
|
| 220: | trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE);
|
| 221: | }
|
| 222: | }
|
| 223: | }
|
| 224: | }
|
| 225: |
|
| 226: |
|
| 227: | |