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