MDL-67115 htmlpurifier: php74 params order for implode()
[moodle.git] / lib / htmlpurifier / HTMLPurifier / Printer / HTMLDefinition.php
1 <?php\r
2 \r
3 class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer\r
4 {\r
5 \r
6     /**\r
7      * @type HTMLPurifier_HTMLDefinition, for easy access\r
8      */\r
9     protected $def;\r
10 \r
11     /**\r
12      * @param HTMLPurifier_Config $config\r
13      * @return string\r
14      */\r
15     public function render($config)\r
16     {\r
17         $ret = '';\r
18         $this->config =& $config;\r
19 \r
20         $this->def = $config->getHTMLDefinition();\r
21 \r
22         $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer'));\r
23 \r
24         $ret .= $this->renderDoctype();\r
25         $ret .= $this->renderEnvironment();\r
26         $ret .= $this->renderContentSets();\r
27         $ret .= $this->renderInfo();\r
28 \r
29         $ret .= $this->end('div');\r
30 \r
31         return $ret;\r
32     }\r
33 \r
34     /**\r
35      * Renders the Doctype table\r
36      * @return string\r
37      */\r
38     protected function renderDoctype()\r
39     {\r
40         $doctype = $this->def->doctype;\r
41         $ret = '';\r
42         $ret .= $this->start('table');\r
43         $ret .= $this->element('caption', 'Doctype');\r
44         $ret .= $this->row('Name', $doctype->name);\r
45         $ret .= $this->row('XML', $doctype->xml ? 'Yes' : 'No');\r
46         $ret .= $this->row('Default Modules', implode(', ', $doctype->modules));\r
47         $ret .= $this->row('Default Tidy Modules', implode(', ', $doctype->tidyModules));\r
48         $ret .= $this->end('table');\r
49         return $ret;\r
50     }\r
51 \r
52 \r
53     /**\r
54      * Renders environment table, which is miscellaneous info\r
55      * @return string\r
56      */\r
57     protected function renderEnvironment()\r
58     {\r
59         $def = $this->def;\r
60 \r
61         $ret = '';\r
62 \r
63         $ret .= $this->start('table');\r
64         $ret .= $this->element('caption', 'Environment');\r
65 \r
66         $ret .= $this->row('Parent of fragment', $def->info_parent);\r
67         $ret .= $this->renderChildren($def->info_parent_def->child);\r
68         $ret .= $this->row('Block wrap name', $def->info_block_wrapper);\r
69 \r
70         $ret .= $this->start('tr');\r
71         $ret .= $this->element('th', 'Global attributes');\r
72         $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr), null, 0);\r
73         $ret .= $this->end('tr');\r
74 \r
75         $ret .= $this->start('tr');\r
76         $ret .= $this->element('th', 'Tag transforms');\r
77         $list = array();\r
78         foreach ($def->info_tag_transform as $old => $new) {\r
79             $new = $this->getClass($new, 'TagTransform_');\r
80             $list[] = "<$old> with $new";\r
81         }\r
82         $ret .= $this->element('td', $this->listify($list));\r
83         $ret .= $this->end('tr');\r
84 \r
85         $ret .= $this->start('tr');\r
86         $ret .= $this->element('th', 'Pre-AttrTransform');\r
87         $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre));\r
88         $ret .= $this->end('tr');\r
89 \r
90         $ret .= $this->start('tr');\r
91         $ret .= $this->element('th', 'Post-AttrTransform');\r
92         $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post));\r
93         $ret .= $this->end('tr');\r
94 \r
95         $ret .= $this->end('table');\r
96         return $ret;\r
97     }\r
98 \r
99     /**\r
100      * Renders the Content Sets table\r
101      * @return string\r
102      */\r
103     protected function renderContentSets()\r
104     {\r
105         $ret = '';\r
106         $ret .= $this->start('table');\r
107         $ret .= $this->element('caption', 'Content Sets');\r
108         foreach ($this->def->info_content_sets as $name => $lookup) {\r
109             $ret .= $this->heavyHeader($name);\r
110             $ret .= $this->start('tr');\r
111             $ret .= $this->element('td', $this->listifyTagLookup($lookup));\r
112             $ret .= $this->end('tr');\r
113         }\r
114         $ret .= $this->end('table');\r
115         return $ret;\r
116     }\r
117 \r
118     /**\r
119      * Renders the Elements ($info) table\r
120      * @return string\r
121      */\r
122     protected function renderInfo()\r
123     {\r
124         $ret = '';\r
125         $ret .= $this->start('table');\r
126         $ret .= $this->element('caption', 'Elements ($info)');\r
127         ksort($this->def->info);\r
128         $ret .= $this->heavyHeader('Allowed tags', 2);\r
129         $ret .= $this->start('tr');\r
130         $ret .= $this->element('td', $this->listifyTagLookup($this->def->info), array('colspan' => 2));\r
131         $ret .= $this->end('tr');\r
132         foreach ($this->def->info as $name => $def) {\r
133             $ret .= $this->start('tr');\r
134             $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2));\r
135             $ret .= $this->end('tr');\r
136             $ret .= $this->start('tr');\r
137             $ret .= $this->element('th', 'Inline content');\r
138             $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No');\r
139             $ret .= $this->end('tr');\r
140             if (!empty($def->excludes)) {\r
141                 $ret .= $this->start('tr');\r
142                 $ret .= $this->element('th', 'Excludes');\r
143                 $ret .= $this->element('td', $this->listifyTagLookup($def->excludes));\r
144                 $ret .= $this->end('tr');\r
145             }\r
146             if (!empty($def->attr_transform_pre)) {\r
147                 $ret .= $this->start('tr');\r
148                 $ret .= $this->element('th', 'Pre-AttrTransform');\r
149                 $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre));\r
150                 $ret .= $this->end('tr');\r
151             }\r
152             if (!empty($def->attr_transform_post)) {\r
153                 $ret .= $this->start('tr');\r
154                 $ret .= $this->element('th', 'Post-AttrTransform');\r
155                 $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post));\r
156                 $ret .= $this->end('tr');\r
157             }\r
158             if (!empty($def->auto_close)) {\r
159                 $ret .= $this->start('tr');\r
160                 $ret .= $this->element('th', 'Auto closed by');\r
161                 $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close));\r
162                 $ret .= $this->end('tr');\r
163             }\r
164             $ret .= $this->start('tr');\r
165             $ret .= $this->element('th', 'Allowed attributes');\r
166             $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0);\r
167             $ret .= $this->end('tr');\r
168 \r
169             if (!empty($def->required_attr)) {\r
170                 $ret .= $this->row('Required attributes', $this->listify($def->required_attr));\r
171             }\r
172 \r
173             $ret .= $this->renderChildren($def->child);\r
174         }\r
175         $ret .= $this->end('table');\r
176         return $ret;\r
177     }\r
178 \r
179     /**\r
180      * Renders a row describing the allowed children of an element\r
181      * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element\r
182      * @return string\r
183      */\r
184     protected function renderChildren($def)\r
185     {\r
186         $context = new HTMLPurifier_Context();\r
187         $ret = '';\r
188         $ret .= $this->start('tr');\r
189         $elements = array();\r
190         $attr = array();\r
191         if (isset($def->elements)) {\r
192             if ($def->type == 'strictblockquote') {\r
193                 $def->validateChildren(array(), $this->config, $context);\r
194             }\r
195             $elements = $def->elements;\r
196         }\r
197         if ($def->type == 'chameleon') {\r
198             $attr['rowspan'] = 2;\r
199         } elseif ($def->type == 'empty') {\r
200             $elements = array();\r
201         } elseif ($def->type == 'table') {\r
202             $elements = array_flip(\r
203                 array(\r
204                     'col',\r
205                     'caption',\r
206                     'colgroup',\r
207                     'thead',\r
208                     'tfoot',\r
209                     'tbody',\r
210                     'tr'\r
211                 )\r
212             );\r
213         }\r
214         $ret .= $this->element('th', 'Allowed children', $attr);\r
215 \r
216         if ($def->type == 'chameleon') {\r
217 \r
218             $ret .= $this->element(\r
219                 'td',\r
220                 '<em>Block</em>: ' .\r
221                 $this->escape($this->listifyTagLookup($def->block->elements)),\r
222                 null,\r
223                 0\r
224             );\r
225             $ret .= $this->end('tr');\r
226             $ret .= $this->start('tr');\r
227             $ret .= $this->element(\r
228                 'td',\r
229                 '<em>Inline</em>: ' .\r
230                 $this->escape($this->listifyTagLookup($def->inline->elements)),\r
231                 null,\r
232                 0\r
233             );\r
234 \r
235         } elseif ($def->type == 'custom') {\r
236 \r
237             $ret .= $this->element(\r
238                 'td',\r
239                 '<em>' . ucfirst($def->type) . '</em>: ' .\r
240                 $def->dtd_regex\r
241             );\r
242 \r
243         } else {\r
244             $ret .= $this->element(\r
245                 'td',\r
246                 '<em>' . ucfirst($def->type) . '</em>: ' .\r
247                 $this->escape($this->listifyTagLookup($elements)),\r
248                 null,\r
249                 0\r
250             );\r
251         }\r
252         $ret .= $this->end('tr');\r
253         return $ret;\r
254     }\r
255 \r
256     /**\r
257      * Listifies a tag lookup table.\r
258      * @param array $array Tag lookup array in form of array('tagname' => true)\r
259      * @return string\r
260      */\r
261     protected function listifyTagLookup($array)\r
262     {\r
263         ksort($array);\r
264         $list = array();\r
265         foreach ($array as $name => $discard) {\r
266             if ($name !== '#PCDATA' && !isset($this->def->info[$name])) {\r
267                 continue;\r
268             }\r
269             $list[] = $name;\r
270         }\r
271         return $this->listify($list);\r
272     }\r
273 \r
274     /**\r
275      * Listifies a list of objects by retrieving class names and internal state\r
276      * @param array $array List of objects\r
277      * @return string\r
278      * @todo Also add information about internal state\r
279      */\r
280     protected function listifyObjectList($array)\r
281     {\r
282         ksort($array);\r
283         $list = array();\r
284         foreach ($array as $obj) {\r
285             $list[] = $this->getClass($obj, 'AttrTransform_');\r
286         }\r
287         return $this->listify($list);\r
288     }\r
289 \r
290     /**\r
291      * Listifies a hash of attributes to AttrDef classes\r
292      * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef)\r
293      * @return string\r
294      */\r
295     protected function listifyAttr($array)\r
296     {\r
297         ksort($array);\r
298         $list = array();\r
299         foreach ($array as $name => $obj) {\r
300             if ($obj === false) {\r
301                 continue;\r
302             }\r
303             $list[] = "$name&nbsp;=&nbsp;<i>" . $this->getClass($obj, 'AttrDef_') . '</i>';\r
304         }\r
305         return $this->listify($list);\r
306     }\r
307 \r
308     /**\r
309      * Creates a heavy header row\r
310      * @param string $text\r
311      * @param int $num\r
312      * @return string\r
313      */\r
314     protected function heavyHeader($text, $num = 1)\r
315     {\r
316         $ret = '';\r
317         $ret .= $this->start('tr');\r
318         $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy'));\r
319         $ret .= $this->end('tr');\r
320         return $ret;\r
321     }\r
322 }\r
323 \r
324 // vim: et sw=4 sts=4\r