‪TYPO3CMS  9.5
BackendLayoutView.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 
22 
28 {
33 
37  protected ‪$selectedCombinedIdentifier = [];
38 
42  protected ‪$selectedBackendLayout = [];
43 
47  public function ‪__construct()
48  {
50  }
51 
55  protected function ‪initializeDataProviderCollection()
56  {
58  ‪$dataProviderCollection = GeneralUtility::makeInstance(
59  BackendLayout\DataProviderCollection::class
60  );
61 
63  'default',
64  \‪TYPO3\CMS\Backend\View\BackendLayout\DefaultDataProvider::class
65  );
66 
67  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['BackendLayoutDataProvider'])) {
68  $dataProviders = (array)‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['BackendLayoutDataProvider'];
69  foreach ($dataProviders as $identifier => $className) {
70  ‪$dataProviderCollection->add($identifier, $className);
71  }
72  }
73 
75  }
76 
80  public function ‪setDataProviderCollection(BackendLayout\DataProviderCollection ‪$dataProviderCollection)
81  {
82  $this->dataProviderCollection = ‪$dataProviderCollection;
83  }
84 
88  public function ‪getDataProviderCollection()
89  {
91  }
92 
100  public function ‪addBackendLayoutItems(array $parameters)
101  {
102  $pageId = $this->‪determinePageId($parameters['table'], $parameters['row']);
103  $pageTsConfig = (array)‪BackendUtility::getPagesTSconfig($pageId);
104  $identifiersToBeExcluded = $this->‪getIdentifiersToBeExcluded($pageTsConfig);
105 
106  $dataProviderContext = $this->‪createDataProviderContext()
107  ->setPageId($pageId)
108  ->setData($parameters['row'])
109  ->setTableName($parameters['table'])
110  ->setFieldName($parameters['field'])
111  ->setPageTsConfig($pageTsConfig);
112 
113  $backendLayoutCollections = $this->‪getDataProviderCollection()->getBackendLayoutCollections($dataProviderContext);
114  foreach ($backendLayoutCollections as $backendLayoutCollection) {
115  $combinedIdentifierPrefix = '';
116  if ($backendLayoutCollection->getIdentifier() !== 'default') {
117  $combinedIdentifierPrefix = $backendLayoutCollection->getIdentifier() . '__';
118  }
119 
120  foreach ($backendLayoutCollection->getAll() as $backendLayout) {
121  $combinedIdentifier = $combinedIdentifierPrefix . $backendLayout->getIdentifier();
122 
123  if (in_array($combinedIdentifier, $identifiersToBeExcluded, true)) {
124  continue;
125  }
126 
127  $parameters['items'][] = [
128  $this->‪getLanguageService()->‪sL($backendLayout->getTitle()),
129  $combinedIdentifier,
130  $backendLayout->getIconPath(),
131  ];
132  }
133  }
134  }
135 
143  protected function ‪determinePageId($tableName, array $data)
144  {
145  if (strpos($data['uid'], 'NEW') === 0) {
146  // negative uid_pid values of content elements indicate that the element
147  // has been inserted after an existing element so there is no pid to get
148  // the backendLayout for and we have to get that first
149  if ($data['pid'] < 0) {
150  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
151  ->getQueryBuilderForTable($tableName);
152  $queryBuilder->getRestrictions()
153  ->removeAll();
154  $pageId = $queryBuilder
155  ->select('pid')
156  ->from($tableName)
157  ->where(
158  $queryBuilder->expr()->eq(
159  'uid',
160  $queryBuilder->createNamedParameter(abs($data['pid']), \PDO::PARAM_INT)
161  )
162  )
163  ->execute()
164  ->fetchColumn();
165  } else {
166  $pageId = $data['pid'];
167  }
168  } elseif ($tableName === 'pages') {
169  $pageId = $data['uid'];
170  } else {
171  $pageId = $data['pid'];
172  }
173 
174  return $pageId;
175  }
176 
183  public function ‪getSelectedCombinedIdentifier($pageId)
184  {
185  if (!isset($this->selectedCombinedIdentifier[$pageId])) {
186  $page = $this->‪getPage($pageId);
187  $this->selectedCombinedIdentifier[$pageId] = (string)$page['backend_layout'];
188 
189  if ($this->selectedCombinedIdentifier[$pageId] === '-1') {
190  // If it is set to "none" - don't use any
191  $this->selectedCombinedIdentifier[$pageId] = false;
192  } elseif ($this->selectedCombinedIdentifier[$pageId] === '' || $this->selectedCombinedIdentifier[$pageId] === '0') {
193  // If it not set check the root-line for a layout on next level and use this
194  // (root-line starts with current page and has page "0" at the end)
195  $rootLine = $this->‪getRootLine($pageId);
196  // Remove first and last element (current and root page)
197  array_shift($rootLine);
198  array_pop($rootLine);
199  foreach ($rootLine as $rootLinePage) {
200  $this->selectedCombinedIdentifier[$pageId] = (string)$rootLinePage['backend_layout_next_level'];
201  if ($this->selectedCombinedIdentifier[$pageId] === '-1') {
202  // If layout for "next level" is set to "none" - don't use any and stop searching
203  $this->selectedCombinedIdentifier[$pageId] = false;
204  break;
205  }
206  if ($this->selectedCombinedIdentifier[$pageId] !== '' && $this->selectedCombinedIdentifier[$pageId] !== '0') {
207  // Stop searching if a layout for "next level" is set
208  break;
209  }
210  }
211  }
212  }
213  // If it is set to a positive value use this
214  return $this->selectedCombinedIdentifier[$pageId];
215  }
216 
223  protected function ‪getIdentifiersToBeExcluded(array $pageTSconfig)
224  {
225  $identifiersToBeExcluded = [];
226 
227  if (‪ArrayUtility::isValidPath($pageTSconfig, 'options./backendLayout./exclude')) {
228  $identifiersToBeExcluded = GeneralUtility::trimExplode(
229  ',',
230  ‪ArrayUtility::getValueByPath($pageTSconfig, 'options./backendLayout./exclude'),
231  true
232  );
233  }
234 
235  return $identifiersToBeExcluded;
236  }
237 
245  public function ‪colPosListItemProcFunc(array $parameters)
246  {
247  $pageId = $this->‪determinePageId($parameters['table'], $parameters['row']);
248 
249  if ($pageId !== false) {
250  $parameters['items'] = $this->‪addColPosListLayoutItems($pageId, $parameters['items']);
251  }
252  }
253 
261  protected function ‪addColPosListLayoutItems($pageId, $items)
262  {
263  $layout = $this->‪getSelectedBackendLayout($pageId);
264  if ($layout && $layout['__items']) {
265  $items = $layout['__items'];
266  }
267  return $items;
268  }
269 
276  public function ‪getColPosListItemsParsed($id)
277  {
278  $tsConfig = ‪BackendUtility::getPagesTSconfig($id)['TCEFORM.']['tt_content.']['colPos.'] ?? [];
279  $tcaConfig = ‪$GLOBALS['TCA']['tt_content']['columns']['colPos']['config'];
280  $tcaItems = $tcaConfig['items'];
281  $tcaItems = $this->‪addItems($tcaItems, $tsConfig['addItems.']);
282  if (isset($tcaConfig['itemsProcFunc']) && $tcaConfig['itemsProcFunc']) {
283  $tcaItems = $this->‪addColPosListLayoutItems($id, $tcaItems);
284  }
285  if (!empty($tsConfig['removeItems'])) {
286  foreach (GeneralUtility::trimExplode(',', $tsConfig['removeItems'], true) as $removeId) {
287  foreach ($tcaItems as $key => $item) {
288  if ($item[1] == $removeId) {
289  unset($tcaItems[$key]);
290  }
291  }
292  }
293  }
294  return $tcaItems;
295  }
296 
308  protected function ‪addItems($items, $iArray)
309  {
310  $languageService = static::getLanguageService();
311  if (is_array($iArray)) {
312  foreach ($iArray as $value => $label) {
313  // if the label is an array (that means it is a subelement
314  // like "34.icon = mylabel.png", skip it (see its usage below)
315  if (is_array($label)) {
316  continue;
317  }
318  // check if the value "34 = mylabel" also has a "34.icon = myimage.png"
319  if (isset($iArray[$value . '.']) && $iArray[$value . '.']['icon']) {
320  $icon = $iArray[$value . '.']['icon'];
321  } else {
322  $icon = '';
323  }
324  $items[] = [$languageService->sL($label), $value, $icon];
325  }
326  }
327  return $items;
328  }
329 
336  public function ‪getSelectedBackendLayout($pageId)
337  {
338  if (isset($this->selectedBackendLayout[$pageId])) {
339  return $this->selectedBackendLayout[$pageId];
340  }
341  $backendLayoutData = null;
342 
344  // If no backend layout is selected, use default
345  if (empty(‪$selectedCombinedIdentifier)) {
346  ‪$selectedCombinedIdentifier = 'default';
347  }
348 
349  $backendLayout = $this->‪getDataProviderCollection()->getBackendLayout(‪$selectedCombinedIdentifier, $pageId);
350  // If backend layout is not found available anymore, use default
351  if ($backendLayout === null) {
352  ‪$selectedCombinedIdentifier = 'default';
353  $backendLayout = $this->‪getDataProviderCollection()->getBackendLayout(‪$selectedCombinedIdentifier, $pageId);
354  }
355 
356  if (!empty($backendLayout)) {
358  ‪$parser = GeneralUtility::makeInstance(TypoScriptParser::class);
360  $conditionMatcher = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher::class);
361  ‪$parser->parse(‪TypoScriptParser::checkIncludeLines($backendLayout->getConfiguration()), $conditionMatcher);
362 
363  $backendLayoutData = [];
364  $backendLayoutData['config'] = $backendLayout->getConfiguration();
365  $backendLayoutData['__config'] = ‪$parser->setup;
366  $backendLayoutData['__items'] = [];
367  $backendLayoutData['__colPosList'] = [];
368 
369  // create items and colPosList
370  if (!empty($backendLayoutData['__config']['backend_layout.']['rows.'])) {
371  foreach ($backendLayoutData['__config']['backend_layout.']['rows.'] as $row) {
372  if (!empty($row['columns.'])) {
373  foreach ($row['columns.'] as $column) {
374  if (!isset($column['colPos'])) {
375  continue;
376  }
377  $backendLayoutData['__items'][] = [
378  $this->‪getColumnName($column),
379  $column['colPos'],
380  null
381  ];
382  $backendLayoutData['__colPosList'][] = $column['colPos'];
383  }
384  }
385  }
386  }
387 
388  $this->selectedBackendLayout[$pageId] = $backendLayoutData;
389  }
390 
391  return $backendLayoutData;
392  }
393 
400  public static function ‪getDefaultColumnLayout()
401  {
402  return '
403  backend_layout {
404  colCount = 1
405  rowCount = 1
406  rows {
407  1 {
408  columns {
409  1 {
410  name = LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:colPos.I.1
411  colPos = 0
412  }
413  }
414  }
415  }
416  }
417  ';
418  }
419 
426  protected function ‪getPage($pageId)
427  {
428  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
429  ->getQueryBuilderForTable('pages');
430  $queryBuilder->getRestrictions()
431  ->removeAll();
432  $page = $queryBuilder
433  ->select('uid', 'pid', 'backend_layout')
434  ->from('pages')
435  ->where(
436  $queryBuilder->expr()->eq(
437  'uid',
438  $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
439  )
440  )
441  ->execute()
442  ->fetch();
443  ‪BackendUtility::workspaceOL('pages', $page);
444 
445  return $page;
446  }
447 
454  protected function ‪getRootLine($pageId)
455  {
456  return ‪BackendUtility::BEgetRootLine($pageId, '', true);
457  }
458 
462  protected function ‪createDataProviderContext()
463  {
464  return GeneralUtility::makeInstance(BackendLayout\DataProviderContext::class);
465  }
466 
470  protected function ‪getLanguageService()
471  {
472  return ‪$GLOBALS['LANG'];
473  }
474 
481  protected function ‪getColumnName($column)
482  {
483  $columnName = $column['name'];
484 
485  if (GeneralUtility::isFirstPartOfStr($columnName, 'LLL:')) {
486  $columnName = $this->‪getLanguageService()->‪sL($columnName);
487  }
488 
489  return $columnName;
490  }
491 }
‪TYPO3\CMS\Backend\View\BackendLayoutView\getSelectedBackendLayout
‪array null getSelectedBackendLayout($pageId)
Definition: BackendLayoutView.php:333
‪TYPO3\CMS\Backend\View\BackendLayoutView\setDataProviderCollection
‪setDataProviderCollection(BackendLayout\DataProviderCollection $dataProviderCollection)
Definition: BackendLayoutView.php:77
‪TYPO3\CMS\Backend\View\BackendLayoutView\addColPosListLayoutItems
‪array addColPosListLayoutItems($pageId, $items)
Definition: BackendLayoutView.php:258
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
Definition: TypoScriptParser.php:37
‪TYPO3\CMS\Backend\View\BackendLayoutView\createDataProviderContext
‪BackendLayout DataProviderContext createDataProviderContext()
Definition: BackendLayoutView.php:459
‪TYPO3\CMS\Backend\View
‪TYPO3
‪TYPO3\CMS\Backend\View\BackendLayoutView\colPosListItemProcFunc
‪colPosListItemProcFunc(array $parameters)
Definition: BackendLayoutView.php:242
‪TYPO3\CMS\Backend\View\BackendLayoutView\getIdentifiersToBeExcluded
‪array getIdentifiersToBeExcluded(array $pageTSconfig)
Definition: BackendLayoutView.php:220
‪TYPO3\CMS\Backend\View\BackendLayoutView\getRootLine
‪array getRootLine($pageId)
Definition: BackendLayoutView.php:451
‪TYPO3\CMS\Core\Utility\ArrayUtility\isValidPath
‪static bool isValidPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:143
‪TYPO3\CMS\Backend\View\BackendLayoutView\$selectedBackendLayout
‪array $selectedBackendLayout
Definition: BackendLayoutView.php:39
‪$parser
‪$parser
Definition: annotationChecker.php:100
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderCollection
Definition: DataProviderCollection.php:21
‪TYPO3\CMS\Backend\View\BackendLayoutView\determinePageId
‪int bool determinePageId($tableName, array $data)
Definition: BackendLayoutView.php:140
‪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\Backend\View\BackendLayoutView\initializeDataProviderCollection
‪initializeDataProviderCollection()
Definition: BackendLayoutView.php:52
‪TYPO3\CMS\Backend\View\BackendLayoutView\getColumnName
‪string getColumnName($column)
Definition: BackendLayoutView.php:478
‪TYPO3\CMS\Backend\View\BackendLayoutView\getDataProviderCollection
‪BackendLayout DataProviderCollection getDataProviderCollection()
Definition: BackendLayoutView.php:85
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static mixed getValueByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:179
‪TYPO3\CMS\Backend\View\BackendLayoutView\__construct
‪__construct()
Definition: BackendLayoutView.php:44
‪TYPO3\CMS\Backend\View\BackendLayoutView\getDefaultColumnLayout
‪static string getDefaultColumnLayout()
Definition: BackendLayoutView.php:397
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser\checkIncludeLines
‪static string array checkIncludeLines($string, $cycle_counter=1, $returnFiles=false, $parentFilenameOrPath='')
Definition: TypoScriptParser.php:814
‪TYPO3\CMS\Backend\View\BackendLayoutView\getLanguageService
‪TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: BackendLayoutView.php:467
‪TYPO3\CMS\Backend\View\BackendLayoutView\addItems
‪array addItems($items, $iArray)
Definition: BackendLayoutView.php:305
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Backend\Utility\BackendUtility\getPagesTSconfig
‪static array getPagesTSconfig($id, $rootLine=null, $returnPartArray=false)
Definition: BackendUtility.php:864
‪TYPO3\CMS\Backend\View\BackendLayoutView
Definition: BackendLayoutView.php:28
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:23
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$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\Backend\View\BackendLayoutView\getColPosListItemsParsed
‪array getColPosListItemsParsed($id)
Definition: BackendLayoutView.php:273
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\View\BackendLayoutView\getPage
‪array null getPage($pageId)
Definition: BackendLayoutView.php:423
‪TYPO3\CMS\Backend\View\BackendLayoutView\getSelectedCombinedIdentifier
‪bool string getSelectedCombinedIdentifier($pageId)
Definition: BackendLayoutView.php:180
‪TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext
Definition: DataProviderContext.php:21
‪TYPO3\CMS\Backend\View\BackendLayoutView\addBackendLayoutItems
‪addBackendLayoutItems(array $parameters)
Definition: BackendLayoutView.php:97
‪TYPO3\CMS\Backend\View\BackendLayoutView\$selectedCombinedIdentifier
‪array $selectedCombinedIdentifier
Definition: BackendLayoutView.php:35
‪TYPO3\CMS\Backend\View\BackendLayoutView\$dataProviderCollection
‪BackendLayout DataProviderCollection $dataProviderCollection
Definition: BackendLayoutView.php:31