diff --git a/typo3/sysext/backend/Classes/Controller/EditDocumentController.php b/typo3/sysext/backend/Classes/Controller/EditDocumentController.php index e4f89f914a15fb511f1d68c1238f6a28c3f6b424..263db21d9159ed75c3495e5cf4bfd28b8e73723b 100644 --- a/typo3/sysext/backend/Classes/Controller/EditDocumentController.php +++ b/typo3/sysext/backend/Classes/Controller/EditDocumentController.php @@ -1291,7 +1291,7 @@ class EditDocumentController { $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); - if ($this->firstEl !== null) { + if (!empty($this->firstEl)) { $record = BackendUtility::getRecord($this->firstEl['table'], $this->firstEl['uid']); $TCActrl = $GLOBALS['TCA'][$this->firstEl['table']]['ctrl']; @@ -2118,6 +2118,11 @@ class EditDocumentController } else { $availableLanguages = $this->getLanguages((int)$pid, $table); } + // Remove default language, if user does not have access. This is necessary, since + // the default language is always added when fetching the system languages (#88504). + if (isset($availableLanguages[0]) && !$this->getBackendUser()->checkLanguageAccess(0)) { + unset($availableLanguages[0]); + } // Page available in other languages than default language? if (count($availableLanguages) > 1) { $rowsByLang = []; diff --git a/typo3/sysext/backend/Classes/Controller/PageLayoutController.php b/typo3/sysext/backend/Classes/Controller/PageLayoutController.php index 2e3f5c9b68dd0b55f0ddfadeaa24259bb37c94ab..7a46059531109691f7d840533fea2cf82a402b5f 100644 --- a/typo3/sysext/backend/Classes/Controller/PageLayoutController.php +++ b/typo3/sysext/backend/Classes/Controller/PageLayoutController.php @@ -312,7 +312,8 @@ class PageLayoutController 1 => $this->getLanguageService()->getLL('m_function_1'), ]; // Find if there are ANY languages at all (and if not, do not show the language option from function menu). - if (count($this->availableLanguages) > 1) { + // The second check is for an edge case: Only two languages in the site and the default is not allowed. + if (count($this->availableLanguages) > 1 || (int)array_key_first($this->availableLanguages) > 0) { $actions[2] = $this->getLanguageService()->getLL('m_function_2'); } // Page / user TSconfig blinding of menu-items @@ -823,69 +824,70 @@ class PageLayoutController ->setIcon($this->iconFactory->getIcon('actions-system-cache-clear', Icon::SIZE_SMALL)); $this->buttonBar->addButton($clearCacheButton, ButtonBar::BUTTON_POSITION_RIGHT, 1); - // Edit page properties and page language overlay icons + // Edit page properties if ($this->isPageEditable(0)) { - /** @var \TYPO3\CMS\Core\Http\NormalizedParams */ - $normalizedParams = $request->getAttribute('normalizedParams'); - // Edit localized pages only when one specific language is selected - if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) { - $localizationParentField = $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']; - $languageField = $GLOBALS['TCA']['pages']['ctrl']['languageField']; - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('pages'); - $queryBuilder->getRestrictions() - ->removeAll() - ->add(GeneralUtility::makeInstance(DeletedRestriction::class)) - ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->getBackendUser()->workspace)); - $overlayRecord = $queryBuilder - ->select('uid') - ->from('pages') - ->where( - $queryBuilder->expr()->eq( - $localizationParentField, - $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) - ), - $queryBuilder->expr()->eq( - $languageField, - $queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT) - ) - ) - ->setMaxResults(1) - ->execute() - ->fetchAssociative(); - BackendUtility::workspaceOL('pages', $overlayRecord, (int)$this->getBackendUser()->workspace); - // Edit button - $urlParameters = [ + $url = (string)$this->uriBuilder->buildUriFromRoute( + 'record_edit', + [ 'edit' => [ 'pages' => [ - $overlayRecord['uid'] => 'edit', + $this->id => 'edit', ], ], - 'returnUrl' => $normalizedParams->getRequestUri(), - ]; - - $url = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters); - $editLanguageButton = $this->buttonBar->makeLinkButton() - ->setHref($url) - ->setTitle($lang->getLL('editPageLanguageOverlayProperties')) - ->setIcon($this->iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)); - $this->buttonBar->addButton($editLanguageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); - } - $urlParameters = [ - 'edit' => [ - 'pages' => [ - $this->id => 'edit', - ], - ], - 'returnUrl' => $normalizedParams->getRequestUri(), - ]; - $url = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters); + 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(), + ] + ); $editPageButton = $this->buttonBar->makeLinkButton() ->setHref($url) ->setTitle($lang->getLL('editPageProperties')) ->setIcon($this->iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)); $this->buttonBar->addButton($editPageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); } + + // Edit page properties of page language overlay (Only when one specific language is selected) + if ((int)$this->MOD_SETTINGS['function'] === 1 + && $this->current_sys_language > 0 + && $this->isPageEditable($this->current_sys_language) + ) { + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); + $queryBuilder->getRestrictions() + ->removeAll() + ->add(GeneralUtility::makeInstance(DeletedRestriction::class)) + ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->getBackendUser()->workspace)); + $overlayRecord = $queryBuilder + ->select('uid') + ->from('pages') + ->where( + $queryBuilder->expr()->eq( + $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'], + $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) + ), + $queryBuilder->expr()->eq( + $GLOBALS['TCA']['pages']['ctrl']['languageField'], + $queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT) + ) + ) + ->setMaxResults(1) + ->execute() + ->fetchAssociative(); + BackendUtility::workspaceOL('pages', $overlayRecord, $this->getBackendUser()->workspace); + $url = (string)$this->uriBuilder->buildUriFromRoute( + 'record_edit', + [ + 'edit' => [ + 'pages' => [ + $overlayRecord['uid'] => 'edit', + ], + ], + 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(), + ] + ); + $editLanguageButton = $this->buttonBar->makeLinkButton() + ->setHref($url) + ->setTitle($lang->getLL('editPageLanguageOverlayProperties')) + ->setIcon($this->iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)); + $this->buttonBar->addButton($editLanguageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); + } } /******************************* diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php index ffa29adc77e9d8d70862cf6b2fb56420535606b3..ed26b35203c93a53a146a2f44166319268c2ed40 100644 --- a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php +++ b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php @@ -70,7 +70,7 @@ class OtherLanguageContent extends AbstractNode $defaultLanguageRow['pid'] ) ?? ''; if ($defaultLanguageValue !== '') { - $iconIdentifier = $this->data['systemLanguageRows'][0]['flagIconIdentifier'] ?: 'flags-multiple'; + $iconIdentifier = ($this->data['systemLanguageRows'][0]['flagIconIdentifier'] ?? false) ?: 'flags-multiple'; $html[] = '<div class="t3-form-original-language">'; $html[] = $iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->render(); $html[] = $this->previewFieldValue($defaultLanguageValue); diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php index 590bcd18e2ab278896c050472f761b22c19974dd..8bb20fbddf726350df01b6227a2781913d43abb8 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php @@ -108,7 +108,8 @@ class LanguageColumn extends AbstractGridObject public function getAllowEditPage(): bool { - return $this->getBackendUser()->check('tables_modify', 'pages'); + return $this->getBackendUser()->check('tables_modify', 'pages') + && $this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage()->getLanguageId()); } public function getPageEditTitle(): string diff --git a/typo3/sysext/backend/Classes/View/PageLayoutContext.php b/typo3/sysext/backend/Classes/View/PageLayoutContext.php index 5d69bdbac0577d21cfda13dcfbc85e0c0f75ee6b..e226f2846efb28cf3981c8a816be2000551111bd 100644 --- a/typo3/sysext/backend/Classes/View/PageLayoutContext.php +++ b/typo3/sysext/backend/Classes/View/PageLayoutContext.php @@ -191,7 +191,16 @@ class PageLayoutContext { $selectedLanguageId = $this->drawingConfiguration->getSelectedLanguageId(); if ($selectedLanguageId === -1) { - return $this->getSiteLanguages(); + $languages = $this->getSiteLanguages(); + if (!isset($languages[0])) { + // $languages may not contain the default (0) in case the user does not have access to it. + // However, as for selected pages, it should also be displayed readonly in the "all languages" view + $languages = [ + $this->site->getDefaultLanguage(), + ...$languages, + ]; + } + return $languages; } if ($selectedLanguageId > 0) { // A specific language is selected; compose a list of default language plus selected language