‪TYPO3CMS  ‪main
BackendLayoutWizardElement.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
25 
39 {
45  protected ‪$defaultFieldInformation = [
46  'tcaDescription' => [
47  'renderType' => 'tcaDescription',
48  ],
49  ];
50 
51  protected array ‪$rows = [];
52  protected int ‪$colCount = 0;
53  protected int ‪$rowCount = 0;
54 
55  public function ‪__construct(
56  private readonly ‪TypoScriptStringFactory $typoScriptStringFactory,
57  ) {}
58 
59  public function ‪render(): array
60  {
61  $lang = $this->‪getLanguageService();
62  $resultArray = $this->‪initializeResultArray();
63  $this->‪initializeWizard();
64 
65  $row = $this->data['databaseRow'];
66  ‪$tca = $this->data['processedTca'];
67  $parameterArray = $this->data['parameterArray'];
68 
69  // readOnly is not supported as columns config but might be set by SingleFieldContainer in case
70  // "l10n_display" is set to "defaultAsReadonly". To prevent misbehaviour for fields, which falsely
71  // set this, we also check for "defaultAsReadonly" being set and whether the record is an overlay.
72  $readOnly = ($parameterArray['fieldConf']['config']['readOnly'] ?? false)
73  && (‪$tca['ctrl']['transOrigPointerField'] ?? false)
74  && ($row[‪$tca['ctrl']['transOrigPointerField']][0] ?? $row[‪$tca['ctrl']['transOrigPointerField']] ?? false)
75  && ‪GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'] ?? '', 'defaultAsReadonly');
76 
77  $fieldInformationResult = $this->‪renderFieldInformation();
78  $fieldInformationHtml = $fieldInformationResult['html'];
79  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
80 
81  $fieldWizardResult = $this->‪renderFieldWizard();
82  $fieldWizardHtml = $fieldWizardResult['html'];
83  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
84 
85  // Use CodeMirror if available
86  $codeMirrorConfig = [
87  'label' => $lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:buttons.pageTsConfig'),
88  'panel' => 'top',
89  'mode' => GeneralUtility::jsonEncodeForHtmlAttribute(‪JavaScriptModuleInstruction::create('@typo3/backend/code-editor/language/typoscript.js', 'typoscript')->invoke(), false),
90  'nolazyload' => 'true',
91  'readonly' => 'true',
92  ];
93 
94  $resultArray['javaScriptModules'][] = ‪JavaScriptModuleInstruction::create('@typo3/backend/code-editor/element/code-mirror-element.js');
95 
96  $json = (string)json_encode($this->rows, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS);
97  $codeMirrorConfig = (string)json_encode($codeMirrorConfig, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS);
98  $html = [];
99  $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
100  $html[] = $fieldInformationHtml;
101  $html[] = '<div class="form-control-wrap">';
102  $html[] = '<div class="form-wizards-wrap">';
103  $html[] = '<div class="form-wizards-element">';
104  $html[] = '<input';
105  $html[] = ' type="hidden"';
106  $html[] = ' name="' . htmlspecialchars($this->data['parameterArray']['itemFormElName']) . '"';
107  $html[] = ' value="' . htmlspecialchars($this->data['parameterArray']['itemFormElValue']) . '"';
108  $html[] = '/>';
109  $html[] = '<typo3-backend-grid-editor';
110  $html[] = ' data="' . htmlspecialchars($json) . '"';
111  $html[] = ' rowCount="' . (int)$this->rowCount . '"';
112  $html[] = ' colCount="' . (int)$this->colCount . '"';
113  $html[] = ($readOnly ? 'readonly="true"' : '');
114  $html[] = ' fieldName="' . htmlspecialchars($this->data['parameterArray']['itemFormElName']) . '"';
115  $html[] = ' codeMirrorConfig="' . htmlspecialchars($codeMirrorConfig) . '"';
116  $html[] = '></typo3-backend-grid-editor>';
117  if (!$readOnly && !empty($fieldWizardHtml)) {
118  $html[] = '<div class="form-wizards-items-bottom">' . $fieldWizardHtml . '</div>';
119  }
120  $html[] = '</div>';
121  $html[] = '</div>';
122  $html[] = '</div>';
123  $html[] = '</div>';
124 
125  $html = implode(LF, $html);
126  $resultArray['html'] = $this->‪wrapWithFieldsetAndLegend($html);
127  $resultArray['javaScriptModules'][] = ‪JavaScriptModuleInstruction::create(
128  '@typo3/backend/grid-editor.js',
129  'GridEditor'
130  )->instance();
131  $resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:core/Resources/Private/Language/locallang_wizards.xlf';
132  $resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:backend/Resources/Private/Language/locallang.xlf';
133  $resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf';
134 
135  return $resultArray;
136  }
137 
138  protected function ‪initializeWizard(): void
139  {
140  // Initialize default values
141  ‪$rows = [[['colspan' => 1, 'rowspan' => 1, 'spanned' => 0, 'name' => '0x0']]];
142  ‪$colCount = 1;
143  ‪$rowCount = 1;
144 
145  if (!empty($this->data['parameterArray']['itemFormElValue'])) {
146  // Parse the TypoScript a-like syntax in case we already have a config (e.g. database value or default from TCA)
147  $typoScriptTree = $this->typoScriptStringFactory->parseFromString($this->data['parameterArray']['itemFormElValue'], new ‪AstBuilder(new ‪NoopEventDispatcher()));
148  $typoScriptArray = $typoScriptTree->toArray();
149  if (is_array($typoScriptArray['backend_layout.'] ?? false)) {
150  // Only evaluate, in case the "backend_layout." array exists on root level
151  ‪$data = $typoScriptArray['backend_layout.'];
152  ‪$rows = [];
153  ‪$colCount = ‪$data['colCount'];
154  ‪$rowCount = ‪$data['rowCount'];
155  $dataRows = ‪$data['rows.'];
156  $spannedMatrix = [];
157  for ($i = 1; $i <= ‪$rowCount; $i++) {
158  $cells = [];
159  $row = array_shift($dataRows);
160  $columns = $row['columns.'];
161  for ($j = 1; $j <= ‪$colCount; $j++) {
162  $cellData = [];
163  if (!($spannedMatrix[$i][$j] ?? false)) {
164  if (is_array($columns) && !empty($columns)) {
165  $column = array_shift($columns);
166  if (isset($column['colspan'])) {
167  $cellData['colspan'] = (int)$column['colspan'];
168  $columnColSpan = (int)$column['colspan'];
169  if (isset($column['rowspan'])) {
170  $columnRowSpan = (int)$column['rowspan'];
171  for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
172  for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
173  $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1;
174  }
175  }
176  } else {
177  for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
178  $spannedMatrix[$i][$j + $spanColumn] = 1;
179  }
180  }
181  } else {
182  $cellData['colspan'] = 1;
183  if (isset($column['rowspan'])) {
184  $columnRowSpan = (int)$column['rowspan'];
185  for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
186  $spannedMatrix[$i + $spanRow][$j] = 1;
187  }
188  }
189  }
190  if (isset($column['rowspan'])) {
191  $cellData['rowspan'] = (int)$column['rowspan'];
192  } else {
193  $cellData['rowspan'] = 1;
194  }
195  if (isset($column['name'])) {
196  $cellData['name'] = $column['name'];
197  }
198  if (isset($column['colPos'])) {
199  $cellData['column'] = (int)$column['colPos'];
200  }
201  }
202  } else {
203  $cellData = ['colspan' => 1, 'rowspan' => 1, 'spanned' => 1];
204  }
205  $cells[] = $cellData;
206  }
207  ‪$rows[] = $cells;
208  if (!empty($spannedMatrix[$i]) && is_array($spannedMatrix[$i])) {
209  ksort($spannedMatrix[$i]);
210  }
211  }
212  }
213  }
214 
215  $this->rows = ‪$rows;
216  $this->colCount = (int)‪$colCount;
217  $this->rowCount = (int)‪$rowCount;
218  }
219 }
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldInformation
‪array renderFieldInformation()
Definition: AbstractFormElement.php:73
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\$defaultFieldInformation
‪array $defaultFieldInformation
Definition: BackendLayoutWizardElement.php:44
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement
Definition: BackendLayoutWizardElement.php:39
‪TYPO3\CMS\Backend\Form\AbstractNode\mergeChildReturnIntoExistingResult
‪array mergeChildReturnIntoExistingResult(array $existing, array $childReturn, bool $mergeHtml=true)
Definition: AbstractNode.php:104
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\create
‪static create(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:47
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\__construct
‪__construct(private readonly TypoScriptStringFactory $typoScriptStringFactory,)
Definition: BackendLayoutWizardElement.php:54
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement
Definition: AbstractFormElement.php:37
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Backend\Form\Element
Definition: AbstractFormElement.php:16
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\initializeWizard
‪initializeWizard()
Definition: BackendLayoutWizardElement.php:137
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\wrapWithFieldsetAndLegend
‪wrapWithFieldsetAndLegend(string $innerHTML)
Definition: AbstractFormElement.php:133
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\getLanguageService
‪getLanguageService()
Definition: AbstractFormElement.php:456
‪TYPO3\CMS\Backend\Form\AbstractNode\$data
‪array $data
Definition: AbstractNode.php:35
‪TYPO3\CMS\Core\TypoScript\AST\AstBuilder
Definition: AstBuilder.php:45
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\$rows
‪array $rows
Definition: BackendLayoutWizardElement.php:50
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\$rowCount
‪int $rowCount
Definition: BackendLayoutWizardElement.php:52
‪TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher
Definition: NoopEventDispatcher.php:29
‪$tca
‪$tca
Definition: sys_file_metadata.php:5
‪TYPO3\CMS\Core\Utility\GeneralUtility\inList
‪static bool inList($list, $item)
Definition: GeneralUtility.php:422
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\render
‪render()
Definition: BackendLayoutWizardElement.php:58
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Form\Element\BackendLayoutWizardElement\$colCount
‪int $colCount
Definition: BackendLayoutWizardElement.php:51
‪TYPO3\CMS\Core\TypoScript\TypoScriptStringFactory
Definition: TypoScriptStringFactory.php:37
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldWizard
‪array renderFieldWizard()
Definition: AbstractFormElement.php:105
‪TYPO3\CMS\Backend\Form\AbstractNode\initializeResultArray
‪initializeResultArray()
Definition: AbstractNode.php:77