[TASK] Fix CGL violations against SuperfluousWhitespace
[Packages/TYPO3.CMS.git] / typo3 / wizard_tsconfig.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 /**
29 * Wizard for inserting TSconfig in form fields. (page,user or TS)
30 *
31 * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj
32 * XHTML compliant
33 *
34 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
35 */
36
37 $GLOBALS['BACK_PATH'] = '';
38 require('init.php');
39 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_wizards.xml');
40
41 /**
42 * TypoScript parser extension class.
43 *
44 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
45 * @package TYPO3
46 * @subpackage core
47 */
48 class ext_TSparser extends t3lib_tsparser_ext {
49
50 /**
51 * Pass through of incoming value for link.
52 *
53 * @param array $P P array
54 * @return string The "_LINK" key value, straight away.
55 */
56 function makeHtmlspecialchars($P) {
57 return $P['_LINK'];
58 }
59 }
60
61 /**
62 * Script Class for rendering the TSconfig/TypoScript property browser.
63 *
64 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
65 * @package TYPO3
66 * @subpackage core
67 */
68 class SC_wizard_tsconfig {
69
70 // Internal, dynamic:
71 /**
72 * document template object
73 *
74 * @var mediumDoc
75 */
76 var $doc;
77 // Content accumulation for the module.
78 var $content;
79
80 // Internal, static: GPvars
81 // Wizard parameters, coming from TCEforms linking to the wizard.
82 var $P;
83 // "page", "tsref" or "beuser"
84 var $mode;
85 // Pointing to an entry in static_tsconfig_help to show.
86 var $show;
87 // Object path - for display.
88 var $objString;
89 // If set, the "mixed-field" is not shown and you can select only one property at a time.
90 var $onlyProperty;
91
92 /**
93 * Initialization of the class
94 *
95 * @return void
96 */
97 function init() {
98 // Check if the tsconfig_help extension is loaded - which is mandatory for this wizard to work.
99 t3lib_extMgm::isLoaded('tsconfig_help', 1);
100
101 // Init GPvars:
102 $this->P = t3lib_div::_GP('P');
103 $this->mode = t3lib_div::_GP('mode');
104 $this->show = t3lib_div::_GP('show');
105 $this->objString = t3lib_div::_GP('objString');
106 $this->onlyProperty = t3lib_div::_GP('onlyProperty');
107 // Preparing some JavaScript code:
108 if (!$this->areFieldChangeFunctionsValid()) {
109 $this->P['fieldChangeFunc']=array();
110 }
111 unset($this->P['fieldChangeFunc']['alert']);
112 $update='';
113 foreach ($this->P['fieldChangeFunc'] as $k=>$v) {
114 $update .= '
115 window.opener.'.$v;
116 }
117
118 // Init the document table object:
119 $this->doc = t3lib_div::makeInstance('template');
120 $this->doc->backPath = $GLOBALS['BACK_PATH'];
121 $this->doc->form = '<form action="" name="editform">';
122
123 // Adding Styles (should go into stylesheet?)
124 $this->doc->inDocStylesArray[] = '
125 A:link {text-decoration: bold; color: '.$this->doc->hoverColor.';}
126 A:visited {text-decoration: bold; color: '.$this->doc->hoverColor.';}
127 A:active {text-decoration: bold; color: '.$this->doc->hoverColor.';}
128 A:hover {color: '.$this->doc->bgColor2.'}
129 ';
130
131 $this->doc->JScode.=$this->doc->wrapScriptTags('
132 function checkReference_name() { // Checks if the input field containing the name exists in the document
133 if (window.opener && window.opener.document && window.opener.document.'.$this->P['formName'].' && window.opener.document.'.$this->P['formName'].'["'.$this->P['itemName'].'"] ) {
134 return window.opener.document.'.$this->P['formName'].'["'.$this->P['itemName'].'"];
135 }
136 }
137 function checkReference_value() { // Checks if the input field containing the value exists in the document
138 if (window.opener && window.opener.document && window.opener.document.'.$this->P['formName'].' && window.opener.document.'.$this->P['formName'].'["'.$this->P['itemValue'].'"] ) {
139 return window.opener.document.'.$this->P['formName'].'["'.$this->P['itemValue'].'"];
140 }
141 }
142
143 /**
144 * [Describe function...]
145 *
146 * @param [type] $field,value: ...
147 * @return [type] ...
148 */
149 function setValue(field,value) {
150 var nameField = checkReference_name();
151 var valueField = checkReference_value();
152 if (nameField) {
153 if (valueField) { // This applies to the TS Object Browser module
154 nameField.value=field;
155 valueField.value=value;
156 } else { // This applies to the Info/Modify module and the Page TSconfig field
157 if (value) {
158 nameField.value=field+"="+value+"\n"+nameField.value;
159 } else {
160 nameField.value=field+"\n"+nameField.value;
161 }
162 }
163 '.$update.'
164 window.opener.focus();
165 }
166 close();
167 }
168 function getValue() { // This is never used. Remove it?
169 var field = checkReference_name();
170 if (field) {
171 return field.value;
172 } else {
173 close();
174 }
175 }
176
177 /**
178 * [Describe function...]
179 *
180 * @param [type] $cmd,objString: ...
181 * @return [type] ...
182 */
183 function mixerField(cmd,objString) {
184 var temp;
185 switch(cmd) {
186 case "Indent":
187 temp = str_replace("\n","\n ","\n"+document.editform.mixer.value);
188 document.editform.mixer.value = temp.substr(1);
189 break;
190 case "Outdent":
191 temp = str_replace("\n ","\n","\n"+document.editform.mixer.value);
192 document.editform.mixer.value = temp.substr(1);
193 break;
194 case "Transfer":
195 setValue(document.editform.mixer.value);
196 break;
197 case "Wrap":
198 document.editform.mixer.value=objString+" {\n"+document.editform.mixer.value+"\n}";
199 break;
200 }
201 }
202
203 /**
204 * [Describe function...]
205 *
206 * @param [type] $match,replace,string: ...
207 * @return [type] ...
208 */
209 function str_replace(match,replace,string) {
210 var input = ""+string;
211 var matchStr = ""+match;
212 if (!matchStr) {return string;}
213 var output = "";
214 var pointer=0;
215 var pos = input.indexOf(matchStr);
216 while (pos!=-1) {
217 output+=""+input.substr(pointer, pos-pointer)+replace;
218 pointer=pos+matchStr.length;
219 pos = input.indexOf(match, pos+1);
220 }
221 output+=""+input.substr(pointer);
222 return output;
223 }
224
225 /**
226 * [Describe function...]
227 *
228 * @param [type] $show,objString: ...
229 * @return [type] ...
230 */
231 function jump(show, objString) {
232 window.location.href = "'.t3lib_div::linkThisScript(array('show'=>'', 'objString'=>'')).'&show="+show+"&objString="+objString;
233 }
234 ');
235
236 // Start the page:
237 $this->content .= $this->doc->startPage($GLOBALS['LANG']->getLL('tsprop'));
238 }
239
240 /**
241 * Main function, rendering the content of the TypoScript property browser, including links to online resources
242 *
243 * @return void
244 */
245 function main() {
246 // Adding module content:
247 $this->content.=$this->doc->section($GLOBALS['LANG']->getLL('tsprop'), $this->browseTSprop($this->mode, $this->show), 0, 1);
248
249 // Adding link to TSref:
250 if ($this->mode == 'tsref') {
251 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('tsprop_TSref'), '
252 <a href="' . TYPO3_URL_DOCUMENTATION_TSREF . '" target="_blank">' . $GLOBALS['LANG']->getLL('tsprop_TSref', 1) . '</a>
253 ', 0, 1);
254 }
255 // Adding link to admin guides etc:
256 if ($this->mode == 'page' || $this->mode == 'beuser') {
257 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('tsprop_tsconfig'), '
258 <a href="' . TYPO3_URL_DOCUMENTATION_TSCONFIG . '" target="_blank">' . $GLOBALS['LANG']->getLL('tsprop_tsconfig', 1) . '</a>
259 ', 0, 1);
260 }
261 }
262
263 /**
264 * Outputting the accumulated content to screen
265 *
266 * @return void
267 */
268 function printContent() {
269 $this->content .= $this->doc->endPage();
270 $this->content = $this->doc->insertStylesAndJS($this->content);
271 echo $this->content;
272 }
273
274 /**
275 * Create the content of the module:
276 *
277 * @param string $mode Object string
278 * @param integer $show Pointing to an entry in static_tsconfig_help to show.
279 * @return string HTML
280 */
281 function browseTSprop($mode, $show) {
282 // Get object tree:
283 $objTree = $this->getObjTree();
284
285 // Show single element, if show is set.
286 $out = '';
287 if ($show) {
288 // Get the entry data:
289 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'static_tsconfig_help', 'uid='.intval($show));
290 $rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
291 $table = unserialize($rec['appdata']);
292 // Title:
293 $obj_string = strtr($this->objString, '()', '[]');
294
295 // Title and description:
296 $out .= '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('show'=>''))).'" class="typo3-goBack">'.
297 t3lib_iconWorks::getSpriteIcon('actions-view-go-back') .
298 htmlspecialchars($obj_string).
299 '</a><br />';
300 if ($rec['title']) {
301 $out .= '<strong>'.htmlspecialchars($rec['title']).': </strong>';
302 }
303 if ($rec['description']) {
304 $out .= nl2br(htmlspecialchars(trim($rec['description']))).'<br />';
305 }
306
307 // Printing the content:
308 $out .= '<br />'.$this->printTable($table, $obj_string, $objTree[$mode.'.']);
309 $out .='<hr />';
310
311 // Printing the "mixer-field":
312 if (!$this->onlyProperty) {
313 $links = array();
314 $links[] = '<a href="#" onclick="mixerField(\'Indent\');return false;">'.$GLOBALS['LANG']->getLL('tsprop_mixer_indent', 1).'</a>';
315 $links[] = '<a href="#" onclick="mixerField(\'Outdent\');return false;">'.$GLOBALS['LANG']->getLL('tsprop_mixer_outdent', 1).'</a>';
316 $links[] = '<a href="#" onclick="mixerField(\'Wrap\',unescape(\''.rawurlencode($obj_string).'\'));return false;">'.$GLOBALS['LANG']->getLL('tsprop_mixer_wrap', 1).'</a>';
317 $links[] = '<a href="#" onclick="mixerField(\'Transfer\');return false;">'.$GLOBALS['LANG']->getLL('tsprop_mixer_transfer', 1).'</a>';
318 $out .= '<textarea rows="5" name="mixer" wrap="off"'.$this->doc->formWidthText(48, '', 'off').' class="fixed-font enable-tab"></textarea>';
319 $out .= '<br /><strong>'.implode('&nbsp; | &nbsp;', $links).'</strong>';
320 $out .= '<hr />';
321 }
322 }
323
324 // SECTION: Showing property tree:
325 $tmpl = t3lib_div::makeInstance('ext_TSparser');
326 // Do not log time-performance information
327 $tmpl->tt_track = 0;
328 $tmpl->fixedLgd = 0;
329 $tmpl->linkObjects = 0;
330 $tmpl->bType = '';
331 $tmpl->ext_expandAllNotes = 1;
332 $tmpl->ext_noPMicons = 1;
333 $tmpl->ext_noSpecialCharsOnLabels = 1;
334
335 if (is_array($objTree[$mode.'.'])) {
336 $out .= '
337
338
339 <!--
340 TSconfig, object tree:
341 -->
342 <table border="0" cellpadding="0" cellspacing="0" class="t3-tree t3-tree-config" id="typo3-objtree">
343 <tr class="t3-row-header"><td>TSref</td></tr>
344 <tr>
345 <td nowrap="nowrap">'.$tmpl->ext_getObjTree($this->removePointerObjects($objTree[$mode.'.']), '', '', '', '', '1').'</td>
346 </tr>
347 </table>';
348 }
349
350 return $out;
351 }
352
353 /***************************
354 *
355 * Module functions
356 *
357 ***************************/
358
359 /**
360 * Create object tree from static_tsconfig_help table
361 *
362 * @return array Object tree.
363 * @access private
364 */
365 function getObjTree() {
366 $objTree = array();
367
368 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,obj_string,title', 'static_tsconfig_help', '');
369 while ($rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
370 $rec['obj_string'] = $this->revertFromSpecialChars($rec['obj_string']);
371 $p = explode(';', $rec['obj_string']);
372 foreach ($p as $v) {
373 $p2 = t3lib_div::trimExplode(':', $v, 1);
374 $subp = t3lib_div::trimExplode('/', $p2[1], 1);
375 foreach ($subp as $v2) {
376 $this->setObj($objTree, explode('.', $p2[0].'.'.$v2), array($rec, $v2));
377 }
378 }
379 }
380 return $objTree;
381 }
382
383 /**
384 * Sets the information from a static_tsconfig_help record in the object array.
385 * Makes recursive calls.
386 *
387 * @param array $objTree Object tree array, passed by value!
388 * @param array $strArr Array of elements from object path (?)
389 * @param array $params Array with record and something else (?)
390 * @return void
391 * @access private
392 * @see getObjTree()
393 */
394 function setObj(&$objTree, $strArr, $params) {
395 $key = current($strArr);
396 reset($strArr);
397 if (count($strArr) > 1) {
398 array_shift($strArr);
399 if (!isset($objTree[$key.'.'])) {
400 $objTree[$key.'.'] = array();
401 }
402 $this->setObj($objTree[$key.'.'], $strArr, $params);
403 } else {
404 $objTree[$key]=$params;
405 $objTree[$key]['_LINK']=$this->doLink($params);
406 }
407 }
408
409 /**
410 * Converts &gt; and &lt; to > and <
411 *
412 * @param string $str Input string
413 * @return string Output string
414 * @access private
415 */
416 function revertFromSpecialChars($str) {
417 $str = str_replace('&gt;', '>', $str);
418 $str = str_replace('&lt;', '<', $str);
419 return $str;
420 }
421
422 /**
423 * Creates a link based on input params array:
424 *
425 * @param array $params Parameters
426 * @return string The link.
427 * @access private
428 */
429 function doLink($params) {
430 $title = trim($params[0]['title'])?trim($params[0]['title']):'[GO]';
431 $str = $this->linkToObj($title, $params[0]['uid'], $params[1]);
432 return $str;
433 }
434
435 /**
436 * Remove pointer strings from an array
437 *
438 * @param array $objArray Input array
439 * @return array Modified input array
440 * @access private
441 */
442 function removePointerObjects($objArray) {
443 foreach ($objArray as $k => $value) {
444 if (substr(trim($k), 0, 2) == '->' && trim($k) != '->.') {
445 $objArray['->.'][substr(trim($k), 2)]=$objArray[$k];
446 unset($objArray[$k]);
447 }
448 }
449 return $objArray;
450 }
451
452 /**
453 * Linking string to object by UID
454 *
455 * @param string $str String to link
456 * @param integer $uid UID of a static_tsconfig_help record.
457 * @param string $objString Title string for that record!
458 * @return string Linked string
459 */
460 function linkToObj($str, $uid, $objString = '') {
461 $aOnClick = 'jump(\''.rawurlencode($uid).'\',\''.rawurlencode($objString).'\');return false;';
462 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.htmlspecialchars($str).'</a>';
463 }
464
465 /**
466 * Creates a table of properties:
467 *
468 * @param array $table Array with properties for the current object path
469 * @param string $objString Object path
470 * @param array $objTree Object tree
471 * @return string HTML content.
472 */
473 function printTable($table, $objString, $objTree) {
474 if (is_array($table['rows'])) {
475
476 // Initialize:
477 $lines = array();
478
479 // Adding header:
480 $lines[] = '
481 <tr class="t3-row-header">
482 <td>Property:</td>
483 <td>Data type:</td>
484 <td>Description:</td>
485 <td>Default:</td>
486 </tr>';
487
488 // Traverse the content of "rows":
489 foreach ($table['rows'] as $i => $row) {
490
491 // Linking:
492 $lP = t3lib_div::trimExplode(LF, $row['property'], 1);
493 $lP2 = array();
494 foreach ($lP as $k => $lStr) {
495 $lP2[$k] = $this->linkProperty($lStr, $lStr, $objString, $row['datatype']);
496 }
497 $linkedProperties = implode('<hr />', $lP2);
498
499 // Data type:
500 $dataType = $row['datatype'];
501
502 // Generally "->[something]"
503 $reg = array();
504 preg_match('/->[[:alnum:]_]*/', $dataType, $reg);
505 if ($reg[0] && is_array($objTree[$reg[0]])) {
506 $dataType = str_replace($reg[0], '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array('show' => $objTree[$reg[0]][0]['uid'], 'objString' => $objString . '.' . $lP[0]))) . '">' . htmlspecialchars($reg[0]) . '</a>', $dataType);
507 }
508
509 // stdWrap
510 if (!strstr($dataType, '->stdWrap') && strstr(strip_tags($dataType), 'stdWrap')) {
511 // Potential problem can be that "stdWrap" is substituted inside another A-tag. So maybe we should even check if there is already a <A>-tag present and if so, not make a substitution?
512 $dataType = str_replace('stdWrap', '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('show'=>$objTree['->stdWrap'][0]['uid'], 'objString'=>$objString.'.'.$lP[0]))).'">stdWrap</a>', $dataType);
513 }
514
515 $lines[] = '
516 <tr class="t3-row ' . ($i % 2 ? 't3-row-even' : 't3-row-odd') . '">
517 <td valign="top" class="bgColor4-20" nowrap="nowrap"><strong>'.$linkedProperties.'</strong></td>
518 <td valign="top">'.nl2br($dataType.'&nbsp;').'</td>
519 <td valign="top">'.nl2br($row['description']).'</td>
520 <td valign="top">'.nl2br($row['default']).'</td>
521 </tr>';
522 }
523 // Return it all:
524 return '
525
526
527
528 <!--
529 TSconfig, attribute selector:
530 -->
531 <table border="0" cellpadding="0" cellspacing="1" width="98%" class="t3-table" id="typo3-attributes">
532 '.implode('', $lines).'
533 </table>';
534 }
535 }
536
537 /**
538 * Creates a link on a property.
539 *
540 * @param string $str String to link
541 * @param string $propertyName Property value.
542 * @param string $prefix Object path prefix to value
543 * @param string $datatype Data type
544 * @return string Linked $str
545 */
546 function linkProperty($str, $propertyName, $prefix, $datatype) {
547 $out = '';
548
549 // Setting preset value:
550 if (strstr($datatype, 'boolean')) {
551 // preset "1" to boolean values.
552 $propertyVal = '1';
553 }
554
555 // Adding mixer features; The plus icon:
556 if (!$this->onlyProperty) {
557 $aOnClick = 'document.editform.mixer.value=unescape(\' '.rawurlencode($propertyName.'='.$propertyVal).'\')+\'\n\'+document.editform.mixer.value; return false;';
558 $out .= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
559 t3lib_iconWorks::getSpriteIcon('actions-edit-add', array('title' => $GLOBALS['LANG']->getLL('tsprop_addToList', TRUE))) .
560 '</a>';
561 $propertyName = $prefix.'.'.$propertyName;
562 }
563
564 // Wrap string:
565 $aOnClick = 'setValue(unescape(\''.rawurlencode($propertyName).'\'), unescape(\''.rawurlencode($propertyVal).'\')); return false;';
566 $out .= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.$str.'</a>';
567
568 // Return link:
569 return $out;
570 }
571
572 /**
573 * Determines whether submitted field change functions are valid
574 * and are coming from the system and not from an external abuse.
575 *
576 * @return boolean Whether the submitted field change functions are valid
577 */
578 protected function areFieldChangeFunctionsValid() {
579 return (
580 isset($this->P['fieldChangeFunc']) && is_array($this->P['fieldChangeFunc']) && isset($this->P['fieldChangeFuncHash'])
581 && $this->P['fieldChangeFuncHash'] === t3lib_div::hmac(serialize($this->P['fieldChangeFunc']))
582 );
583 }
584 }
585
586 // Make instance:
587 $SOBE = t3lib_div::makeInstance('SC_wizard_tsconfig');
588 $SOBE->init();
589 $SOBE->main();
590 $SOBE->printContent();
591
592 ?>