getAttribute("frontend.page.information"); if ($pi !== null) { $pageId = (int)$pi->getId(); } } if ($pageId <= 0) { $pageId = (int)($GLOBALS["TSFE"]->id ?? 0); } $qb = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('tt_content'); $rows = $qb ->select('*') ->from('tt_content') ->where( $qb->expr()->eq('pid', $qb->createNamedParameter($pageId, ParameterType::INTEGER)), $qb->expr()->or( $qb->expr()->eq('CType', $qb->createNamedParameter('vitec_downloadcardcollection', ParameterType::STRING)), $qb->expr()->and( $qb->expr()->eq('CType', $qb->createNamedParameter('list', ParameterType::STRING)), $qb->expr()->eq('CType', $qb->createNamedParameter('vitec_downloadcardcollection', ParameterType::STRING)) ) ), $qb->expr()->eq('deleted', 0), $qb->expr()->eq('hidden', 0) ) ->executeQuery() ->fetchAllAssociative(); if (empty($rows)) { return ''; } return $this->renderForRecord($rows[0]); } /** * @param array $contentElement */ public function renderForRecord(array $contentElement): string { try { $ttContentUid = (int)($contentElement['uid'] ?? 0); $flexFormService = GeneralUtility::makeInstance(FlexFormService::class); $flexFormData = $flexFormService->convertFlexFormContentToArray($contentElement['pi_flexform'] ?? ''); $settings = $flexFormData['settings'] ?? []; $debugMode = (bool)($settings['debug'] ?? false); // Pass-through settings for the frontend $settingsOut = [ 'layout' => (string)($settings['layout'] ?? ''), 'magstyle' => (bool)($settings['magstyle'] ?? false), 'magheader' => (string)($settings['magheader'] ?? ''), 'magtext' => (string)($settings['magtext'] ?? ''), 'maglink' => (string)($settings['maglink'] ?? ''), 'adddetaillink' => (bool)($settings['adddetaillink'] ?? false), ]; // --- Downloads: comma-separated UID list from settings.download --- $downloadUids = $this->parseUidList($settings['download'] ?? ''); $downloads = $downloadUids === [] ? [] : $this->fetchDownloadsByUids($downloadUids); // --- Header image (inline FAL on this tt_content element, fieldname=image) --- $image = $this->getCollectionImage($ttContentUid); $response = [ 'image' => $image, 'downloads' => array_map(fn($r) => $this->serializeDownload($r), $downloads), 'settings' => $settingsOut, ]; if ($debugMode) { $response['debug'] = [ 'ttContentUid' => $ttContentUid, 'downloadUids' => $downloadUids, 'downloadCount' => count($downloads), 'settings' => $settings, ]; } return json_encode($response); } catch (\Throwable $e) { return ''; } } /** * Accepts "5,7,12" or "5,,7" or even an array-like value. Returns int[]. * * @return int[] */ private function parseUidList(mixed $raw): array { if (is_array($raw)) { $raw = implode(',', $raw); } $raw = (string)$raw; if ($raw === '') { return []; } $uids = array_filter(array_map('intval', explode(',', $raw)), static fn(int $u) => $u > 0); return array_values(array_unique($uids)); } /** * @param int[] $uids * @return array> */ private function fetchDownloadsByUids(array $uids): array { $qb = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('tx_vitec_domain_model_download'); $rows = $qb ->select('*') ->from('tx_vitec_domain_model_download') ->where( $qb->expr()->in('uid', $qb->createNamedParameter($uids, Connection::PARAM_INT_ARRAY)), $qb->expr()->eq('deleted', 0), $qb->expr()->eq('hidden', 0), $qb->expr()->eq('hideonwebsite', 0) ) ->executeQuery() ->fetchAllAssociative(); // Preserve the editor-defined order from $uids $orderMap = array_flip($uids); usort($rows, static function ($a, $b) use ($orderMap) { return ($orderMap[(int)$a['uid']] ?? PHP_INT_MAX) <=> ($orderMap[(int)$b['uid']] ?? PHP_INT_MAX); }); return $rows; } /** * Resolve the inline FAL header image stored on this tt_content row * (tablenames='tt_content', fieldname='image'). * * @return array|null */ private function getCollectionImage(int $ttContentUid): ?array { $qb = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_file_reference'); $fileRefData = $qb ->select('sfr.uid', 'sfr.title', 'sfr.description', 'sfr.alternative', 'sfr.crop') ->from('sys_file_reference', 'sfr') ->where( $qb->expr()->eq('sfr.tablenames', $qb->createNamedParameter('tt_content', ParameterType::STRING)), $qb->expr()->eq('sfr.fieldname', $qb->createNamedParameter('image', ParameterType::STRING)), $qb->expr()->eq('sfr.uid_foreign', $qb->createNamedParameter($ttContentUid, ParameterType::INTEGER)), $qb->expr()->eq('sfr.deleted', 0), $qb->expr()->eq('sfr.hidden', 0) ) ->orderBy('sfr.sorting_foreign') ->setMaxResults(1) ->executeQuery() ->fetchAssociative(); if (!$fileRefData) { return null; } try { $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class); $imageService = GeneralUtility::makeInstance(ImageService::class); $fileReference = $resourceFactory->getFileReferenceObject((int)$fileRefData['uid']); $srcset = []; foreach ([400, 800, 1200, 1600] as $width) { $variant = $imageService->applyProcessingInstructions( $fileReference, ['width' => $width, 'crop' => $fileRefData['crop'] ?? null] ); $srcset[] = [ 'url' => $imageService->getImageUri($variant), 'width' => $width, 'descriptor' => $width . 'w', ]; } $default = $imageService->applyProcessingInstructions( $fileReference, ['width' => 800, 'crop' => $fileRefData['crop'] ?? null] ); return [ 'uid' => (int)$fileRefData['uid'], 'url' => $imageService->getImageUri($default), 'title' => $fileRefData['title'] ?? '', 'alternative' => $fileRefData['alternative'] ?? '', 'description' => $fileRefData['description'] ?? '', 'srcset' => $srcset, 'properties' => [ 'width' => $fileReference->getProperty('width'), 'height' => $fileReference->getProperty('height'), 'mimeType' => $fileReference->getProperty('mime_type'), ], ]; } catch (\Exception $e) { return null; } } /** * @param array $download * @return array */ protected function serializeDownload(array $download): array { $uid = (int)$download['uid']; return [ 'uid' => $uid, 'title' => (string)($download['title'] ?? ''), 'slug' => (string)($download['slug'] ?? ''), 'teaser' => (string)($download['teaser'] ?? ''), 'description' => (string)($download['description'] ?? ''), 'keywords' => (string)($download['keywords'] ?? ''), 'icon' => (string)($download['icon'] ?? ''), 'filepath' => (string)($download['filepath'] ?? ''), 'fileprefix' => (string)($download['fileprefix'] ?? ''), 'private_download' => (bool)($download['private_download'] ?? false), 'hideonapp' => (bool)($download['hideonapp'] ?? false), 'hideonwebsite' => (bool)($download['hideonwebsite'] ?? false), 'hideondatasheets' => (bool)($download['hideondatasheets'] ?? false), 'hideonproducts' => (bool)($download['hideonproducts'] ?? false), 'file' => $this->getDownloadFile($uid), ]; } /** * Resolve the FAL file reference (fieldname=file) for a download. * * @return array|null */ protected function getDownloadFile(int $downloadUid): ?array { $qb = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_file_reference'); $row = $qb ->select('fr.uid', 'fr.title', 'fr.description', 'f.uid AS file_uid', 'f.identifier', 'f.name', 'f.size', 'f.extension', 'f.mime_type') ->from('sys_file_reference', 'fr') ->join('fr', 'sys_file', 'f', 'fr.uid_local = f.uid') ->where( $qb->expr()->eq('fr.tablenames', $qb->createNamedParameter('tx_vitec_domain_model_download', ParameterType::STRING)), $qb->expr()->eq('fr.fieldname', $qb->createNamedParameter('file', ParameterType::STRING)), $qb->expr()->eq('fr.uid_foreign', $qb->createNamedParameter($downloadUid, ParameterType::INTEGER)), $qb->expr()->eq('fr.deleted', 0), $qb->expr()->eq('f.missing', 0) ) ->orderBy('fr.sorting_foreign', 'ASC') ->setMaxResults(1) ->executeQuery() ->fetchAssociative(); if (!$row) { return null; } return [ 'uid' => (int)$row['file_uid'], 'name' => (string)($row['name'] ?? ''), 'url' => '/fileadmin' . ($row['identifier'] ?? ''), 'size' => (int)($row['size'] ?? 0), 'extension' => (string)($row['extension'] ?? ''), 'mimeType' => (string)($row['mime_type'] ?? ''), 'title' => (string)($row['title'] ?? ''), 'description' => (string)($row['description'] ?? ''), ]; } }