Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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