Skip to content

Commit

Permalink
[TASK] Separation of concerns while rendering Page module
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bmack committed Mar 8, 2024
1 parent d8a9458 commit 31439e9
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 140 deletions.
41 changes: 13 additions & 28 deletions typo3/sysext/backend/Classes/Controller/PageLayoutController.php
Expand Up @@ -38,6 +38,7 @@
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;
Expand Down Expand Up @@ -124,7 +125,7 @@ public function mainAction(ServerRequestInterface $request): ResponseInterface
}

$tsConfig = BackendUtility::getPagesTSconfig($this->id);
$this->menuConfig($request);
$this->menuConfig();
$this->currentSelectedLanguage = (int)$this->moduleData->get('language');
$this->addJavaScriptModuleInstructions();
$this->makeActionMenu($view, $tsConfig);
Expand All @@ -134,9 +135,7 @@ public function mainAction(ServerRequestInterface $request): ResponseInterface

$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);

Expand All @@ -145,13 +144,13 @@ public function mainAction(ServerRequestInterface $request): ResponseInterface
$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(),
]);
Expand All @@ -161,21 +160,18 @@ public function mainAction(ServerRequestInterface $request): ResponseInterface
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();
Expand Down Expand Up @@ -462,18 +458,6 @@ protected function getPageLinksWhereContentIsAlsoShownOn(int $pageId): string
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
*/
Expand Down Expand Up @@ -686,8 +670,9 @@ protected function makeLanguageSwitchButton(ButtonBar $buttonbar): ?ButtonInterf
* 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()
Expand All @@ -712,7 +697,7 @@ protected function getNumberOfHiddenElements(bool $isLanguageModeActive): int
[-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(
Expand Down Expand Up @@ -816,7 +801,7 @@ protected function isContentEditable(int $languageId): bool
*/
protected function getTargetPageIfVisible(array $targetPage): array
{
return !(bool)($targetPage['hidden'] ?? false) ? $targetPage : [];
return !($targetPage['hidden'] ?? false) ? $targetPage : [];
}

/**
Expand Down
Expand Up @@ -75,7 +75,7 @@ public function getContentRecordsPerColumn(?int $columnNumber = null, ?int $lang
$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);
Expand All @@ -84,7 +84,7 @@ public function getContentRecordsPerColumn(?int $columnNumber = null, ?int $lang
$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 {
Expand Down
Expand Up @@ -22,7 +22,6 @@
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.
Expand All @@ -46,11 +45,6 @@ public function __construct(protected PageLayoutContext $context)
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
}

public function getUniqueId(): string
{
return StringUtility::getUniqueId();
}

public function getContext(): PageLayoutContext
{
return $this->context;
Expand Down
Expand Up @@ -66,7 +66,7 @@ public function getColumns(): iterable

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;
Expand Down
24 changes: 14 additions & 10 deletions typo3/sysext/backend/Classes/View/BackendLayout/Grid/GridColumn.php
Expand Up @@ -114,15 +114,15 @@ public function getIcon(): string

public function getColSpan(): int
{
if ($this->context->getDrawingConfiguration()->getLanguageMode()) {
if ($this->context->getDrawingConfiguration()->isLanguageComparisonMode()) {
return 1;
}
return $this->colSpan;
}

public function getRowSpan(): int
{
if ($this->context->getDrawingConfiguration()->getLanguageMode()) {
if ($this->context->getDrawingConfiguration()->isLanguageComparisonMode()) {
return 1;
}
return $this->rowSpan;
Expand All @@ -147,15 +147,19 @@ public function getEditUrl(): ?string
}
$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
Expand All @@ -168,7 +172,7 @@ public function getNewContentUrl(): string
'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(),
]);
}

Expand Down Expand Up @@ -229,7 +233,7 @@ public function isContentEditable(): bool
$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());
}

/**
Expand Down
Expand Up @@ -125,7 +125,7 @@ public function getDeleteUrl(): string
],
],
],
'redirect' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(),
'redirect' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(),
]
);
}
Expand Down Expand Up @@ -278,14 +278,12 @@ public function isInconsistentLanguage(): bool
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(),
]);
}

Expand All @@ -307,7 +305,7 @@ public function getVisibilityToggleUrl(): string
],
],
],
'redirect' => $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri(),
'redirect' => $this->context->getCurrentRequest()->getAttribute('normalizedParams')->getRequestUri(),
]
) . '#element-' . $this->table . '-' . $this->record['uid'];
}
Expand Down Expand Up @@ -345,7 +343,7 @@ public function getEditUrl(): string
$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'];
Expand Down
Expand Up @@ -44,15 +44,12 @@
*/
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
Expand All @@ -72,7 +69,7 @@ public function getPageIcon(): string

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
Expand All @@ -82,23 +79,13 @@ public function getTranslationData(): array

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
Expand All @@ -110,7 +97,7 @@ public function getPageEditUrl(): string
$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'] ?? '') !== '') {
Expand All @@ -124,11 +111,6 @@ public function getAllowViewPage(): bool
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();
Expand Down
Expand Up @@ -27,7 +27,7 @@ class RecordRememberer implements SingletonInterface
/**
* @var int[]
*/
protected $rememberedUids = [];
protected array $rememberedUids = [];

public function rememberRecords(iterable $records): void
{
Expand Down

0 comments on commit 31439e9

Please sign in to comment.