diff --git a/Classes/DataProcessing/ContentAreaProcessor.php b/Classes/DataProcessing/ContentAreaProcessor.php new file mode 100644 index 00000000..b12d9337 --- /dev/null +++ b/Classes/DataProcessing/ContentAreaProcessor.php @@ -0,0 +1,117 @@ + + * + */ +#[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, + ) {} + + public function process( + ContentObjectRenderer $cObj, + array $contentObjectConfiguration, + array $processorConfiguration, + array $processedData, + ): array { + if ($this->typo3Version->getMajorVersion() <= 13) { + throw new \Exception(self::class . ' requires TYPO3 v14 or higher', 1773664279); + } + + $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['allowed.']['CType'] ?? '', true), + GeneralUtility::trimExplode(',', $contentDefenderConfiguration['disallowed.']['CType'] ?? '', 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 = [];