diff --git a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php index 5c7adb56fec76d7dcee10372c631e50424dfca5c..38b0e1d1235b6fc9e49a261cc3d38f54416622da 100644 --- a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php +++ b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php @@ -400,7 +400,8 @@ class StandardContentPreviewRenderer implements PreviewRendererInterface, Logger */ protected function linkEditContent(string $linkText, $row): string { - if ($this->getBackendUser()->recordEditAccessInternals('tt_content', $row)) { + $backendUser = $this->getBackendUser(); + if ($backendUser->check('tables_modify', 'tt_content') && $backendUser->recordEditAccessInternals('tt_content', $row)) { $urlParameters = [ 'edit' => [ 'tt_content' => [ diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php b/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php index 4bffb76b62f63e42c9547409a87857e8ca224588..e0c4671496856083c509f91afc221035ed56643c 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php @@ -280,18 +280,13 @@ class BackendLayout public function getLanguageColumns(): iterable { if (empty($this->languageColumns)) { - $defaultLanguageElements = []; - $contentByColumn = $this->getContentFetcher()->getContentRecordsPerColumn(null, 0); - if (!empty($contentByColumn)) { - $defaultLanguageElements = array_merge(...$contentByColumn); - } foreach ($this->getDrawingConfiguration()->getSiteLanguages() as $siteLanguage) { if (!in_array($siteLanguage->getLanguageId(), $this->getDrawingConfiguration()->getLanguageColumns())) { continue; } $backendLayout = clone $this; $backendLayout->getDrawingConfiguration()->setLanguageColumnsPointer($siteLanguage->getLanguageId()); - $this->languageColumns[] = GeneralUtility::makeInstance(LanguageColumn::class, $backendLayout, $siteLanguage, $defaultLanguageElements); + $this->languageColumns[] = GeneralUtility::makeInstance(LanguageColumn::class, $backendLayout, $siteLanguage); } } return $this->languageColumns; diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php b/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php index 757ce29ab57f614bbd8475f911f25a5fab6b35bf..1d79bec530c27c79bfac3724b9c2866ac8635aef 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php @@ -128,6 +128,16 @@ class ContentFetcher } if (!isset($this->languageHasTranslationsCache[$language])) { + if ($language) { + $contentRecordsInDefaultLanguage = $this->getContentRecordsPerColumn(null, 0); + if (!empty($contentRecordsInDefaultLanguage)) { + $contentRecordsInDefaultLanguage = array_merge(...$contentRecordsInDefaultLanguage); + } + } else { + $contentRecordsInDefaultLanguage = $contentElements; + } + $untranslatedRecordUids = array_flip(array_column($contentRecordsInDefaultLanguage, 'uid')); + foreach ($contentElements as $contentElement) { if ((int)$contentElement['l18n_parent'] === 0) { $this->languageHasTranslationsCache[$language]['hasStandAloneContent'] = true; @@ -137,10 +147,14 @@ class ContentFetcher $this->languageHasTranslationsCache[$language]['hasTranslations'] = true; $this->languageHasTranslationsCache[$language]['mode'] = 'connected'; } + if ((int)$contentElement['l10n_source'] > 0) { + unset($untranslatedRecordUids[(int)$contentElement['l10n_source']]); + } } if (!isset($this->languageHasTranslationsCache[$language])) { $this->languageHasTranslationsCache[$language]['hasTranslations'] = false; } + $this->languageHasTranslationsCache[$language]['untranslatedRecordUids'] = array_keys($untranslatedRecordUids); // Check for inconsistent translations, force "mixed" mode and dispatch a FlashMessage to user if such a case is encountered. if (isset($this->languageHasTranslationsCache[$language]['hasStandAloneContent']) diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php index 4e0196813a4de17c23b2bdf7ab2a572b1135852b..3ee084a47b72ca5300a96fe7576ef1ed35bc8571 100644 --- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php +++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php @@ -54,23 +54,18 @@ class LanguageColumn extends AbstractGridObject /** * @var array */ - protected $defaultLanguageElements = []; - - /** - * @var array - */ - protected $flatContentOfLanguage = []; + protected $localizationConfiguration = []; /** * @var GridColumn|null */ protected $grid; - public function __construct(BackendLayout $backendLayout, SiteLanguage $language, array $defaultLanguageElements) + public function __construct(BackendLayout $backendLayout, SiteLanguage $language) { parent::__construct($backendLayout); $this->siteLanguage = $language; - $this->defaultLanguageElements = $defaultLanguageElements; + $this->localizationConfiguration = BackendUtility::getPagesTSconfig($backendLayout->getDrawingConfiguration()->getPageId())['mod.']['web_layout.']['localization.'] ?? []; if ($this->siteLanguage->getLanguageId() > 0) { $pageLocalizationRecord = BackendUtility::getRecordLocalization( 'pages', @@ -85,14 +80,6 @@ class LanguageColumn extends AbstractGridObject } else { $this->localizedPageRecord = $backendLayout->getDrawingConfiguration()->getPageRecord(); } - - $contentFetcher = $backendLayout->getContentFetcher(); - $contentRecords = $contentFetcher->getContentRecordsPerColumn(null, $language->getLanguageId()); - if (!empty($contentRecords)) { - $this->flatContentOfLanguage = array_merge(...$contentRecords); - } else { - $this->flatContentOfLanguage = []; - } } public function getLocalizedPageRecord(): ?array @@ -149,55 +136,18 @@ class LanguageColumn extends AbstractGridObject public function getAllowTranslate(): bool { - if ($this->siteLanguage->getLanguageId() === 0) { - return false; - } - - $localizationTsConfig = BackendUtility::getPagesTSconfig($this->backendLayout->getDrawingConfiguration()->getPageId())['mod.']['web_layout.']['localization.'] ?? []; - $allowTranslate = (bool)($localizationTsConfig['enableTranslate'] ?? true); - if (!$allowTranslate) { - return false; - } - - $translationData = $this->backendLayout->getContentFetcher()->getTranslationData($this->flatContentOfLanguage, $this->siteLanguage->getLanguageId()); - if (!empty($translationData)) { - if (isset($translationData['hasStandAloneContent'])) { - return false; - } - } - - $defaultLanguageUids = array_flip(array_column($this->defaultLanguageElements, 'uid')); - $translatedLanguageUids = array_column($this->flatContentOfLanguage, 'l10n_source'); - if (empty($translatedLanguageUids)) { - return true; - } - - foreach ($translatedLanguageUids as $translatedUid) { - unset($defaultLanguageUids[$translatedUid]); - } - - return !empty($defaultLanguageUids); + return ($this->localizationConfiguration['enableTranslate'] ?? true) && !($this->getTranslationData()['hasStandAloneContent'] ?? false); } public function getTranslationData(): array { $contentFetcher = $this->backendLayout->getContentFetcher(); - return $contentFetcher->getTranslationData($this->defaultLanguageElements, $this->siteLanguage->getLanguageId()); + return $contentFetcher->getTranslationData($contentFetcher->getFlatContentRecords(), $this->siteLanguage->getLanguageId()); } public function getAllowTranslateCopy(): bool { - $localizationTsConfig = BackendUtility::getPagesTSconfig($this->backendLayout->getDrawingConfiguration()->getPageId())['mod.']['web_layout.']['localization.'] ?? []; - $allowCopy = (bool)($localizationTsConfig['enableCopy'] ?? true); - if (!empty($translationData)) { - if (isset($translationData['hasStandAloneContent'])) { - return false; - } - if (isset($translationData['hasTranslations'])) { - $allowCopy = $allowCopy && !$translationData['hasTranslations']; - } - } - return $allowCopy; + return ($this->localizationConfiguration['enableCopy'] ?? true) && !($this->getTranslationData()['hasTranslations'] ?? false); } public function getTranslatePageTitle(): string diff --git a/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php b/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php index dace807aab1442a304985a8df8fda7b0ab2ceaaf..fe6b6ddaee425203028a7943880de10c9cea206e 100644 --- a/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php +++ b/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php @@ -98,6 +98,7 @@ class BackendLayoutRenderer } $this->view->assign('newContentTitle', $this->getLanguageService()->getLL('newContentElement')); $this->view->assign('newContentTitleShort', $this->getLanguageService()->getLL('content')); + $this->view->assign('allowEditContent', $this->getBackendUser()->check('tables_modify', 'tt_content')); $rendered = $this->view->render('PageLayout'); if ($renderUnused) { diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html index e1935eb681f165423cf6027a4a1664f18690b28c..838fa0d8be81c7966208b45942ec9f937c82087f 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html @@ -8,7 +8,7 @@ <f:if condition="{column.active}"> <f:then> <div class="t3-page-column-header-icons"> - <f:if condition="{column.editUrl}"> + <f:if condition="{allowEditContent} && {column.editUrl}"> <a href="{column.editUrl}" title="{column.editLinkTitle}"><core:icon identifier="actions-document-open" /></a> </f:if> </div> @@ -25,7 +25,7 @@ </f:else> </f:if> </div> - <f:if condition="{column.contentEditable} && {grid.allowNewContent}"> + <f:if condition="{allowEditContent} && {column.contentEditable} && {grid.allowNewContent}"> <div class="t3-page-ce t3js-page-ce" data-page="{column.backendLayout.drawingConfiguration.pageId}" id="{column.uniqueId}"> <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-{column.columnNumber}-page-{column.backendLayout.drawingConfiguration.pageId}-{column.uniqueId}"> <a href="{column.newContentUrl}" title="{newContentTitle}" data-title="{newContentTitle}" diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html index d7cbb286e89074670dd3f0d7198044a4264313bf..46711817a8029a05001c651efdc7336d52fa2d46 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html @@ -35,7 +35,7 @@ <core:icon identifier="actions-open" /> </a> </f:if> - <f:if condition="{languageColumn.allowTranslate}"> + <f:if condition="{allowEditContent} && {languageColumn.siteLanguage.languageId} && {languageColumn.translationData.untranslatedRecordUids}"> <a href="#" class="btn btn-default btn-sm t3js-localize disabled" title="{languageColumn.translatePageTitle}" data-page="{languageColumn.localizedPageRecord.title}" diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html index 8dc2731d838612f9fda6f23a4f1c0a6d23d56b14..bfaaaeb252f9b3ea3d46e5b931c772ed936381ff 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html @@ -2,7 +2,7 @@ <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}" style="{style}"> <div class="t3-page-ce-dragitem" id="{item.uniqueId}"> <f:render partial="PageLayout/Record/{item.record.CType}/Header" optional="1"> - <f:render partial="PageLayout/Record/Header" arguments="{item: item}" /> + <f:render partial="PageLayout/Record/Header" arguments="{_all}" /> </f:render> <div class="t3-page-ce-body"> <div class="t3-page-ce-body-inner"> @@ -13,11 +13,11 @@ </div> </div> <f:render partial="PageLayout/Record/{item.record.CType}/Footer" optional="1"> - <f:render partial="PageLayout/Record/Footer" arguments="{item: item}" /> + <f:render partial="PageLayout/Record/Footer" arguments="{_all}" /> </f:render> </div> </div> - <f:if condition="{item.column.contentEditable} && {grid.allowNewContent}"> + <f:if condition="{allowEditContent} && {item.column.contentEditable} && {grid.allowNewContent}"> <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-{item.column.columnNumber}-page-{item.column.backendLayout.drawingConfiguration.pageId}-{item.column.uniqueId}"> <a href="{item.newContentAfterUrl}" title="{item.newContentAfterLinkTitle}" data-title="{item.newContentAfterLinkTitle}" class="btn btn-default btn-sm t3js-toggle-new-content-element-wizard"> <core:icon identifier="actions-add" /> diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html index 2cf6917020e772eba93b98aa92a095dac1811e76..4f3b5e74bdea6a40d1a153de48156284d0203b1c 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html @@ -1,9 +1,9 @@ -<div class="t3-page-ce-header {f:if(condition: item.dragAndDropAllowed, then: 't3-page-ce-header-draggable t3js-page-ce-draghandle')}"> +<div class="t3-page-ce-header {f:if(condition: '{allowEditContent} && {item.dragAndDropAllowed}', then: 't3-page-ce-header-draggable t3js-page-ce-draghandle')}"> <div class="t3-page-ce-header-icons-left"> {item.icons -> f:format.raw()} </div> <div class="t3-page-ce-header-icons-right"> - <f:if condition="{item.editable}"> + <f:if condition="{item.editable} && {allowEditContent}"> <div class="btn-toolbar"> <div class="btn-group btn-group-sm"> <a href="{item.editUrl}" class="btn btn-default">