Skip to content

Commit

Permalink
[TASK] Reduce overhead in BackendLayoutView
Browse files Browse the repository at this point in the history
BackendLayoutView is used to build the BackendLayout
structure, and does a few things too much:

a) it uses ArrayUtility over a simple isset() check for pageTsconfig
b) it resolves LLL labels directly, even if MoveContent wizard and Page module handle that as well
c) it re-builds logic only used in Move Content which is not needed due to a properly resolved colPos list already

All of this internal code can be removed and thus reduced to
a minimum, with Page module, FormEngine (pages+tt_content) and Move
Content Wizard continue to work, because FormEngine and all
other modules already use the proper API for rendering already.

Resolves: #103463
Releases: main
Change-Id: Ib3878d08936e60a9cbd2f405260f3badcefcf8ae
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83565
Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de>
Tested-by: Andreas Kienast <a.fernandez@scripting-base.de>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
  • Loading branch information
bmack authored and o-ba committed Mar 22, 2024
1 parent 39e97c6 commit 3c5e869
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 97 deletions.
5 changes: 0 additions & 5 deletions Build/phpstan/phpstan-baseline.neon
Expand Up @@ -155,11 +155,6 @@ parameters:
count: 1
path: ../../typo3/sysext/backend/Classes/Tree/Renderer/UnorderedListTreeRenderer.php

-
message: "#^Variable \\$columnsConfiguration in empty\\(\\) always exists and is not falsy\\.$#"
count: 1
path: ../../typo3/sysext/backend/Classes/Tree/View/AbstractContentPagePositionMap.php

-
message: "#^Else branch is unreachable because previous condition is always true\\.$#"
count: 2
Expand Down
Expand Up @@ -283,28 +283,28 @@ protected function printRecordMap(array $lines, array $tcaColumnsConfiguration,
* Fetch TCA colPos list from BackendLayoutView and prepare for map generation.
* This also takes the "colPos_list" TSconfig into account.
*/
protected function getColumnsConfiguration(int $id): array
protected function getColumnsConfiguration(int $pageId): array
{
$columnsConfiguration = $this->backendLayoutView->getColPosListItemsParsed($id);
if ($columnsConfiguration === []) {
$backendLayout = $this->backendLayoutView->getBackendLayoutForPage($pageId);
if (!$backendLayout) {
return [];
}

$items = [];
// Prepare the columns configuration (using named keys, etc.)
foreach ($columnsConfiguration as &$item) {
$item = [
'title' => $item['label'] ?? '',
'colPos' => (int)($item['value'] ?? 0),
foreach ($backendLayout->getUsedColumns() as $colPos => $label) {
$items[] = [
'title' => $label,
'colPos' => (int)$colPos,
'isRestricted' => false,
];
}
unset($item);

$sharedColPosList = trim(BackendUtility::getPagesTSconfig($id)['mod.']['SHARED.']['colPos_list'] ?? '');
$sharedColPosList = trim(BackendUtility::getPagesTSconfig($pageId)['mod.']['SHARED.']['colPos_list'] ?? '');
if ($sharedColPosList !== '') {
$activeColPosArray = array_unique(GeneralUtility::intExplode(',', $sharedColPosList));
if (!empty($columnsConfiguration) && !empty($activeColPosArray)) {
foreach ($columnsConfiguration as &$item) {
if (!empty($items) && !empty($activeColPosArray)) {
foreach ($items as &$item) {
if (!in_array((int)$item['colPos'], $activeColPosArray, true)) {
$item['isRestricted'] = true;
}
Expand All @@ -313,7 +313,7 @@ protected function getColumnsConfiguration(int $id): array
}
}

return $columnsConfiguration;
return $items;
}

protected function getBackendUser(): BackendUserAuthentication
Expand Down
86 changes: 6 additions & 80 deletions typo3/sysext/backend/Classes/View/BackendLayoutView.php
Expand Up @@ -24,10 +24,8 @@
use TYPO3\CMS\Backend\View\BackendLayout\DefaultDataProvider;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\TypoScript\TypoScriptStringFactory;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
Expand Down Expand Up @@ -93,7 +91,7 @@ public function addBackendLayoutItems(array &$parameters)
}

$parameters['items'][] = [
'label' => $this->getLanguageService()->sL($backendLayout->getTitle()),
'label' => $backendLayout->getTitle(),
'value' => $combinedIdentifier,
'icon' => $backendLayout->getIconPath(),
];
Expand Down Expand Up @@ -187,17 +185,14 @@ protected function getSelectedCombinedIdentifier(int $pageId): string|false
*/
protected function getIdentifiersToBeExcluded(array $pageTSconfig): array
{
$identifiersToBeExcluded = [];

if (ArrayUtility::isValidPath($pageTSconfig, 'options./backendLayout./exclude')) {
$identifiersToBeExcluded = GeneralUtility::trimExplode(
if (isset($pageTSconfig['options.']['backendLayout.']['exclude'])) {
return GeneralUtility::trimExplode(
',',
ArrayUtility::getValueByPath($pageTSconfig, 'options./backendLayout./exclude'),
$pageTSconfig['options.']['backendLayout.']['exclude'],
true
);
}

return $identifiersToBeExcluded;
return [];
}

/**
Expand Down Expand Up @@ -226,62 +221,6 @@ protected function addColPosListLayoutItems(int $pageId, array $items): array
return $items;
}

/**
* Gets the list of available columns for a given page id
* @todo: will be removed once Page Position Map for content is removed.
*/
public function getColPosListItemsParsed(int $id): array
{
$tsConfig = BackendUtility::getPagesTSconfig($id)['TCEFORM.']['tt_content.']['colPos.'] ?? [];
$tcaConfig = $GLOBALS['TCA']['tt_content']['columns']['colPos']['config'] ?? [];
$tcaItems = $tcaConfig['items'];
$tcaItems = $this->addItems($tcaItems, $tsConfig['addItems.'] ?? []);
if (isset($tcaConfig['itemsProcFunc']) && $tcaConfig['itemsProcFunc']) {
$tcaItems = $this->addColPosListLayoutItems($id, $tcaItems);
}
if (!empty($tsConfig['removeItems'])) {
foreach (GeneralUtility::trimExplode(',', $tsConfig['removeItems'], true) as $removeId) {
foreach ($tcaItems as $key => $item) {
if ($item[1] == $removeId) {
unset($tcaItems[$key]);
}
}
}
}
return $tcaItems;
}

/**
* Merges items into an item-array, optionally with an icon
* example:
* TCEFORM.pages.doktype.addItems.13 = My Label
* TCEFORM.pages.doktype.addItems.13.icon = EXT:t3skin/icons/gfx/i/pages.gif
*
* @param array $items The existing item array
* @param array $iArray An array of items to add. NOTICE: The keys are mapped to values, and the values and mapped to be labels. No possibility of adding an icon.
* @return array The updated $item array
* @internal
*/
protected function addItems(array $items, array $iArray): array
{
$languageService = $this->getLanguageService();
foreach ($iArray as $value => $label) {
// if the label is an array (that means it is a subelement
// like "34.icon = mylabel.png", skip it (see its usage below)
if (is_array($label)) {
continue;
}
// check if the value "34 = mylabel" also has a "34.icon = myimage.png"
if (isset($iArray[$value . '.']) && $iArray[$value . '.']['icon']) {
$icon = $iArray[$value . '.']['icon'];
} else {
$icon = '';
}
$items[] = [$languageService->sL($label), $value, $icon];
}
return $items;
}

/**
* Gets the selected backend layout structure as an array
*/
Expand Down Expand Up @@ -342,7 +281,7 @@ public function parseStructure(BackendLayout $backendLayout): array
continue;
}
$backendLayoutData['__items'][] = [
'label' => $this->getColumnName($column),
'label' => $column['name'],
'value' => $column['colPos'],
'icon' => null,
];
Expand Down Expand Up @@ -404,17 +343,4 @@ protected function getPage(int $pageId): ?array

return is_array($page) ? $page : null;
}

protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}

/**
* Get column name from colPos item structure
*/
protected function getColumnName(array $column): string
{
return $this->getLanguageService()->sL($column['name']);
}
}

0 comments on commit 3c5e869

Please sign in to comment.