Fixed issue #17284: Formprotection persistToken method is called too often, causing...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_syntaxhl.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains a class for various syntax highlighting.
29 *
30 * $Id$
31 *
32 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
33 */
34 /**
35 * [CLASS/FUNCTION INDEX of SCRIPT]
36 *
37 *
38 *
39 * 84: class t3lib_syntaxhl
40 *
41 * SECTION: Markup of Data Structure, <T3DataStructure>
42 * 156: function highLight_DS($str)
43 * 183: function highLight_DS_markUpRecursively($struct,$parent='',$app='')
44 *
45 * SECTION: Markup of Data Structure, <T3FlexForms>
46 * 268: function highLight_FF($str)
47 * 295: function highLight_FF_markUpRecursively($struct,$parent='',$app='')
48 *
49 * SECTION: Various
50 * 376: function getAllTags($str)
51 * 407: function splitXMLbyTags($tagList,$str)
52 *
53 * TOTAL FUNCTIONS: 6
54 * (This index is automatically created/updated by the extension "extdeveval")
55 *
56 */
57
58
59 /**
60 * Syntax Highlighting class.
61 *
62 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
63 * @package TYPO3
64 * @subpackage t3lib
65 */
66 class t3lib_syntaxhl {
67
68 // Internal, dynamic:
69 var $htmlParse; // Parse object.
70
71 // External, static:
72 var $DS_wrapTags = array(
73 'T3DataStructure' => array('<span style="font-weight: bold;">', '</span>'),
74 'type' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
75 'section' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
76 'el' => array('<span style="font-weight: bold; color: #800000;">', '</span>'),
77 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
78 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
79
80 '_applicationTag' => array('<span style="font-weight: bold; color: #FF6600;">', '</span>'),
81 '_applicationContents' => array('<span style="font-style: italic; color: #C29336;">', '</span>'),
82
83 'sheets' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
84 'parent:sheets' => array('<span style="color: #008000;">', '</span>'),
85
86 'ROOT' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
87 'parent:el' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
88
89 'langDisable' => array('<span style="color: #000080;">', '</span>'),
90 'langChildren' => array('<span style="color: #000080;">', '</span>'),
91 );
92
93 var $FF_wrapTags = array(
94 'T3FlexForms' => array('<span style="font-weight: bold;">', '</span>'),
95 'meta' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
96 'data' => array('<span style="font-weight: bold; color: #800080;">', '</span>'),
97 'el' => array('<span style="font-weight: bold; color: #80a000;">', '</span>'),
98 'itemType' => array('<span style="font-weight: bold; color: #804000;">', '</span>'),
99 'section' => array('<span style="font-weight: bold; color: #604080;">', '</span>'),
100 'numIndex' => array('<span style="color: #333333;">', '</span>'),
101 '_unknown' => array('<span style="font-style: italic; color: #666666;">', '</span>'),
102
103
104 'sDEF' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
105 'level:sheet' => array('<span style="font-weight: bold; color: #008000;">', '</span>'),
106
107 'lDEF' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
108 'level:language' => array('<span style="font-weight: bold; color: #000080;">', '</span>'),
109
110 'level:fieldname' => array('<span style="font-weight: bold; color: #666666;">', '</span>'),
111
112 'vDEF' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
113 'level:value' => array('<span style="font-weight: bold; color: #008080;">', '</span>'),
114
115 'currentSheetId' => array('<span style="color: #000080;">', '</span>'),
116 'currentLangId' => array('<span style="color: #000080;">', '</span>'),
117 );
118
119
120 /*************************************
121 *
122 * Markup of Data Structure, <T3DataStructure>
123 *
124 *************************************/
125
126 /**
127 * Makes syntax highlighting of a Data Structure, <T3DataStructure>
128 *
129 * @param string Data Structure XML, must be valid since it's parsed.
130 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
131 */
132 function highLight_DS($str) {
133
134 // Parse DS to verify that it is valid:
135 $DS = t3lib_div::xml2array($str);
136 if (is_array($DS)) {
137 $completeTagList = array_unique($this->getAllTags($str)); // Complete list of tags in DS
138
139 // Highlighting source:
140 $this->htmlParse = t3lib_div::makeInstance('t3lib_parsehtml'); // Init parser object
141 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str); // Split the XML by the found tags, recursively into LARGE array.
142 $markUp = $this->highLight_DS_markUpRecursively($struct); // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
143
144 // Return content:
145 return $markUp;
146 } else {
147 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
148 }
149 return $error;
150 }
151
152 /**
153 * Making syntax highlighting of the parsed Data Structure XML.
154 * Called recursively.
155 *
156 * @param array The structure, see splitXMLbyTags()
157 * @param string Parent tag.
158 * @param string "Application" - used to denote if we are 'inside' a section
159 * @return string HTML
160 */
161 function highLight_DS_markUpRecursively($struct, $parent = '', $app = '') {
162 $output = '';
163 foreach ($struct as $k => $v) {
164 if ($k % 2) {
165 $nextApp = $app;
166 $wrap = array('', '');
167
168 switch ($app) {
169 case 'TCEforms':
170 case 'tx_templavoila':
171 $wrap = $this->DS_wrapTags['_applicationContents'];
172 break;
173 case 'el':
174 default:
175 if ($parent == 'el') {
176 $wrap = $this->DS_wrapTags['parent:el'];
177 $nextApp = 'el';
178 } elseif ($parent == 'sheets') {
179 $wrap = $this->DS_wrapTags['parent:sheets'];
180 } else {
181 $wrap = $this->DS_wrapTags[$v['tagName']];
182 $nextApp = '';
183 }
184
185 // If no wrap defined, us "unknown" definition
186 if (!is_array($wrap)) {
187 $wrap = $this->DS_wrapTags['_unknown'];
188 }
189
190 // Check for application sections in the XML:
191 if ($app == 'el' || $parent == 'ROOT') {
192 switch ($v['tagName']) {
193 case 'TCEforms':
194 case 'tx_templavoila':
195 $nextApp = $v['tagName'];
196 $wrap = $this->DS_wrapTags['_applicationTag'];
197 break;
198 }
199 }
200 break;
201 }
202
203 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
204 $output .= $this->highLight_DS_markUpRecursively($v['sub'], $v['tagName'], $nextApp);
205 $output .= $wrap[0] . htmlspecialchars('</' . $v['tagName'] . '>') . $wrap[1];
206 } else {
207 $output .= htmlspecialchars($v);
208 }
209 }
210
211 return $output;
212 }
213
214
215 /*************************************
216 *
217 * Markup of Data Structure, <T3FlexForms>
218 *
219 *************************************/
220
221 /**
222 * Makes syntax highlighting of a FlexForm Data, <T3FlexForms>
223 *
224 * @param string Data Structure XML, must be valid since it's parsed.
225 * @return string HTML code with highlighted content. Must be wrapped in <PRE> tags
226 */
227 function highLight_FF($str) {
228
229 // Parse DS to verify that it is valid:
230 $DS = t3lib_div::xml2array($str);
231 if (is_array($DS)) {
232 $completeTagList = array_unique($this->getAllTags($str)); // Complete list of tags in DS
233
234 // Highlighting source:
235 $this->htmlParse = t3lib_div::makeInstance('t3lib_parsehtml'); // Init parser object
236 $struct = $this->splitXMLbyTags(implode(',', $completeTagList), $str); // Split the XML by the found tags, recursively into LARGE array.
237 $markUp = $this->highLight_FF_markUpRecursively($struct); // Perform color-markup on the parsed content. Markup preserves the LINE formatting of the XML.
238
239 // Return content:
240 return $markUp;
241 } else {
242 $error = 'ERROR: The input content failed XML parsing: ' . $DS;
243 }
244 return $error;
245 }
246
247 /**
248 * Making syntax highlighting of the parsed FlexForm XML.
249 * Called recursively.
250 *
251 * @param array The structure, see splitXMLbyTags()
252 * @param string Parent tag.
253 * @param string "Application" - used to denote if we are 'inside' a section
254 * @return string HTML
255 */
256 function highLight_FF_markUpRecursively($struct, $parent = '', $app = '') {
257 $output = '';
258
259 // Setting levels:
260 if ($parent == 'data') {
261 $app = 'sheet';
262 } elseif ($app == 'sheet') {
263 $app = 'language';
264 } elseif ($app == 'language') {
265 $app = 'fieldname';
266 } elseif ($app == 'fieldname') {
267 $app = 'value';
268 } elseif ($app == 'el' || $app == 'numIndex') {
269 $app = 'fieldname';
270 }
271
272 // Traverse structure:
273 foreach ($struct as $k => $v) {
274 if ($k % 2) {
275 $wrap = array('', '');
276
277 if ($v['tagName'] == 'numIndex') {
278 $app = 'numIndex';
279 }
280
281 // Default wrap:
282 $wrap = $this->FF_wrapTags[$v['tagName']];
283
284 // If no wrap defined, us "unknown" definition
285 if (!is_array($wrap)) {
286 switch ($app) {
287 case 'sheet':
288 case 'language':
289 case 'fieldname':
290 case 'value':
291 $wrap = $this->FF_wrapTags['level:' . $app];
292 break;
293 default:
294 $wrap = $this->FF_wrapTags['_unknown'];
295 break;
296 }
297 }
298
299 if ($v['tagName'] == 'el') {
300 $app = 'el';
301 }
302
303 $output .= $wrap[0] . htmlspecialchars($v['tag']) . $wrap[1];
304 $output .= $this->highLight_FF_markUpRecursively($v['sub'], $v['tagName'], $app);
305 $output .= $wrap[0] . htmlspecialchars('</' . $v['tagName'] . '>') . $wrap[1];
306 } else {
307 $output .= htmlspecialchars($v);
308 }
309 }
310
311 return $output;
312 }
313
314
315 /*************************************
316 *
317 * Various
318 *
319 *************************************/
320
321 /**
322 * Returning all tag names found in XML/HTML input string
323 *
324 * @param string HTML/XML input
325 * @return array Array with all found tags (starttags only)
326 */
327 function getAllTags($str) {
328
329 // Init:
330 $tags = array();
331 $token = md5(microtime());
332
333 // Markup all tag names with token.
334 $markUpStr = preg_replace('/<([[:alnum:]_]+)[^>]*>/', $token . '${1}' . $token, $str);
335
336 // Splitting by token:
337 $parts = explode($token, $markUpStr);
338
339 // Traversing parts:
340 foreach ($parts as $k => $v) {
341 if ($k % 2) {
342 $tags[] = $v;
343 }
344 }
345
346 // Returning tags:
347 return $tags;
348 }
349
350 /**
351 * Splitting the input source by the tags listing in $tagList.
352 * Called recursively.
353 *
354 * @param string Commalist of tags to split source by (into blocks, ALL being block-tags!)
355 * @param string Input string.
356 * @return array Array with the content arranged hierarchically.
357 */
358 function splitXMLbyTags($tagList, $str) {
359 $struct = $this->htmlParse->splitIntoBlock($tagList, $str);
360
361 // Traverse level:
362 foreach ($struct as $k => $v) {
363 if ($k % 2) {
364 $tag = $this->htmlParse->getFirstTag($v);
365 $tagName = $this->htmlParse->getFirstTagName($tag, TRUE);
366 $struct[$k] = array(
367 'tag' => $tag,
368 'tagName' => $tagName,
369 'sub' => $this->splitXMLbyTags($tagList, $this->htmlParse->removeFirstAndLastTag($struct[$k]))
370 );
371 }
372 }
373
374 return $struct;
375 }
376 }
377
378
379 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_syntaxhl.php'])) {
380 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_syntaxhl.php']);
381 }
382
383 ?>