cObj->data ?? null) ? $this->cObj->data : null; if ($row && (string)($row['CType'] ?? '') === 'vitec_solutionshow') { return $this->renderForRecord($row); } // 2) Page-id via v14 request attribute (TSFE->id is often null in JSON cObj context) $pageId = 0; $request = $GLOBALS['TYPO3_REQUEST'] ?? null; if ($request !== null) { $pageInfo = $request->getAttribute('frontend.page.information'); if ($pageInfo !== null) { $pageId = (int)$pageInfo->getId(); } } if ($pageId <= 0) { $pageId = (int)($GLOBALS['TSFE']->id ?? 0); } if ($pageId <= 0) { return ''; } $queryBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ConnectionPool::class) ->getQueryBuilderForTable('tt_content'); $contentElements = $queryBuilder ->select('*') ->from('tt_content') ->where( $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pageId, ParameterType::INTEGER)), $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('vitec_solutionshow', ParameterType::STRING)), $queryBuilder->expr()->eq('deleted', 0), $queryBuilder->expr()->eq('hidden', 0) ) ->executeQuery() ->fetchAllAssociative(); if (empty($contentElements)) { return ''; } return $this->renderForRecord($contentElements[0]); } /** * @param array $contentElement */ public function renderForRecord(array $contentElement): string { try { $pageId = (int)($GLOBALS['TSFE']->id ?? 0); $flexFormService = GeneralUtility::makeInstance(FlexFormService::class); $flexFormData = $flexFormService->convertFlexFormContentToArray($contentElement['pi_flexform'] ?? ''); $settings = $flexFormData['settings'] ?? []; $solutionUid = (int)($settings['solution'] ?? 0); $layout = (string)($settings['layout'] ?? 'default'); $debugMode = (bool)($settings['debug'] ?? false); // Fallback: route / query parameter (numeric uid only — Market has no slug) if (!$solutionUid) { $routeParams = $GLOBALS['TYPO3_REQUEST']->getQueryParams(); $solutionParam = $routeParams['tx_vitec_solutionshow']['solution'] ?? null; if ($solutionParam && is_numeric($solutionParam)) { $solutionUid = (int)$solutionParam; } } if (!$solutionUid) { return $debugMode ? json_encode(['error' => 'No solution selected or found', 'debug' => ['settings' => $settings]]) : ''; } $solutionQb = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('tx_vitec_domain_model_solution'); $solution = $solutionQb ->select('*') ->from('tx_vitec_domain_model_solution') ->where( $solutionQb->expr()->eq('uid', $solutionQb->createNamedParameter($solutionUid, ParameterType::INTEGER)), $solutionQb->expr()->eq('deleted', 0), $solutionQb->expr()->eq('hidden', 0) ) ->executeQuery() ->fetchAssociative(); if (!$solution) { return $debugMode ? json_encode(['error' => 'Solution not found', 'debug' => ['solutionUid' => $solutionUid]]) : ''; } $response = [ 'solution' => $this->serializeSolution($solution), 'layout' => $layout, 'settings' => [ 'layout' => $layout, ], ]; if ($debugMode) { $response['debug'] = [ 'pageId' => $pageId, 'solutionUid' => $solutionUid, 'layout' => $layout, 'settings' => $settings, ]; } return json_encode($response); } catch (\Throwable $e) { return ''; } } /** * @param array $solution * @return array */ protected function serializeSolution(array $solution): array { $uid = (int)$solution['uid']; return [ 'uid' => $uid, 'title' => (string)($solution['title'] ?? ''), 'slug' => (string)($solution['slug'] ?? ''), 'subtitle' => (string)($solution['subtitle'] ?? ''), 'teaser' => (string)($solution['teaser'] ?? ''), 'description' => RteResolver::html($solution['description'] ?? ''), 'categories' => $this->getSolutionCategories($uid), 'image' => $this->getSolutionImage($uid), ]; } /** * Resolve the single image FAL reference for a market (fieldname=image). * * @return array|null */ protected function getSolutionImage(int $solutionUid): ?array { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_file_reference'); $fileRefData = $queryBuilder ->select('sfr.uid', 'sfr.title', 'sfr.description', 'sfr.alternative', 'sfr.crop') ->from('sys_file_reference', 'sfr') ->where( $queryBuilder->expr()->eq('sfr.tablenames', $queryBuilder->createNamedParameter('tx_vitec_domain_model_solution', ParameterType::STRING)), $queryBuilder->expr()->eq('sfr.fieldname', $queryBuilder->createNamedParameter('image', ParameterType::STRING)), $queryBuilder->expr()->eq('sfr.uid_foreign', $queryBuilder->createNamedParameter($solutionUid, ParameterType::INTEGER)), $queryBuilder->expr()->eq('sfr.deleted', 0), $queryBuilder->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, 'fileExtension' => 'webp'] ); $srcset[] = [ 'url' => $imageService->getImageUri($variant), 'width' => $width, 'descriptor' => $width . 'w', ]; } $default = $imageService->applyProcessingInstructions( $fileReference, ['width' => 800, 'crop' => $fileRefData['crop'] ?? null, 'fileExtension' => 'webp'] ); 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; } } protected function getSolutionCategories(int $solutionUid): array { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_category'); $categories = $queryBuilder ->select('c.uid', 'c.title', 'c.description') ->from('sys_category', 'c') ->join( 'c', 'sys_category_record_mm', 'mm', 'mm.uid_local = c.uid AND mm.tablenames = ' . $queryBuilder->createNamedParameter('tx_vitec_domain_model_solution', ParameterType::STRING) . ' AND mm.fieldname = ' . $queryBuilder->createNamedParameter('categories', ParameterType::STRING) ) ->where( $queryBuilder->expr()->eq('mm.uid_foreign', $queryBuilder->createNamedParameter($solutionUid, ParameterType::INTEGER)), $queryBuilder->expr()->eq('c.deleted', 0), $queryBuilder->expr()->eq('c.hidden', 0) ) ->orderBy('mm.sorting', 'ASC') ->executeQuery() ->fetchAllAssociative(); return array_map(static function ($cat) { return [ 'uid' => (int)$cat['uid'], 'title' => $cat['title'] ?? '', 'description' => $cat['description'] ?? '', ]; }, $categories); } }