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