The TYPO3 10 drawItem hooks become one preview renderer registered per
CType in TCA; it renders the old templates from a46918d with the same
variables (f:format.html is not allowed in the backend: f:sanitize.html).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
121 lines
5.8 KiB
PHP
121 lines
5.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace EP\EpTheme\Preview;
|
|
|
|
use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer;
|
|
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
|
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
|
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
|
use TYPO3\CMS\Core\Resource\FileRepository;
|
|
use TYPO3\CMS\Core\Service\FlexFormService;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
use TYPO3\CMS\Core\View\ViewFactoryData;
|
|
use TYPO3\CMS\Core\View\ViewFactoryInterface;
|
|
|
|
/**
|
|
* Page module previews of the theme's content elements, rendered from
|
|
* Templates/PreviewRenderer/<CType>.html as the TYPO3 10 drawItem hooks did
|
|
* (Classes/Hooks/PageLayoutView in a46918d), with the same template variables.
|
|
* Registered per CType in TCA (['types'][<CType>]['previewRenderer']).
|
|
*/
|
|
class ContentPreviewRenderer extends StandardContentPreviewRenderer
|
|
{
|
|
/**
|
|
* CType => [field holding the related uid, related table, template variable]
|
|
*/
|
|
protected const RELATED_RECORDS = [
|
|
'teaser_country' => ['tx_eptheme_context_country', 'tx_epproducts_domain_model_country', 'country'],
|
|
'teaser_region' => ['tx_eptheme_context_region', 'tx_epproducts_domain_model_region', 'region'],
|
|
'teaser_city' => ['tx_eptheme_context_city', 'tx_epproducts_domain_model_city', 'city'],
|
|
'teaser_hotel' => ['tx_eptheme_context_hotel', 'tx_epproducts_domain_model_hotel', 'hotel'],
|
|
'teaser_concept' => ['tx_eptheme_context_concept', 'tx_epproducts_domain_model_concept', 'concept'],
|
|
'teaser_product' => ['tx_eptheme_context_product', 'tx_epproducts_domain_model_product', 'product'],
|
|
'teaser_booking_link' => ['tx_eptheme_context_product', 'tx_epproducts_domain_model_product', 'product'],
|
|
];
|
|
|
|
public function renderPageModulePreviewContent(GridColumnItem $item): string
|
|
{
|
|
$row = $item->getRecord();
|
|
$cType = (string)$row['CType'];
|
|
$template = GeneralUtility::getFileAbsFileName(
|
|
'EXT:ep_theme/Resources/Private/Templates/PreviewRenderer/' . GeneralUtility::underscoredToUpperCamelCase($cType) . '.html'
|
|
);
|
|
if (!is_file($template)) {
|
|
return parent::renderPageModulePreviewContent($item);
|
|
}
|
|
|
|
$images = $this->getImages((int)$row['uid'], 'tt_content', 'image');
|
|
$variables = [
|
|
'data' => $row,
|
|
'flexForm' => GeneralUtility::makeInstance(FlexFormService::class)->convertFlexFormContentToArray((string)($row['pi_flexform'] ?? '')),
|
|
'firstImage' => $images[0] ?? null,
|
|
'images' => $images,
|
|
];
|
|
$variables = array_replace($variables, $this->getAssignmentsForTemplate($cType, $row));
|
|
|
|
$view = GeneralUtility::makeInstance(ViewFactoryInterface::class)->create(new ViewFactoryData(
|
|
templatePathAndFilename: $template,
|
|
request: $item->getContext()->getCurrentRequest(),
|
|
));
|
|
$view->assignMultiple($variables);
|
|
return $view->render();
|
|
}
|
|
|
|
protected function getAssignmentsForTemplate(string $cType, array $row): array
|
|
{
|
|
if (isset(self::RELATED_RECORDS[$cType])) {
|
|
[$field, $table, $name] = self::RELATED_RECORDS[$cType];
|
|
$uid = (int)($row[$field] ?? 0);
|
|
$assignments = [
|
|
'images' => $this->getImages($uid, $table, 'teaser_images'),
|
|
$name => $uid > 0 ? BackendUtility::getRecord($table, $uid) : null,
|
|
];
|
|
if ($cType === 'teaser_product') {
|
|
$hotelUid = (int)($row['tx_eptheme_context_hotel'] ?? 0);
|
|
$assignments['hotel'] = $hotelUid > 0 ? BackendUtility::getRecord('tx_epproducts_domain_model_hotel', $hotelUid) : null;
|
|
}
|
|
return $assignments;
|
|
}
|
|
|
|
switch ($cType) {
|
|
case 'gmap':
|
|
$regionUid = (int)($row['tx_eptheme_context_region'] ?? 0);
|
|
$content = $regionUid > 0
|
|
? BackendUtility::getRecord('tx_epproducts_domain_model_region', $regionUid)
|
|
: BackendUtility::getRecord('tx_epproducts_domain_model_hotel', (int)($row['tx_eptheme_context_hotel'] ?? 0));
|
|
return ['content' => $content];
|
|
case 'disrupter':
|
|
// tx_eptheme_disrupter is an MM relation; the field itself only holds the count
|
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_eptheme_ttcontent_tx_eptheme_disrupter_mm');
|
|
$disrupterUid = (int)$queryBuilder->select('uid_foreign')
|
|
->from('tx_eptheme_ttcontent_tx_eptheme_disrupter_mm')
|
|
->where($queryBuilder->expr()->eq('uid_local', $queryBuilder->createNamedParameter((int)$row['uid'])))
|
|
->orderBy('sorting')
|
|
->setMaxResults(1)
|
|
->executeQuery()
|
|
->fetchOne();
|
|
return ['content' => $disrupterUid > 0 ? BackendUtility::getRecord('tx_eptheme_domain_model_disrupter', $disrupterUid) : null];
|
|
case 'lineup':
|
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_eptheme_domain_model_lineup');
|
|
$rows = $queryBuilder->select('*')
|
|
->from('tx_eptheme_domain_model_lineup')
|
|
->where($queryBuilder->expr()->eq('tt_content', $queryBuilder->createNamedParameter((int)$row['uid'])))
|
|
->orderBy('sorting')
|
|
->executeQuery()
|
|
->fetchAllAssociative();
|
|
return ['rows' => $rows];
|
|
}
|
|
return [];
|
|
}
|
|
|
|
protected function getImages(int $uid, string $table, string $field): array
|
|
{
|
|
if ($uid <= 0) {
|
|
return [];
|
|
}
|
|
return GeneralUtility::makeInstance(FileRepository::class)->findByRelation($table, $field, $uid);
|
|
}
|
|
}
|