From a80012629478276688b9cf4466034bfb646ec1b8 Mon Sep 17 00:00:00 2001 From: Achim Fritz Date: Fri, 3 Apr 2026 12:33:05 +0200 Subject: [PATCH] [TASK] Add visual feedback if CType is not allowed in column s. https://review.typo3.org/c/Packages/TYPO3.CMS/+/92668 --- .../Backend/Grid/ContainerGridColumnItem.php | 8 +++-- Classes/Backend/Preview/GridRenderer.php | 2 +- .../Listener/PageContentPreviewRendering.php | 14 +++++++++ Classes/Tca/Registry.php | 30 +++++++++++++++++-- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/Classes/Backend/Grid/ContainerGridColumnItem.php b/Classes/Backend/Grid/ContainerGridColumnItem.php index 60d22e71..652db62a 100644 --- a/Classes/Backend/Grid/ContainerGridColumnItem.php +++ b/Classes/Backend/Grid/ContainerGridColumnItem.php @@ -13,6 +13,7 @@ */ use B13\Container\Domain\Model\Container; +use B13\Container\Tca\Registry; use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem; use TYPO3\CMS\Backend\View\PageLayoutContext; use TYPO3\CMS\Core\Domain\RecordFactory; @@ -21,7 +22,7 @@ class ContainerGridColumnItem extends GridColumnItem { - public function __construct(PageLayoutContext $context, ContainerGridColumn $column, array $record, protected Container $container, protected ?string $newContentUrl) + public function __construct(PageLayoutContext $context, ContainerGridColumn $column, array $record, protected Registry $tcaRegistry, protected Container $container, protected ?string $newContentUrl) { if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() > 13) { $recordFactory = GeneralUtility::makeInstance(RecordFactory::class); @@ -44,7 +45,10 @@ public function getWrapperClassName(): string if ($this->isDisabled()) { $wrapperClassNames[] = 't3-page-ce-hidden t3js-hidden-record'; } - // we do not need a "t3-page-ce-warning" class because we are build from Container + $record = $this->record; + if (!$this->tcaRegistry->recordIsAllowedInContainerColumn($record)) { + $wrapperClassNames[] = 't3-page-ce-warning'; + } return implode(' ', $wrapperClassNames); } diff --git a/Classes/Backend/Preview/GridRenderer.php b/Classes/Backend/Preview/GridRenderer.php index c3dd040e..fb397369 100644 --- a/Classes/Backend/Preview/GridRenderer.php +++ b/Classes/Backend/Preview/GridRenderer.php @@ -65,7 +65,7 @@ public function renderGrid(array $record, PageLayoutContext $context): string $records = $container->getChildrenByColPos($col['colPos']); foreach ($records as $contentRecord) { $url = $this->newContentUrlBuilder->getNewContentUrlAfterChild($context, $container, (int)$col['colPos'], (int)$contentRecord['uid'], $defVals); - $columnItem = GeneralUtility::makeInstance(ContainerGridColumnItem::class, $context, $columnObject, $contentRecord, $container, $url); + $columnItem = GeneralUtility::makeInstance(ContainerGridColumnItem::class, $context, $columnObject, $contentRecord, $this->tcaRegistry, $container, $url); $columnObject->addItem($columnItem); } } diff --git a/Classes/Listener/PageContentPreviewRendering.php b/Classes/Listener/PageContentPreviewRendering.php index 08ae4032..4f8ba9d3 100644 --- a/Classes/Listener/PageContentPreviewRendering.php +++ b/Classes/Listener/PageContentPreviewRendering.php @@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Attribute\AsEventListener; use TYPO3\CMS\Core\Domain\Record; use TYPO3\CMS\Core\Information\Typo3Version; +use TYPO3\CMS\Core\Localization\LanguageService; #[AsEventListener(identifier: 'tx-container-page-content-preview-rendering', before: 'typo3-backend/fluid-preview/content')] class PageContentPreviewRendering @@ -37,6 +38,14 @@ public function __invoke(PageContentPreviewRenderingEvent $event): void } $record = $event->getRecord(); + if ($this->tcaRegistry->recordIsAllowedInContainerColumn($record) === false) { + $labels = $event->getPageLayoutContext()->getContentTypeLabels(); + $label = $labels[$record->getRecordType()] ?? $record->getRecordType(); + $label = sprintf($this->getLanguageService()->sL('core.core:labels.typeNotAllowedInColumn'), $label); + $content = '' . $label . ''; + $event->setPreviewContent($content); + return; + } $recordType = $record->getRecordType(); if (!$this->tcaRegistry->isContainerElement($recordType)) { return; @@ -47,4 +56,9 @@ public function __invoke(PageContentPreviewRenderingEvent $event): void $event->setRecord($recordWithRenderedGrid); } } + + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } } diff --git a/Classes/Tca/Registry.php b/Classes/Tca/Registry.php index ba5ef71b..5f793362 100644 --- a/Classes/Tca/Registry.php +++ b/Classes/Tca/Registry.php @@ -15,6 +15,7 @@ use B13\Container\Events\BeforeContainerConfigurationIsAppliedEvent; use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; +use TYPO3\CMS\Core\Domain\RecordInterface; use TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider; use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; use TYPO3\CMS\Core\Imaging\IconRegistry; @@ -108,10 +109,35 @@ public function getContentDefenderConfiguration(string $cType, int $colPos): arr public function getAllowedCTypesInColumn(string $cType, int $colPos): ?array { $contentDefenderConfiguration = $this->getContentDefenderConfiguration($cType, $colPos); - if (empty($contentDefenderConfiguration['allowed.']['CType'])) { + if (empty($contentDefenderConfiguration['allowedContentTypes'])) { return null; } - return GeneralUtility::trimExplode(',', $contentDefenderConfiguration['allowed.']['CType'] ?? '', true); + return GeneralUtility::trimExplode(',', $contentDefenderConfiguration['allowedContentTypes'], true); + } + + public function recordIsAllowedInContainerColumn(RecordInterface $record): bool + { + $recordType = $record->getRecordType(); + if ($record->has('tx_container_parent')) { + $containerRecord = $record->get('tx_container_parent'); + if ($containerRecord instanceof RecordInterface) { + $containerRecordType = $containerRecord->getRecordType(); + if ($this->isContainerElement($containerRecordType)) { + return $this->isAllowedInColumn($recordType, (int)$record->get('colPos'), $containerRecordType); + } + } + } + return true; + } + + public function isAllowedInColumn(string $cType, int $colPos, string $containerCType): bool + { + $contentDefenderConfiguration = $this->getContentDefenderConfiguration($cType, $colPos); + $disallowed = GeneralUtility::trimExplode(',', $contentDefenderConfiguration['disallowedContentTypes'] ?? '', true); + if (in_array($cType, $disallowed)) { + return false; + } + return in_array($cType, $this->getAllowedCTypesInColumn($containerCType, $colPos)); } public function getAllAvailableColumnsColPos(string $cType): array