thumbnail of the actual image (hero background, intro image, insights cover), key copy in the summary line, full details expanded; card and intro-paragraph previews are wrapped in the same mechanism - New SubmarketPluginPreview for vitec_usecaselist / vitec_productfeature / vitec_productlist: instead of bare standard boxes they now list the selected story titles (flagging stories that still lack a quote), the featured product and the hand-picked products in order - Container-style collapse for whole page-module COLUMNS: a chevron at the right of every column header folds a section down to its title row, state kept per page and colPos in localStorage - the slot view of a sub-market page folds to six slim bands - Previews sit under the page module's pointer-events lock and its click-to-edit layer: pointer events are re-enabled inside the collapse markup and the toggle runs on pointerdown in the capture phase - Two more v14 removals fixed on the way, both latent in the OLDER preview classes too (Usecaseshow, Modelcard would have crashed the page module): GridColumnItem::getRecord() now returns a Domain\Record object, and StandaloneView is gone - previews normalize the record via a shared helper and render through the ViewFactory
148 lines
5.8 KiB
PHP
Executable File
148 lines
5.8 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Evomedien\Vitec\Preview;
|
|
|
|
use Doctrine\DBAL\ParameterType;
|
|
use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer;
|
|
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
|
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
|
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
|
use TYPO3\CMS\Core\Service\FlexFormService;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
|
|
/**
|
|
* Page-module preview for the VITEC Card plugin (vitec_modelcard):
|
|
* type badge, selected record title, thumbnail and layout badge.
|
|
* Registered via TCA types.vitec_modelcard.previewRenderer.
|
|
*/
|
|
class ModelcardPreviewRenderer extends StandardContentPreviewRenderer
|
|
{
|
|
private const MODEL_TABLES = [
|
|
'product' => 'tx_vitec_domain_model_product',
|
|
'story' => 'tx_vitec_domain_model_usecase',
|
|
'market' => 'tx_vitec_domain_model_market',
|
|
'solution' => 'tx_vitec_domain_model_solution',
|
|
];
|
|
|
|
private const TYPE_LABELS = [
|
|
'product' => 'Product',
|
|
'story' => 'Success Story',
|
|
'market' => 'Market',
|
|
'solution' => 'Solution',
|
|
];
|
|
|
|
/** Card-image FAL field per model type (first hit wins). */
|
|
private const IMAGE_FIELDS = [
|
|
'product' => ['image', 'productimage'],
|
|
'story' => ['card_image', 'hero_bgimage'],
|
|
'market' => ['image'],
|
|
'solution' => ['image'],
|
|
];
|
|
|
|
public function renderPageModulePreviewContent(GridColumnItem $item): string
|
|
{
|
|
try {
|
|
$record = $this->recordArray($item);
|
|
|
|
$flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
|
|
$flexFormData = $flexFormService->convertFlexFormContentToArray($record['pi_flexform'] ?? '');
|
|
$settings = $flexFormData['settings'] ?? [];
|
|
|
|
$modelType = (string)($settings['modelType'] ?? 'product');
|
|
$layout = (string)($settings['layout'] ?? 'vertical');
|
|
$recordUid = (int)($settings[$modelType === 'story' ? 'story' : $modelType] ?? 0);
|
|
|
|
$title = '';
|
|
$subtitle = '';
|
|
$imageUrl = '';
|
|
if ($recordUid > 0 && isset(self::MODEL_TABLES[$modelType])) {
|
|
$table = self::MODEL_TABLES[$modelType];
|
|
$qb = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
|
|
$row = $qb
|
|
->select('*')
|
|
->from($table)
|
|
->where(
|
|
$qb->expr()->eq('uid', $qb->createNamedParameter($recordUid, ParameterType::INTEGER)),
|
|
$qb->expr()->eq('deleted', 0)
|
|
)
|
|
->executeQuery()
|
|
->fetchAssociative();
|
|
if ($row) {
|
|
$title = (string)($row['title'] ?? '');
|
|
$subtitle = (string)($row['subtitle'] ?? ($row['teaser'] ?? ''));
|
|
$imageUrl = $this->firstImageUrl($table, $recordUid, self::IMAGE_FIELDS[$modelType]);
|
|
}
|
|
}
|
|
|
|
// v14: StandaloneView was removed - views come from the ViewFactory.
|
|
$view = GeneralUtility::makeInstance(\TYPO3\CMS\Core\View\ViewFactoryInterface::class)
|
|
->create(new \TYPO3\CMS\Core\View\ViewFactoryData(
|
|
templatePathAndFilename: 'EXT:vitec/Resources/Private/Templates/Preview/Modelcard.html',
|
|
request: $GLOBALS['TYPO3_REQUEST'] ?? null,
|
|
));
|
|
$view->assignMultiple([
|
|
'typeLabel' => self::TYPE_LABELS[$modelType] ?? $modelType,
|
|
'layout' => $layout,
|
|
'recordUid' => $recordUid,
|
|
'title' => $title,
|
|
'subtitle' => $subtitle,
|
|
'imageUrl' => $imageUrl,
|
|
]);
|
|
|
|
return $view->render();
|
|
} catch (\Throwable $e) {
|
|
return parent::renderPageModulePreviewContent($item);
|
|
}
|
|
}
|
|
|
|
/** @param string[] $fieldNames */
|
|
private function firstImageUrl(string $table, int $uid, array $fieldNames): string
|
|
{
|
|
try {
|
|
$qb = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
|
|
foreach ($fieldNames as $fieldName) {
|
|
$ref = $qb
|
|
->select('uid')
|
|
->from('sys_file_reference')
|
|
->where(
|
|
$qb->expr()->eq('tablenames', $qb->createNamedParameter($table, ParameterType::STRING)),
|
|
$qb->expr()->eq('fieldname', $qb->createNamedParameter($fieldName, ParameterType::STRING)),
|
|
$qb->expr()->eq('uid_foreign', $qb->createNamedParameter($uid, ParameterType::INTEGER)),
|
|
$qb->expr()->eq('deleted', 0),
|
|
$qb->expr()->eq('hidden', 0)
|
|
)
|
|
->setMaxResults(1)
|
|
->executeQuery()
|
|
->fetchAssociative();
|
|
if ($ref) {
|
|
$file = GeneralUtility::makeInstance(ResourceFactory::class)
|
|
->getFileReferenceObject((int)$ref['uid']);
|
|
return (string)$file->getPublicUrl();
|
|
}
|
|
}
|
|
} catch (\Throwable $e) {
|
|
// no thumb
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* v14: GridColumnItem::getRecord() returns a Domain\Record object, no
|
|
* longer an array (found 2026-10-02 - crashed the page module preview).
|
|
* Normalizes both shapes to the raw database array.
|
|
*
|
|
* @return array<string,mixed>
|
|
*/
|
|
private function recordArray(GridColumnItem $item): array
|
|
{
|
|
$record = $item->getRecord();
|
|
if ($record instanceof \TYPO3\CMS\Core\Domain\Record) {
|
|
$raw = $record->getRawRecord();
|
|
return $raw !== null ? $raw->toArray() : [];
|
|
}
|
|
return (array)$record;
|
|
}
|
|
}
|