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