Updated Copyright notices
[Packages/TYPO3.CMS.git] / typo3 / wizard_tsconfig.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2008 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->docType = 'xhtml_trans';
178 $this->doc->backPath = $BACK_PATH;
179 $this->doc->form='<form action="" name="editform">';
180
181 // Adding Styles (should go into stylesheet?)
182 $this->doc->inDocStylesArray[] = '
183 A:link {text-decoration: bold; color: '.$this->doc->hoverColor.';}
184 A:visited {text-decoration: bold; color: '.$this->doc->hoverColor.';}
185 A:active {text-decoration: bold; color: '.$this->doc->hoverColor.';}
186 A:hover {color: '.$this->doc->bgColor2.'}
187 ';
188
189 $this->doc->JScode.=$this->doc->wrapScriptTags('
190 function checkReference_name() { // Checks if the input field containing the name exists in the document
191 if (window.opener && window.opener.document && window.opener.document.'.$this->P['formName'].' && window.opener.document.'.$this->P['formName'].'["'.$this->P['itemName'].'"] ) {
192 return window.opener.document.'.$this->P['formName'].'["'.$this->P['itemName'].'"];
193 }
194 }
195 function checkReference_value() { // Checks if the input field containing the value exists in the document
196 if (window.opener && window.opener.document && window.opener.document.'.$this->P['formName'].' && window.opener.document.'.$this->P['formName'].'["'.$this->P['itemValue'].'"] ) {
197 return window.opener.document.'.$this->P['formName'].'["'.$this->P['itemValue'].'"];
198 }
199 }
200
201 /**
202 * [Describe function...]
203 *
204 * @param [type] $field,value: ...
205 * @return [type] ...
206 */
207 function setValue(field,value) {
208 var nameField = checkReference_name();
209 var valueField = checkReference_value();
210 if (nameField) {
211 if (valueField) { // This applies to the TS Object Browser module
212 nameField.value=field;
213 valueField.value=value;
214 } else { // This applies to the Info/Modify module and the Page TSconfig field
215 if (value) {
216 nameField.value=field+"="+value+"\n"+nameField.value;
217 } else {
218 nameField.value=field+"\n"+nameField.value;
219 }
220 }
221 '.$update.'
222 window.opener.focus();
223 }
224 close();
225 }
226 function getValue() { // This is never used. Remove it?
227 var field = checkReference_name();
228 if (field) {
229 return field.value;
230 } else {
231 close();
232 }
233 }
234
235 /**
236 * [Describe function...]
237 *
238 * @param [type] $cmd,objString: ...
239 * @return [type] ...
240 */
241 function mixerField(cmd,objString) {
242 var temp;
243 switch(cmd) {
244 case "Indent":
245 temp = str_replace("\n","\n ","\n"+document.editform.mixer.value);
246 document.editform.mixer.value = temp.substr(1);
247 break;
248 case "Outdent":
249 temp = str_replace("\n ","\n","\n"+document.editform.mixer.value);
250 document.editform.mixer.value = temp.substr(1);
251 break;
252 case "Transfer":
253 setValue(document.editform.mixer.value);
254 break;
255 case "Wrap":
256 document.editform.mixer.value=objString+" {\n"+document.editform.mixer.value+"\n}";
257 break;
258 }
259 }
260
261 /**
262 * [Describe function...]
263 *
264 * @param [type] $match,replace,string: ...
265 * @return [type] ...
266 */
267 function str_replace(match,replace,string) {
268 var input = ""+string;
269 var matchStr = ""+match;
270 if (!matchStr) {return string;}
271 var output = "";
272 var pointer=0;
273 var pos = input.indexOf(matchStr);
274 while (pos!=-1) {
275 output+=""+input.substr(pointer, pos-pointer)+replace;
276 pointer=pos+matchStr.length;
277 pos = input.indexOf(match,pos+1);
278 }
279 output+=""+input.substr(pointer);
280 return output;
281 }
282
283 /**
284 * [Describe function...]
285 *
286 * @param [type] $show,objString: ...
287 * @return [type] ...
288 */
289 function jump(show,objString) {
290 window.location.href = "'.t3lib_div::linkThisScript(array('show'=>'','objString'=>'')).'&show="+show+"&objString="+objString;
291 }
292 ');
293
294
295 // Start the page:
296 $this->content.=$this->doc->startPage($LANG->getLL('tsprop'));
297 }
298
299 /**
300 * Main function, rendering the content of the TypoScript property browser, including links to online resources
301 *
302 * @return void
303 */
304 function main() {
305 global $LANG;
306
307 // Adding module content:
308 $this->content.=$this->doc->section($LANG->getLL('tsprop'),$this->browseTSprop($this->mode,$this->show),0,1);
309
310 // Adding link to TSref:
311 if ($this->mode=='tsref') {
312 $this->content.=$this->doc->section($LANG->getLL('tsprop_TSref'),'
313 <a href="'.htmlspecialchars('http://typo3.org/documentation/document-library/references/doc_core_tsref/current/view/').'" target="_blank">'.$LANG->getLL('tsprop_TSref',1).'</a>
314 ',0,1);
315 }
316 // Adding link to admin guides etc:
317 if ($this->mode=='page' || $this->mode=='beuser') {
318 $this->content.=$this->doc->section($LANG->getLL('tsprop_tsconfig'),'
319 <a href="'.htmlspecialchars('http://typo3.org/documentation/document-library/references/doc_core_tsconfig/current/view/').'" target="_blank">'.$LANG->getLL('tsprop_tsconfig',1).'</a>
320 ',0,1);
321 }
322 }
323
324 /**
325 * Outputting the accumulated content to screen
326 *
327 * @return void
328 */
329 function printContent() {
330 $this->content.= $this->doc->endPage();
331 $this->content = $this->doc->insertStylesAndJS($this->content);
332 echo $this->content;
333 }
334
335 /**
336 * Create the content of the module:
337 *
338 * @param string Object string
339 * @param integer Pointing to an entry in static_tsconfig_help to show.
340 * @return string HTML
341 */
342 function browseTSprop($mode,$show) {
343 global $LANG;
344
345 // Get object tree:
346 $objTree = $this->getObjTree();
347
348 // Show single element, if show is set.
349 $out='';
350 if ($show) {
351 // Get the entry data:
352 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'static_tsconfig_help', 'uid='.intval($show));
353 $rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
354 $table = unserialize($rec['appdata']);
355 $obj_string = strtr($this->objString,'()','[]'); // Title:
356
357 // Title and description:
358 $out.='<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('show'=>''))).'" class="typo3-goBack">'.
359 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/goback.gif','width="14" height="14"').' alt="" />'.
360 htmlspecialchars($obj_string).
361 '</a><br />';
362 if ($rec['title']) $out.= '<strong>'.htmlspecialchars($rec['title']).': </strong>';
363 if ($rec['description']) $out.= nl2br(htmlspecialchars(trim($rec['description']))).'<br />';
364
365 // Printing the content:
366 $out.= '<br />'.$this->printTable($table, $obj_string, $objTree[$mode.'.']);
367 $out.='<hr />';
368
369 // Printing the "mixer-field":
370 if (!$this->onlyProperty) {
371 $links=array();
372 $links[]='<a href="#" onclick="mixerField(\'Indent\');return false;">'.$LANG->getLL('tsprop_mixer_indent',1).'</a>';
373 $links[]='<a href="#" onclick="mixerField(\'Outdent\');return false;">'.$LANG->getLL('tsprop_mixer_outdent',1).'</a>';
374 $links[]='<a href="#" onclick="mixerField(\'Wrap\',unescape(\''.rawurlencode($obj_string).'\'));return false;">'.$LANG->getLL('tsprop_mixer_wrap',1).'</a>';
375 $links[]='<a href="#" onclick="mixerField(\'Transfer\');return false;">'.$LANG->getLL('tsprop_mixer_transfer',1).'</a>';
376 $out.='<textarea rows="5" name="mixer" wrap="off"'.$this->doc->formWidthText(48,'','off').' class="fixed-font enable-tab"></textarea>';
377 $out.='<br /><strong>'.implode('&nbsp; | &nbsp;',$links).'</strong>';
378 $out.='<hr />';
379 }
380 }
381
382
383 // SECTION: Showing property tree:
384 $tmpl = t3lib_div::makeInstance('ext_TSparser');
385 $tmpl->tt_track = 0; // Do not log time-performance information
386 $tmpl->fixedLgd=0;
387 $tmpl->linkObjects=0;
388 $tmpl->bType='';
389 $tmpl->ext_expandAllNotes=1;
390 $tmpl->ext_noPMicons=1;
391 $tmpl->ext_noSpecialCharsOnLabels=1;
392
393 if (is_array($objTree[$mode.'.'])) {
394 $out.='
395
396
397 <!--
398 TSconfig, object tree:
399 -->
400 <table border="0" cellpadding="0" cellspacing="0" id="typo3-objtree">
401 <tr>
402 <td nowrap="nowrap">'.$tmpl->ext_getObjTree($this->removePointerObjects($objTree[$mode.'.']),'','','','','1').'</td>
403 </tr>
404 </table>';
405 }
406
407 return $out;
408 }
409
410
411
412
413
414
415
416 /***************************
417 *
418 * Module functions
419 *
420 ***************************/
421
422 /**
423 * Create object tree from static_tsconfig_help table
424 *
425 * @return array Object tree.
426 * @access private
427 */
428 function getObjTree() {
429 $objTree=array();
430
431 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,obj_string,title', 'static_tsconfig_help', '');
432 while($rec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
433 $rec['obj_string'] = $this->revertFromSpecialChars($rec['obj_string']);
434 $p = explode(';',$rec['obj_string']);
435 while(list(,$v)=each($p)) {
436 $p2 = t3lib_div::trimExplode(':',$v,1);
437 $subp=t3lib_div::trimExplode('/',$p2[1],1);
438 while(list(,$v2)=each($subp)) {
439 $this->setObj($objTree,explode('.',$p2[0].'.'.$v2),array($rec,$v2));
440 }
441 }
442 }
443 return $objTree;
444 }
445
446 /**
447 * Sets the information from a static_tsconfig_help record in the object array.
448 * Makes recursive calls.
449 *
450 * @param array Object tree array, passed by value!
451 * @param array Array of elements from object path (?)
452 * @param array Array with record and something else (?)
453 * @return void
454 * @access private
455 * @see getObjTree()
456 */
457 function setObj(&$objTree,$strArr,$params) {
458 $key = current($strArr);
459 reset($strArr);
460 if (count($strArr)>1) {
461 array_shift($strArr);
462 if (!isset($objTree[$key.'.'])) $objTree[$key.'.']=array();
463 $this->setObj($objTree[$key.'.'],$strArr,$params);
464 } else {
465 $objTree[$key]=$params;
466 $objTree[$key]['_LINK']=$this->doLink($params);
467 }
468 }
469
470 /**
471 * Converts &gt; and &lt; to > and <
472 *
473 * @param string Input string
474 * @return string Output string
475 * @access private
476 */
477 function revertFromSpecialChars($str) {
478 $str = str_replace('&gt;','>',$str);
479 $str = str_replace('&lt;','<',$str);
480 return $str;
481 }
482
483 /**
484 * Creates a link based on input params array:
485 *
486 * @param array Parameters
487 * @return string The link.
488 * @access private
489 */
490 function doLink($params) {
491 $title = trim($params[0]['title'])?trim($params[0]['title']):'[GO]';
492 $str = $this->linkToObj($title,$params[0]['uid'],$params[1]);
493 return $str;
494 }
495
496 /**
497 * Remove pointer strings from an array
498 *
499 * @param array Input array
500 * @return array Modified input array
501 * @access private
502 */
503 function removePointerObjects($objArray) {
504 reset($objArray);
505 while(list($k)=each($objArray)) {
506 if (substr(trim($k),0,2)=="->" && trim($k)!='->.') {
507 $objArray['->.'][substr(trim($k),2)]=$objArray[$k];
508 unset($objArray[$k]);
509 }
510 }
511 return $objArray;
512 }
513
514 /**
515 * Linking string to object by UID
516 *
517 * @param string String to link
518 * @param integer UID of a static_tsconfig_help record.
519 * @param string Title string for that record!
520 * @return string Linked string
521 */
522 function linkToObj($str,$uid,$objString='') {
523 $aOnClick='jump(\''.rawurlencode($uid).'\',\''.rawurlencode($objString).'\');return false;';
524 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.htmlspecialchars($str).'</a>';
525 }
526
527 /**
528 * Creates a table of properties:
529 *
530 * @param array Array with properties for the current object path
531 * @param string Object path
532 * @param array Object tree
533 * @return string HTML content.
534 */
535 function printTable($table,$objString,$objTree) {
536 if (is_array($table['rows'])) {
537
538 // Initialize:
539 $lines=array();
540
541 // Adding header:
542 $lines[]='
543 <tr>
544 <td><img src="clear.gif" width="175" height="1" alt="" /></td>
545 <td><img src="clear.gif" width="100" height="1" alt="" /></td>
546 <td><img src="clear.gif" width="400" height="1" alt="" /></td>
547 <td><img src="clear.gif" width="70" height="1" alt="" /></td>
548 </tr>';
549 $lines[]='
550 <tr class="bgColor5">
551 <td><strong>Property:</strong></td>
552 <td><strong>Data type:</strong></td>
553 <td><strong>Description:</strong></td>
554 <td><strong>Default:</strong></td>
555 </tr>';
556
557 // Traverse the content of "rows":
558 foreach($table['rows'] as $row) {
559
560 // Linking:
561 $lP=t3lib_div::trimExplode(chr(10),$row['property'],1);
562 $lP2=array();
563 while(list($k,$lStr)=each($lP)) {
564 $lP2[$k] = $this->linkProperty($lStr,$lStr,$objString,$row['datatype']);
565 }
566 $linkedProperties=implode('<hr />',$lP2);
567
568 // Data type:
569 $dataType = $row['datatype'];
570
571 // Generally "->[something]"
572 $reg=array();
573 ereg('->[[:alnum:]_]*',$dataType,$reg);
574 if ($reg[0] && is_array($objTree[$reg[0]])) {
575 $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);
576 }
577
578 // stdWrap
579 if (!strstr($dataType,'->stdWrap') && strstr(strip_tags($dataType),'stdWrap')) {
580 // 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?
581 $dataType = str_replace('stdWrap','<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('show'=>$objTree['->stdWrap'][0]['uid'],'objString'=>$objString.'.'.$lP[0]))).'">stdWrap</a>',$dataType);
582 }
583
584
585 $lines[]='
586 <tr class="bgColor4">
587 <td valign="top" class="bgColor4-20"><strong>'.$linkedProperties.'</strong></td>
588 <td valign="top">'.nl2br($dataType.'&nbsp;').'</td>
589 <td valign="top">'.nl2br($row['description']).'</td>
590 <td valign="top">'.nl2br($row['default']).'</td>
591 </tr>';
592 }
593 // Return it all:
594 return '
595
596
597
598 <!--
599 TSconfig, attribute selector:
600 -->
601 <table border="0" cellpadding="0" cellspacing="1" width="500" id="typo3-attributes">
602 '.implode('',$lines).'
603 </table>';
604 }
605 }
606
607 /**
608 * Creates a link on a property.
609 *
610 * @param string String to link
611 * @param string Property value.
612 * @param string Object path prefix to value
613 * @param string Data type
614 * @return string Linked $str
615 */
616 function linkProperty($str,$propertyName,$prefix,$datatype) {
617 $out='';
618
619 // Setting preset value:
620 if (strstr($datatype,'boolean')) {
621 $propertyVal='1'; // preset "1" to boolean values.
622 }
623
624 // Adding mixer features; The plus icon:
625 if(!$this->onlyProperty) {
626 $aOnClick = 'document.editform.mixer.value=unescape(\' '.rawurlencode($propertyName.'='.$propertyVal).'\')+\'\n\'+document.editform.mixer.value; return false;';
627 $out.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
628 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/plusbullet2.gif','width="18" height="16"').' title="'.$GLOBALS['LANG']->getLL('tsprop_addToList',1).'" align="top" alt="" />'.
629 '</a>';
630 $propertyName = $prefix.'.'.$propertyName;
631 }
632
633 // Wrap string:
634 $aOnClick = 'setValue(unescape(\''.rawurlencode($propertyName).'\'),unescape(\''.rawurlencode($propertyVal).'\')); return false;';
635 $out.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.$str.'</a>';
636
637 // Return link:
638 return $out;
639 }
640 }
641
642 // Include extension?
643 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/wizard_tsconfig.php']) {
644 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/wizard_tsconfig.php']);
645 }
646
647
648
649
650
651
652
653
654
655
656
657
658 // Make instance:
659 $SOBE = t3lib_div::makeInstance('SC_wizard_tsconfig');
660 $SOBE->init();
661 $SOBE->main();
662 $SOBE->printContent();
663 ?>