‪TYPO3CMS  10.4
BackendLayoutView.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
30 
36 {
41 
45  protected ‪$selectedCombinedIdentifier = [];
46 
50  protected ‪$selectedBackendLayout = [];
51 
55  public function ‪__construct()
56  {
58  }
59 
63  protected function ‪initializeDataProviderCollection()
64  {
65  ‪$dataProviderCollection = GeneralUtility::makeInstance(DataProviderCollection::class);
66  ‪$dataProviderCollection->‪add('default', DefaultDataProvider::class);
67 
68  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['BackendLayoutDataProvider'])) {
69  $dataProviders = (array)‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['BackendLayoutDataProvider'];
70  foreach ($dataProviders as $identifier => $className) {
71  ‪$dataProviderCollection->‪add($identifier, $className);
72  }
73  }
74 
76  }
77 
82  {
83  $this->dataProviderCollection = ‪$dataProviderCollection;
84  }
85 
89  public function ‪getDataProviderCollection()
90  {
92  }
93 
101  public function ‪addBackendLayoutItems(array $parameters)
102  {
103  $pageId = $this->‪determinePageId($parameters['table'], $parameters['row']) ?: 0;
104  $pageTsConfig = (array)‪BackendUtility::getPagesTSconfig($pageId);
105  $identifiersToBeExcluded = $this->‪getIdentifiersToBeExcluded($pageTsConfig);
106 
107  $dataProviderContext = $this->‪createDataProviderContext()
108  ->‪setPageId($pageId)
109  ->‪setData($parameters['row'])
110  ->‪setTableName($parameters['table'])
111  ->‪setFieldName($parameters['field'])
112  ->‪setPageTsConfig($pageTsConfig);
113 
114  $backendLayoutCollections = $this->‪getDataProviderCollection()->‪getBackendLayoutCollections($dataProviderContext);
115  foreach ($backendLayoutCollections as $backendLayoutCollection) {
116  $combinedIdentifierPrefix = '';
117  if ($backendLayoutCollection->getIdentifier() !== 'default') {
118  $combinedIdentifierPrefix = $backendLayoutCollection->‪getIdentifier() . '__';
119  }
120 
121  foreach ($backendLayoutCollection->getAll() as $backendLayout) {
122  $combinedIdentifier = $combinedIdentifierPrefix . $backendLayout->getIdentifier();
123 
124  if (in_array($combinedIdentifier, $identifiersToBeExcluded, true)) {
125  continue;
126  }
127 
128  $parameters['items'][] = [
129  $this->‪getLanguageService()->‪sL($backendLayout->getTitle()),
130  $combinedIdentifier,
131  $backendLayout->getIconPath(),
132  ];
133  }
134  }
135  }
136 
144  protected function ‪determinePageId($tableName, array $data)
145  {
146  if (strpos($data['uid'], 'NEW') === 0) {
147  // negative uid_pid values of content elements indicate that the element
148  // has been inserted after an existing element so there is no pid to get
149  // the backendLayout for and we have to get that first
150  if ($data['pid'] < 0) {
151  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
152  ->getQueryBuilderForTable($tableName);
153  $queryBuilder->getRestrictions()
154  ->removeAll();
155  $pageId = $queryBuilder
156  ->select('pid')
157  ->from($tableName)
158  ->where(
159  $queryBuilder->expr()->eq(
160  'uid',
161  $queryBuilder->createNamedParameter(abs($data['pid']), \PDO::PARAM_INT)
162  )
163  )
164  ->execute()
165  ->fetchColumn();
166  } else {
167  $pageId = $data['pid'];
168  }
169  } elseif ($tableName === 'pages') {
170  $pageId = $data['uid'];
171  } else {
172  $pageId = $data['pid'];
173  }
174 
175  return $pageId;
176  }
177 
184  public function ‪getSelectedCombinedIdentifier($pageId)
185  {
186  if (!isset($this->selectedCombinedIdentifier[$pageId])) {
187  $page = $this->‪getPage($pageId);
188  $this->selectedCombinedIdentifier[$pageId] = (string)$page['backend_layout'];
189 
190  if ($this->selectedCombinedIdentifier[$pageId] === '-1') {
191  // If it is set to "none" - don't use any
192  $this->selectedCombinedIdentifier[$pageId] = false;
193  } elseif ($this->selectedCombinedIdentifier[$pageId] === '' || $this->selectedCombinedIdentifier[$pageId] === '0') {
194  // If it not set check the root-line for a layout on next level and use this
195  // (root-line starts with current page and has page "0" at the end)
196  $rootLine = $this->‪getRootLine($pageId);
197  // Remove first and last element (current and root page)
198  array_shift($rootLine);
199  array_pop($rootLine);
200  foreach ($rootLine as $rootLinePage) {
201  $this->selectedCombinedIdentifier[$pageId] = (string)$rootLinePage['backend_layout_next_level'];
202  if ($this->selectedCombinedIdentifier[$pageId] === '-1') {
203  // If layout for "next level" is set to "none" - don't use any and stop searching
204  $this->selectedCombinedIdentifier[$pageId] = false;
205  break;
206  }
207  if ($this->selectedCombinedIdentifier[$pageId] !== '' && $this->selectedCombinedIdentifier[$pageId] !== '0') {
208  // Stop searching if a layout for "next level" is set
209  break;
210  }
211  }
212  }
213  }
214  // If it is set to a positive value use this
215  return $this->selectedCombinedIdentifier[$pageId];
216  }
217 
224  protected function ‪getIdentifiersToBeExcluded(array $pageTSconfig)
225  {
226  $identifiersToBeExcluded = [];
227 
228  if (‪ArrayUtility::isValidPath($pageTSconfig, 'options./backendLayout./exclude')) {
229  $identifiersToBeExcluded = ‪GeneralUtility::trimExplode(
230  ',',
231  ‪ArrayUtility::getValueByPath($pageTSconfig, 'options./backendLayout./exclude'),
232  true
233  );
234  }
235 
236  return $identifiersToBeExcluded;
237  }
238 
246  public function ‪colPosListItemProcFunc(array $parameters)
247  {
248  $pageId = $this->‪determinePageId($parameters['table'], $parameters['row']);
249 
250  if ($pageId !== false) {
251  $parameters['items'] = $this->‪addColPosListLayoutItems($pageId, $parameters['items']);
252  }
253  }
254 
262  protected function ‪addColPosListLayoutItems($pageId, $items)
263  {
264  $layout = $this->‪getSelectedBackendLayout($pageId);
265  if ($layout && $layout['__items']) {
266  $items = $layout['__items'];
267  }
268  return $items;
269  }
270 
277  public function ‪getColPosListItemsParsed($id)
278  {
279  $tsConfig = ‪BackendUtility::getPagesTSconfig($id)['TCEFORM.']['tt_content.']['colPos.'] ?? [];
280  $tcaConfig = ‪$GLOBALS['TCA']['tt_content']['columns']['colPos']['config'];
281  $tcaItems = $tcaConfig['items'];
282  $tcaItems = $this->‪addItems($tcaItems, $tsConfig['addItems.']);
283  if (isset($tcaConfig['itemsProcFunc']) && $tcaConfig['itemsProcFunc']) {
284  $tcaItems = $this->‪addColPosListLayoutItems($id, $tcaItems);
285  }
286  if (!empty($tsConfig['removeItems'])) {
287  foreach (‪GeneralUtility::trimExplode(',', $tsConfig['removeItems'], true) as $removeId) {
288  foreach ($tcaItems as $key => $item) {
289  if ($item[1] == $removeId) {
290  unset($tcaItems[$key]);
291  }
292  }
293  }
294  }
295  return $tcaItems;
296  }
297 
309  protected function ‪addItems($items, $iArray)
310  {
311  $languageService = static::getLanguageService();
312  if (is_array($iArray)) {
313  foreach ($iArray as $value => $label) {
314  // if the label is an array (that means it is a subelement
315  // like "34.icon = mylabel.png", skip it (see its usage below)
316  if (is_array($label)) {
317  continue;
318  }
319  // check if the value "34 = mylabel" also has a "34.icon = myimage.png"
320  if (isset($iArray[$value . '.']) && $iArray[$value . '.']['icon']) {
321  $icon = $iArray[$value . '.']['icon'];
322  } else {
323  $icon = '';
324  }
325  $items[] = [$languageService->sL($label), $value, $icon];
326  }
327  }
328  return $items;
329  }
330 
337  public function ‪getSelectedBackendLayout($pageId)
338  {
339  $layout = $this->‪getBackendLayoutForPage((int)$pageId);
340  if ($layout instanceof ‪BackendLayout) {
341  return $layout->getStructure();
342  }
343  return null;
344  }
345 
351  public function ‪getBackendLayoutForPage(int $pageId): ?‪BackendLayout
352  {
353  if (isset($this->selectedBackendLayout[$pageId])) {
354  return $this->selectedBackendLayout[$pageId];
355  }
357  // If no backend layout is selected, use default
358  if (empty(‪$selectedCombinedIdentifier)) {
359  ‪$selectedCombinedIdentifier = 'default';
360  }
362  // If backend layout is not found available anymore, use default
363  if ($backendLayout === null) {
364  $backendLayout = $this->‪getDataProviderCollection()->‪getBackendLayout('default', $pageId);
365  }
366 
367  if ($backendLayout instanceof ‪BackendLayout) {
368  $this->selectedBackendLayout[$pageId] = $backendLayout;
369  }
370  return $backendLayout;
371  }
372 
378  public function ‪parseStructure(‪BackendLayout $backendLayout): array
379  {
380  ‪$parser = GeneralUtility::makeInstance(TypoScriptParser::class);
381  $conditionMatcher = GeneralUtility::makeInstance(ConditionMatcher::class);
382  ‪$parser->parse(‪TypoScriptParser::checkIncludeLines($backendLayout->‪getConfiguration()), $conditionMatcher);
383 
384  $backendLayoutData = [];
385  $backendLayoutData['config'] = $backendLayout->‪getConfiguration();
386  $backendLayoutData['__config'] = ‪$parser->setup;
387  $backendLayoutData['__items'] = [];
388  $backendLayoutData['__colPosList'] = [];
389  $backendLayoutData['usedColumns'] = [];
390 
391  // create items and colPosList
392  if (!empty($backendLayoutData['__config']['backend_layout.']['rows.'])) {
393  foreach ($backendLayoutData['__config']['backend_layout.']['rows.'] as $row) {
394  if (!empty($row['columns.'])) {
395  foreach ($row['columns.'] as $column) {
396  if (!isset($column['colPos'])) {
397  continue;
398  }
399  $backendLayoutData['__items'][] = [
400  $this->‪getColumnName($column),
401  $column['colPos'],
402  null
403  ];
404  $backendLayoutData['__colPosList'][] = $column['colPos'];
405  $backendLayoutData['usedColumns'][(int)$column['colPos']] = $column['name'];
406  }
407  }
408  }
409  }
410  return $backendLayoutData;
411  }
412 
419  public static function ‪getDefaultColumnLayout()
420  {
421  return '
422  backend_layout {
423  colCount = 1
424  rowCount = 1
425  rows {
426  1 {
427  columns {
428  1 {
429  name = LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:colPos.I.1
430  colPos = 0
431  }
432  }
433  }
434  }
435  }
436  ';
437  }
438 
445  protected function ‪getPage($pageId)
446  {
447  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
448  ->getQueryBuilderForTable('pages');
449  $queryBuilder->getRestrictions()
450  ->removeAll();
451  $page = $queryBuilder
452  ->select('uid', 'pid', 'backend_layout')
453  ->from('pages')
454  ->where(
455  $queryBuilder->expr()->eq(
456  'uid',
457  $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
458  )
459  )
460  ->execute()
461  ->fetch();
462  ‪BackendUtility::workspaceOL('pages', $page);
463 
464  return $page;
465  }
466 
473  protected function ‪getRootLine($pageId)
474  {
475  return ‪BackendUtility::BEgetRootLine($pageId, '', true);
476  }
477 
481  protected function ‪createDataProviderContext()
482  {
483  return GeneralUtility::makeInstance(DataProviderContext::class);
484  }
485 
489  protected function ‪getLanguageService()
490  {
491  return ‪$GLOBALS['LANG'];
492  }
493 
500  protected function ‪getColumnName($column)
501  {
502  $columnName = $column['name'];
503 
504  if (GeneralUtility::isFirstPartOfStr($columnName, 'LLL:')) {
505  $columnName = $this->‪getLanguageService()->‪sL($columnName);
506  }
507 
508  return $columnName;
509  }
510 }
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext\setPageId
‪DataProviderContext setPageId($pageId)
Definition: DataProviderContext.php:57
‪TYPO3\CMS\Backend\View\BackendLayoutView\determinePageId
‪int false determinePageId($tableName, array $data)
Definition: BackendLayoutView.php:141
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext\setTableName
‪DataProviderContext setTableName($tableName)
Definition: DataProviderContext.php:75
‪TYPO3\CMS\Backend\View\BackendLayoutView\getSelectedBackendLayout
‪array null getSelectedBackendLayout($pageId)
Definition: BackendLayoutView.php:334
‪TYPO3\CMS\Backend\View\BackendLayoutView\addColPosListLayoutItems
‪array addColPosListLayoutItems($pageId, $items)
Definition: BackendLayoutView.php:259
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
Definition: TypoScriptParser.php:37
‪TYPO3\CMS\Backend\View
Definition: ArrayBrowser.php:18
‪TYPO3\CMS\Backend\View\BackendLayoutView\colPosListItemProcFunc
‪colPosListItemProcFunc(array $parameters)
Definition: BackendLayoutView.php:243
‪TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
Definition: ConditionMatcher.php:30
‪TYPO3\CMS\Backend\View\BackendLayoutView\getIdentifiersToBeExcluded
‪array getIdentifiersToBeExcluded(array $pageTSconfig)
Definition: BackendLayoutView.php:221
‪TYPO3\CMS\Backend\View\BackendLayoutView\getRootLine
‪array getRootLine($pageId)
Definition: BackendLayoutView.php:470
‪TYPO3\CMS\Core\Utility\ArrayUtility\isValidPath
‪static bool isValidPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:144
‪TYPO3\CMS\Backend\View\BackendLayoutView\$selectedBackendLayout
‪array $selectedBackendLayout
Definition: BackendLayoutView.php:47
‪$parser
‪$parser
Definition: annotationChecker.php:108
‪TYPO3\CMS\Backend\View\BackendLayoutView\createDataProviderContext
‪DataProviderContext createDataProviderContext()
Definition: BackendLayoutView.php:478
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderCollection
Definition: DataProviderCollection.php:25
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext\setFieldName
‪DataProviderContext setFieldName($fieldName)
Definition: DataProviderContext.php:93
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:194
‪TYPO3\CMS\Backend\View\BackendLayoutView\parseStructure
‪array parseStructure(BackendLayout $backendLayout)
Definition: BackendLayoutView.php:375
‪TYPO3\CMS\Backend\View\BackendLayoutView\$dataProviderCollection
‪DataProviderCollection $dataProviderCollection
Definition: BackendLayoutView.php:39
‪TYPO3\CMS\Backend\Utility\BackendUtility\BEgetRootLine
‪static array BEgetRootLine($uid, $clause='', $workspaceOL=false, array $additionalFields=[])
Definition: BackendUtility.php:343
‪TYPO3\CMS\Backend\View\BackendLayoutView\setDataProviderCollection
‪setDataProviderCollection(DataProviderCollection $dataProviderCollection)
Definition: BackendLayoutView.php:78
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext\setPageTsConfig
‪DataProviderContext setPageTsConfig(array $pageTsConfig)
Definition: DataProviderContext.php:129
‪TYPO3\CMS\Backend\View\BackendLayoutView\initializeDataProviderCollection
‪initializeDataProviderCollection()
Definition: BackendLayoutView.php:60
‪TYPO3\CMS\Backend\View\BackendLayoutView\getColumnName
‪string getColumnName($column)
Definition: BackendLayoutView.php:497
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static mixed getValueByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:180
‪TYPO3\CMS\Backend\View\BackendLayoutView\getLanguageService
‪LanguageService getLanguageService()
Definition: BackendLayoutView.php:486
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderCollection\add
‪add($identifier, $classNameOrObject)
Definition: DataProviderCollection.php:42
‪TYPO3\CMS\Backend\View\BackendLayout\BackendLayoutCollection\getIdentifier
‪string getIdentifier()
Definition: BackendLayoutCollection.php:42
‪TYPO3\CMS\Backend\View\BackendLayoutView\__construct
‪__construct()
Definition: BackendLayoutView.php:52
‪TYPO3\CMS\Backend\View\BackendLayoutView\getDefaultColumnLayout
‪static string getDefaultColumnLayout()
Definition: BackendLayoutView.php:416
‪TYPO3\CMS\Backend\View\BackendLayout\BackendLayout\getConfiguration
‪string getConfiguration()
Definition: BackendLayout.php:164
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser\checkIncludeLines
‪static string array checkIncludeLines($string, $cycle_counter=1, $returnFiles=false, $parentFilenameOrPath='')
Definition: TypoScriptParser.php:792
‪TYPO3\CMS\Backend\Utility\BackendUtility\getPagesTSconfig
‪static array getPagesTSconfig($id)
Definition: BackendUtility.php:698
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderCollection\getBackendLayoutCollections
‪array BackendLayoutCollection[] getBackendLayoutCollections(DataProviderContext $dataProviderContext)
Definition: DataProviderCollection.php:77
‪TYPO3\CMS\Backend\View\BackendLayoutView\addItems
‪array addItems($items, $iArray)
Definition: BackendLayoutView.php:306
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Backend\View\BackendLayoutView
Definition: BackendLayoutView.php:36
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:24
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:23
‪$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:3586
‪TYPO3\CMS\Backend\View\BackendLayoutView\getDataProviderCollection
‪DataProviderCollection getDataProviderCollection()
Definition: BackendLayoutView.php:86
‪TYPO3\CMS\Backend\View\BackendLayout\BackendLayout
Definition: BackendLayout.php:25
‪TYPO3\CMS\Backend\View\BackendLayoutView\getColPosListItemsParsed
‪array getColPosListItemsParsed($id)
Definition: BackendLayoutView.php:274
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext\setData
‪DataProviderContext setData(array $data)
Definition: DataProviderContext.php:111
‪TYPO3\CMS\Backend\View\BackendLayoutView\getPage
‪array null getPage($pageId)
Definition: BackendLayoutView.php:442
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderCollection\getBackendLayout
‪BackendLayout null getBackendLayout($combinedIdentifier, $pageId)
Definition: DataProviderCollection.php:100
‪TYPO3\CMS\Backend\View\BackendLayoutView\getSelectedCombinedIdentifier
‪bool string getSelectedCombinedIdentifier($pageId)
Definition: BackendLayoutView.php:181
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext
Definition: DataProviderContext.php:24
‪TYPO3\CMS\Backend\View\BackendLayoutView\getBackendLayoutForPage
‪BackendLayout getBackendLayoutForPage(int $pageId)
Definition: BackendLayoutView.php:348
‪TYPO3\CMS\Backend\View\BackendLayoutView\addBackendLayoutItems
‪addBackendLayoutItems(array $parameters)
Definition: BackendLayoutView.php:98
‪TYPO3\CMS\Backend\View\BackendLayout\DefaultDataProvider
Definition: DefaultDataProvider.php:31
‪TYPO3\CMS\Backend\View\BackendLayoutView\$selectedCombinedIdentifier
‪array $selectedCombinedIdentifier
Definition: BackendLayoutView.php:43