Skip to content

Instantly share code, notes, and snippets.

@smichaelsen
Last active September 2, 2022 10:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save smichaelsen/7947087dabf0e9a4deebcd07cd1da2a4 to your computer and use it in GitHub Desktop.
Save smichaelsen/7947087dabf0e9a4deebcd07cd1da2a4 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace Vendor\Sitepackage\DataProcessing;
use Doctrine\DBAL\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendWorkspaceRestriction;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
/**
* Usage:
*
* dataProcessing {
* 10 = Vendor\Sitepackage\DataProcessing\InlineItemsDataProcessor
* 10 {
* inlineFieldName = my_inline_field
* as = inlineItems
* localTable = tx_my_table # defaults to tt_content
* dataProcessing {
* # optional further processing of individual items
* }
* }
* }
*/
class InlineItemsDataProcessor implements DataProcessorInterface
{
protected ContentDataProcessor $contentDataProcessor;
public function __construct(ContentDataProcessor $contentDataProcessor)
{
$this->contentDataProcessor = $contentDataProcessor;
}
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData): array
{
$localTable = $processorConfiguration['localTable'] ?? 'tt_content';
$inlineFieldName = $processorConfiguration['inlineFieldName'];
if (!isset($GLOBALS['TCA'][$localTable]['columns'][$inlineFieldName])) {
throw new \Exception('Tried to process inline records for non existing field ' . $localTable . '.' . $inlineFieldName, 1587038305);
}
$inlineFieldTca = $GLOBALS['TCA'][$localTable]['columns'][$inlineFieldName];
$foreignTable = $inlineFieldTca['config']['foreign_table'];
$foreignField = $inlineFieldTca['config']['foreign_field'];
$foreignTableTca = $GLOBALS['TCA'][$foreignTable];
$foreignSortby = $inlineFieldTca['config']['foreign_sortby'] ?? $foreignTableTca['ctrl']['sortby'] ?? null;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($foreignTable);
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(FrontendWorkspaceRestriction::class));
$contentElementId = $cObj->data['_LOCALIZED_UID'] ?? $cObj->data['uid'];
$constraints = [];
if (!empty($foreignField)) {
$constraints[] = $queryBuilder->expr()->eq($foreignField, $queryBuilder->createNamedParameter($contentElementId, \PDO::PARAM_INT));
} else {
$constraints[] = $queryBuilder->expr()->in('uid', $queryBuilder->createNamedParameter(GeneralUtility::intExplode(',', $cObj->data[$inlineFieldName]), Connection::PARAM_INT_ARRAY));
}
if (isset($foreignTableTca['ctrl']['languageField'])) {
$constraints[] = $queryBuilder->expr()->in($foreignTableTca['ctrl']['languageField'], $queryBuilder->createNamedParameter([-1, $cObj->data['sys_language_uid']], Connection::PARAM_INT_ARRAY));
}
$queryBuilder->select('*')->from($foreignTable)->where(...$constraints);
if ($foreignSortby) {
$queryBuilder->orderBy($foreignSortby);
}
$queriedItems = $queryBuilder->execute()->fetchAllAssociative();
$processedItems = [];
foreach ($queriedItems as $item) {
// workspace overlay:
self::getPageRepository()->versionOL($foreignTable, $item);
if ($item === false) {
continue;
}
$recordContentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
$recordContentObjectRenderer->start($item, $foreignTable);
$renderedItem = ['data' => $item];
$renderedItem = $this->contentDataProcessor->process($recordContentObjectRenderer, $processorConfiguration, $renderedItem);
$processedItems[] = $renderedItem;
}
if (!empty($foreignSortby)) {
// sort items again after workspace overlay
usort($processedItems, static function (array $itemA, array $itemB) use ($foreignSortby) {
return $itemA['data'][$foreignSortby] <=> $itemB['data'][$foreignSortby];
});
}
$reverse = $cObj->stdWrapValue('reverse', $processorConfiguration);
if ($reverse) {
$processedItems = array_reverse($processedItems);
}
$processedData[$processorConfiguration['as']] = $processedItems;
return $processedData;
}
protected static function getPageRepository(): PageRepository
{
// @extensionScannerIgnoreLine
return $GLOBALS['TSFE']->sys_page;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment