]> git.mxchange.org Git - friendica.git/blob - library/ezyang/htmlpurifier/library/HTMLPurifier/Printer/ConfigForm.php
Update HTMLPurifier to v4.7.0
[friendica.git] / library / ezyang / htmlpurifier / library / HTMLPurifier / Printer / ConfigForm.php
1 <?php
2
3 /**
4  * @todo Rewrite to use Interchange objects
5  */
6 class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
7 {
8
9     /**
10      * Printers for specific fields.
11      * @type HTMLPurifier_Printer[]
12      */
13     protected $fields = array();
14
15     /**
16      * Documentation URL, can have fragment tagged on end.
17      * @type string
18      */
19     protected $docURL;
20
21     /**
22      * Name of form element to stuff config in.
23      * @type string
24      */
25     protected $name;
26
27     /**
28      * Whether or not to compress directive names, clipping them off
29      * after a certain amount of letters. False to disable or integer letters
30      * before clipping.
31      * @type bool
32      */
33     protected $compress = false;
34
35     /**
36      * @param string $name Form element name for directives to be stuffed into
37      * @param string $doc_url String documentation URL, will have fragment tagged on
38      * @param bool $compress Integer max length before compressing a directive name, set to false to turn off
39      */
40     public function __construct(
41         $name,
42         $doc_url = null,
43         $compress = false
44     ) {
45         parent::__construct();
46         $this->docURL = $doc_url;
47         $this->name = $name;
48         $this->compress = $compress;
49         // initialize sub-printers
50         $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default();
51         $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool();
52     }
53
54     /**
55      * Sets default column and row size for textareas in sub-printers
56      * @param $cols Integer columns of textarea, null to use default
57      * @param $rows Integer rows of textarea, null to use default
58      */
59     public function setTextareaDimensions($cols = null, $rows = null)
60     {
61         if ($cols) {
62             $this->fields['default']->cols = $cols;
63         }
64         if ($rows) {
65             $this->fields['default']->rows = $rows;
66         }
67     }
68
69     /**
70      * Retrieves styling, in case it is not accessible by webserver
71      */
72     public static function getCSS()
73     {
74         return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css');
75     }
76
77     /**
78      * Retrieves JavaScript, in case it is not accessible by webserver
79      */
80     public static function getJavaScript()
81     {
82         return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js');
83     }
84
85     /**
86      * Returns HTML output for a configuration form
87      * @param HTMLPurifier_Config|array $config Configuration object of current form state, or an array
88      *        where [0] has an HTML namespace and [1] is being rendered.
89      * @param array|bool $allowed Optional namespace(s) and directives to restrict form to.
90      * @param bool $render_controls
91      * @return string
92      */
93     public function render($config, $allowed = true, $render_controls = true)
94     {
95         if (is_array($config) && isset($config[0])) {
96             $gen_config = $config[0];
97             $config = $config[1];
98         } else {
99             $gen_config = $config;
100         }
101
102         $this->config = $config;
103         $this->genConfig = $gen_config;
104         $this->prepareGenerator($gen_config);
105
106         $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $config->def);
107         $all = array();
108         foreach ($allowed as $key) {
109             list($ns, $directive) = $key;
110             $all[$ns][$directive] = $config->get($ns . '.' . $directive);
111         }
112
113         $ret = '';
114         $ret .= $this->start('table', array('class' => 'hp-config'));
115         $ret .= $this->start('thead');
116         $ret .= $this->start('tr');
117         $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive'));
118         $ret .= $this->element('th', 'Value', array('class' => 'hp-value'));
119         $ret .= $this->end('tr');
120         $ret .= $this->end('thead');
121         foreach ($all as $ns => $directives) {
122             $ret .= $this->renderNamespace($ns, $directives);
123         }
124         if ($render_controls) {
125             $ret .= $this->start('tbody');
126             $ret .= $this->start('tr');
127             $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls'));
128             $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit'));
129             $ret .= '[<a href="?">Reset</a>]';
130             $ret .= $this->end('td');
131             $ret .= $this->end('tr');
132             $ret .= $this->end('tbody');
133         }
134         $ret .= $this->end('table');
135         return $ret;
136     }
137
138     /**
139      * Renders a single namespace
140      * @param $ns String namespace name
141      * @param array $directives array of directives to values
142      * @return string
143      */
144     protected function renderNamespace($ns, $directives)
145     {
146         $ret = '';
147         $ret .= $this->start('tbody', array('class' => 'namespace'));
148         $ret .= $this->start('tr');
149         $ret .= $this->element('th', $ns, array('colspan' => 2));
150         $ret .= $this->end('tr');
151         $ret .= $this->end('tbody');
152         $ret .= $this->start('tbody');
153         foreach ($directives as $directive => $value) {
154             $ret .= $this->start('tr');
155             $ret .= $this->start('th');
156             if ($this->docURL) {
157                 $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL);
158                 $ret .= $this->start('a', array('href' => $url));
159             }
160             $attr = array('for' => "{$this->name}:$ns.$directive");
161
162             // crop directive name if it's too long
163             if (!$this->compress || (strlen($directive) < $this->compress)) {
164                 $directive_disp = $directive;
165             } else {
166                 $directive_disp = substr($directive, 0, $this->compress - 2) . '...';
167                 $attr['title'] = $directive;
168             }
169
170             $ret .= $this->element(
171                 'label',
172                 $directive_disp,
173                 // component printers must create an element with this id
174                 $attr
175             );
176             if ($this->docURL) {
177                 $ret .= $this->end('a');
178             }
179             $ret .= $this->end('th');
180
181             $ret .= $this->start('td');
182             $def = $this->config->def->info["$ns.$directive"];
183             if (is_int($def)) {
184                 $allow_null = $def < 0;
185                 $type = abs($def);
186             } else {
187                 $type = $def->type;
188                 $allow_null = isset($def->allow_null);
189             }
190             if (!isset($this->fields[$type])) {
191                 $type = 0;
192             } // default
193             $type_obj = $this->fields[$type];
194             if ($allow_null) {
195                 $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj);
196             }
197             $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config));
198             $ret .= $this->end('td');
199             $ret .= $this->end('tr');
200         }
201         $ret .= $this->end('tbody');
202         return $ret;
203     }
204
205 }
206
207 /**
208  * Printer decorator for directives that accept null
209  */
210 class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer
211 {
212     /**
213      * Printer being decorated
214      * @type HTMLPurifier_Printer
215      */
216     protected $obj;
217
218     /**
219      * @param HTMLPurifier_Printer $obj Printer to decorate
220      */
221     public function __construct($obj)
222     {
223         parent::__construct();
224         $this->obj = $obj;
225     }
226
227     /**
228      * @param string $ns
229      * @param string $directive
230      * @param string $value
231      * @param string $name
232      * @param HTMLPurifier_Config|array $config
233      * @return string
234      */
235     public function render($ns, $directive, $value, $name, $config)
236     {
237         if (is_array($config) && isset($config[0])) {
238             $gen_config = $config[0];
239             $config = $config[1];
240         } else {
241             $gen_config = $config;
242         }
243         $this->prepareGenerator($gen_config);
244
245         $ret = '';
246         $ret .= $this->start('label', array('for' => "$name:Null_$ns.$directive"));
247         $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose'));
248         $ret .= $this->text(' Null/Disabled');
249         $ret .= $this->end('label');
250         $attr = array(
251             'type' => 'checkbox',
252             'value' => '1',
253             'class' => 'null-toggle',
254             'name' => "$name" . "[Null_$ns.$directive]",
255             'id' => "$name:Null_$ns.$directive",
256             'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!!
257         );
258         if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) {
259             // modify inline javascript slightly
260             $attr['onclick'] =
261                 "toggleWriteability('$name:Yes_$ns.$directive',checked);" .
262                 "toggleWriteability('$name:No_$ns.$directive',checked)";
263         }
264         if ($value === null) {
265             $attr['checked'] = 'checked';
266         }
267         $ret .= $this->elementEmpty('input', $attr);
268         $ret .= $this->text(' or ');
269         $ret .= $this->elementEmpty('br');
270         $ret .= $this->obj->render($ns, $directive, $value, $name, array($gen_config, $config));
271         return $ret;
272     }
273 }
274
275 /**
276  * Swiss-army knife configuration form field printer
277  */
278 class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer
279 {
280     /**
281      * @type int
282      */
283     public $cols = 18;
284
285     /**
286      * @type int
287      */
288     public $rows = 5;
289
290     /**
291      * @param string $ns
292      * @param string $directive
293      * @param string $value
294      * @param string $name
295      * @param HTMLPurifier_Config|array $config
296      * @return string
297      */
298     public function render($ns, $directive, $value, $name, $config)
299     {
300         if (is_array($config) && isset($config[0])) {
301             $gen_config = $config[0];
302             $config = $config[1];
303         } else {
304             $gen_config = $config;
305         }
306         $this->prepareGenerator($gen_config);
307         // this should probably be split up a little
308         $ret = '';
309         $def = $config->def->info["$ns.$directive"];
310         if (is_int($def)) {
311             $type = abs($def);
312         } else {
313             $type = $def->type;
314         }
315         if (is_array($value)) {
316             switch ($type) {
317                 case HTMLPurifier_VarParser::LOOKUP:
318                     $array = $value;
319                     $value = array();
320                     foreach ($array as $val => $b) {
321                         $value[] = $val;
322                     }
323                     //TODO does this need a break?
324                 case HTMLPurifier_VarParser::ALIST:
325                     $value = implode(PHP_EOL, $value);
326                     break;
327                 case HTMLPurifier_VarParser::HASH:
328                     $nvalue = '';
329                     foreach ($value as $i => $v) {
330                         $nvalue .= "$i:$v" . PHP_EOL;
331                     }
332                     $value = $nvalue;
333                     break;
334                 default:
335                     $value = '';
336             }
337         }
338         if ($type === HTMLPurifier_VarParser::MIXED) {
339             return 'Not supported';
340             $value = serialize($value);
341         }
342         $attr = array(
343             'name' => "$name" . "[$ns.$directive]",
344             'id' => "$name:$ns.$directive"
345         );
346         if ($value === null) {
347             $attr['disabled'] = 'disabled';
348         }
349         if (isset($def->allowed)) {
350             $ret .= $this->start('select', $attr);
351             foreach ($def->allowed as $val => $b) {
352                 $attr = array();
353                 if ($value == $val) {
354                     $attr['selected'] = 'selected';
355                 }
356                 $ret .= $this->element('option', $val, $attr);
357             }
358             $ret .= $this->end('select');
359         } elseif ($type === HTMLPurifier_VarParser::TEXT ||
360                 $type === HTMLPurifier_VarParser::ITEXT ||
361                 $type === HTMLPurifier_VarParser::ALIST ||
362                 $type === HTMLPurifier_VarParser::HASH ||
363                 $type === HTMLPurifier_VarParser::LOOKUP) {
364             $attr['cols'] = $this->cols;
365             $attr['rows'] = $this->rows;
366             $ret .= $this->start('textarea', $attr);
367             $ret .= $this->text($value);
368             $ret .= $this->end('textarea');
369         } else {
370             $attr['value'] = $value;
371             $attr['type'] = 'text';
372             $ret .= $this->elementEmpty('input', $attr);
373         }
374         return $ret;
375     }
376 }
377
378 /**
379  * Bool form field printer
380  */
381 class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer
382 {
383     /**
384      * @param string $ns
385      * @param string $directive
386      * @param string $value
387      * @param string $name
388      * @param HTMLPurifier_Config|array $config
389      * @return string
390      */
391     public function render($ns, $directive, $value, $name, $config)
392     {
393         if (is_array($config) && isset($config[0])) {
394             $gen_config = $config[0];
395             $config = $config[1];
396         } else {
397             $gen_config = $config;
398         }
399         $this->prepareGenerator($gen_config);
400         $ret = '';
401         $ret .= $this->start('div', array('id' => "$name:$ns.$directive"));
402
403         $ret .= $this->start('label', array('for' => "$name:Yes_$ns.$directive"));
404         $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose'));
405         $ret .= $this->text(' Yes');
406         $ret .= $this->end('label');
407
408         $attr = array(
409             'type' => 'radio',
410             'name' => "$name" . "[$ns.$directive]",
411             'id' => "$name:Yes_$ns.$directive",
412             'value' => '1'
413         );
414         if ($value === true) {
415             $attr['checked'] = 'checked';
416         }
417         if ($value === null) {
418             $attr['disabled'] = 'disabled';
419         }
420         $ret .= $this->elementEmpty('input', $attr);
421
422         $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive"));
423         $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose'));
424         $ret .= $this->text(' No');
425         $ret .= $this->end('label');
426
427         $attr = array(
428             'type' => 'radio',
429             'name' => "$name" . "[$ns.$directive]",
430             'id' => "$name:No_$ns.$directive",
431             'value' => '0'
432         );
433         if ($value === false) {
434             $attr['checked'] = 'checked';
435         }
436         if ($value === null) {
437             $attr['disabled'] = 'disabled';
438         }
439         $ret .= $this->elementEmpty('input', $attr);
440
441         $ret .= $this->end('div');
442
443         return $ret;
444     }
445 }
446
447 // vim: et sw=4 sts=4