‪TYPO3CMS  9.5
ExtendedTemplateService.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
31 
39 {
43  public ‪$categories = [
44  'basic' => [],
45  // 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.
46  'menu' => [],
47  // Menu setup. This includes fontfiles, sizes, background images. Depending on the menutype.
48  'content' => [],
49  // All constants related to the display of pagecontent elements
50  'page' => [],
51  // General configuration like metatags, link targets
52  'advanced' => [],
53  // Advanced functions, which are used very seldom.
54  'all' => []
55  ];
56 
62  protected ‪$categoryLabels = [];
63 
69  public ‪$subCategories = [
70  // Standard categories:
71  'enable' => ['Enable features', 'a'],
72  'dims' => ['Dimensions, widths, heights, pixels', 'b'],
73  'file' => ['Files', 'c'],
74  'typo' => ['Typography', 'd'],
75  'color' => ['Colors', 'e'],
76  'links' => ['Links and targets', 'f'],
77  'language' => ['Language specific constants', 'g'],
78  // subcategories based on the default content elements
79  'cheader' => ['Content: \'Header\'', 'ma'],
80  'cheader_g' => ['Content: \'Header\', Graphical', 'ma'],
81  'ctext' => ['Content: \'Text\'', 'mb'],
82  'cimage' => ['Content: \'Image\'', 'md'],
83  'ctextmedia' => ['Content: \'Textmedia\'', 'ml'],
84  'cbullets' => ['Content: \'Bullet list\'', 'me'],
85  'ctable' => ['Content: \'Table\'', 'mf'],
86  'cuploads' => ['Content: \'Filelinks\'', 'mg'],
87  'cmultimedia' => ['Content: \'Multimedia\'', 'mh'],
88  'cmedia' => ['Content: \'Media\'', 'mr'],
89  'cmailform' => ['Content: \'Form\'', 'mi'],
90  'csearch' => ['Content: \'Search\'', 'mj'],
91  'clogin' => ['Content: \'Login\'', 'mk'],
92  'cmenu' => ['Content: \'Menu/Sitemap\'', 'mm'],
93  'cshortcut' => ['Content: \'Insert records\'', 'mn'],
94  'clist' => ['Content: \'List of records\'', 'mo'],
95  'chtml' => ['Content: \'HTML\'', 'mq']
96  ];
97 
103  public ‪$ext_inBrace = 0;
104 
110  public ‪$tsbrowser_searchKeys = [];
111 
115  public ‪$tsbrowser_depthKeys = [];
116 
120  public ‪$constantMode = '';
121 
125  public ‪$regexMode = '';
126 
130  public ‪$fixedLgd = '';
131 
135  public ‪$ext_lineNumberOffset = 0;
136 
140  public ‪$ext_expandAllNotes = 0;
141 
145  public ‪$ext_noPMicons = 0;
146 
150  public ‪$ext_listOfTemplatesArr = [];
151 
156 
162  public ‪$ext_dontCheckIssetValues = 0;
163 
167  public ‪$ext_printAll = 0;
168 
172  public ‪$ext_CEformName = 'forms[0]';
173 
178 
184  public ‪$templateTitles = [];
185 
189  protected ‪$lnToScript;
190 
195 
200 
204  public ‪$bType = '';
205 
209  public ‪$linkObjects = false;
210 
214  public ‪$changed = false;
215 
219  protected ‪$objReg = [];
220 
224  public ‪$raw = [];
225 
229  public ‪$rawP = 0;
230 
234  public ‪$lastComment = '';
235 
239  protected ‪$inlineJavaScript = [];
240 
244  public function ‪__construct(‪Context ‪$context = null)
245  {
246  parent::__construct(‪$context);
247  // Disabled in backend context
248  $this->tt_track = false;
249  $this->verbose = false;
250  }
251 
257  public function ‪getInlineJavaScript()
258  {
260  }
261 
268  public function ‪substituteConstants($all)
269  {
270  return preg_replace_callback('/\\{\\$(.[^}]+)\\}/', [$this, 'substituteConstantsCallBack'], $all);
271  }
272 
280  public function ‪substituteConstantsCallBack($matches)
281  {
282  $marker = substr(md5($matches[0]), 0, 6);
283  switch ($this->constantMode) {
284  case 'const':
285  $ret_val = isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? '##' . $marker . '_B##' . $this->flatSetup[$matches[1]] . '##' . $marker . '_M##' . $matches[0] . '##' . $marker . '_E##' : $matches[0];
286  break;
287  case 'subst':
288  $ret_val = isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? '##' . $marker . '_B##' . $matches[0] . '##' . $marker . '_M##' . $this->flatSetup[$matches[1]] . '##' . $marker . '_E##' : $matches[0];
289  break;
290  case 'untouched':
291  $ret_val = $matches[0];
292  break;
293  default:
294  $ret_val = isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? $this->flatSetup[$matches[1]] : $matches[0];
295  }
296  return $ret_val;
297  }
298 
306  public function ‪substituteCMarkers($all)
307  {
308  switch ($this->constantMode) {
309  case 'const':
310  case 'subst':
311  $all = preg_replace(
312  '/##[a-z0-9]{6}_B##(.*?)##[a-z0-9]{6}_M##(.*?)##[a-z0-9]{6}_E##/',
313  '<strong class="text-success" data-toggle="tooltip" data-placement="top" data-title="$1" title="$1">$2</strong>',
314  $all
315  );
316  break;
317  default:
318  }
319  return $all;
320  }
321 
328  public function ‪generateConfig_constants()
329  {
330  // These vars are also set lateron...
331  $this->setup['sitetitle'] = ‪$this->sitetitle;
332  // Parse constants
333  ‪$constants = GeneralUtility::makeInstance(Parser\TypoScriptParser::class);
334  // Register comments!
335  ‪$constants->regComments = true;
338  $matchObj = GeneralUtility::makeInstance(ConditionMatcher::class);
339  // Matches ALL conditions in TypoScript
340  $matchObj->setSimulateMatchResult(true);
341  $c = 0;
342  $cc = count($this->constants);
343  $defaultConstants = [];
344  foreach ($this->constants as $str) {
345  $c++;
346  if ($c == $cc) {
347  $this->flatSetup = [];
348  $this->‪flattenSetup(‪$constants->setup, '');
349  $defaultConstants = ‪$this->flatSetup;
350  }
351  ‪$constants->parse($str, $matchObj);
352  }
353  $this->flatSetup = [];
354  $this->‪flattenSetup(‪$constants->setup, '');
355  $this->setup['constants'] = ‪$constants->setup;
356  return $this->‪ext_compareFlatSetups($defaultConstants);
357  }
358 
364  public function ‪ext_getSetup($theSetup, $theKey)
365  {
366  $parts = explode('.', $theKey, 2);
367  if ((string)$parts[0] !== '' && is_array($theSetup[$parts[0] . '.'])) {
368  if (trim($parts[1]) !== '') {
369  return $this->‪ext_getSetup($theSetup[$parts[0] . '.'], trim($parts[1]));
370  }
371  return [$theSetup[$parts[0] . '.'], $theSetup[$parts[0]]];
372  }
373  if (trim($theKey) !== '') {
374  return [[], $theSetup[$theKey]];
375  }
376  return [$theSetup, ''];
377  }
378 
390  public function ‪ext_getObjTree($arr, $depth_in, $depthData, $parentType = '', $parentValue = '', $alphaSort = '0')
391  {
392  $HTML = '';
393  if ($alphaSort == '1') {
394  ksort($arr);
395  }
396  $keyArr_num = [];
397  $keyArr_alpha = [];
399  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
400  foreach ($arr as $key => $value) {
401  // Don't do anything with comments / linenumber registrations...
402  if (substr($key, -2) !== '..') {
403  $key = preg_replace('/\\.$/', '', $key);
404  if (substr($key, -1) !== '.') {
406  $keyArr_num[$key] = $arr[$key];
407  } else {
408  $keyArr_alpha[$key] = $arr[$key];
409  }
410  }
411  }
412  }
413  ksort($keyArr_num);
414  $keyArr = $keyArr_num + $keyArr_alpha;
415  if ($depth_in) {
416  $depth_in = $depth_in . '.';
417  }
418  foreach ($keyArr as $key => $value) {
419  $depth = $depth_in . $key;
420  // This excludes all constants starting with '_' from being shown.
421  if ($this->bType !== 'const' || $depth[0] !== '_') {
422  $goto = substr(md5($depth), 0, 6);
423  $deeper = is_array($arr[$key . '.']) && ($this->tsbrowser_depthKeys[$depth] || ‪$this->ext_expandAllNotes);
424  $PM = is_array($arr[$key . '.']) && !$this->ext_noPMicons ? ($deeper ? 'minus' : 'plus') : 'join';
425  $HTML .= $depthData . '<li><span class="list-tree-group">';
426  if ($PM !== 'join') {
427  $urlParameters = [
428  'id' => (int)GeneralUtility::_GP('id'),
429  'tsbr[' . $depth . ']' => $deeper ? 0 : 1
430  ];
431  if (GeneralUtility::_GP('breakPointLN')) {
432  $urlParameters['breakPointLN'] = GeneralUtility::_GP('breakPointLN');
433  }
434  $aHref = (string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters) . '#' . $goto;
435  $HTML .= '<a class="list-tree-control' . ($PM === 'minus' ? ' list-tree-control-open' : ' list-tree-control-closed') . '" name="' . $goto . '" href="' . htmlspecialchars($aHref) . '"><i class="fa"></i></a>';
436  }
437  $label = $key;
438  // Read only...
439  if (($depth === 'types' || $depth === 'resources' || $depth === 'sitetitle') && $this->bType === 'setup') {
440  $label = '<span style="color: #666666;">' . $label . '</span>';
441  } else {
442  if ($this->linkObjects) {
443  $urlParameters = [
444  'id' => (int)GeneralUtility::_GP('id'),
445  'sObj' => $depth
446  ];
447  if (GeneralUtility::_GP('breakPointLN')) {
448  $urlParameters['breakPointLN'] = GeneralUtility::_GP('breakPointLN');
449  }
450  $aHref = (string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters);
451  if ($this->bType !== 'const') {
452  $ln = is_array($arr[$key . '.ln..']) ? 'Defined in: ' . $this->‪lineNumberToScript($arr[$key . '.ln..']) : 'N/A';
453  } else {
454  $ln = '';
455  }
456  if ($this->tsbrowser_searchKeys[$depth] & 4) {
457  // The key has matched the search string
458  $label = '<strong class="text-danger">' . $label . '</strong>';
459  }
460  $label = '<a href="' . htmlspecialchars($aHref) . '" title="' . htmlspecialchars($depth_in . $key . ' ' . $ln) . '">' . $label . '</a>';
461  }
462  }
463  $HTML .= '<span class="list-tree-label" title="' . htmlspecialchars($depth_in . $key) . '">[' . $label . ']</span>';
464  if (isset($arr[$key])) {
465  $theValue = $arr[$key];
466  if ($this->fixedLgd) {
467  $imgBlocks = ceil(1 + strlen($depthData) / 77);
468  $lgdChars = 68 - ceil(strlen('[' . $key . ']') * 0.8) - $imgBlocks * 3;
469  $theValue = $this->‪ext_fixed_lgd($theValue, $lgdChars);
470  }
471  // The value has matched the search string
472  if ($this->tsbrowser_searchKeys[$depth] & 2) {
473  $HTML .= ' = <span class="list-tree-value text-danger">' . htmlspecialchars($theValue) . '</span>';
474  } else {
475  $HTML .= ' = <span class="list-tree-value">' . htmlspecialchars($theValue) . '</span>';
476  }
477  if ($this->ext_regComments && isset($arr[$key . '..'])) {
478  $comment = $arr[$key . '..'];
479  // Skip INCLUDE_TYPOSCRIPT comments, they are almost useless
480  if (!preg_match('/### <INCLUDE_TYPOSCRIPT:.*/', $comment)) {
481  // Remove linebreaks, replace with ' '
482  $comment = preg_replace('/[\\r\\n]/', ' ', $comment);
483  // Remove # and * if more than twice in a row
484  $comment = preg_replace('/[#\\*]{2,}/', '', $comment);
485  // Replace leading # (just if it exists) and add it again. Result: Every comment should be prefixed by a '#'.
486  $comment = preg_replace('/^[#\\*\\s]+/', '# ', $comment);
487  // Masking HTML Tags: Replace < with &lt; and > with &gt;
488  $comment = htmlspecialchars($comment);
489  $HTML .= ' <i class="text-muted">' . trim($comment) . '</i>';
490  }
491  }
492  }
493  $HTML .= '</span>';
494  if ($deeper) {
495  $HTML .= $this->‪ext_getObjTree($arr[$key . '.'], $depth, $depthData, '', $arr[$key], $alphaSort);
496  }
497  }
498  }
499  if ($HTML !== '') {
500  $HTML = '<ul class="list-tree text-monospace">' . $HTML . '</ul>';
501  }
502 
503  return $HTML;
504  }
505 
516  public function ‪lineNumberToScript(array $lnArr)
517  {
518  // On the first call, construct the lnToScript array.
519  if (!is_array($this->lnToScript)) {
520  $this->lnToScript = [];
521 
522  // aggregatedTotalLineCount
523  $c = 0;
524  foreach ($this->hierarchyInfo as $templateNumber => $info) {
525  // hierarchyInfo has the number of lines in configLines, but unfortunately this value
526  // was calculated *before* processing of any INCLUDE instructions
527  // for some yet unknown reason we have to add an extra +2 offset
528  $linecountAfterIncludeProcessing = substr_count($this->config[$templateNumber], LF) + 2;
529  $c += $linecountAfterIncludeProcessing;
530  $this->lnToScript[$c] = $info['title'];
531  }
532  }
533 
534  foreach ($lnArr as $k => $ln) {
535  foreach ($this->lnToScript as $endLn => $title) {
536  if ($endLn >= (int)$ln) {
537  $lnArr[$k] = '"' . $title . '", ' . $ln;
538  break;
539  }
540  }
541  }
542 
543  return implode('; ', $lnArr);
544  }
545 
554  public function ‪ext_getSearchKeys($arr, $depth_in, $searchString, $keyArray)
555  {
556  $keyArr = [];
557  foreach ($arr as $key => $value) {
558  $key = preg_replace('/\\.$/', '', $key);
559  if (substr($key, -1) !== '.') {
560  $keyArr[$key] = 1;
561  }
562  }
563  if ($depth_in) {
564  $depth_in = $depth_in . '.';
565  }
566  $searchPattern = '';
567  if ($this->regexMode) {
568  $searchPattern = '/' . addcslashes($searchString, '/') . '/';
569  $matchResult = @preg_match($searchPattern, '');
570  if ($matchResult === false) {
571  throw new Exception(sprintf('Error evaluating regular expression "%s".', $searchPattern), 1446559458);
572  }
573  }
574  foreach ($keyArr as $key => $value) {
575  $depth = $depth_in . $key;
576  $deeper = is_array($arr[$key . '.']);
577  if ($this->regexMode) {
578  // The value has matched
579  if (preg_match($searchPattern, $arr[$key])) {
580  $this->tsbrowser_searchKeys[$depth] += 2;
581  }
582  // The key has matched
583  if (preg_match($searchPattern, $key)) {
584  $this->tsbrowser_searchKeys[$depth] += 4;
585  }
586  // Just open this subtree if the parent key has matched the search
587  if (preg_match($searchPattern, $depth_in)) {
588  $this->tsbrowser_searchKeys[$depth] = 1;
589  }
590  } else {
591  // The value has matched
592  if (stristr($arr[$key], $searchString)) {
593  $this->tsbrowser_searchKeys[$depth] += 2;
594  }
595  // The key has matches
596  if (stristr($key, $searchString)) {
597  $this->tsbrowser_searchKeys[$depth] += 4;
598  }
599  // Just open this subtree if the parent key has matched the search
600  if (stristr($depth_in, $searchString)) {
601  $this->tsbrowser_searchKeys[$depth] = 1;
602  }
603  }
604  if ($deeper) {
605  $cS = count($this->tsbrowser_searchKeys);
606  $keyArray = $this->‪ext_getSearchKeys($arr[$key . '.'], $depth, $searchString, $keyArray);
607  if ($cS != count($this->tsbrowser_searchKeys)) {
608  $keyArray[$depth] = 1;
609  }
610  }
611  }
612  return $keyArray;
613  }
614 
619  public function ‪ext_getRootlineNumber($pid)
620  {
621  if ($pid) {
622  foreach ($this->‪getRootLine() as $key => $val) {
623  if ((int)$val['uid'] === (int)$pid) {
624  return (int)$key;
625  }
626  }
627  }
628  return -1;
629  }
630 
638  public function ‪ext_getTemplateHierarchyArr($arr, $depthData, $keyArray, $first = 0)
639  {
640  $keyArr = [];
641  foreach ($arr as $key => $value) {
642  $key = preg_replace('/\\.$/', '', $key);
643  if (substr($key, -1) !== '.') {
644  $keyArr[$key] = 1;
645  }
646  }
647  $a = 0;
648  $c = count($keyArr);
650  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
652  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
653  foreach ($keyArr as $key => $value) {
654  $HTML = '';
655  $a++;
656  $deeper = is_array($arr[$key . '.']);
657  $row = $arr[$key];
658  $LN = $a == $c ? 'blank' : 'line';
659  $BTM = $a == $c ? 'top' : '';
660  $HTML .= $depthData;
661  $alttext = '[' . $row['templateID'] . ']';
662  $alttext .= $row['pid'] ? ' - ' . ‪BackendUtility::getRecordPath($row['pid'], '1=1', 20) : '';
663  $icon = strpos($row['templateID'], 'sys') === 0
664  ? '<span title="' . htmlspecialchars($alttext) . '">' . $iconFactory->getIconForRecord('sys_template', $row, ‪Icon::SIZE_SMALL)->render() . '</span>'
665  : '<span title="' . htmlspecialchars($alttext) . '">' . $iconFactory->getIcon('mimetypes-x-content-template-static', ‪Icon::SIZE_SMALL)->render() . '</span>';
666  if (in_array($row['templateID'], $this->clearList_const) || in_array($row['templateID'], $this->clearList_setup)) {
667  $urlParameters = [
668  'id' => (int)GeneralUtility::_GP('id'),
669  'template' => $row['templateID']
670  ];
671  $aHref = (string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters);
672  $A_B = '<a href="' . htmlspecialchars($aHref) . '">';
673  $A_E = '</a>';
674  if (GeneralUtility::_GP('template') == $row['templateID']) {
675  $A_B = '<strong>' . $A_B;
676  $A_E .= '</strong>';
677  }
678  } else {
679  $A_B = '';
680  $A_E = '';
681  }
682  $HTML .= ($first ? '' : '<span class="treeline-icon treeline-icon-join' . $BTM . '"></span>') . $icon . ' ' . $A_B
683  . htmlspecialchars(GeneralUtility::fixed_lgd_cs($row['title'], ‪$GLOBALS['BE_USER']->uc['titleLen']))
684  . $A_E . '&nbsp;&nbsp;';
685  $RL = $this->‪ext_getRootlineNumber($row['pid']);
686  $statusCheckedIcon = $iconFactory->getIcon('status-status-checked', ‪Icon::SIZE_SMALL)->render();
687  $keyArray[] = '<tr>
688  <td class="nowrap">' . $HTML . '</td>
689  <td align="center">' . ($row['root'] ? $statusCheckedIcon : '') . '</td>
690  <td align="center">' . ($row['clConf'] ? $statusCheckedIcon : '') . '</td>
691  <td align="center">' . ($row['clConst'] ? $statusCheckedIcon : '') . '</td>
692  <td align="center">' . ($row['pid'] ?: '') . '</td>
693  <td align="center">' . ($RL >= 0 ? $RL : '') . '</td>
694  <td>' . ($row['next'] ? $row['next'] : '') . '</td>
695  </tr>';
696  if ($deeper) {
697  $keyArray = $this->‪ext_getTemplateHierarchyArr($arr[$key . '.'], $depthData . ($first ? '' : '<span class="treeline-icon treeline-icon-' . $LN . '"></span>'), $keyArray);
698  }
699  }
700  return $keyArray;
701  }
702 
711  public function ‪ext_process_hierarchyInfo(array $depthDataArr, &$pointer)
712  {
713  $parent = $this->hierarchyInfo[$pointer - 1]['templateParent'];
714  while ($pointer > 0 && $this->hierarchyInfo[$pointer - 1]['templateParent'] == $parent) {
715  $pointer--;
716  $row = $this->hierarchyInfo[$pointer];
717  $depthDataArr[$row['templateID']] = $row;
718  unset($this->clearList_setup_temp[$row['templateID']]);
719  unset($this->clearList_const_temp[$row['templateID']]);
720  $this->templateTitles[$row['templateID']] = $row['title'];
721  if ($row['templateID'] == $this->hierarchyInfo[$pointer - 1]['templateParent']) {
722  $depthDataArr[$row['templateID'] . '.'] = $this->‪ext_process_hierarchyInfo([], $pointer);
723  }
724  }
725  return $depthDataArr;
726  }
727 
739  public function ‪ext_outputTS(
740  array ‪$config,
741  $lineNumbers = false,
742  $comments = false,
743  $crop = false,
744  $syntaxHL = false,
745  $syntaxHLBlockmode = 0
746  ) {
747  $all = '';
748  foreach (‪$config as $str) {
749  $all .= '[GLOBAL]' . LF . $str;
750  }
751  if ($syntaxHL) {
752  $tsparser = GeneralUtility::makeInstance(Parser\TypoScriptParser::class);
753  $tsparser->lineNumberOffset = $this->ext_lineNumberOffset + 1;
754  $tsparser->parentObject = $this;
755  return $tsparser->doSyntaxHighlight($all, $lineNumbers ? [$this->ext_lineNumberOffset + 1] : '', $syntaxHLBlockmode);
756  }
757  return $this->‪ext_formatTS($all, $lineNumbers, $comments, $crop);
758  }
759 
769  public function ‪ext_fixed_lgd($string, $chars)
770  {
771  if ($chars >= 4) {
772  if (strlen($string) > $chars) {
773  if (strlen($string) > 24 && preg_match('/^##[a-z0-9]{6}_B##$/', substr($string, 0, 12))) {
774  $string = GeneralUtility::fixed_lgd_cs(substr($string, 12, -12), $chars - 3);
775  $marker = substr(md5($string), 0, 6);
776  return '##' . $marker . '_B##' . $string . '##' . $marker . '_E##';
777  }
778  return GeneralUtility::fixed_lgd_cs($string, $chars - 3);
779  }
780  }
781  return $string;
782  }
783 
789  public function ‪ext_lnBreakPointWrap($lineNumber, $str)
790  {
791  return '<a href="#" id="line-' . $lineNumber . '" onClick="return brPoint(' . $lineNumber . ','
792  . ($this->ext_lineNumberOffset_mode === 'setup' ? 1 : 0) . ');">' . $str . '</a>';
793  }
794 
802  public function ‪ext_formatTS($input, $ln, $comments = true, $crop = false)
803  {
804  $cArr = explode(LF, $input);
805  $n = ceil(log10(count($cArr) + $this->ext_lineNumberOffset));
806  $lineNum = '';
807  foreach ($cArr as $k => $v) {
808  $lln = $k + $this->ext_lineNumberOffset + 1;
809  if ($ln) {
810  $lineNum = $this->‪ext_lnBreakPointWrap($lln, str_replace(' ', '&nbsp;', sprintf('% ' . $n . 'd', $lln))) . ': ';
811  }
812  $v = htmlspecialchars($v);
813  if ($crop) {
814  $v = $this->‪ext_fixed_lgd($v, $ln ? 71 : 77);
815  }
816  $cArr[$k] = $lineNum . str_replace(' ', '&nbsp;', $v);
817  $firstChar = substr(trim($v), 0, 1);
818  if ($firstChar === '[') {
819  $cArr[$k] = '<strong class="text-success">' . $cArr[$k] . '</strong>';
820  } elseif ($firstChar === '/' || $firstChar === '#') {
821  if ($comments) {
822  $cArr[$k] = '<span class="text-muted">' . $cArr[$k] . '</span>';
823  } else {
824  unset($cArr[$k]);
825  }
826  }
827  }
828  ‪$output = implode('<br />', $cArr) . '<br />';
829  return ‪$output;
830  }
831 
841  public function ‪ext_getFirstTemplate($pid, $templateUid = 0)
842  {
843  if (empty($pid)) {
844  return null;
845  }
846 
847  // Query is taken from the runThroughTemplates($theRootLine) function in the parent class.
848  $queryBuilder = $this->‪getTemplateQueryBuilder($pid)
849  ->‪setMaxResults(1);
850  if ($templateUid) {
851  $queryBuilder->‪andWhere(
852  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($templateUid, \PDO::PARAM_INT))
853  );
854  }
855  $row = $queryBuilder->‪execute()->fetch();
856  ‪BackendUtility::workspaceOL('sys_template', $row);
857 
858  return $row;
859  }
860 
867  public function ‪ext_getAllTemplates($pid): array
868  {
869  if (empty($pid)) {
870  return [];
871  }
872  $result = $this->‪getTemplateQueryBuilder($pid)->‪execute();
873  $outRes = [];
874  while ($row = $result->fetch()) {
875  ‪BackendUtility::workspaceOL('sys_template', $row);
876  if (is_array($row)) {
877  $outRes[] = $row;
878  }
879  }
880  return $outRes;
881  }
882 
890  protected function ‪getTemplateQueryBuilder(int $pid): ‪QueryBuilder
891  {
892  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
893  ->getQueryBuilderForTable('sys_template');
894  $queryBuilder->‪getRestrictions()
895  ->‪removeAll()
896  ->‪add(GeneralUtility::makeInstance(DeletedRestriction::class))
897  ->‪add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
898 
899  $queryBuilder->select('*')
900  ->from('sys_template')
901  ->where(
902  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT))
903  );
904  if (!empty(‪$GLOBALS['TCA']['sys_template']['ctrl']['sortby'])) {
905  $queryBuilder->orderBy(‪$GLOBALS['TCA']['sys_template']['ctrl']['sortby']);
906  }
907 
908  return $queryBuilder;
909  }
910 
918  public function ‪ext_compareFlatSetups($default)
919  {
920  $editableComments = [];
921  $counter = 0;
922  foreach ($this->flatSetup as $const => $value) {
923  if (substr($const, -2) === '..' || !isset($this->flatSetup[$const . '..'])) {
924  continue;
925  }
926  $counter++;
927  $comment = trim($this->flatSetup[$const . '..']);
928  $c_arr = explode(LF, $comment);
929  foreach ($c_arr as $k => $v) {
930  $line = trim(preg_replace('/^[#\\/]*/', '', $v));
931  if (!$line) {
932  continue;
933  }
934  $parts = explode(';', $line);
935  foreach ($parts as $par) {
936  if (strstr($par, '=')) {
937  $keyValPair = explode('=', $par, 2);
938  switch (trim(strtolower($keyValPair[0]))) {
939  case 'type':
940  // Type:
941  $editableComments[$const]['type'] = trim($keyValPair[1]);
942  break;
943  case 'cat':
944  // List of categories.
945  $catSplit = explode('/', strtolower($keyValPair[1]));
946  $catSplit[0] = trim($catSplit[0]);
947  if (isset($this->categoryLabels[$catSplit[0]])) {
948  $catSplit[0] = $this->categoryLabels[$catSplit[0]];
949  }
950  $editableComments[$const]['cat'] = $catSplit[0];
951  // This is the subcategory. Must be a key in $this->subCategories[].
952  // catSplit[2] represents the search-order within the subcat.
953  $catSplit[1] = trim($catSplit[1]);
954  if ($catSplit[1] && isset($this->subCategories[$catSplit[1]])) {
955  $editableComments[$const]['subcat_name'] = $catSplit[1];
956  $orderIdentifier = isset($catSplit[2]) ? trim($catSplit[2]) : $counter;
957  $editableComments[$const]['subcat'] = $this->subCategories[$catSplit[1]][1]
958  . '/' . $catSplit[1] . '/' . $orderIdentifier . 'z';
959  } elseif (isset($catSplit[2])) {
960  $editableComments[$const]['subcat'] = 'x' . '/' . trim($catSplit[2]) . 'z';
961  } else {
962  $editableComments[$const]['subcat'] = 'x' . '/' . $counter . 'z';
963  }
964  break;
965  case 'label':
966  // Label
967  $editableComments[$const]['label'] = trim($keyValPair[1]);
968  break;
969  case 'customcategory':
970  // Custom category label
971  $customCategory = explode('=', $keyValPair[1], 2);
972  if (trim($customCategory[0])) {
973  $categoryKey = strtolower($customCategory[0]);
974  $this->categoryLabels[$categoryKey] = $this->‪getLanguageService()->‪sL($customCategory[1]);
975  }
976  break;
977  case 'customsubcategory':
978  // Custom subCategory label
979  $customSubcategory = explode('=', $keyValPair[1], 2);
980  if (trim($customSubcategory[0])) {
981  $subCategoryKey = strtolower($customSubcategory[0]);
982  $this->subCategories[$subCategoryKey][0] = $this->‪getLanguageService()->‪sL($customSubcategory[1]);
983  }
984  break;
985  }
986  }
987  }
988  }
989  if (isset($editableComments[$const])) {
990  $editableComments[$const]['name'] = $const;
991  $editableComments[$const]['value'] = trim($value);
992  if (isset($default[$const])) {
993  $editableComments[$const]['default_value'] = trim($default[$const]);
994  }
995  }
996  }
997  return $editableComments;
998  }
999 
1003  public function ‪ext_categorizeEditableConstants($editConstArray)
1004  {
1005  // Runs through the available constants and fills the $this->categories array with pointers and priority-info
1006  foreach ($editConstArray as $constName => $constData) {
1007  if (!$constData['type']) {
1008  $constData['type'] = 'string';
1009  }
1010  $cats = explode(',', $constData['cat']);
1011  // if = only one category, while allows for many. We have agreed on only one category is the most basic way...
1012  foreach ($cats as $theCat) {
1013  $theCat = trim($theCat);
1014  if ($theCat) {
1015  $this->categories[$theCat][$constName] = $constData['subcat'];
1016  }
1017  }
1018  }
1019  }
1020 
1024  public function ‪ext_getCategoryLabelArray()
1025  {
1026  // Returns array used for labels in the menu.
1027  $retArr = [];
1028  foreach ($this->categories as $k => $v) {
1029  if (!empty($v)) {
1030  $retArr[$k] = strtoupper($k) . ' (' . count($v) . ')';
1031  }
1032  }
1033  return $retArr;
1034  }
1035 
1040  public function ‪ext_getTypeData($type)
1041  {
1042  $retArr = [];
1043  $type = trim($type);
1044  if (!$type) {
1045  $retArr['type'] = 'string';
1046  } else {
1047  $m = strcspn($type, ' [');
1048  $retArr['type'] = strtolower(substr($type, 0, $m));
1049  $types = ['int' => 1, 'options' => 1, 'file' => 1, 'boolean' => 1, 'offset' => 1, 'user' => 1];
1050  if (isset($types[$retArr['type']])) {
1051  $p = trim(substr($type, $m));
1052  $reg = [];
1053  preg_match('/\\[(.*)\\]/', $p, $reg);
1054  $p = trim($reg[1]);
1055  if ($p) {
1056  $retArr['paramstr'] = $p;
1057  switch ($retArr['type']) {
1058  case 'int':
1059  if ($retArr['paramstr'][0] === '-') {
1060  $retArr['params'] = GeneralUtility::intExplode('-', substr($retArr['paramstr'], 1));
1061  $retArr['params'][0] = (int)('-' . $retArr['params'][0]);
1062  } else {
1063  $retArr['params'] = GeneralUtility::intExplode('-', $retArr['paramstr']);
1064  }
1065  $retArr['min'] = $retArr['params'][0];
1066  $retArr['max'] = $retArr['params'][1];
1067  $retArr['paramstr'] = $retArr['params'][0] . ' - ' . $retArr['params'][1];
1068  break;
1069  case 'options':
1070  $retArr['params'] = explode(',', $retArr['paramstr']);
1071  break;
1072  }
1073  }
1074  }
1075  }
1076  return $retArr;
1077  }
1078 
1083  public function ‪ext_fNandV($params)
1084  {
1085  $fN = 'data[' . $params['name'] . ']';
1086  $idName = str_replace('.', '-', $params['name']);
1087  $fV = $params['value'];
1088  // Values entered from the constantsedit cannot be constants! 230502; removed \{ and set {
1089  if (preg_match('/^{[\\$][a-zA-Z0-9\\.]*}$/', trim($fV), $reg)) {
1090  $fV = '';
1091  }
1092  $fV = htmlspecialchars($fV);
1093  return [$fN, $fV, $params, $idName];
1094  }
1095 
1103  public function ‪ext_printFields($theConstants, $category)
1104  {
1105  reset($theConstants);
1106  ‪$output = '';
1107  $subcat = '';
1108  if (is_array($this->categories[$category])) {
1109  if (!$this->doNotSortCategoriesBeforeMakingForm) {
1110  asort($this->categories[$category]);
1111  }
1113  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
1114  foreach ($this->categories[$category] as $name => $type) {
1115  $params = $theConstants[$name];
1116  if (is_array($params)) {
1117  if ($subcat != $params['subcat_name']) {
1118  $subcat = $params['subcat_name'];
1119  $subcat_name = $params['subcat_name'] ? $this->subCategories[$params['subcat_name']][0] : 'Others';
1120  ‪$output .= '<h3>' . $subcat_name . '</h3>';
1121  }
1122  $label = $this->‪getLanguageService()->‪sL($params['label']);
1123  $label_parts = explode(':', $label, 2);
1124  if (count($label_parts) === 2) {
1125  $head = trim($label_parts[0]);
1126  $body = trim($label_parts[1]);
1127  } else {
1128  $head = trim($label_parts[0]);
1129  $body = '';
1130  }
1131  $typeDat = $this->‪ext_getTypeData($params['type']);
1132  $p_field = '';
1133  $raname = substr(md5($params['name']), 0, 10);
1134  $aname = '\'' . $raname . '\'';
1135  list($fN, $fV, $params, $idName) = $this->‪ext_fNandV($params);
1136  $idName = htmlspecialchars($idName);
1137  $hint = '';
1138  switch ($typeDat['type']) {
1139  case 'int':
1140  case 'int+':
1141  $additionalAttributes = '';
1142  if ($typeDat['paramstr']) {
1143  $hint = ' Range: ' . $typeDat['paramstr'];
1144  } elseif ($typeDat['type'] === 'int+') {
1145  $hint = ' Range: 0 - ';
1146  $typeDat['min'] = 0;
1147  } else {
1148  $hint = ' (Integer)';
1149  }
1150 
1151  if (isset($typeDat['min'])) {
1152  $additionalAttributes .= ' min="' . (int)$typeDat['min'] . '" ';
1153  }
1154  if (isset($typeDat['max'])) {
1155  $additionalAttributes .= ' max="' . (int)$typeDat['max'] . '" ';
1156  }
1157 
1158  $p_field =
1159  '<input class="form-control" id="' . $idName . '" type="number"'
1160  . ' name="' . $fN . '" value="' . $fV . '"' . ' onChange="uFormUrl(' . $aname . ')"' . $additionalAttributes . ' />';
1161  break;
1162  case 'color':
1163  $p_field = '
1164  <input class="form-control formengine-colorpickerelement t3js-color-picker" type="text" id="input-' . $idName . '" rel="' . $idName .
1165  '" name="' . $fN . '" value="' . $fV . '" onChange="uFormUrl(' . $aname . ')" />';
1166 
1167  if (empty($this->inlineJavaScript[$typeDat['type']])) {
1168  $this->inlineJavaScript[$typeDat['type']] = 'require([\'TYPO3/CMS/Backend/ColorPicker\'], function(ColorPicker){ColorPicker.initialize()});';
1169  }
1170  break;
1171  case 'wrap':
1172  $wArr = explode('|', $fV);
1173  $p_field = '<div class="input-group">
1174  <input class="form-control form-control-adapt" type="text" id="' . $idName . '" name="' . $fN . '" value="' . $wArr[0] . '" onChange="uFormUrl(' . $aname . ')" />
1175  <span class="input-group-addon input-group-icon">|</span>
1176  <input class="form-control form-control-adapt" type="text" name="W' . $fN . '" value="' . $wArr[1] . '" onChange="uFormUrl(' . $aname . ')" />
1177  </div>';
1178  break;
1179  case 'offset':
1180  $wArr = explode(',', $fV);
1181  $labels = GeneralUtility::trimExplode(',', $typeDat['paramstr']);
1182  $p_field = '<span class="input-group-addon input-group-icon">' . ($labels[0] ?: 'x') . '</span><input type="text" class="form-control form-control-adapt" name="' . $fN . '" value="' . $wArr[0] . '" onChange="uFormUrl(' . $aname . ')" />';
1183  $p_field .= '<span class="input-group-addon input-group-icon">' . ($labels[1] ?: 'y') . '</span><input type="text" name="W' . $fN . '" value="' . $wArr[1] . '" class="form-control form-control-adapt" onChange="uFormUrl(' . $aname . ')" />';
1184  $labelsCount = count($labels);
1185  for ($aa = 2; $aa < $labelsCount; $aa++) {
1186  if ($labels[$aa]) {
1187  $p_field .= '<span class="input-group-addon input-group-icon">' . $labels[$aa] . '</span><input type="text" name="W' . $aa . $fN . '" value="' . $wArr[$aa] . '" class="form-control form-control-adapt" onChange="uFormUrl(' . $aname . ')" />';
1188  } else {
1189  $p_field .= '<input type="hidden" name="W' . $aa . $fN . '" value="' . $wArr[$aa] . '" />';
1190  }
1191  }
1192  $p_field = '<div class="input-group">' . $p_field . '</div>';
1193  break;
1194  case 'options':
1195  if (is_array($typeDat['params'])) {
1196  $p_field = '';
1197  foreach ($typeDat['params'] as $val) {
1198  $vParts = explode('=', $val, 2);
1199  $label = $vParts[0];
1200  $val = $vParts[1] ?? $vParts[0];
1201  // option tag:
1202  $sel = '';
1203  if ($val === $params['value']) {
1204  $sel = ' selected';
1205  }
1206  $p_field .= '<option value="' . htmlspecialchars($val) . '"' . $sel . '>' . $this->‪getLanguageService()->‪sL($label) . '</option>';
1207  }
1208  $p_field = '<select class="form-control" id="' . $idName . '" name="' . $fN . '" onChange="uFormUrl(' . $aname . ')">' . $p_field . '</select>';
1209  }
1210  break;
1211  case 'boolean':
1212  $sel = $fV ? 'checked' : '';
1213  $p_field =
1214  '<input type="hidden" name="' . $fN . '" value="0" />'
1215  . '<label class="btn btn-default btn-checkbox">'
1216  . '<input id="' . $idName . '" type="checkbox" name="' . $fN . '" value="' . ($typeDat['paramstr'] ? $typeDat['paramstr'] : 1) . '" ' . $sel . ' onClick="uFormUrl(' . $aname . ')" />'
1217  . '<span class="t3-icon fa"></span>'
1218  . '</label>';
1219  break;
1220  case 'comment':
1221  $sel = $fV ? '' : 'checked';
1222  $p_field =
1223  '<input type="hidden" name="' . $fN . '" value="" />'
1224  . '<label class="btn btn-default btn-checkbox">'
1225  . '<input id="' . $idName . '" type="checkbox" name="' . $fN . '" value="1" ' . $sel . ' onClick="uFormUrl(' . $aname . ')" />'
1226  . '<span class="t3-icon fa"></span>'
1227  . '</label>';
1228  break;
1229  case 'file':
1230  // extensionlist
1231  $extList = $typeDat['paramstr'];
1232  if ($extList === 'IMAGE_EXT') {
1233  $extList = ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
1234  }
1235  $p_field = '<option value="">(' . $extList . ')</option>';
1236  if (trim($params['value'])) {
1237  $val = $params['value'];
1238  $p_field .= '<option value=""></option>';
1239  $p_field .= '<option value="' . htmlspecialchars($val) . '" selected>' . $val . '</option>';
1240  }
1241  $p_field = '<select class="form-select" id="' . $idName . '" name="' . $fN . '" onChange="uFormUrl(' . $aname . ')">' . $p_field . '</select>';
1242  break;
1243  case 'user':
1244  $userFunction = $typeDat['paramstr'];
1245  $userFunctionParams = ['fieldName' => $fN, 'fieldValue' => $fV];
1246  $p_field = GeneralUtility::callUserFunction($userFunction, $userFunctionParams, $this);
1247  break;
1248  default:
1249  $p_field = '<input class="form-control" id="' . $idName . '" type="text" name="' . $fN . '" value="' . $fV . '"'
1250  . ' onChange="uFormUrl(' . $aname . ')" />';
1251  }
1252  // Define default names and IDs
1253  $userTyposcriptID = 'userTS-' . $idName;
1254  $defaultTyposcriptID = 'defaultTS-' . $idName;
1255  $checkboxName = 'check[' . $params['name'] . ']';
1256  $checkboxID = 'check-' . $idName;
1257  $userTyposcriptStyle = '';
1258  $deleteIconHTML = '';
1259  $constantCheckbox = '';
1260  $constantDefaultRow = '';
1261  if (!$this->ext_dontCheckIssetValues) {
1262  // Set the default styling options
1263  if (isset($this->objReg[$params['name']])) {
1264  $checkboxValue = 'checked';
1265  $defaultTyposcriptStyle = 'style="display:none;"';
1266  } else {
1267  $checkboxValue = '';
1268  $userTyposcriptStyle = 'style="display:none;"';
1269  $defaultTyposcriptStyle = '';
1270  }
1271  $deleteTitle = htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.deleteTitle'));
1272  $deleteIcon = $iconFactory->getIcon('actions-edit-undo', ‪Icon::SIZE_SMALL)->render();
1273  $deleteIconHTML =
1274  '<button type="button" class="btn btn-default t3js-toggle" data-toggle="undo" rel="' . $idName . '">'
1275  . '<span title="' . $deleteTitle . '" alt="' . $deleteTitle . '">'
1276  . $deleteIcon
1277  . '</span>'
1278  . '</button>';
1279  $editTitle = htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.editTitle'));
1280  $editIcon = $iconFactory->getIcon('actions-open', ‪Icon::SIZE_SMALL)->render();
1281  $editIconHTML =
1282  '<button type="button" class="btn btn-default t3js-toggle" data-toggle="edit" rel="' . $idName . '">'
1283  . '<span title="' . $editTitle . '" alt="' . $editTitle . '">'
1284  . $editIcon
1285  . '</span>'
1286  . '</button>';
1287  $constantCheckbox = '<input type="hidden" name="' . $checkboxName . '" id="' . $checkboxID . '" value="' . $checkboxValue . '"/>';
1288  // If there's no default value for the field, use a static label.
1289  if (!$params['default_value']) {
1290  $params['default_value'] = '[Empty]';
1291  }
1292  $constantDefaultRow =
1293  '<div class="input-group defaultTS" id="' . $defaultTyposcriptID . '" ' . $defaultTyposcriptStyle . '>'
1294  . '<span class="input-group-btn">' . $editIconHTML . '</span>'
1295  . '<input class="form-control" type="text" placeholder="' . htmlspecialchars($params['default_value']) . '" readonly>'
1296  . '</div>';
1297  }
1298  $constantEditRow =
1299  '<div class="input-group userTS" id="' . $userTyposcriptID . '" ' . $userTyposcriptStyle . '>'
1300  . '<span class="input-group-btn">' . $deleteIconHTML . '</span>'
1301  . $p_field
1302  . '</div>';
1303  $constantLabel = '<label class="t3js-formengine-label"><span>' . htmlspecialchars($head) . '</span></label>';
1304  $constantName = '<span class="help-block">[' . $params['name'] . ']</span>';
1305  $constantDescription = $body ? '<p class="help-block">' . htmlspecialchars($body) . '</p>' : '';
1306  $constantData = '';
1307  if ($hint !== '') {
1308  $constantData .= '<span class="help-block">' . $hint . '</span>';
1309  }
1310  $constantData .=
1311  $constantCheckbox
1312  . $constantEditRow
1313  . $constantDefaultRow;
1314 
1315  ‪$output .=
1316  '<fieldset class="form-section">'
1317  . '<a name="' . $raname . '"></a>'
1318  . '<div class="form-group">'
1319  . $constantLabel . $constantName . $constantDescription . $constantData
1320  . '</div>'
1321  . '</fieldset>';
1322  } else {
1323  ‪debug('Error. Constant did not exist. Should not happen.');
1324  }
1325  }
1326  }
1327  return '<div class="tstemplate-constanteditor">' . ‪$output . '</div>';
1328  }
1329 
1330  /***************************
1331  *
1332  * Processing input values
1333  *
1334  ***************************/
1338  public function ‪ext_regObjectPositions(‪$constants)
1339  {
1340  // This runs through the lines of the constants-field of the active template and registers the constants-names
1341  // and line positions in an array, $this->objReg
1342  $this->raw = explode(LF, ‪$constants);
1343  $this->rawP = 0;
1344  // Resetting the objReg if the divider is found!!
1345  $this->objReg = [];
1346  $this->‪ext_regObjects('');
1347  }
1348 
1352  public function ‪ext_regObjects($pre)
1353  {
1354  // Works with regObjectPositions. "expands" the names of the TypoScript objects
1355  while (isset($this->raw[$this->rawP])) {
1356  $line = ltrim($this->raw[$this->rawP]);
1357  $this->rawP++;
1358  if ($line) {
1359  if ($line[0] === '[') {
1360  } elseif (strcspn($line, '}#/') != 0) {
1361  $varL = strcspn($line, ' {=<');
1362  $var = substr($line, 0, $varL);
1363  $line = ltrim(substr($line, $varL));
1364  switch ($line[0]) {
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 ($line[0] === '}') {
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 
1391  public function ‪ext_putValueInConf($key, $var)
1392  {
1393  // Puts the value $var to the TypoScript value $key in the current lines of the templates.
1394  // If the $key is not found in the template constants field, a new line is inserted in the bottom.
1395  $theValue = ' ' . trim($var);
1396  if (isset($this->objReg[$key])) {
1397  $lineNum = $this->objReg[$key];
1398  $parts = explode('=', $this->raw[$lineNum], 2);
1399  if (count($parts) === 2) {
1400  $parts[1] = $theValue;
1401  }
1402  $this->raw[$lineNum] = implode('=', $parts);
1403  } else {
1404  $this->raw[] = $key . ' =' . $theValue;
1405  }
1406  $this->changed = true;
1407  }
1408 
1412  public function ‪ext_removeValueInConf($key)
1413  {
1414  // Removes the value in the configuration
1415  if (isset($this->objReg[$key])) {
1416  $lineNum = $this->objReg[$key];
1417  unset($this->raw[$lineNum]);
1418  }
1419  $this->changed = true;
1420  }
1421 
1427  public function ‪ext_depthKeys($arr, $settings)
1428  {
1429  $tsbrArray = [];
1430  foreach ($arr as $theK => $theV) {
1431  $theKeyParts = explode('.', $theK);
1432  $depth = '';
1433  $c = count($theKeyParts);
1434  $a = 0;
1435  foreach ($theKeyParts as $p) {
1436  $a++;
1437  $depth .= ($depth ? '.' : '') . $p;
1438  $tsbrArray[$depth] = $c == $a ? $theV : 1;
1439  }
1440  }
1441  // Modify settings
1442  foreach ($tsbrArray as $theK => $theV) {
1443  if ($theV) {
1444  $settings[$theK] = 1;
1445  } else {
1446  unset($settings[$theK]);
1447  }
1448  }
1449  return $settings;
1450  }
1451 
1460  public function ‪ext_procesInput($http_post_vars, $http_post_files, $theConstants, $tplRow)
1461  {
1462  $data = $http_post_vars['data'];
1463  $check = $http_post_vars['check'];
1464  $Wdata = $http_post_vars['Wdata'];
1465  $W2data = $http_post_vars['W2data'];
1466  $W3data = $http_post_vars['W3data'];
1467  $W4data = $http_post_vars['W4data'];
1468  $W5data = $http_post_vars['W5data'];
1469  if (is_array($data)) {
1470  foreach ($data as $key => $var) {
1471  if (isset($theConstants[$key])) {
1472  // If checkbox is set, update the value
1473  if ($this->ext_dontCheckIssetValues || isset($check[$key])) {
1474  // Exploding with linebreak, just to make sure that no multiline input is given!
1475  list($var) = explode(LF, $var);
1476  $typeDat = $this->‪ext_getTypeData($theConstants[$key]['type']);
1477  switch ($typeDat['type']) {
1478  case 'int':
1479  if ($typeDat['paramstr']) {
1480  $var = ‪MathUtility::forceIntegerInRange($var, $typeDat['params'][0], $typeDat['params'][1]);
1481  } else {
1482  $var = (int)$var;
1483  }
1484  break;
1485  case 'int+':
1486  $var = max(0, (int)$var);
1487  break;
1488  case 'color':
1489  $col = [];
1490  if ($var) {
1491  $var = preg_replace('/[^A-Fa-f0-9]*/', '', $var);
1492  $useFulHex = strlen($var) > 3;
1493  $col[] = hexdec($var[0]);
1494  $col[] = hexdec($var[1]);
1495  $col[] = hexdec($var[2]);
1496  if ($useFulHex) {
1497  $col[] = hexdec($var[3]);
1498  $col[] = hexdec($var[4]);
1499  $col[] = hexdec($var[5]);
1500  }
1501  $var = substr('0' . dechex($col[0]), -1) . substr('0' . dechex($col[1]), -1) . substr('0' . dechex($col[2]), -1);
1502  if ($useFulHex) {
1503  $var .= substr('0' . dechex($col[3]), -1) . substr('0' . dechex($col[4]), -1) . substr('0' . dechex($col[5]), -1);
1504  }
1505  $var = '#' . strtoupper($var);
1506  }
1507  break;
1508  case 'comment':
1509  if ($var) {
1510  $var = '';
1511  } else {
1512  $var = '#';
1513  }
1514  break;
1515  case 'wrap':
1516  if (isset($Wdata[$key])) {
1517  $var .= '|' . $Wdata[$key];
1518  }
1519  break;
1520  case 'offset':
1521  if (isset($Wdata[$key])) {
1522  $var = (int)$var . ',' . (int)$Wdata[$key];
1523  if (isset($W2data[$key])) {
1524  $var .= ',' . (int)$W2data[$key];
1525  if (isset($W3data[$key])) {
1526  $var .= ',' . (int)$W3data[$key];
1527  if (isset($W4data[$key])) {
1528  $var .= ',' . (int)$W4data[$key];
1529  if (isset($W5data[$key])) {
1530  $var .= ',' . (int)$W5data[$key];
1531  }
1532  }
1533  }
1534  }
1535  }
1536  break;
1537  case 'boolean':
1538  if ($var) {
1539  $var = $typeDat['paramstr'] ? $typeDat['paramstr'] : 1;
1540  }
1541  break;
1542  }
1543  if ($this->ext_printAll || (string)$theConstants[$key]['value'] !== (string)$var) {
1544  // Put value in, if changed.
1545  $this->‪ext_putValueInConf($key, $var);
1546  }
1547  // Remove the entry because it has been "used"
1548  unset($check[$key]);
1549  } else {
1550  $this->‪ext_removeValueInConf($key);
1551  }
1552  }
1553  }
1554  }
1555  // Remaining keys in $check indicates fields that are just clicked "on" to be edited.
1556  // Therefore we get the default value and puts that in the template as a start...
1557  if (!$this->ext_dontCheckIssetValues && is_array($check)) {
1558  foreach ($check as $key => $var) {
1559  if (isset($theConstants[$key])) {
1560  $dValue = $theConstants[$key]['default_value'];
1561  $this->‪ext_putValueInConf($key, $dValue);
1562  }
1563  }
1564  }
1565  }
1572  public function ‪ext_prevPageWithTemplate($id, $perms_clause)
1573  {
1574  ‪$rootLine = ‪BackendUtility::BEgetRootLine($id, $perms_clause ? ' AND ' . $perms_clause : '');
1575  foreach (‪$rootLine as $p) {
1576  if ($this->‪ext_getFirstTemplate($p['uid'])) {
1577  return $p;
1578  }
1579  }
1580  return [];
1581  }
1582 
1588  protected function ‪getRootLine()
1589  {
1590  return is_array($this->absoluteRootLine) ? $this->absoluteRootLine : [];
1591  }
1592 
1596  protected function ‪getLanguageService()
1597  {
1598  return ‪$GLOBALS['LANG'];
1599  }
1600 
1604  protected function ‪getDocumentTemplate()
1605  {
1606  return ‪$GLOBALS['TBE_TEMPLATE'];
1607  }
1608 }
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_noPMicons
‪int $ext_noPMicons
Definition: ExtendedTemplateService.php:133
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:29
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_inBrace
‪int $ext_inBrace
Definition: ExtendedTemplateService.php:99
‪TYPO3\CMS\Core\TypoScript\TemplateService\$constants
‪array $constants
Definition: TemplateService.php:187
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_lineNumberOffset
‪int $ext_lineNumberOffset
Definition: ExtendedTemplateService.php:125
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:73
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_outputTS
‪string ext_outputTS(array $config, $lineNumbers=false, $comments=false, $crop=false, $syntaxHL=false, $syntaxHLBlockmode=0)
Definition: ExtendedTemplateService.php:709
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getFirstTemplate
‪array null ext_getFirstTemplate($pid, $templateUid=0)
Definition: ExtendedTemplateService.php:811
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_regObjectPositions
‪ext_regObjectPositions($constants)
Definition: ExtendedTemplateService.php:1308
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_compareFlatSetups
‪array ext_compareFlatSetups($default)
Definition: ExtendedTemplateService.php:888
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getSearchKeys
‪array ext_getSearchKeys($arr, $depth_in, $searchString, $keyArray)
Definition: ExtendedTemplateService.php:524
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_prevPageWithTemplate
‪array ext_prevPageWithTemplate($id, $perms_clause)
Definition: ExtendedTemplateService.php:1542
‪TYPO3\CMS\Core\TypoScript\TemplateService\$context
‪Context $context
Definition: TemplateService.php:340
‪TYPO3\CMS\Core\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:25
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_regObjects
‪ext_regObjects($pre)
Definition: ExtendedTemplateService.php:1322
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_removeValueInConf
‪ext_removeValueInConf($key)
Definition: ExtendedTemplateService.php:1382
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getTemplateHierarchyArr
‪array ext_getTemplateHierarchyArr($arr, $depthData, $keyArray, $first=0)
Definition: ExtendedTemplateService.php:608
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_lnBreakPointWrap
‪string ext_lnBreakPointWrap($lineNumber, $str)
Definition: ExtendedTemplateService.php:759
‪TYPO3
‪TYPO3\CMS\Core\TypoScript\TemplateService\$flatSetup
‪array $flatSetup
Definition: TemplateService.php:173
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface\removeAll
‪QueryRestrictionContainerInterface removeAll()
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\generateConfig_constants
‪array generateConfig_constants()
Definition: ExtendedTemplateService.php:298
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\substituteCMarkers
‪string substituteCMarkers($all)
Definition: ExtendedTemplateService.php:276
‪TYPO3\CMS\Core\Exception
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getObjTree
‪string ext_getObjTree($arr, $depth_in, $depthData, $parentType='', $parentValue='', $alphaSort='0')
Definition: ExtendedTemplateService.php:360
‪TYPO3\CMS\Core\TypoScript\TemplateService\$sitetitle
‪string $sitetitle
Definition: TemplateService.php:247
‪TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction
Definition: BackendWorkspaceRestriction.php:28
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_formatTS
‪string ext_formatTS($input, $ln, $comments=true, $crop=false)
Definition: ExtendedTemplateService.php:772
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\getRestrictions
‪QueryRestrictionContainerInterface getRestrictions()
Definition: QueryBuilder.php:89
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\getRootLine
‪array getRootLine()
Definition: ExtendedTemplateService.php:1558
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$constantMode
‪string $constantMode
Definition: ExtendedTemplateService.php:113
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService
Definition: ExtendedTemplateService.php:39
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$categories
‪array $categories
Definition: ExtendedTemplateService.php:42
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_CEformName
‪string $ext_CEformName
Definition: ExtendedTemplateService.php:155
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:158
‪TYPO3\CMS\Backend\Utility\BackendUtility\BEgetRootLine
‪static array BEgetRootLine($uid, $clause='', $workspaceOL=false, array $additionalFields=[])
Definition: BackendUtility.php:374
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\getInlineJavaScript
‪array getInlineJavaScript()
Definition: ExtendedTemplateService.php:227
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:49
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_categorizeEditableConstants
‪ext_categorizeEditableConstants($editConstArray)
Definition: ExtendedTemplateService.php:973
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$bType
‪string $bType
Definition: ExtendedTemplateService.php:181
‪TYPO3\CMS\Core\Database\Query\QueryBuilder
Definition: QueryBuilder.php:47
‪TYPO3\CMS\Core\TypoScript
Definition: ConfigurationForm.php:2
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$categoryLabels
‪array $categoryLabels
Definition: ExtendedTemplateService.php:60
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$objReg
‪int[] $objReg
Definition: ExtendedTemplateService.php:193
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\lineNumberToScript
‪array lineNumberToScript(array $lnArr)
Definition: ExtendedTemplateService.php:486
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$tsbrowser_searchKeys
‪array $tsbrowser_searchKeys
Definition: ExtendedTemplateService.php:105
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\andWhere
‪QueryBuilder andWhere(... $where)
Definition: QueryBuilder.php:647
‪TYPO3\CMS\Backend\Template\DocumentTemplate
Definition: DocumentTemplate.php:48
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_printFields
‪string ext_printFields($theConstants, $category)
Definition: ExtendedTemplateService.php:1073
‪TYPO3\CMS\Core\TypoScript\TemplateService\mergeConstantsFromPageTSconfig
‪array mergeConstantsFromPageTSconfig($constArray)
Definition: TemplateService.php:1257
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_dontCheckIssetValues
‪int $ext_dontCheckIssetValues
Definition: ExtendedTemplateService.php:147
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_depthKeys
‪array ext_depthKeys($arr, $settings)
Definition: ExtendedTemplateService.php:1397
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\getLanguageService
‪LanguageService getLanguageService()
Definition: ExtendedTemplateService.php:1566
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$lastComment
‪string $lastComment
Definition: ExtendedTemplateService.php:205
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\getTemplateQueryBuilder
‪QueryBuilder getTemplateQueryBuilder(int $pid)
Definition: ExtendedTemplateService.php:860
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$doNotSortCategoriesBeforeMakingForm
‪bool $doNotSortCategoriesBeforeMakingForm
Definition: ExtendedTemplateService.php:159
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_process_hierarchyInfo
‪array ext_process_hierarchyInfo(array $depthDataArr, &$pointer)
Definition: ExtendedTemplateService.php:681
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getTypeData
‪array ext_getTypeData($type)
Definition: ExtendedTemplateService.php:1010
‪TYPO3\CMS\Core\TypoScript\TemplateService\$config
‪array $config
Definition: TemplateService.php:181
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getRootlineNumber
‪int ext_getRootlineNumber($pid)
Definition: ExtendedTemplateService.php:589
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\execute
‪Doctrine DBAL Driver Statement int execute()
Definition: QueryBuilder.php:178
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$clearList_setup_temp
‪array $clearList_setup_temp
Definition: ExtendedTemplateService.php:177
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_listOfTemplatesArr
‪array $ext_listOfTemplatesArr
Definition: ExtendedTemplateService.php:137
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$raw
‪array $raw
Definition: ExtendedTemplateService.php:197
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$tsbrowser_depthKeys
‪array $tsbrowser_depthKeys
Definition: ExtendedTemplateService.php:109
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_printAll
‪int $ext_printAll
Definition: ExtendedTemplateService.php:151
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$templateTitles
‪array $templateTitles
Definition: ExtendedTemplateService.php:165
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\setMaxResults
‪QueryBuilder setMaxResults(int $maxResults)
Definition: QueryBuilder.php:329
‪TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
Definition: ConditionMatcher.php:33
‪$output
‪$output
Definition: annotationChecker.php:113
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getCategoryLabelArray
‪array ext_getCategoryLabelArray()
Definition: ExtendedTemplateService.php:994
‪debug
‪debug($variable='', $title=null, $group=null)
Definition: GlobalDebugFunctions.php:5
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getAllTemplates
‪array[] ext_getAllTemplates($pid)
Definition: ExtendedTemplateService.php:837
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$subCategories
‪array $subCategories
Definition: ExtendedTemplateService.php:66
‪TYPO3\CMS\Core\TypoScript\TemplateService
Definition: TemplateService.php:50
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\getDocumentTemplate
‪DocumentTemplate getDocumentTemplate()
Definition: ExtendedTemplateService.php:1574
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\substituteConstants
‪string substituteConstants($all)
Definition: ExtendedTemplateService.php:238
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Utility\BackendUtility\workspaceOL
‪static workspaceOL($table, &$row, $wsid=-99, $unsetMovePointers=false)
Definition: BackendUtility.php:4048
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_expandAllNotes
‪int $ext_expandAllNotes
Definition: ExtendedTemplateService.php:129
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$regexMode
‪string $regexMode
Definition: ExtendedTemplateService.php:117
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\__construct
‪__construct(Context $context=null)
Definition: ExtendedTemplateService.php:214
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$inlineJavaScript
‪array $inlineJavaScript
Definition: ExtendedTemplateService.php:209
‪TYPO3\CMS\Core\TypoScript\TemplateService\$rootLine
‪array $rootLine
Definition: TemplateService.php:223
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_procesInput
‪ext_procesInput($http_post_vars, $http_post_files, $theConstants, $tplRow)
Definition: ExtendedTemplateService.php:1430
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$ext_lineNumberOffset_mode
‪string $ext_lineNumberOffset_mode
Definition: ExtendedTemplateService.php:141
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$clearList_const_temp
‪array $clearList_const_temp
Definition: ExtendedTemplateService.php:173
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$changed
‪bool $changed
Definition: ExtendedTemplateService.php:189
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$lnToScript
‪array null $lnToScript
Definition: ExtendedTemplateService.php:169
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface\add
‪QueryRestrictionContainerInterface add(QueryRestrictionInterface $restriction)
‪TYPO3\CMS\Core\TypoScript\TemplateService\flattenSetup
‪flattenSetup($setupArray, $prefix)
Definition: TemplateService.php:1326
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordPath
‪static mixed getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
Definition: BackendUtility.php:572
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$rawP
‪int $rawP
Definition: ExtendedTemplateService.php:201
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_fNandV
‪array ext_fNandV($params)
Definition: ExtendedTemplateService.php:1053
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_fixed_lgd
‪string ext_fixed_lgd($string, $chars)
Definition: ExtendedTemplateService.php:739
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_getSetup
‪array ext_getSetup($theSetup, $theKey)
Definition: ExtendedTemplateService.php:334
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$linkObjects
‪bool $linkObjects
Definition: ExtendedTemplateService.php:185
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\$fixedLgd
‪string $fixedLgd
Definition: ExtendedTemplateService.php:121
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\ext_putValueInConf
‪ext_putValueInConf($key, $var)
Definition: ExtendedTemplateService.php:1361
‪TYPO3\CMS\Core\TypoScript\ExtendedTemplateService\substituteConstantsCallBack
‪string substituteConstantsCallBack($matches)
Definition: ExtendedTemplateService.php:250