From 31439e93ffe4ea8de1588a3494b08c06bedd3823 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Fri, 8 Mar 2024 10:10:34 +0100 Subject: [PATCH] [TASK] Separation of concerns while rendering Page module All PageTsConfig options are now in DrawingConfiguration and named properly. All plain labels are now moved to Fluid directly via <f:translate> Random id="{uniqueId}" are removed from markup, reducing the usages to the AbstractGridObject, which hopefully will vanish in the near future. RecordRememberer is a singleton and injected as much as possible. The "languageMode" is now resolved into a PageViewMode enum. Resolves: #103345 Releases: main Change-Id: I78f33fed409db2a1c5528e734ed19ad67aeb4e89 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83322 Reviewed-by: Nikita Hovratov <nikita.h@live.de> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: core-ci <typo3@b13.com> Tested-by: Andreas Kienast <a.fernandez@scripting-base.de> Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de> Tested-by: Nikita Hovratov <nikita.h@live.de> --- .../Controller/PageLayoutController.php | 41 ++++--------- .../View/BackendLayout/ContentFetcher.php | 4 +- .../BackendLayout/Grid/AbstractGridObject.php | 6 -- .../Classes/View/BackendLayout/Grid/Grid.php | 2 +- .../View/BackendLayout/Grid/GridColumn.php | 24 ++++---- .../BackendLayout/Grid/GridColumnItem.php | 12 ++-- .../BackendLayout/Grid/LanguageColumn.php | 26 ++------ .../View/BackendLayout/RecordRememberer.php | 2 +- .../View/Drawing/BackendLayoutRenderer.php | 13 ++-- .../View/Drawing/DrawingConfiguration.php | 60 +++++++++++++------ .../Classes/View/PageLayoutContext.php | 15 ++--- .../backend/Classes/View/PageViewMode.php | 35 +++++++++++ .../PageLayout/Grid/ColumnHeader.html | 8 +-- .../Partials/PageLayout/LanguageColumns.html | 8 +-- .../Private/Partials/PageLayout/Record.html | 6 +- .../Templates/PageLayout/PageLayout.html | 2 +- .../Templates/PageLayout/PageModule.html | 2 +- .../Drawing/BackendLayoutRendererTest.php | 41 ++++++++++--- .../BackendUserAuthentication.php | 18 ++++-- .../core/Classes/Site/Entity/NullSite.php | 2 +- .../sysext/core/Classes/Site/Entity/Site.php | 2 +- .../Middleware/SiteBaseRedirectResolver.php | 2 +- 22 files changed, 191 insertions(+), 140 deletions(-) create mode 100644 typo3/sysext/backend/Classes/View/PageViewMode.php diff --git a/typo3/sysext/backend/Classes/Controller/PageLayoutController.php b/typo3/sysext/backend/Classes/Controller/PageLayoutController.php index 99c8d3e8ebd5..61142f8ac452 100644 --- a/typo3/sysext/backend/Classes/Controller/PageLayoutController.php +++ b/typo3/sysext/backend/Classes/Controller/PageLayoutController.php @@ -38,6 +38,7 @@ use TYPO3\CMS\Backend\View\BackendLayoutView; use TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer; use TYPO3\CMS\Backend\View\Drawing\DrawingConfiguration; use TYPO3\CMS\Backend\View\PageLayoutContext; +use TYPO3\CMS\Backend\View\PageViewMode; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -124,7 +125,7 @@ class PageLayoutController } $tsConfig = BackendUtility::getPagesTSconfig($this->id); - $this->menuConfig($request); + $this->menuConfig(); $this->currentSelectedLanguage = (int)$this->moduleData->get('language'); $this->addJavaScriptModuleInstructions(); $this->makeActionMenu($view, $tsConfig); @@ -134,9 +135,7 @@ class PageLayoutController $pageLayoutContext = $this->createPageLayoutContext($request, $tsConfig); $mainLayoutHtml = $this->backendLayoutRenderer->drawContent($request, $pageLayoutContext); - $numberOfHiddenElements = $this->getNumberOfHiddenElements( - $pageLayoutContext->getDrawingConfiguration()->getLanguageMode() - ); + $numberOfHiddenElements = $this->getNumberOfHiddenElements($pageLayoutContext->getDrawingConfiguration()); $pageLocalizationRecord = $this->getLocalizedPageRecord($this->currentSelectedLanguage); @@ -145,13 +144,13 @@ class PageLayoutController $view->assignMultiple([ 'pageId' => $this->id, 'localizedPageId' => $pageLocalizationRecord['uid'] ?? 0, + 'pageLayoutContext' => $pageLayoutContext, 'infoBoxes' => $this->generateMessagesForCurrentPage($request), 'isPageEditable' => $this->isPageEditable($this->currentSelectedLanguage), - 'localizedPageTitle' => $this->getLocalizedPageTitle($this->currentSelectedLanguage, $this->pageinfo), + 'localizedPageTitle' => $pageLocalizationRecord['title'] ?? $this->pageinfo['title'] ?? '', 'eventContentHtmlTop' => $event->getHeaderContent(), 'mainContentHtml' => $mainLayoutHtml, 'hiddenElementsShowToggle' => ($this->getBackendUser()->check('tables_select', 'tt_content') && ($numberOfHiddenElements > 0)), - 'hiddenElementsState' => (bool)$this->moduleData->get('showHidden'), 'hiddenElementsCount' => $numberOfHiddenElements, 'eventContentHtmlBottom' => $event->getFooterContent(), ]); @@ -161,21 +160,18 @@ class PageLayoutController protected function createPageLayoutContext(ServerRequestInterface $request, array $tsConfig): PageLayoutContext { $backendLayout = $this->backendLayoutView->getBackendLayoutForPage($this->id); - $configuration = DrawingConfiguration::create($backendLayout, $tsConfig); + $viewMode = (int)$this->moduleData->get('function') === 2 ? PageViewMode::LanguageComparisonView : PageViewMode::LayoutView; + $configuration = DrawingConfiguration::create($backendLayout, $tsConfig, $viewMode); $configuration->setShowHidden((bool)$this->moduleData->get('showHidden')); $configuration->setLanguageColumns($this->MOD_MENU['language']); $configuration->setSelectedLanguageId($this->currentSelectedLanguage); - if ((int)$this->moduleData->get('function') === 2) { - $configuration->setLanguageMode(true); - } - - return PageLayoutContext::create($this->pageinfo, $backendLayout, $request->getAttribute('site'), $configuration, $tsConfig); + return GeneralUtility::makeInstance(PageLayoutContext::class, $this->pageinfo, $backendLayout, $request->getAttribute('site'), $configuration, $request); } /** * Initialize menu array */ - protected function menuConfig(ServerRequestInterface $request): void + protected function menuConfig(): void { $backendUser = $this->getBackendUser(); $languageService = $this->getLanguageService(); @@ -462,18 +458,6 @@ class PageLayoutController return implode(', ', $links); } - protected function getLocalizedPageTitle(int $currentSelectedLanguage, array $pageInfo): string - { - if ($currentSelectedLanguage <= 0) { - return $pageInfo['title']; - } - $pageLocalizationRecord = $this->getLocalizedPageRecord($currentSelectedLanguage); - if (!is_array($pageLocalizationRecord)) { - return $pageInfo['title']; - } - return $pageLocalizationRecord['title'] ?? ''; - } - /** * Initializes the clipboard for generating paste links dynamically via JavaScript after each "+ Content" symbol */ @@ -686,8 +670,9 @@ class PageLayoutController * Returns the number of hidden elements (including those hidden by start/end times) * on the current page (for the current site language) */ - protected function getNumberOfHiddenElements(bool $isLanguageModeActive): int + protected function getNumberOfHiddenElements(DrawingConfiguration $drawingConfiguration): int { + $isLanguageComparisonModeActive = $drawingConfiguration->isLanguageComparisonMode(); $andWhere = []; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); $queryBuilder->getRestrictions() @@ -712,7 +697,7 @@ class PageLayoutController [-1, 0] ) ); - } elseif ($isLanguageModeActive && $this->currentSelectedLanguage !== -1) { + } elseif ($isLanguageComparisonModeActive && $this->currentSelectedLanguage !== -1) { // Multi-language view with any translation is active - // consider "all languages", the default and the translation $queryBuilder->andWhere( @@ -816,7 +801,7 @@ class PageLayoutController */ protected function getTargetPageIfVisible(array $targetPage): array { - return !(bool)($targetPage['hidden'] ?? false) ? $targetPage : []; + return !($targetPage['hidden'] ?? false) ? $targetPage : []; } /** diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php b/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php index 6c237bcff7df..ef1529ffbe83 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php @@ -75,7 +75,7 @@ class ContentFetcher $languageId = $languageId ?? $this->context->getSiteLanguage()->getLanguageId(); if (empty($this->fetchedContentRecords)) { - $isLanguageMode = $this->context->getDrawingConfiguration()->getLanguageMode(); + $isLanguageComparisonMode = $this->context->getDrawingConfiguration()->isLanguageComparisonMode(); $queryBuilder = $this->getQueryBuilder(); $result = $queryBuilder->executeQuery(); $records = $this->getResult($result); @@ -84,7 +84,7 @@ class ContentFetcher $recordColumnNumber = (int)$record['colPos']; if ($recordLanguage === -1) { // Record is set to "all languages", place it according to view mode. - if ($isLanguageMode) { + if ($isLanguageComparisonMode) { // Force the record to only be shown in default language in "Languages" view mode. $recordLanguage = 0; } else { diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/AbstractGridObject.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/AbstractGridObject.php index 3c26eb09cfb6..7265766aedbc 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/AbstractGridObject.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/AbstractGridObject.php @@ -22,7 +22,6 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\StringUtility; /** * Base class for objects which constitute a page layout grid. @@ -46,11 +45,6 @@ abstract class AbstractGridObject $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class); } - public function getUniqueId(): string - { - return StringUtility::getUniqueId(); - } - public function getContext(): PageLayoutContext { return $this->context; diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/Grid.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/Grid.php index 4d9a49d4f7af..56125a50e851 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/Grid.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/Grid.php @@ -66,7 +66,7 @@ class Grid extends AbstractGridObject public function getSpan(): int { - if (!isset($this->rows[0]) || $this->context->getDrawingConfiguration()->getLanguageMode()) { + if (!isset($this->rows[0]) || $this->context->getDrawingConfiguration()->isLanguageComparisonMode()) { return 1; } $span = 0; diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumn.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumn.php index 04db560122ce..890702d18a8b 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumn.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumn.php @@ -114,7 +114,7 @@ class GridColumn extends AbstractGridObject public function getColSpan(): int { - if ($this->context->getDrawingConfiguration()->getLanguageMode()) { + if ($this->context->getDrawingConfiguration()->isLanguageComparisonMode()) { return 1; } return $this->colSpan; @@ -122,7 +122,7 @@ class GridColumn extends AbstractGridObject public function getRowSpan(): int { - if ($this->context->getDrawingConfiguration()->getLanguageMode()) { + if ($this->context->getDrawingConfiguration()->isLanguageComparisonMode()) { return 1; } return $this->rowSpan; @@ -147,15 +147,19 @@ class GridColumn extends AbstractGridObject } $pageRecord = $this->context->getPageRecord(); if (!$this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT) - || !$this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage()->getLanguageId())) { + || !$this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage())) { return null; } - $pageTitleParamForAltDoc = '&recTitle=' . rawurlencode( - BackendUtility::getRecordTitle('pages', $pageRecord, true) - ); - $editParam = '&edit[' . $this->table . '][' . implode(',', $this->getAllContainedItemUids()) . ']=edit' . $pageTitleParamForAltDoc; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); - return $uriBuilder->buildUriFromRoute('record_edit') . $editParam . '&returnUrl=' . rawurlencode($GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri()); + return (string)$uriBuilder->buildUriFromRoute('record_edit', [ + 'edit' => [ + $this->table => [ + implode(',', $this->getAllContainedItemUids()) => 'edit', + ], + ], + 'recTitle' => rawurlencode(BackendUtility::getRecordTitle('pages', $pageRecord, true)), + 'returnUrl' => rawurlencode($this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri()), + ]); } public function getNewContentUrl(): string @@ -168,7 +172,7 @@ class GridColumn extends AbstractGridObject 'sys_language_uid' => $this->context->getSiteLanguage()->getLanguageId(), 'colPos' => $this->getColumnNumber(), 'uid_pid' => $pageId, - 'returnUrl' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(), + 'returnUrl' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(), ]); } @@ -229,7 +233,7 @@ class GridColumn extends AbstractGridObject $pageRecord = $this->context->getPageRecord(); return !$pageRecord['editlock'] && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT) - && $this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage()->getLanguageId()); + && $this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage()); } /** diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumnItem.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumnItem.php index d46dc6fb53aa..4087ffc22325 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumnItem.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumnItem.php @@ -125,7 +125,7 @@ class GridColumnItem extends AbstractGridObject ], ], ], - 'redirect' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(), + 'redirect' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(), ] ); } @@ -278,14 +278,12 @@ class GridColumnItem extends AbstractGridObject public function getNewContentAfterUrl(): string { $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); - $pageId = $this->context->getPageId(); - return (string)$uriBuilder->buildUriFromRoute('new_content_element_wizard', [ - 'id' => $pageId, + 'id' => $this->context->getPageId(), 'sys_language_uid' => $this->context->getSiteLanguage()->getLanguageId(), 'colPos' => $this->column->getColumnNumber(), 'uid_pid' => -$this->record['uid'], - 'returnUrl' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(), + 'returnUrl' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(), ]); } @@ -307,7 +305,7 @@ class GridColumnItem extends AbstractGridObject ], ], ], - 'redirect' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(), + 'redirect' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(), ] ) . '#element-' . $this->table . '-' . $this->record['uid']; } @@ -345,7 +343,7 @@ class GridColumnItem extends AbstractGridObject $this->record['uid'] => 'edit', ], ], - 'returnUrl' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri() . '#element-' . $this->table . '-' . $this->record['uid'], + 'returnUrl' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri() . '#element-' . $this->table . '-' . $this->record['uid'], ]; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); return $uriBuilder->buildUriFromRoute('record_edit', $urlParameters) . '#element-' . $this->table . '-' . $this->record['uid']; diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php index a5dcd6b39be1..5853cccdfe92 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php @@ -44,15 +44,12 @@ use TYPO3\CMS\Core\Versioning\VersionState; */ class LanguageColumn extends AbstractGridObject { - protected readonly array $localizationConfiguration; - public function __construct( protected PageLayoutContext $context, protected readonly Grid $grid, protected readonly array $translationInfo ) { parent::__construct($context); - $this->localizationConfiguration = BackendUtility::getPagesTSconfig($context->getPageId())['mod.']['web_layout.']['localization.'] ?? []; } public function getGrid(): Grid @@ -72,7 +69,7 @@ class LanguageColumn extends AbstractGridObject public function getAllowTranslate(): bool { - return ($this->localizationConfiguration['enableTranslate'] ?? true) && !($this->getTranslationData()['hasStandAloneContent'] ?? false); + return $this->context->getDrawingConfiguration()->translateModeForTranslationsAllowed() && !($this->getTranslationData()['hasStandAloneContent'] ?? false); } public function getTranslationData(): array @@ -82,23 +79,13 @@ class LanguageColumn extends AbstractGridObject public function getAllowTranslateCopy(): bool { - return ($this->localizationConfiguration['enableCopy'] ?? true) && !($this->getTranslationData()['hasTranslations'] ?? false); - } - - public function getTranslatePageTitle(): string - { - return $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newPageContent_translate'); + return $this->context->getDrawingConfiguration()->copyModeForTranslationsAllowed() && !($this->getTranslationData()['hasTranslations'] ?? false); } public function getAllowEditPage(): bool { return $this->getBackendUser()->check('tables_modify', 'pages') - && $this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage()->getLanguageId()); - } - - public function getPageEditTitle(): string - { - return $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:edit'); + && $this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage()); } public function getPageEditUrl(): string @@ -110,7 +97,7 @@ class LanguageColumn extends AbstractGridObject $pageRecordUid => 'edit', ], ], - 'returnUrl' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(), + 'returnUrl' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(), ]; // Disallow manual adjustment of the language field for pages if (($languageField = $GLOBALS['TCA']['pages']['ctrl']['languageField'] ?? '') !== '') { @@ -124,11 +111,6 @@ class LanguageColumn extends AbstractGridObject return VersionState::tryFrom($this->context->getPageRecord()['t3ver_state'] ?? 0) !== VersionState::DELETE_PLACEHOLDER; } - public function getViewPageLinkTitle(): string - { - return $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage'); - } - public function getPreviewUrlAttributes(): string { $pageId = $this->context->getPageId(); diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/RecordRememberer.php b/typo3/sysext/backend/Classes/View/BackendLayout/RecordRememberer.php index d01e7c3ae9f1..19d93258cea4 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/RecordRememberer.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/RecordRememberer.php @@ -27,7 +27,7 @@ class RecordRememberer implements SingletonInterface /** * @var int[] */ - protected $rememberedUids = []; + protected array $rememberedUids = []; public function rememberRecords(iterable $records): void { diff --git a/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php b/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php index 1357c705d773..d1c01a4a34fe 100644 --- a/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php +++ b/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php @@ -18,7 +18,6 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\View\Drawing; use Psr\Http\Message\ServerRequestInterface; -use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\View\BackendLayout\ContentFetcher; use TYPO3\CMS\Backend\View\BackendLayout\Grid\Grid; use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumn; @@ -48,14 +47,14 @@ class BackendLayoutRenderer { public function __construct( protected readonly BackendViewFactory $backendViewFactory, + protected readonly RecordRememberer $recordRememberer ) {} public function getGridForPageLayoutContext(PageLayoutContext $context): Grid { $contentFetcher = GeneralUtility::makeInstance(ContentFetcher::class, $context); $grid = GeneralUtility::makeInstance(Grid::class, $context); - $recordRememberer = GeneralUtility::makeInstance(RecordRememberer::class); - if ($context->getDrawingConfiguration()->getLanguageMode()) { + if ($context->getDrawingConfiguration()->isLanguageComparisonMode()) { $languageId = $context->getSiteLanguage()->getLanguageId(); } else { $languageId = $context->getDrawingConfiguration()->getSelectedLanguageId(); @@ -69,7 +68,7 @@ class BackendLayoutRenderer $rowObject->addColumn($columnObject); if (isset($column['colPos'])) { $records = $contentFetcher->getContentRecordsPerColumn((int)$column['colPos'], $languageId); - $recordRememberer->rememberRecords($records); + $this->recordRememberer->rememberRecords($records); foreach ($records as $contentRecord) { $columnItem = GeneralUtility::makeInstance(GridColumnItem::class, $context, $columnObject, $contentRecord); $columnObject->addItem($columnItem); @@ -92,14 +91,12 @@ class BackendLayoutRenderer $view = $this->backendViewFactory->create($request); $view->assignMultiple([ 'context' => $pageLayoutContext, - 'hideRestrictedColumns' => (bool)(BackendUtility::getPagesTSconfig($pageLayoutContext->getPageId())['mod.']['web_layout.']['hideRestrictedCols'] ?? false), - 'newContentTitle' => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newContentElement'), - 'newContentTitleShort' => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:content'), + 'hideRestrictedColumns' => $pageLayoutContext->getDrawingConfiguration()->shouldHideRestrictedColumns(), 'allowEditContent' => $backendUser->check('tables_modify', 'tt_content'), 'maxTitleLength' => $backendUser->uc['titleLen'] ?? 20, ]); - if ($pageLayoutContext->getDrawingConfiguration()->getLanguageMode()) { + if ($pageLayoutContext->getDrawingConfiguration()->isLanguageComparisonMode()) { if ($pageLayoutContext->getDrawingConfiguration()->getDefaultLanguageBinding()) { $view->assign('languageColumns', $this->getLanguageColumnsWithDefLangBindingForPageLayoutContext($pageLayoutContext)); } else { diff --git a/typo3/sysext/backend/Classes/View/Drawing/DrawingConfiguration.php b/typo3/sysext/backend/Classes/View/Drawing/DrawingConfiguration.php index 7b39d6b6e7a5..01abd38e13f7 100644 --- a/typo3/sysext/backend/Classes/View/Drawing/DrawingConfiguration.php +++ b/typo3/sysext/backend/Classes/View/Drawing/DrawingConfiguration.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\View\Drawing; use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout; +use TYPO3\CMS\Backend\View\PageViewMode; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -39,7 +40,7 @@ class DrawingConfiguration /** * Corresponds to web.layout.allowInconsistentLanguageHandling TSconfig property */ - protected bool $allowInconsistentLanguageHandling = false; + protected bool $allowInconsistentLanguageHandling; /** * Determines whether rendering should happen with a visually aligned @@ -47,13 +48,7 @@ class DrawingConfiguration * with this flag enabled, any translated versions are vertically * aligned so they are rendered in the same visual row as the original. */ - protected bool $defaultLanguageBinding = true; - - /** - * If TRUE, indicates that the current rendering method shows multiple - * languages (e.g. the "page" module is set in "Languages" mode. - */ - protected bool $languageMode = false; + protected bool $defaultLanguageBinding; /** * Key => "Language ID", Value "Label of language" @@ -72,18 +67,37 @@ class DrawingConfiguration */ protected array $activeColumns = [1, 0, 2, 3]; - public static function create(BackendLayout $backendLayout, array $pageTsConfig): self + /** + * Whether or not to allow the translate mode for translations + */ + protected bool $allowTranslateModeForTranslations; + + /** + * Whether or not to allow the copy mode for translations + */ + protected bool $allowCopyModeForTranslations; + + protected bool $shouldHideRestrictedColumns; + + protected PageViewMode $pageViewMode; + + public static function create(BackendLayout $backendLayout, array $pageTsConfig, PageViewMode $pageViewMode): self { $obj = new self(); + $obj->pageViewMode = $pageViewMode; $obj->defaultLanguageBinding = !empty($pageTsConfig['mod.']['web_layout.']['defLangBinding']); $obj->allowInconsistentLanguageHandling = (bool)($pageTsConfig['mod.']['web_layout.']['allowInconsistentLanguageHandling'] ?? false); + $obj->shouldHideRestrictedColumns = (bool)($pageTsConfig['mod.']['web_layout.']['hideRestrictedCols'] ?? false); $availableColumnPositionsFromBackendLayout = array_unique($backendLayout->getColumnPositionNumbers()); $allowedColumnPositionsByTsConfig = array_unique(GeneralUtility::intExplode(',', (string)($pageTsConfig['mod.']['SHARED.']['colPos_list'] ?? ''), true)); - $obj->activeColumns = $availableColumnPositionsFromBackendLayout; + // If there is no tsConfig colPos_list, no restriction. Else create intersection of available and allowed. if (!empty($allowedColumnPositionsByTsConfig)) { - // If there is no tsConfig colPos_list, no restriction. Else create intersection of available and allowed. $obj->activeColumns = array_intersect($availableColumnPositionsFromBackendLayout, $allowedColumnPositionsByTsConfig); + } else { + $obj->activeColumns = $availableColumnPositionsFromBackendLayout; } + $obj->allowTranslateModeForTranslations = $pageTsConfig['mod.']['web_layout.']['localization.']['enableTranslate'] ?? true; + $obj->allowCopyModeForTranslations = $pageTsConfig['mod.']['web_layout.']['localization.']['enableCopy'] ?? true; return $obj; } @@ -108,14 +122,9 @@ class DrawingConfiguration return $this->defaultLanguageBinding; } - public function getLanguageMode(): bool + public function isLanguageComparisonMode(): bool { - return $this->languageMode; - } - - public function setLanguageMode(bool $languageMode): void - { - $this->languageMode = $languageMode; + return $this->pageViewMode === PageViewMode::LanguageComparisonView; } public function getLanguageColumns(): array @@ -145,4 +154,19 @@ class DrawingConfiguration { return $this->activeColumns; } + + public function translateModeForTranslationsAllowed(): bool + { + return $this->allowTranslateModeForTranslations; + } + + public function copyModeForTranslationsAllowed(): bool + { + return $this->allowCopyModeForTranslations; + } + + public function shouldHideRestrictedColumns(): bool + { + return $this->shouldHideRestrictedColumns; + } } diff --git a/typo3/sysext/backend/Classes/View/PageLayoutContext.php b/typo3/sysext/backend/Classes/View/PageLayoutContext.php index 91683c730025..b70d3e8d1b60 100644 --- a/typo3/sysext/backend/Classes/View/PageLayoutContext.php +++ b/typo3/sysext/backend/Classes/View/PageLayoutContext.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\View; +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout; @@ -71,7 +72,7 @@ class PageLayoutContext protected readonly BackendLayout $backendLayout, protected readonly SiteInterface $site, protected readonly DrawingConfiguration $drawingConfiguration, - protected readonly array $tsConfig + protected readonly ServerRequestInterface $request ) { $this->pageId = (int)($pageRecord['uid'] ?? 0); $this->contentFetcher = GeneralUtility::makeInstance(ContentFetcher::class, $this); @@ -79,11 +80,6 @@ class PageLayoutContext $this->siteLanguage = $this->site->getDefaultLanguage(); } - public static function create(array $pageRecord, BackendLayout $backendLayout, SiteInterface $site, DrawingConfiguration $drawingConfiguration, array $tsConfig): self - { - return new self($pageRecord, $backendLayout, $site, $drawingConfiguration, $tsConfig); - } - public function cloneForLanguage(SiteLanguage $language): self { $copy = clone $this; @@ -303,7 +299,7 @@ class PageLayoutContext 'record_edit', [ 'justLocalized' => 'pages:' . $this->pageId . ':' . $languageUid, - 'returnUrl' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(), + 'returnUrl' => $this->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(), ] ), ] @@ -314,6 +310,11 @@ class PageLayoutContext return $options; } + public function getCurrentRequest(): ServerRequestInterface + { + return $this->request; + } + public function getLocalizedPageTitle(): string { return $this->localizedPageRecord['title'] ?? $this->pageRecord['title']; diff --git a/typo3/sysext/backend/Classes/View/PageViewMode.php b/typo3/sysext/backend/Classes/View/PageViewMode.php new file mode 100644 index 000000000000..8e25c9f342ef --- /dev/null +++ b/typo3/sysext/backend/Classes/View/PageViewMode.php @@ -0,0 +1,35 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\View; + +/** + * State how to render the page layout module. + * @todo: we could move the "mod.defLangBinding" option as a separate View in here as well. + * + * @internal + */ +enum PageViewMode +{ + case LayoutView; + + /** + * Indicates that the current rendering method shows multiple + * languages side-by-side. + */ + case LanguageComparisonView; +} diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/ColumnHeader.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/ColumnHeader.html index 3de62ffbc83b..909948917a98 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/ColumnHeader.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/ColumnHeader.html @@ -23,11 +23,11 @@ </div> <f:format.raw>{column.beforeSectionMarkup}</f:format.raw> <f:if condition="{allowEditContent} && {column.contentEditable} && {column.context.allowNewContent} && {column.active}"> - <div class="t3-page-ce t3js-page-ce" data-page="{column.context.pageId}" id="{column.uniqueId}"> - <div class="t3-page-ce-actions t3js-page-new-ce" id="colpos-{column.columnNumber}-page-{column.context.pageId}-{column.uniqueId}"> - <typo3-backend-new-content-element-wizard-button class="btn btn-default btn-sm" url="{column.newContentUrl}" subject="{newContentTitle}"> + <div class="t3-page-ce t3js-page-ce" data-page="{column.context.pageId}"> + <div class="t3-page-ce-actions t3js-page-new-ce"> + <typo3-backend-new-content-element-wizard-button class="btn btn-default btn-sm" url="{column.newContentUrl}" subject="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newContentElement')}"> <core:icon identifier="actions-plus" /> - {newContentTitleShort} + <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:content" /> </typo3-backend-new-content-element-wizard-button> </div> <div class="t3-page-ce-dropzone t3js-page-ce-dropzone-available"></div> diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html index 54e799867896..f1d9de9af455 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html @@ -32,18 +32,18 @@ <td class="t3-page-column t3-page-lang-label nowrap"> <div class="btn-group"> <f:if condition="{languageColumn.allowViewPage}"> - <button class="btn btn-default btn-sm" {f:if(condition: languageColumn.previewUrlAttributes, then: '{languageColumn.previewUrlAttributes -> f:format.raw()}', else: 'disabled="true"')} title="{languageColumn.viewPageLinkTitle}"> + <button class="btn btn-default btn-sm" {f:if(condition: languageColumn.previewUrlAttributes, then: '{languageColumn.previewUrlAttributes -> f:format.raw()}', else: 'disabled="true"')} title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage')}"> <core:icon identifier="actions-view" /> </button> </f:if> <f:if condition="{languageColumn.allowEditPage}"> - <a href="{languageColumn.pageEditUrl}" class="btn btn-default btn-sm" title="{languageColumn.pageEditTitle}"> + <a href="{languageColumn.pageEditUrl}" class="btn btn-default btn-sm" title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:edit')}"> <core:icon identifier="actions-open" /> </a> </f:if> <f:if condition="{allowEditContent} && {languageColumn.context.siteLanguage.languageId} && {languageColumn.translationData.untranslatedRecordUids}"> <a href="#" class="btn btn-default btn-sm t3js-localize disabled" - title="{languageColumn.context.translatePageTitle}" + title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newPageContent_translate')}" data-page="{languageColumn.context.localizedPageRecord.title}" data-has-elements="{languageColumn.translationData.hasTranslations as integer}" data-allow-copy="{languageColumn.allowTranslateCopy as integer}" @@ -53,7 +53,7 @@ data-language-id="{languageColumn.context.siteLanguage.languageId}" data-language-name="{languageColumn.context.siteLanguage.title}"> <core:icon identifier="actions-localize" /> - {languageColumn.translatePageTitle} + <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newPageContent_translate" /> </a> </f:if> </div> diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html index 1f812c5335cf..2d1304484f53 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html @@ -1,6 +1,6 @@ {f:if(condition: '{item.disabled} && {item.context.drawingConfiguration.showHidden} == 0', then: 'height: 0; position: absolute;') -> f:variable(name: 'style')} <div class="t3-page-ce {item.wrapperClassName} t3js-page-ce t3js-page-ce-sortable" id="element-tt_content-{item.record.uid}" data-table="tt_content" data-uid="{item.record.uid}" data-language-uid="{item.record.sys_language_uid}" style="{style}"> - <div class="t3-page-ce-element t3-page-ce-dragitem" id="{item.uniqueId}"> + <div class="t3-page-ce-element t3-page-ce-dragitem"> <f:render partial="PageLayout/Record/{item.record.CType}/Header" arguments="{_all}" optional="1"> <f:render partial="PageLayout/RecordDefault/Header" arguments="{_all}" /> </f:render> @@ -19,8 +19,8 @@ </f:if> </div> <f:if condition="{allowEditContent} && {item.column.contentEditable} && {column.context.allowNewContent} && {column.active}"> - <div class="t3-page-ce-actions t3js-page-new-ce" id="colpos-{item.column.columnNumber}-page-{item.context.pageId}-{item.column.uniqueId}"> - <typo3-backend-new-content-element-wizard-button class="btn btn-default btn-sm" url="{item.newContentAfterUrl}" subject="{newContentTitle}"> + <div class="t3-page-ce-actions t3js-page-new-ce"> + <typo3-backend-new-content-element-wizard-button class="btn btn-default btn-sm" url="{item.newContentAfterUrl}" subject="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newContentElement')}"> <core:icon identifier="actions-plus" /> <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:content" /> </typo3-backend-new-content-element-wizard-button> diff --git a/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageLayout.html b/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageLayout.html index 2de35153b6e4..a26e10243a9a 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageLayout.html +++ b/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageLayout.html @@ -1,5 +1,5 @@ {namespace be=TYPO3\CMS\Backend\ViewHelpers} -<f:if condition="{context.drawingConfiguration.languageMode}"> +<f:if condition="{context.drawingConfiguration.languageComparisonMode}"> <f:then> <f:render partial="PageLayout/LanguageColumns" arguments="{_all}" /> </f:then> diff --git a/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageModule.html b/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageModule.html index a97f3c6cab31..818a0b54d8d5 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageModule.html +++ b/typo3/sysext/backend/Resources/Private/Templates/PageLayout/PageModule.html @@ -61,7 +61,7 @@ class="form-check-input" name="showHidden" value="1" - {f:if(condition:'{hiddenElementsState} == 1', then:'checked="checked"')} + {f:if(condition:'{pageLayoutContext.drawingConfiguration.showHidden}', then:'checked="checked"')} /> <label class="form-check-label" for="checkShowHidden"> <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:hiddenCE" /> ({hiddenElementsCount}) diff --git a/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php b/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php index 9b85f825287a..75083b490387 100644 --- a/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php +++ b/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php @@ -20,6 +20,7 @@ namespace TYPO3\CMS\Backend\Tests\Functional\View\Drawing; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout; +use TYPO3\CMS\Backend\View\BackendLayout\RecordRememberer; use TYPO3\CMS\Backend\View\BackendViewFactory; use TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer; use TYPO3\CMS\Backend\View\PageLayoutContext; @@ -89,7 +90,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase 'rows.' => [], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(0, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); } @@ -104,7 +108,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(1, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(0, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); } @@ -123,7 +130,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(2, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(0, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); } @@ -143,7 +153,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(1, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(1, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); foreach ($subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns() as $column) { @@ -169,7 +182,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(1, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(2, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); foreach ($subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns() as $column) { @@ -199,7 +215,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(2, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(2, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); foreach ($subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns() as $column) { @@ -235,7 +254,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(2, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(4, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); foreach ($subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns() as $column) { @@ -259,7 +281,10 @@ final class BackendLayoutRendererTest extends FunctionalTestCase ], ]; $pageLayoutContext = $this->getPageLayoutContext(1100, $configuration); - $subject = new BackendLayoutRenderer(new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class))); + $subject = new BackendLayoutRenderer( + new BackendViewFactory($this->get(RenderingContextFactory::class), $this->get(PackageManager::class)), + new RecordRememberer() + ); self::assertCount(1, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows()); self::assertCount(1, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns()); foreach ($subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns() as $column) { diff --git a/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php index fe48c2265efb..1dafb4d0b6ba 100644 --- a/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php +++ b/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php @@ -36,6 +36,7 @@ use TYPO3\CMS\Core\Package\PackageManager; use TYPO3\CMS\Core\Resource\Filter\FileNameFilter; use TYPO3\CMS\Core\Resource\StorageRepository; use TYPO3\CMS\Core\Routing\BackendEntryPointResolver; +use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\SysLog\Action as SystemLogGenericAction; use TYPO3\CMS\Core\SysLog\Error as SystemLogErrorClassification; use TYPO3\CMS\Core\SysLog\Type; @@ -576,18 +577,23 @@ class BackendUserAuthentication extends AbstractUserAuthentication /** * Checking if a language value (-1, 0 and >0) is allowed to be edited by the user. * - * @param int $langValue Language value to evaluate + * @param int|SiteLanguage|string $langValue Language value to evaluate * @return bool Returns TRUE if the language value is allowed, otherwise FALSE. */ public function checkLanguageAccess($langValue) { // The users language list must be non-blank - otherwise all languages are allowed. - if (trim($this->groupData['allowed_languages']) !== '') { + if (trim($this->groupData['allowed_languages']) === '') { + return true; + } + if ($langValue instanceof SiteLanguage) { + $langValue = $langValue->getLanguageId(); + } else { $langValue = (int)$langValue; - // Language must either be explicitly allowed OR the lang Value be "-1" (all languages) - if ($langValue != -1 && !$this->check('allowed_languages', (string)$langValue)) { - return false; - } + } + // Language must either be explicitly allowed OR the lang Value be "-1" (all languages) + if ($langValue !== -1 && !$this->check('allowed_languages', (string)$langValue)) { + return false; } return true; } diff --git a/typo3/sysext/core/Classes/Site/Entity/NullSite.php b/typo3/sysext/core/Classes/Site/Entity/NullSite.php index 7d3a23bc0f7d..5358cee3937b 100644 --- a/typo3/sysext/core/Classes/Site/Entity/NullSite.php +++ b/typo3/sysext/core/Classes/Site/Entity/NullSite.php @@ -144,7 +144,7 @@ class NullSite implements SiteInterface $disabledLanguages = GeneralUtility::intExplode(',', (string)($pageTs['disableLanguages'] ?? ''), true); // Do not add the ones that are not allowed by the user foreach ($this->languages as $language) { - if ($user->checkLanguageAccess($language->getLanguageId()) && !in_array($language->getLanguageId(), $disabledLanguages, true)) { + if ($user->checkLanguageAccess($language) && !in_array($language->getLanguageId(), $disabledLanguages, true)) { if ($language->getLanguageId() === 0) { // 0: "Default" language $defaultLanguageLabel = 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage'; diff --git a/typo3/sysext/core/Classes/Site/Entity/Site.php b/typo3/sysext/core/Classes/Site/Entity/Site.php index d22a2c5f651a..0a97eda58c66 100644 --- a/typo3/sysext/core/Classes/Site/Entity/Site.php +++ b/typo3/sysext/core/Classes/Site/Entity/Site.php @@ -261,7 +261,7 @@ class Site implements SiteInterface // Do not add the ones that are not allowed by the user foreach ($this->languages as $language) { - if ($user->checkLanguageAccess($language->getLanguageId())) { + if ($user->checkLanguageAccess($language)) { $availableLanguages[$language->getLanguageId()] = $language; } } diff --git a/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php b/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php index 41a66db9ec88..b555a914dc36 100644 --- a/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php +++ b/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php @@ -96,7 +96,7 @@ class SiteBaseRedirectResolver implements MiddlewareInterface protected function isLanguageEnabled(SiteLanguage $language, ?BackendUserAuthentication $user = null): bool { // language is hidden, check if a possible backend user is allowed to access the language - if ($language->enabled() || $user?->checkLanguageAccess($language->getLanguageId())) { + if ($language->enabled() || $user?->checkLanguageAccess($language)) { return true; } return false; -- GitLab