ef41d5f487b117ef7503f1da3778af4eab7bc27f
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / TypoScript / ExtendedTemplateService.php
1 <?php
2 namespace TYPO3\CMS\Core\TypoScript;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * TSParser extension class to t3lib_TStemplate
31 * Contains functions for the TS module in TYPO3 backend
32 *
33 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
34 * @package TYPO3
35 * @subpackage t3lib
36 */
37 class ExtendedTemplateService extends \TYPO3\CMS\Core\TypoScript\TemplateService {
38
39 // This string is used to indicate the point in a template from where the editable constants are listed. Any vars before this point (if it exists though) is regarded as default values.
40 /**
41 * @todo Define visibility
42 */
43 public $edit_divider = '###MOD_TS:EDITABLE_CONSTANTS###';
44
45 /**
46 * @todo Define visibility
47 */
48 public $HTMLcolorList = 'aqua,beige,black,blue,brown,fuchsia,gold,gray,green,lime,maroon,navy,olive,orange,purple,red,silver,tan,teal,turquoise,yellow,white';
49
50 // internal
51 /**
52 * @todo Define visibility
53 */
54 public $categories = array(
55 'basic' => array(),
56 // Constants of superior importance for the template-layout. This is dimensions, imagefiles and enabling of various features. The most basic constants, which you would almost always want to configure.
57 'menu' => array(),
58 // Menu setup. This includes fontfiles, sizes, background images. Depending on the menutype.
59 'content' => array(),
60 // All constants related to the display of pagecontent elements
61 'page' => array(),
62 // General configuration like metatags, link targets
63 'advanced' => array(),
64 // Advanced functions, which are used very seldomly.
65 'all' => array()
66 );
67
68 // This will be filled with the available categories of the current template.
69 /**
70 * @todo Define visibility
71 */
72 public $subCategories = array(
73 // Standard categories:
74 'enable' => array('Enable features', 'a'),
75 'dims' => array('Dimensions, widths, heights, pixels', 'b'),
76 'file' => array('Files', 'c'),
77 'typo' => array('Typography', 'd'),
78 'color' => array('Colors', 'e'),
79 'links' => array('Links and targets', 'f'),
80 'language' => array('Language specific constants', 'g'),
81 // subcategories based on the default content elements
82 'cheader' => array('Content: \'Header\'', 'ma'),
83 'cheader_g' => array('Content: \'Header\', Graphical', 'ma'),
84 'ctext' => array('Content: \'Text\'', 'mb'),
85 'cimage' => array('Content: \'Image\'', 'md'),
86 'cbullets' => array('Content: \'Bullet list\'', 'me'),
87 'ctable' => array('Content: \'Table\'', 'mf'),
88 'cuploads' => array('Content: \'Filelinks\'', 'mg'),
89 'cmultimedia' => array('Content: \'Multimedia\'', 'mh'),
90 'cmedia' => array('Content: \'Media\'', 'mr'),
91 'cmailform' => array('Content: \'Form\'', 'mi'),
92 'csearch' => array('Content: \'Search\'', 'mj'),
93 'clogin' => array('Content: \'Login\'', 'mk'),
94 'csplash' => array('Content: \'Textbox\'', 'ml'),
95 'cmenu' => array('Content: \'Menu/Sitemap\'', 'mm'),
96 'cshortcut' => array('Content: \'Insert records\'', 'mn'),
97 'clist' => array('Content: \'List of records\'', 'mo'),
98 'chtml' => array('Content: \'HTML\'', 'mq')
99 );
100
101 /**
102 * @todo Define visibility
103 */
104 public $backend_info = 1;
105
106 // Tsconstanteditor
107 /**
108 * @todo Define visibility
109 */
110 public $ext_inBrace = 0;
111
112 // Tsbrowser
113 /**
114 * @todo Define visibility
115 */
116 public $tsbrowser_searchKeys = array();
117
118 /**
119 * @todo Define visibility
120 */
121 public $tsbrowser_depthKeys = array();
122
123 /**
124 * @todo Define visibility
125 */
126 public $constantMode = '';
127
128 /**
129 * @todo Define visibility
130 */
131 public $regexMode = '';
132
133 /**
134 * @todo Define visibility
135 */
136 public $fixedLgd = '';
137
138 /**
139 * @todo Define visibility
140 */
141 public $resourceCheck = 0;
142
143 /**
144 * @todo Define visibility
145 */
146 public $ext_lineNumberOffset = 0;
147
148 /**
149 * @todo Define visibility
150 */
151 public $ext_localGfxPrefix = '';
152
153 /**
154 * @todo Define visibility
155 */
156 public $ext_localWebGfxPrefix = '';
157
158 /**
159 * @todo Define visibility
160 */
161 public $ext_expandAllNotes = 0;
162
163 /**
164 * @todo Define visibility
165 */
166 public $ext_noPMicons = 0;
167
168 /**
169 * @todo Define visibility
170 */
171 public $ext_noSpecialCharsOnLabels = 0;
172
173 /**
174 * @todo Define visibility
175 */
176 public $ext_listOfTemplatesArr = array();
177
178 /**
179 * @todo Define visibility
180 */
181 public $ext_lineNumberOffset_mode = '';
182
183 // Dont change...
184 /**
185 * @todo Define visibility
186 */
187 public $ext_dontCheckIssetValues = 0;
188
189 /**
190 * @todo Define visibility
191 */
192 public $ext_printAll = 0;
193
194 /**
195 * @todo Define visibility
196 */
197 public $ext_CEformName = 'forms[0]';
198
199 /**
200 * @todo Define visibility
201 */
202 public $doNotSortCategoriesBeforeMakingForm = FALSE;
203
204 // Ts analyzer
205 /**
206 * @todo Define visibility
207 */
208 public $templateTitles = array();
209
210 /**
211 * This flattens a hierarchical setuparray to $this->flatSetup
212 * The original function fetched the resource-file if any ('file.'). This functions doesn't.
213 *
214 * @param [type] $setupArray: ...
215 * @param [type] $prefix: ...
216 * @param [type] $resourceFlag: ...
217 * @return [type] ...
218 * @todo Define visibility
219 */
220 public function flattenSetup($setupArray, $prefix, $resourceFlag) {
221 if (is_array($setupArray)) {
222 // Setting absolute prefixed path for relative resources.
223 $this->getFileName_backPath = PATH_site;
224 foreach ($setupArray as $key => $val) {
225 // We don't want 'TSConstantEditor' in the flattend setup.
226 if ($prefix || substr($key, 0, 16) != 'TSConstantEditor') {
227 if (is_array($val)) {
228 $this->flattenSetup($val, $prefix . $key, $key == 'file.');
229 } elseif ($resourceFlag && $this->resourceCheck) {
230 $this->flatSetup[$prefix . $key] = $this->getFileName($val);
231 if ($this->removeFromGetFilePath && substr($this->flatSetup[$prefix . $key], 0, strlen($this->removeFromGetFilePath)) == $this->removeFromGetFilePath) {
232 $this->flatSetup[$prefix . $key] = substr($this->flatSetup[$prefix . $key], strlen($this->removeFromGetFilePath));
233 }
234 } else {
235 $this->flatSetup[$prefix . $key] = $val;
236 }
237 }
238 }
239 }
240 }
241
242 /**
243 * [Describe function...]
244 *
245 * @param [type] $all: ...
246 * @return [type] ...
247 * @todo Define visibility
248 */
249 public function substituteConstants($all) {
250 $this->Cmarker = substr(md5(uniqid('')), 0, 6);
251 return preg_replace_callback('/\\{\\$(.[^}]+)\\}/', array($this, 'substituteConstantsCallBack'), $all);
252 }
253
254 /**
255 * Call back method for preg_replace_callback in substituteConstants
256 *
257 * @param array $matches Regular expression matches
258 * @return string Replacement
259 * @see substituteConstants()
260 * @todo Define visibility
261 */
262 public function substituteConstantsCallBack($matches) {
263 switch ($this->constantMode) {
264 case 'const':
265 $ret_val = isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? '##' . $this->Cmarker . '_B##' . $matches[0] . '##' . $this->Cmarker . '_E##' : $matches[0];
266 break;
267 case 'subst':
268 $ret_val = isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? '##' . $this->Cmarker . '_B##' . $this->flatSetup[$matches[1]] . '##' . $this->Cmarker . '_E##' : $matches[0];
269 break;
270 case 'untouched':
271 $ret_val = $matches[0];
272 break;
273 default:
274 $ret_val = isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? $this->flatSetup[$matches[1]] : $matches[0];
275 }
276 return $ret_val;
277 }
278
279 /**
280 * [Describe function...]
281 *
282 * @param [type] $all: ...
283 * @return [type] ...
284 * @todo Define visibility
285 */
286 public function substituteCMarkers($all) {
287 switch ($this->constantMode) {
288 case 'const':
289 $all = str_replace('##' . $this->Cmarker . '_B##', '<font color="green"><strong>', $all);
290 $all = str_replace('##' . $this->Cmarker . '_E##', '</strong></font>', $all);
291 break;
292 case 'subst':
293 $all = str_replace('##' . $this->Cmarker . '_B##', '<font color="green"><strong>', $all);
294 $all = str_replace('##' . $this->Cmarker . '_E##', '</strong></font>', $all);
295 break;
296 default:
297 $all = $all;
298 break;
299 }
300 return $all;
301 }
302
303 /**
304 * Parses the constants in $this->const with respect to the constant-editor in this module.
305 * In particular comments in the code are registered and the edit_divider is taken into account.
306 *
307 * @return [type] ...
308 * @todo Define visibility
309 */
310 public function generateConfig_constants() {
311 // These vars are also set lateron...
312 $this->setup['resources'] = $this->resources;
313 $this->setup['sitetitle'] = $this->sitetitle;
314 // Parse constants
315 $constants = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\TypoScript\\Parser\\TypoScriptParser');
316 // Register comments!
317 $constants->regComments = 1;
318 $constants->setup = $this->const;
319 $constants->setup = $this->mergeConstantsFromPageTSconfig($constants->setup);
320 /** @var $matchObj \TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher */
321 $matchObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Configuration\\TypoScript\\ConditionMatching\\ConditionMatcher');
322 // Matches ALL conditions in TypoScript
323 $matchObj->setSimulateMatchResult(TRUE);
324 $c = 0;
325 $cc = count($this->constants);
326 foreach ($this->constants as $str) {
327 $c++;
328 if ($c == $cc) {
329 if (strstr($str, $this->edit_divider)) {
330 $parts = explode($this->edit_divider, $str, 2);
331 $str = $parts[1];
332 $constants->parse($parts[0], $matchObj);
333 }
334 $this->flatSetup = array();
335 $this->flattenSetup($constants->setup, '', '');
336 $defaultConstants = $this->flatSetup;
337 }
338 $constants->parse($str, $matchObj);
339 }
340 $this->flatSetup = array();
341 $this->flattenSetup($constants->setup, '', '');
342 $this->setup['constants'] = $constants->setup;
343 return $this->ext_compareFlatSetups($defaultConstants);
344 }
345
346 /**
347 * [Describe function...]
348 *
349 * @param [type] $theSetup: ...
350 * @param [type] $theKey: ...
351 * @return [type] ...
352 * @todo Define visibility
353 */
354 public function ext_getSetup($theSetup, $theKey) {
355 $parts = explode('.', $theKey, 2);
356 if (strcmp($parts[0], '') && is_array($theSetup[$parts[0] . '.'])) {
357 if (strcmp(trim($parts[1]), '')) {
358 return $this->ext_getSetup($theSetup[$parts[0] . '.'], trim($parts[1]));
359 } else {
360 return array($theSetup[$parts[0] . '.'], $theSetup[$parts[0]]);
361 }
362 } else {
363 if (strcmp(trim($theKey), '')) {
364 return array(array(), $theSetup[$theKey]);
365 } else {
366 return array($theSetup, '');
367 }
368 }
369 }
370
371 /**
372 * [Describe function...]
373 *
374 * @param [type] $arr: ...
375 * @param [type] $depth_in: ...
376 * @param [type] $depthData: ...
377 * @param [type] $parentType: ...
378 * @param [type] $parentValue: ...
379 * @param boolean $alphaSort sorts the array keys / tree by alphabet when set to 1
380 * @return [type] ...
381 * @todo Define visibility
382 */
383 public function ext_getObjTree($arr, $depth_in, $depthData, $parentType = '', $parentValue = '', $alphaSort = '0') {
384 $HTML = '';
385 $a = 0;
386 if ($alphaSort == '1') {
387 ksort($arr);
388 }
389 $keyArr_num = array();
390 $keyArr_alpha = array();
391 foreach ($arr as $key => $value) {
392 // Don't do anything with comments / linenumber registrations...
393 if (substr($key, -2) != '..') {
394 $key = preg_replace('/\\.$/', '', $key);
395 if (substr($key, -1) != '.') {
396 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($key)) {
397 $keyArr_num[$key] = $arr[$key];
398 } else {
399 $keyArr_alpha[$key] = $arr[$key];
400 }
401 }
402 }
403 }
404 ksort($keyArr_num);
405 $keyArr = $keyArr_num + $keyArr_alpha;
406 $c = count($keyArr);
407 if ($depth_in) {
408 $depth_in = $depth_in . '.';
409 }
410 foreach ($keyArr as $key => $value) {
411 $a++;
412 $depth = $depth_in . $key;
413 // This excludes all constants starting with '_' from being shown.
414 if ($this->bType != 'const' || substr($depth, 0, 1) != '_') {
415 $goto = substr(md5($depth), 0, 6);
416 $deeper = is_array($arr[$key . '.']) && ($this->tsbrowser_depthKeys[$depth] || $this->ext_expandAllNotes) ? 1 : 0;
417 $PM = 'join';
418 $LN = $a == $c ? 'blank' : 'line';
419 $BTM = $a == $c ? 'bottom' : '';
420 $PM = is_array($arr[$key . '.']) && !$this->ext_noPMicons ? ($deeper ? 'minus' : 'plus') : 'join';
421 $HTML .= $depthData;
422 $theIcon = '<img src="' . $GLOBALS['BACK_PATH'] . 'gfx/ol/' . $PM . $BTM . '.gif" width="18" height="16" align="top" border="0" alt="" />';
423 if ($PM == 'join') {
424 $HTML .= $theIcon;
425 } else {
426 $urlParameters = array(
427 'id' => $GLOBALS['SOBE']->id,
428 'tsbr[' . $depth . ']' => $deeper ? 0 : 1
429 );
430 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('breakPointLN')) {
431 $urlParameters['breakPointLN'] = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('breakPointLN');
432 }
433 $aHref = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('web_ts', $urlParameters) . '#' . $goto;
434 $HTML .= '<a name="' . $goto . '" href="' . htmlspecialchars($aHref) . '">' . $theIcon . '</a>';
435 }
436 $label = $key;
437 // Read only...
438 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList('types,resources,sitetitle', $depth) && $this->bType == 'setup') {
439 $label = '<font color="#666666">' . $label . '</font>';
440 } else {
441 if ($this->linkObjects) {
442 $urlParameters = array(
443 'id' => $GLOBALS['SOBE']->id,
444 'sObj' => $depth
445 );
446 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('breakPointLN')) {
447 $urlParameters['breakPointLN'] = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('breakPointLN');
448 }
449 $aHref = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('web_ts', $urlParameters);
450 if ($this->bType != 'const') {
451 $ln = is_array($arr[$key . '.ln..']) ? 'Defined in: ' . $this->lineNumberToScript($arr[($key . '.ln..')]) : 'N/A';
452 } else {
453 $ln = '';
454 }
455 if ($this->tsbrowser_searchKeys[$depth] & 4) {
456 $label = '<strong><font color="red">' . $label . '</font></strong>';
457 }
458 // The key has matched the search string
459 $label = '<a href="' . htmlspecialchars($aHref) . '" title="' . htmlspecialchars($ln) . '">' . $label . '</a>';
460 }
461 }
462 $HTML .= '[' . $label . ']';
463 if (isset($arr[$key])) {
464 $theValue = $arr[$key];
465 if ($this->fixedLgd) {
466 $imgBlocks = ceil(1 + strlen($depthData) / 77);
467 $lgdChars = 68 - ceil(strlen(('[' . $key . ']')) * 0.8) - $imgBlocks * 3;
468 $theValue = $this->ext_fixed_lgd($theValue, $lgdChars);
469 }
470 // The value has matched the search string
471 if ($this->tsbrowser_searchKeys[$depth] & 2) {
472 $HTML .= '&nbsp;=&nbsp;<strong><font color="red">' . $this->makeHtmlspecialchars($theValue) . '</font></strong>';
473 } else {
474 $HTML .= '&nbsp;=&nbsp;<strong>' . $this->makeHtmlspecialchars($theValue) . '</strong>';
475 }
476 if ($this->ext_regComments && isset($arr[$key . '..'])) {
477 $comment = $arr[$key . '..'];
478 // Skip INCLUDE_TYPOSCRIPT comments, they are almost useless
479 if (!preg_match('/### <INCLUDE_TYPOSCRIPT:.*/', $comment)) {
480 // Remove linebreaks, replace with ' '
481 $comment = preg_replace('/[\\r\\n]/', ' ', $comment);
482 // Remove # and * if more than twice in a row
483 $comment = preg_replace('/[#\\*]{2,}/', '', $comment);
484 // Replace leading # (just if it exists) and add it again. Result: Every comment should be prefixed by a '#'.
485 $comment = preg_replace('/^[#\\*\\s]+/', '# ', $comment);
486 // Masking HTML Tags: Replace < with &lt; and > with &gt;
487 $comment = $this->makeHtmlspecialchars($comment);
488 $HTML .= ' <span class="comment">' . trim($comment) . '</span>';
489 }
490 }
491 }
492 $HTML .= '<br />';
493 if ($deeper) {
494 $HTML .= $this->ext_getObjTree($arr[$key . '.'], $depth, $depthData . '<img src="' . $GLOBALS['BACK_PATH'] . 'gfx/ol/' . $LN . '.gif" width="18" height="16" align="top" alt="" />', '', $arr[$key], $alphaSort);
495 }
496 }
497 }
498 return $HTML;
499 }
500
501 /**
502 * [Describe function...]
503 *
504 * @param [type] $lnArr: ...
505 * @return [type] ...
506 * @todo Define visibility
507 */
508 public function lineNumberToScript($lnArr) {
509 if (!is_array($this->lnToScript)) {
510 $this->lnToScript = array();
511 $c = 1;
512 $c += substr_count($GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'], LF) + 2;
513 $this->lnToScript[$c] = '[Default]';
514 foreach ($this->hierarchyInfoToRoot as $info) {
515 $c += $info['configLines'] + 1;
516 $this->lnToScript[$c] = $info['title'];
517 }
518 }
519 foreach ($lnArr as $k => $ln) {
520 foreach ($this->lnToScript as $endLn => $title) {
521 if ($endLn >= intval($ln)) {
522 $lnArr[$k] = '"' . $title . '", ' . $ln;
523 break;
524 }
525 }
526 }
527 return implode('; ', $lnArr);
528 }
529
530 /**
531 * [Describe function...]
532 *
533 * @param [type] $theValue: ...
534 * @return [type] ...
535 * @todo Define visibility
536 */
537 public function makeHtmlspecialchars($theValue) {
538 return $this->ext_noSpecialCharsOnLabels ? $theValue : htmlspecialchars($theValue);
539 }
540
541 /**
542 * [Describe function...]
543 *
544 * @param [type] $arr: ...
545 * @param [type] $depth_in: ...
546 * @param [type] $searchString: ...
547 * @param [type] $keyArray: ...
548 * @return [type] ...
549 * @todo Define visibility
550 */
551 public function ext_getSearchKeys($arr, $depth_in, $searchString, $keyArray) {
552 $keyArr = array();
553 foreach ($arr as $key => $value) {
554 $key = preg_replace('/\\.$/', '', $key);
555 if (substr($key, -1) != '.') {
556 $keyArr[$key] = 1;
557 }
558 }
559 $c = count($keyArr);
560 if ($depth_in) {
561 $depth_in = $depth_in . '.';
562 }
563 foreach ($keyArr as $key => $value) {
564 $depth = $depth_in . $key;
565 $deeper = is_array($arr[$key . '.']);
566 if ($this->regexMode) {
567 // The value has matched
568 if (preg_match('/' . $searchString . '/', $arr[$key])) {
569 $this->tsbrowser_searchKeys[$depth] += 2;
570 }
571 // The key has matched
572 if (preg_match('/' . $searchString . '/', $key)) {
573 $this->tsbrowser_searchKeys[$depth] += 4;
574 }
575 // Just open this subtree if the parent key has matched the search
576 if (preg_match('/' . $searchString . '/', $depth_in)) {
577 $this->tsbrowser_searchKeys[$depth] = 1;
578 }
579 } else {
580 // The value has matched
581 if (stristr($arr[$key], $searchString)) {
582 $this->tsbrowser_searchKeys[$depth] += 2;
583 }
584 // The key has matches
585 if (stristr($key, $searchString)) {
586 $this->tsbrowser_searchKeys[$depth] += 4;
587 }
588 // Just open this subtree if the parent key has matched the search
589 if (stristr($depth_in, $searchString)) {
590 $this->tsbrowser_searchKeys[$depth] = 1;
591 }
592 }
593 if ($deeper) {
594 $cS = count($this->tsbrowser_searchKeys);
595 $keyArray = $this->ext_getSearchKeys($arr[$key . '.'], $depth, $searchString, $keyArray);
596 if ($cS != count($this->tsbrowser_searchKeys)) {
597 $keyArray[$depth] = 1;
598 }
599 }
600 }
601 return $keyArray;
602 }
603
604 /**
605 * [Describe function...]
606 *
607 * @param [type] $pid: ...
608 * @return [type] ...
609 * @todo Define visibility
610 */
611 public function ext_getRootlineNumber($pid) {
612 if ($pid && is_array($GLOBALS['rootLine'])) {
613 foreach ($GLOBALS['rootLine'] as $key => $val) {
614 if ($val['uid'] == $pid) {
615 return $key;
616 }
617 }
618 }
619 }
620
621 /**
622 * [Describe function...]
623 *
624 * @param [type] $arr: ...
625 * @param [type] $depthData: ...
626 * @param [type] $keyArray: ...
627 * @param [type] $first: ...
628 * @return [type] ...
629 * @todo Define visibility
630 */
631 public function ext_getTemplateHierarchyArr($arr, $depthData, $keyArray, $first = 0) {
632 $keyArr = array();
633 foreach ($arr as $key => $value) {
634 $key = preg_replace('/\\.$/', '', $key);
635 if (substr($key, -1) != '.') {
636 $keyArr[$key] = 1;
637 }
638 }
639 $a = 0;
640 $c = count($keyArr);
641 static $i = 0;
642 foreach ($keyArr as $key => $value) {
643 $HTML = '';
644 $a++;
645 $deeper = is_array($arr[$key . '.']);
646 $row = $arr[$key];
647 $PM = 'join';
648 $LN = $a == $c ? 'blank' : 'line';
649 $BTM = $a == $c ? 'top' : '';
650 $PM = 'join';
651 $HTML .= $depthData;
652 $alttext = '[' . $row['templateID'] . ']';
653 $alttext .= $row['pid'] ? ' - ' . \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($row['pid'], $GLOBALS['SOBE']->perms_clause, 20) : '';
654 $icon = substr($row['templateID'], 0, 3) == 'sys' ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord('sys_template', $row, array('title' => $alttext)) : \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('mimetypes-x-content-template-static', array('title' => $alttext));
655 if (in_array($row['templateID'], $this->clearList_const) || in_array($row['templateID'], $this->clearList_setup)) {
656 $urlParameters = array(
657 'id' => $GLOBALS['SOBE']->id,
658 'template' => $row['templateID']
659 );
660 $aHref = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('web_ts', $urlParameters);
661 $A_B = '<a href="' . htmlspecialchars($aHref) . '">';
662 $A_E = '</a>';
663 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('template') == $row['templateID']) {
664 $A_B = '<strong>' . $A_B;
665 $A_E .= '</strong>';
666 }
667 } else {
668 $A_B = '';
669 $A_E = '';
670 }
671 $HTML .= ($first ? '' : '<img src="' . $GLOBALS['BACK_PATH'] . 'gfx/ol/' . $PM . $BTM . '.gif" width="18" height="16" align="top" border="0" alt="" />') . $icon . $A_B . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($row['title'], $GLOBALS['BE_USER']->uc['titleLen'])) . $A_E . '&nbsp;&nbsp;';
672 $RL = $this->ext_getRootlineNumber($row['pid']);
673 $keyArray[] = '<tr class="' . ($i++ % 2 == 0 ? 'bgColor4' : 'bgColor6') . '">
674 <td nowrap="nowrap">' . $HTML . '</td>
675 <td align="center">' . ($row['root'] ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked') : '') . '&nbsp;&nbsp;</td>
676 <td align="center">' . ($row['clConf'] ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked') : '') . '&nbsp;&nbsp;' . '</td>
677 <td align="center">' . ($row['clConst'] ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked') : '') . '&nbsp;&nbsp;' . '</td>
678 <td align="center">' . ($row['pid'] ? $row['pid'] : '') . '</td>
679 <td align="center">' . (strcmp($RL, '') ? $RL : '') . '</td>
680 <td>' . ($row['next'] ? '&nbsp;' . $row['next'] . '&nbsp;&nbsp;' : '') . '</td>
681 </tr>';
682 if ($deeper) {
683 $keyArray = $this->ext_getTemplateHierarchyArr($arr[$key . '.'], $depthData . ($first ? '' : '<img src="' . $GLOBALS['BACK_PATH'] . 'gfx/ol/' . $LN . '.gif" width="18" height="16" align="top" />'), $keyArray);
684 }
685 }
686 return $keyArray;
687 }
688
689 /**
690 * [Describe function...]
691 *
692 * @param [type] $depthDataArr: ...
693 * @param [type] $pointer: ...
694 * @return [type] ...
695 * @todo Define visibility
696 */
697 public function ext_process_hierarchyInfo($depthDataArr, &$pointer) {
698 $parent = $this->hierarchyInfo[$pointer - 1]['templateParent'];
699 while ($pointer > 0 && $this->hierarchyInfo[$pointer - 1]['templateParent'] == $parent) {
700 $pointer--;
701 $row = $this->hierarchyInfo[$pointer];
702 $depthDataArr[$row['templateID']] = $row;
703 $depthDataArr[$row['templateID']]['bgcolor_setup'] = isset($this->clearList_setup_temp[$row['templateID']]) ? ' class="bgColor5"' : '';
704 $depthDataArr[$row['templateID']]['bgcolor_const'] = isset($this->clearList_const_temp[$row['templateID']]) ? ' class="bgColor5"' : '';
705 unset($this->clearList_setup_temp[$row['templateID']]);
706 unset($this->clearList_const_temp[$row['templateID']]);
707 $this->templateTitles[$row['templateID']] = $row['title'];
708 if ($row['templateID'] == $this->hierarchyInfo[$pointer - 1]['templateParent']) {
709 $depthDataArr[$row['templateID'] . '.'] = $this->ext_process_hierarchyInfo(array(), $pointer);
710 }
711 }
712 return $depthDataArr;
713 }
714
715 /**
716 * [Describe function...]
717 *
718 * @param [type] $config: ...
719 * @param [type] $lineNumbers: ...
720 * @param [type] $comments: ...
721 * @param [type] $crop: ...
722 * @param [type] $syntaxHL: ...
723 * @param [type] $syntaxHLBlockmode: ...
724 * @return [type] ...
725 * @todo Define visibility
726 */
727 public function ext_outputTS($config, $lineNumbers = 0, $comments = 0, $crop = 0, $syntaxHL = 0, $syntaxHLBlockmode = 0) {
728 $all = '';
729 foreach ($config as $str) {
730 $all .= LF . '[GLOBAL]' . LF . $str;
731 }
732 if ($syntaxHL) {
733 $all = preg_replace('/^[^' . LF . ']*./', '', $all);
734 $all = chop($all);
735 $tsparser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\TypoScript\\Parser\\TypoScriptParser');
736 $tsparser->lineNumberOffset = $this->ext_lineNumberOffset + 1;
737 $tsparser->parentObject = $this;
738 return $tsparser->doSyntaxHighlight($all, $lineNumbers ? array($this->ext_lineNumberOffset + 1) : '', $syntaxHLBlockmode);
739 } else {
740 return $this->ext_formatTS($all, $lineNumbers, $comments, $crop);
741 }
742 }
743
744 /**
745 * Returns a new string of max. $chars length
746 * If the string is longer, it will be truncated and prepended with '...'
747 * $chars must be an integer of at least 4
748 *
749 * @param [type] $string: ...
750 * @param [type] $chars: ...
751 * @return [type] ...
752 * @todo Define visibility
753 */
754 public function ext_fixed_lgd($string, $chars) {
755 if ($chars >= 4) {
756 if (strlen($string) > $chars) {
757 if (strlen($string) > 24 && substr($string, 0, 12) == '##' . $this->Cmarker . '_B##') {
758 return '##' . $this->Cmarker . '_B##' . \TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs(substr($string, 12, -12), ($chars - 3)) . '##' . $this->Cmarker . '_E##';
759 } else {
760 return \TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($string, $chars - 3);
761 }
762 }
763 }
764 return $string;
765 }
766
767 /**
768 * [Describe function...]
769 *
770 * @param integer $lineNumber Line Number
771 * @param [type] $str: ...
772 * @return string
773 * @todo Define visibility
774 */
775 public function ext_lnBreakPointWrap($lineNumber, $str) {
776 return '<a href="#" id="line-' . $lineNumber . '" onClick="return brPoint(' . $lineNumber . ',' . ($this->ext_lineNumberOffset_mode == 'setup' ? 1 : 0) . ');">' . $str . '</a>';
777 }
778
779 /**
780 * [Describe function...]
781 *
782 * @param [type] $input: ...
783 * @param [type] $ln: ...
784 * @param [type] $comments: ...
785 * @param [type] $crop: ...
786 * @return [type] ...
787 * @todo Define visibility
788 */
789 public function ext_formatTS($input, $ln, $comments = 1, $crop = 0) {
790 $input = preg_replace('/^[^' . LF . ']*./', '', $input);
791 $input = chop($input);
792 $cArr = explode(LF, $input);
793 $n = ceil(log10(count($cArr) + $this->ext_lineNumberOffset));
794 $lineNum = '';
795 foreach ($cArr as $k => $v) {
796 $lln = $k + $this->ext_lineNumberOffset + 1;
797 if ($ln) {
798 $lineNum = $this->ext_lnBreakPointWrap($lln, str_replace(' ', '&nbsp;', sprintf(('% ' . $n . 'd'), $lln))) . ': ';
799 }
800 $v = htmlspecialchars($v);
801 if ($crop) {
802 $v = $this->ext_fixed_lgd($v, $ln ? 71 : 77);
803 }
804 $cArr[$k] = $lineNum . str_replace(' ', '&nbsp;', $v);
805 $firstChar = substr(trim($v), 0, 1);
806 if ($firstChar == '[') {
807 $cArr[$k] = '<font color="green"><strong>' . $cArr[$k] . '</strong></font>';
808 } elseif ($firstChar == '/' || $firstChar == '#') {
809 if ($comments) {
810 $cArr[$k] = '<span class="typo3-dimmed">' . $cArr[$k] . '</span>';
811 } else {
812 unset($cArr[$k]);
813 }
814 }
815 }
816 $output = implode($cArr, '<br />') . '<br />';
817 return $output;
818 }
819
820 /**
821 * [Describe function...]
822 *
823 * @param [type] $id: ...
824 * @param [type] $template_uid: ...
825 * @return [type] ...
826 * @todo Define visibility
827 */
828 public function ext_getFirstTemplate($id, $template_uid = 0) {
829 // Query is taken from the runThroughTemplates($theRootLine) function in the parent class.
830 if (intval($id)) {
831 if ($template_uid) {
832 $addC = ' AND uid=' . $template_uid;
833 }
834 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'pid=' . intval($id) . $addC . ' ' . $this->whereClause, '', 'sorting', '1');
835 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
836 \TYPO3\CMS\Backend\Utility\BackendUtility::workspaceOL('sys_template', $row);
837 $GLOBALS['TYPO3_DB']->sql_free_result($res);
838 // Returns the template row if found.
839 return $row;
840 }
841 }
842
843 /**
844 * [Describe function...]
845 *
846 * @param [type] $id: ...
847 * @return [type] ...
848 * @todo Define visibility
849 */
850 public function ext_getAllTemplates($id) {
851 // Query is taken from the runThroughTemplates($theRootLine) function in the parent class.
852 if (intval($id)) {
853 $outRes = array();
854 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'pid=' . intval($id) . ' ' . $this->whereClause, '', 'sorting');
855 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
856 \TYPO3\CMS\Backend\Utility\BackendUtility::workspaceOL('sys_template', $row);
857 if (is_array($row)) {
858 $outRes[] = $row;
859 }
860 }
861 $GLOBALS['TYPO3_DB']->sql_free_result($res);
862 // Returns the template rows in an array.
863 return $outRes;
864 }
865 }
866
867 /**
868 * This function compares the flattened constants (default and all).
869 * Returns an array with the constants from the whole template which may be edited by the module.
870 *
871 * @param [type] $default: ...
872 * @return [type] ...
873 * @todo Define visibility
874 */
875 public function ext_compareFlatSetups($default) {
876 $editableComments = array();
877 foreach ($this->flatSetup as $const => $value) {
878 if (substr($const, -2) != '..' && isset($this->flatSetup[$const . '..'])) {
879 $comment = trim($this->flatSetup[$const . '..']);
880 $c_arr = explode(LF, $comment);
881 foreach ($c_arr as $k => $v) {
882 $line = trim(preg_replace('/^[#\\/]*/', '', $v));
883 if ($line) {
884 $parts = explode(';', $line);
885 foreach ($parts as $par) {
886 if (strstr($par, '=')) {
887 $keyValPair = explode('=', $par, 2);
888 switch (trim(strtolower($keyValPair[0]))) {
889 case 'type':
890 // Type:
891 $editableComments[$const]['type'] = trim($keyValPair[1]);
892 break;
893 case 'cat':
894 // List of categories.
895 $catSplit = explode('/', strtolower($keyValPair[1]));
896 $editableComments[$const]['cat'] = trim($catSplit[0]);
897 // This is the subcategory. Must be a key in $this->subCategories[]. catSplit[2] represents the search-order within the subcat.
898 $catSplit[1] = trim($catSplit[1]);
899 if ($catSplit[1] && isset($this->subCategories[$catSplit[1]])) {
900 $editableComments[$const]['subcat_name'] = $catSplit[1];
901 $editableComments[$const]['subcat'] = $this->subCategories[$catSplit[1]][1] . '/' . $catSplit[1] . '/' . trim($catSplit[2]) . 'z';
902 } else {
903 $editableComments[$const]['subcat'] = 'x' . '/' . trim($catSplit[2]) . 'z';
904 }
905 break;
906 case 'label':
907 // Label
908 $editableComments[$const]['label'] = trim($keyValPair[1]);
909 break;
910 case 'customsubcategory':
911 // Custom subCategory label
912 $customSubcategory = explode('=', $keyValPair[1], 2);
913 if (trim($customSubcategory[0])) {
914 $subCategoryKey = strtolower($customSubcategory[0]);
915 $this->subCategories[$subCategoryKey][0] = $GLOBALS['LANG']->sL($customSubcategory[1]);
916 }
917 break;
918 }
919 }
920 }
921 }
922 }
923 }
924 if (isset($editableComments[$const])) {
925 $editableComments[$const]['name'] = $const;
926 $editableComments[$const]['value'] = trim($value);
927 if (isset($default[$const])) {
928 $editableComments[$const]['default_value'] = trim($default[$const]);
929 }
930 }
931 }
932 return $editableComments;
933 }
934
935 /**
936 * [Describe function...]
937 *
938 * @param [type] $editConstArray: ...
939 * @return [type] ...
940 * @todo Define visibility
941 */
942 public function ext_categorizeEditableConstants($editConstArray) {
943 // Runs through the available constants and fills the $this->categories array with pointers and priority-info
944 foreach ($editConstArray as $constName => $constData) {
945 if (!$constData['type']) {
946 $constData['type'] = 'string';
947 }
948 $cats = explode(',', $constData['cat']);
949 // if = only one category, while allows for many. We have agreed on only one category is the most basic way...
950 foreach ($cats as $theCat) {
951 $theCat = trim($theCat);
952 if ($theCat) {
953 $this->categories[$theCat][$constName] = $constData['subcat'];
954 }
955 }
956 }
957 }
958
959 /**
960 * [Describe function...]
961 *
962 * @return [type] ...
963 * @todo Define visibility
964 */
965 public function ext_getCategoryLabelArray() {
966 // Returns array used for labels in the menu.
967 $retArr = array();
968 foreach ($this->categories as $k => $v) {
969 if (count($v)) {
970 $retArr[$k] = strtoupper($k) . ' (' . count($v) . ')';
971 }
972 }
973 return $retArr;
974 }
975
976 /**
977 * [Describe function...]
978 *
979 * @param [type] $type: ...
980 * @return [type] ...
981 * @todo Define visibility
982 */
983 public function ext_getTypeData($type) {
984 $retArr = array();
985 $type = trim($type);
986 if (!$type) {
987 $retArr['type'] = 'string';
988 } else {
989 $m = strcspn($type, ' [');
990 $retArr['type'] = strtolower(substr($type, 0, $m));
991 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList('int,options,file,boolean,offset,user', $retArr['type'])) {
992 $p = trim(substr($type, $m));
993 $reg = array();
994 preg_match('/\\[(.*)\\]/', $p, $reg);
995 $p = trim($reg[1]);
996 if ($p) {
997 $retArr['paramstr'] = $p;
998 switch ($retArr['type']) {
999 case 'int':
1000 if (substr($retArr['paramstr'], 0, 1) == '-') {
1001 $retArr['params'] = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode('-', substr($retArr['paramstr'], 1));
1002 $retArr['params'][0] = intval('-' . $retArr['params'][0]);
1003 } else {
1004 $retArr['params'] = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode('-', $retArr['paramstr']);
1005 }
1006 $retArr['paramstr'] = $retArr['params'][0] . ' - ' . $retArr['params'][1];
1007 break;
1008 case 'options':
1009 $retArr['params'] = explode(',', $retArr['paramstr']);
1010 break;
1011 }
1012 }
1013 }
1014 }
1015 return $retArr;
1016 }
1017
1018 /**
1019 * [Describe function...]
1020 *
1021 * @param [type] $category: ...
1022 * @return [type] ...
1023 * @todo Define visibility
1024 */
1025 public function ext_getTSCE_config($category) {
1026 $catConf = $this->setup['constants']['TSConstantEditor.'][$category . '.'];
1027 $out = array();
1028 if (is_array($catConf)) {
1029 foreach ($catConf as $key => $val) {
1030 switch ($key) {
1031 case 'image':
1032 $out['imagetag'] = $this->ext_getTSCE_config_image($catConf['image']);
1033 break;
1034 case 'description':
1035
1036 case 'bulletlist':
1037
1038 case 'header':
1039 $out[$key] = $val;
1040 break;
1041 default:
1042 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($key)) {
1043 $constRefs = explode(',', $val);
1044 foreach ($constRefs as $const) {
1045 $const = trim($const);
1046 if ($const && $const <= 20) {
1047 $out['constants'][$const] .= $this->ext_getKeyImage($key);
1048 }
1049 }
1050 }
1051 break;
1052 }
1053 }
1054 }
1055 $this->helpConfig = $out;
1056 }
1057
1058 /**
1059 * [Describe function...]
1060 *
1061 * @param [type] $key: ...
1062 * @return [type] ...
1063 * @todo Define visibility
1064 */
1065 public function ext_getKeyImage($key) {
1066 return '<img src="' . $this->ext_localWebGfxPrefix . 'gfx/' . $key . '.gif" align="top" hspace=2>';
1067 }
1068
1069 /**
1070 * [Describe function...]
1071 *
1072 * @param [type] $imgConf: ...
1073 * @return [type] ...
1074 * @todo Define visibility
1075 */
1076 public function ext_getTSCE_config_image($imgConf) {
1077 if (substr($imgConf, 0, 4) == 'gfx/') {
1078 $iFile = $this->ext_localGfxPrefix . $imgConf;
1079 $tFile = $this->ext_localWebGfxPrefix . $imgConf;
1080 } elseif (substr($imgConf, 0, 4) == 'EXT:') {
1081 $iFile = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($imgConf);
1082 if ($iFile) {
1083 $f = substr($iFile, strlen(PATH_site));
1084 $tFile = $GLOBALS['BACK_PATH'] . '../' . $f;
1085 }
1086 }
1087 $imageInfo = @getImagesize($iFile);
1088 return '<img src="' . $tFile . '" ' . $imageInfo[3] . '>';
1089 }
1090
1091 /**
1092 * [Describe function...]
1093 *
1094 * @param [type] $params: ...
1095 * @return [type] ...
1096 * @todo Define visibility
1097 */
1098 public function ext_fNandV($params) {
1099 $fN = 'data[' . $params['name'] . ']';
1100 $fV = $params['value'];
1101 // Values entered from the constantsedit cannot be constants! 230502; removed \{ and set {
1102 if (preg_match('/^{[\\$][a-zA-Z0-9\\.]*}$/', trim($fV), $reg)) {
1103 $fV = '';
1104 }
1105 $fV = htmlspecialchars($fV);
1106 return array($fN, $fV, $params);
1107 }
1108
1109 /**
1110 * This functions returns the HTML-code that creates the editor-layout of the module.
1111 *
1112 * @param [type] $theConstants: ...
1113 * @param [type] $category: ...
1114 * @return [type] ...
1115 * @todo Define visibility
1116 */
1117 public function ext_printFields($theConstants, $category) {
1118 reset($theConstants);
1119 $output = '<script type="text/javascript" src="' . $GLOBALS['BACK_PATH'] . 'js/constantEditor.js"></script>
1120 ';
1121 $subcat = '';
1122 if (is_array($this->categories[$category])) {
1123 $help = $this->helpConfig;
1124 if (!$this->doNotSortCategoriesBeforeMakingForm) {
1125 asort($this->categories[$category]);
1126 }
1127 foreach ($this->categories[$category] as $name => $type) {
1128 $params = $theConstants[$name];
1129 if (is_array($params)) {
1130 if ($subcat != $params['subcat_name']) {
1131 $subcat = $params['subcat_name'];
1132 $subcat_name = $params['subcat_name'] ? $this->subCategories[$params['subcat_name']][0] : 'Others';
1133 $output .= '<h3 class="typo3-tstemplate-ceditor-subcat">' . $subcat_name . '</h3>';
1134 }
1135 $label = $GLOBALS['LANG']->sL($params['label']);
1136 $label_parts = explode(':', $label, 2);
1137 if (count($label_parts) == 2) {
1138 $head = trim($label_parts[0]);
1139 $body = trim($label_parts[1]);
1140 } else {
1141 $head = trim($label_parts[0]);
1142 $body = '';
1143 }
1144 if (strlen($head) > 35) {
1145 if (!$body) {
1146 $body = $head;
1147 }
1148 $head = \TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($head, 35);
1149 }
1150 $typeDat = $this->ext_getTypeData($params['type']);
1151 $checked = '';
1152 $p_field = '';
1153 $raname = substr(md5($params['name']), 0, 10);
1154 $aname = '\'' . $raname . '\'';
1155 list($fN, $fV, $params) = $this->ext_fNandV($params);
1156 switch ($typeDat['type']) {
1157 case 'int':
1158
1159 case 'int+':
1160 $p_field = '<input id="' . $fN . '" type="text" name="' . $fN . '" value="' . $fV . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(5) . ' onChange="uFormUrl(' . $aname . ')" />';
1161 if ($typeDat['paramstr']) {
1162 $p_field .= ' Range: ' . $typeDat['paramstr'];
1163 } elseif ($typeDat['type'] == 'int+') {
1164 $p_field .= ' Range: 0 - ';
1165 } else {
1166 $p_field .= ' (Integer)';
1167 }
1168 break;
1169 case 'color':
1170 $colorNames = explode(',', ',' . $this->HTMLcolorList);
1171 $p_field = '';
1172 foreach ($colorNames as $val) {
1173 $sel = '';
1174 if ($val == strtolower($params['value'])) {
1175 $sel = ' selected';
1176 }
1177 $p_field .= '<option value="' . htmlspecialchars($val) . '"' . $sel . '>' . $val . '</option>';
1178 }
1179 $p_field = '<select id="select-' . $fN . '" rel="' . $fN . '" name="C' . $fN . '" class="typo3-tstemplate-ceditor-color-select" onChange="uFormUrl(' . $aname . ');">' . $p_field . '</select>';
1180 $p_field .= '<input type="text" id="input-' . $fN . '" rel="' . $fN . '" name="' . $fN . '" class="typo3-tstemplate-ceditor-color-input" value="' . $fV . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(7) . ' onChange="uFormUrl(' . $aname . ')" />';
1181 break;
1182 case 'wrap':
1183 $wArr = explode('|', $fV);
1184 $p_field = '<input type="text" id="' . $fN . '" name="' . $fN . '" value="' . $wArr[0] . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(29) . ' onChange="uFormUrl(' . $aname . ')" />';
1185 $p_field .= ' | ';
1186 $p_field .= '<input type="text" name="W' . $fN . '" value="' . $wArr[1] . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(15) . ' onChange="uFormUrl(' . $aname . ')" />';
1187 break;
1188 case 'offset':
1189 $wArr = explode(',', $fV);
1190 $labels = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $typeDat['paramstr']);
1191 $p_field = ($labels[0] ? $labels[0] : 'x') . ':<input type="text" name="' . $fN . '" value="' . $wArr[0] . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(4) . ' onChange="uFormUrl(' . $aname . ')" />';
1192 $p_field .= ' , ';
1193 $p_field .= ($labels[1] ? $labels[1] : 'y') . ':<input type="text" name="W' . $fN . '" value="' . $wArr[1] . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(4) . ' onChange="uFormUrl(' . $aname . ')" />';
1194 $labelsCount = count($labels);
1195 for ($aa = 2; $aa < $labelsCount; $aa++) {
1196 if ($labels[$aa]) {
1197 $p_field .= ' , ' . $labels[$aa] . ':<input type="text" name="W' . $aa . $fN . '" value="' . $wArr[$aa] . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(4) . ' onChange="uFormUrl(' . $aname . ')" />';
1198 } else {
1199 $p_field .= '<input type="hidden" name="W' . $aa . $fN . '" value="' . $wArr[$aa] . '" />';
1200 }
1201 }
1202 break;
1203 case 'options':
1204 if (is_array($typeDat['params'])) {
1205 $p_field = '';
1206 foreach ($typeDat['params'] as $val) {
1207 $vParts = explode('=', $val, 2);
1208 $label = $vParts[0];
1209 $val = isset($vParts[1]) ? $vParts[1] : $vParts[0];
1210 // option tag:
1211 $sel = '';
1212 if ($val == $params['value']) {
1213 $sel = ' selected';
1214 }
1215 $p_field .= '<option value="' . htmlspecialchars($val) . '"' . $sel . '>' . $GLOBALS['LANG']->sL($label) . '</option>';
1216 }
1217 $p_field = '<select id="' . $fN . '" name="' . $fN . '" onChange="uFormUrl(' . $aname . ')">' . $p_field . '</select>';
1218 }
1219 break;
1220 case 'boolean':
1221 $p_field = '<input type="hidden" name="' . $fN . '" value="0" />';
1222 $sel = '';
1223 if ($fV) {
1224 $sel = ' checked';
1225 }
1226 $p_field .= '<input id="' . $fN . '" type="checkbox" name="' . $fN . '" value="' . ($typeDat['paramstr'] ? $typeDat['paramstr'] : 1) . '"' . $sel . ' onClick="uFormUrl(' . $aname . ')" />';
1227 break;
1228 case 'comment':
1229 $p_field = '<input type="hidden" name="' . $fN . '" value="#" />';
1230 $sel = '';
1231 if (!$fV) {
1232 $sel = ' checked';
1233 }
1234 $p_field .= '<input id="' . $fN . '" type="checkbox" name="' . $fN . '" value=""' . $sel . ' onClick="uFormUrl(' . $aname . ')" />';
1235 break;
1236 case 'file':
1237 $p_field = '<option value=""></option>';
1238 $theImage = '';
1239 // extensionlist
1240 $extList = $typeDat['paramstr'];
1241 $p_field = '<option value="">(' . $extList . ')</option>';
1242 if ($extList == 'IMAGE_EXT') {
1243 $extList = $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
1244 }
1245 if (trim($params['value'])) {
1246 $val = $params['value'];
1247 $p_field .= '<option value=""></option>';
1248 $p_field .= '<option value="' . htmlspecialchars($val) . '" selected>' . $val . '</option>';
1249 }
1250 $p_field = '<select id="' . $fN . '" name="' . $fN . '" onChange="uFormUrl(' . $aname . ')">' . $p_field . '</select>';
1251 $p_field .= $theImage;
1252 break;
1253 case 'user':
1254 $userFunction = $typeDat['paramstr'];
1255 $userFunctionParams = array('fieldName' => $fN, 'fieldValue' => $fV);
1256 $p_field = \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($userFunction, $userFunctionParams, $this, '');
1257 break;
1258 case 'small':
1259
1260 default:
1261 $fwidth = $typeDat['type'] == 'small' ? 10 : 46;
1262 $p_field = '<input id="' . $fN . '" type="text" name="' . $fN . '" value="' . $fV . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth($fwidth) . ' onChange="uFormUrl(' . $aname . ')" />';
1263 break;
1264 }
1265 // Define default names and IDs
1266 $userTyposcriptID = 'userTS-' . $params['name'];
1267 $defaultTyposcriptID = 'defaultTS-' . $params['name'];
1268 $checkboxName = 'check[' . $params['name'] . ']';
1269 $checkboxID = $checkboxName;
1270 // Handle type=color specially
1271 if ($typeDat['type'] == 'color' && substr($params['value'], 0, 2) != '{$') {
1272 $color = '<div id="colorbox-' . $fN . '" class="typo3-tstemplate-ceditor-colorblock" style="background-color:' . $params['value'] . ';">&nbsp;</div>';
1273 } else {
1274 $color = '';
1275 }
1276 if (!$this->ext_dontCheckIssetValues) {
1277 // Set the default styling options
1278 if (isset($this->objReg[$params['name']])) {
1279 $checkboxValue = 'checked';
1280 $userTyposcriptStyle = '';
1281 $defaultTyposcriptStyle = 'style="display:none;"';
1282 } else {
1283 $checkboxValue = '';
1284 $userTyposcriptStyle = 'style="display:none;"';
1285 $defaultTyposcriptStyle = '';
1286 }
1287 $deleteIconHTML = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-undo', array(
1288 'class' => 'typo3-tstemplate-ceditor-control undoIcon',
1289 'alt' => 'Revert to default Constant',
1290 'title' => 'Revert to default Constant',
1291 'rel' => $params['name']
1292 ));
1293 $editIconHTML = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-open', array(
1294 'class' => 'typo3-tstemplate-ceditor-control editIcon',
1295 'alt' => 'Edit this Constant',
1296 'title' => 'Edit this Constant',
1297 'rel' => $params['name']
1298 ));
1299 $constantCheckbox = '<input type="hidden" name="' . $checkboxName . '" id="' . $checkboxID . '" value="' . $checkboxValue . '"/>';
1300 // If there's no default value for the field, use a static label.
1301 if (!$params['default_value']) {
1302 $params['default_value'] = '[Empty]';
1303 }
1304 $constantDefaultRow = '<div class="typo3-tstemplate-ceditor-row" id="' . $defaultTyposcriptID . '" ' . $defaultTyposcriptStyle . '>' . $editIconHTML . htmlspecialchars($params['default_value']) . $color . '</div>';
1305 }
1306 $constantEditRow = '<div class="typo3-tstemplate-ceditor-row" id="' . $userTyposcriptID . '" ' . $userTyposcriptStyle . '>' . $deleteIconHTML . $p_field . $color . '</div>';
1307 $constantLabel = '<dt class="typo3-tstemplate-ceditor-label">' . htmlspecialchars($head) . '</dt>';
1308 $constantName = '<dt class="typo3-dimmed">[' . $params['name'] . ']</dt>';
1309 $constantDescription = $body ? '<dd>' . htmlspecialchars($body) . '</dd>' : '';
1310 $constantData = '<dd>' . $constantCheckbox . $constantEditRow . $constantDefaultRow . '</dd>';
1311 $output .= '<a name="' . $raname . '"></a>' . $help['constants'][$params['name']];
1312 $output .= '<dl class="typo3-tstemplate-ceditor-constant">' . $constantLabel . $constantName . $constantDescription . $constantData . '</dl>';
1313 } else {
1314 debug('Error. Constant did not exist. Should not happen.');
1315 }
1316 }
1317 }
1318 return $output;
1319 }
1320
1321 /***************************
1322 *
1323 * Processing input values
1324 *
1325 ***************************/
1326 /**
1327 * @param [type] $constants: ...
1328 * @return [type] ...
1329 * @todo Define visibility
1330 */
1331 public function ext_regObjectPositions($constants) {
1332 // This runs through the lines of the constants-field of the active template and registers the constants-names
1333 // and linepositions in an array, $this->objReg
1334 $this->raw = explode(LF, $constants);
1335 $this->rawP = 0;
1336 // Resetting the objReg if the divider is found!!
1337 $this->objReg = array();
1338 $this->ext_regObjects('');
1339 }
1340
1341 /**
1342 * [Describe function...]
1343 *
1344 * @param [type] $pre: ...
1345 * @return [type] ...
1346 * @todo Define visibility
1347 */
1348 public function ext_regObjects($pre) {
1349 // Works with regObjectPositions. "expands" the names of the TypoScript objects
1350 while (isset($this->raw[$this->rawP])) {
1351 $line = ltrim($this->raw[$this->rawP]);
1352 if (strstr($line, $this->edit_divider)) {
1353 // Resetting the objReg if the divider is found!!
1354 $this->objReg = array();
1355 }
1356 $this->rawP++;
1357 if ($line) {
1358 if (substr($line, 0, 1) == '[') {
1359
1360 } elseif (strcspn($line, '}#/') != 0) {
1361 $varL = strcspn($line, ' {=<');
1362 $var = substr($line, 0, $varL);
1363 $line = ltrim(substr($line, $varL));
1364 switch (substr($line, 0, 1)) {
1365 case '=':
1366 $this->objReg[$pre . $var] = $this->rawP - 1;
1367 break;
1368 case '{':
1369 $this->ext_inBrace++;
1370 $this->ext_regObjects($pre . $var . '.');
1371 break;
1372 }
1373 $this->lastComment = '';
1374 } elseif (substr($line, 0, 1) == '}') {
1375 $this->lastComment = '';
1376 $this->ext_inBrace--;
1377 if ($this->ext_inBrace < 0) {
1378 $this->ext_inBrace = 0;
1379 } else {
1380 break;
1381 }
1382 }
1383 }
1384 }
1385 }
1386
1387 /**
1388 * [Describe function...]
1389 *
1390 * @param [type] $key: ...
1391 * @param [type] $var: ...
1392 * @return [type] ...
1393 * @todo Define visibility
1394 */
1395 public function ext_putValueInConf($key, $var) {
1396 // Puts the value $var to the TypoScript value $key in the current lines of the templates.
1397 // If the $key is not found in the template constants field, a new line is inserted in the bottom.
1398 $theValue = ' ' . trim($var);
1399 if (isset($this->objReg[$key])) {
1400 $lineNum = $this->objReg[$key];
1401 $parts = explode('=', $this->raw[$lineNum], 2);
1402 if (count($parts) == 2) {
1403 $parts[1] = $theValue;
1404 }
1405 $this->raw[$lineNum] = implode($parts, '=');
1406 } else {
1407 $this->raw[] = $key . ' =' . $theValue;
1408 }
1409 $this->changed = 1;
1410 }
1411
1412 /**
1413 * [Describe function...]
1414 *
1415 * @param [type] $key: ...
1416 * @return [type] ...
1417 * @todo Define visibility
1418 */
1419 public function ext_removeValueInConf($key) {
1420 // Removes the value in the configuration
1421 if (isset($this->objReg[$key])) {
1422 $lineNum = $this->objReg[$key];
1423 unset($this->raw[$lineNum]);
1424 }
1425 $this->changed = 1;
1426 }
1427
1428 /**
1429 * [Describe function...]
1430 *
1431 * @param [type] $arr: ...
1432 * @param [type] $settings: ...
1433 * @return [type] ...
1434 * @todo Define visibility
1435 */
1436 public function ext_depthKeys($arr, $settings) {
1437 $tsbrArray = array();
1438 foreach ($arr as $theK => $theV) {
1439 $theKeyParts = explode('.', $theK);
1440 $depth = '';
1441 $c = count($theKeyParts);
1442 $a = 0;
1443 foreach ($theKeyParts as $p) {
1444 $a++;
1445 $depth .= ($depth ? '.' : '') . $p;
1446 $tsbrArray[$depth] = $c == $a ? $theV : 1;
1447 }
1448 }
1449 // Modify settings
1450 foreach ($tsbrArray as $theK => $theV) {
1451 if ($theV) {
1452 $settings[$theK] = 1;
1453 } else {
1454 unset($settings[$theK]);
1455 }
1456 }
1457 return $settings;
1458 }
1459
1460 /**
1461 * [Describe function...]
1462 *
1463 * @param [type] $http_post_vars: ...
1464 * @param array (not used anymore)
1465 * @param [type] $theConstants: ...
1466 * @param [type] $tplRow: ...
1467 * @return [type] ...
1468 * @todo Define visibility
1469 */
1470 public function ext_procesInput($http_post_vars, $http_post_files, $theConstants, $tplRow) {
1471 $data = $http_post_vars['data'];
1472 $check = $http_post_vars['check'];
1473 $Wdata = $http_post_vars['Wdata'];
1474 $W2data = $http_post_vars['W2data'];
1475 $W3data = $http_post_vars['W3data'];
1476 $W4data = $http_post_vars['W4data'];
1477 $W5data = $http_post_vars['W5data'];
1478 if (is_array($data)) {
1479 foreach ($data as $key => $var) {
1480 if (isset($theConstants[$key])) {
1481 // If checkbox is set, update the value
1482 if ($this->ext_dontCheckIssetValues || isset($check[$key])) {
1483 // Exploding with linebreak, just to make sure that no multiline input is given!
1484 list($var) = explode(LF, $var);
1485 $typeDat = $this->ext_getTypeData($theConstants[$key]['type']);
1486 switch ($typeDat['type']) {
1487 case 'int':
1488 if ($typeDat['paramstr']) {
1489 $var = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($var, $typeDat['params'][0], $typeDat['params'][1]);
1490 } else {
1491 $var = intval($var);
1492 }
1493 break;
1494 case 'int+':
1495 $var = max(0, intval($var));
1496 break;
1497 case 'color':
1498 $col = array();
1499 if ($var && !\TYPO3\CMS\Core\Utility\GeneralUtility::inList($this->HTMLcolorList, strtolower($var))) {
1500 $var = preg_replace('/[^A-Fa-f0-9]*/', '', $var);
1501 $useFulHex = strlen($var) > 3;
1502 $col[] = HexDec(substr($var, 0, 1));
1503 $col[] = HexDec(substr($var, 1, 1));
1504 $col[] = HexDec(substr($var, 2, 1));
1505 if ($useFulHex) {
1506 $col[] = HexDec(substr($var, 3, 1));
1507 $col[] = HexDec(substr($var, 4, 1));
1508 $col[] = HexDec(substr($var, 5, 1));
1509 }
1510 $var = substr(('0' . DecHex($col[0])), -1) . substr(('0' . DecHex($col[1])), -1) . substr(('0' . DecHex($col[2])), -1);
1511 if ($useFulHex) {
1512 $var .= substr(('0' . DecHex($col[3])), -1) . substr(('0' . DecHex($col[4])), -1) . substr(('0' . DecHex($col[5])), -1);
1513 }
1514 $var = '#' . strtoupper($var);
1515 }
1516 break;
1517 case 'comment':
1518 if ($var) {
1519 $var = '#';
1520 } else {
1521 $var = '';
1522 }
1523 break;
1524 case 'wrap':
1525 if (isset($Wdata[$key])) {
1526 $var .= '|' . $Wdata[$key];
1527 }
1528 break;
1529 case 'offset':
1530 if (isset($Wdata[$key])) {
1531 $var = intval($var) . ',' . intval($Wdata[$key]);
1532 if (isset($W2data[$key])) {
1533 $var .= ',' . intval($W2data[$key]);
1534 if (isset($W3data[$key])) {
1535 $var .= ',' . intval($W3data[$key]);
1536 if (isset($W4data[$key])) {
1537 $var .= ',' . intval($W4data[$key]);
1538 if (isset($W5data[$key])) {
1539 $var .= ',' . intval($W5data[$key]);
1540 }
1541 }
1542 }
1543 }
1544 }
1545 break;
1546 case 'boolean':
1547 if ($var) {
1548 $var = $typeDat['paramstr'] ? $typeDat['paramstr'] : 1;
1549 }
1550 break;
1551 }
1552 if ($this->ext_printAll || strcmp($theConstants[$key]['value'], $var)) {
1553 // Put value in, if changed.
1554 $this->ext_putValueInConf($key, $var);
1555 }
1556 // Remove the entry because it has been "used"
1557 unset($check[$key]);
1558 } else {
1559 $this->ext_removeValueInConf($key);
1560 }
1561 }
1562 }
1563 }
1564 // Remaining keys in $check indicates fields that are just clicked "on" to be edited. Therefore we get the default value and puts that in the template as a start...
1565 if (!$this->ext_dontCheckIssetValues && is_array($check)) {
1566 foreach ($check as $key => $var) {
1567 if (isset($theConstants[$key])) {
1568 $dValue = $theConstants[$key]['default_value'];
1569 $this->ext_putValueInConf($key, $dValue);
1570 }
1571 }
1572 }
1573 }
1574
1575 /**
1576 * [Describe function...]
1577 *
1578 * @param [type] $id: ...
1579 * @param [type] $perms_clause: ...
1580 * @return [type] ...
1581 * @todo Define visibility
1582 */
1583 public function ext_prevPageWithTemplate($id, $perms_clause) {
1584 $rootLine = \TYPO3\CMS\Backend\Utility\BackendUtility::BEgetRootLine($id, $perms_clause ? ' AND ' . $perms_clause : '');
1585 foreach ($rootLine as $p) {
1586 if ($this->ext_getFirstTemplate($p['uid'])) {
1587 return $p;
1588 }
1589 }
1590 }
1591
1592 }
1593
1594
1595 ?>