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: | |