diff --git a/Classes/DataProcessing/ContentAreaProcessor.php b/Classes/DataProcessing/ContentAreaProcessor.php new file mode 100644 index 00000000..3171e005 --- /dev/null +++ b/Classes/DataProcessing/ContentAreaProcessor.php @@ -0,0 +1,121 @@ + + * + */ +#[Autoconfigure(public: true)] +readonly class ContentAreaProcessor implements DataProcessorInterface +{ + + public function __construct( + protected ContentDataProcessor $contentDataProcessor, + protected Context $context, + protected FrontendContainerFactory $frontendContainerFactory, + protected Registry $tcaRegistry, + protected RecordFactory $recordFactory, + protected Typo3Version $typo3Version, + protected LoggerInterface $logger, + ) {} + + public function process( + ContentObjectRenderer $cObj, + array $contentObjectConfiguration, + array $processorConfiguration, + array $processedData, + ): array { + if (((float)$this->typo3Version->getBranch()) <= 14.1) { + $this->logger->error(ContentAreaProcessor::class . ' requires TYPO3 v14.2 or higher. Please check your configuration.'); + + return $processedData; + } + + $record = $cObj->data; + + $CType = $record['CType'] ?? ''; + if (!$this->tcaRegistry->isContainerElement($CType)) { + return $processedData; + } + + $columnsColPos = $this->tcaRegistry->getAllAvailableColumnsColPos($CType); + + $container = null; + + $areas = []; + foreach ($columnsColPos as $colPos) { + $areas[$colPos] = new ContentAreaClosure( + function () use (&$container, $CType, $cObj, $record, $colPos): ContentArea { + $container ??= $this->frontendContainerFactory->buildContainer($cObj, $this->context, (int)$record['uid']); + + $contentDefenderConfiguration = $this->tcaRegistry->getContentDefenderConfiguration($CType, $colPos); + + $rows = $container->getChildrenByColPos($colPos); + + $records = array_map(fn($row) => $this->recordFactory->createFromDatabaseRow('tt_content', $row), $rows); + return new ContentArea( + (string)$colPos, + $this->tcaRegistry->getColPosName($record['CType'], $colPos), + $colPos, + ContentSlideMode::None, + GeneralUtility::trimExplode(',', $contentDefenderConfiguration['allowedContentTypes'] ?? '', true), + GeneralUtility::trimExplode(',', $contentDefenderConfiguration['disallowedContentTypes'] ?? '', true), + [ + 'container' => $container, + ], + $records, + ); + }, + ); + } + + $processedData[$processedConfiguration['as'] ?? 'content'] = new ContentAreaCollection($areas); + return $processedData; + } +} diff --git a/Classes/Tca/Registry.php b/Classes/Tca/Registry.php index 72ad3c83..941cf19a 100644 --- a/Classes/Tca/Registry.php +++ b/Classes/Tca/Registry.php @@ -187,6 +187,19 @@ public function getContainerLabel(string $cType): string return $GLOBALS['TCA']['tt_content']['containerConfiguration'][$cType]['label'] ?? $cType; } + public function getColPosName(string $cType, int $colPos): ?string + { + $grid = $this->getGrid($cType); + foreach ($grid as $row) { + foreach ($row as $column) { + if ($column['colPos'] === $colPos) { + return (string)$column['name']; + } + } + } + return null; + } + public function getAvailableColumns(string $cType): array { $columns = []; diff --git a/Tests/Functional/Frontend/DefaultLanguageTest.php b/Tests/Functional/Frontend/DefaultLanguageTest.php index 7b0a0e58..0ab829d0 100644 --- a/Tests/Functional/Frontend/DefaultLanguageTest.php +++ b/Tests/Functional/Frontend/DefaultLanguageTest.php @@ -12,6 +12,7 @@ use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Test; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; class DefaultLanguageTest extends AbstractFrontend @@ -39,6 +40,33 @@ public function childrenAreRendered(): void self::assertStringContainsString('