Files
VITEC-website/packages/vitec/Classes/UserFunc/PageCheckJsonRenderer.php
T
orascheandClaude Fable 5.1 20bcbeb731 Page content check for markets and solutions (vitec_pagecheck)
Sibling of the product check (decision Harry 2026-11-13): new content element vitec_pagecheck with a FlexForm scope (markets | solutions) and PageCheckService/PageCheckJsonRenderer. Overview = one row per page of the tree (11 markets + 24 sub-markets, 8 solution groups + 39 sub-solutions) with 18 checks taken from the page elements (hero image and subline, lead, intro text/image/CTA, cards with visuals, testimonials, products, insights text/cover/CTA, logos, CTA banner), the page properties (meta description, OG image, page media) and the market/solution record behind the page; columns a page type does not have come as ok null. ?check=<pageUid> delivers the page detail (elements in page order with texts, links, images, FlexForm settings; SEO, media, record, children). Always USER_INT, check is cHash-excluded already. New command vitec:pagecheck-pages created /markets/market-check (608) and /solutions/solution-check (609) from the product-check page properties; both live on DEV, rendering is front end work.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-13 11:44:41 +01:00

69 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Evomedien\Vitec\UserFunc;
use Evomedien\Vitec\Service\PageCheckService;
use TYPO3\CMS\Core\Attribute\AsAllowedCallable;
use TYPO3\CMS\Core\Service\FlexFormService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**
* JSON for the content element `vitec_pagecheck` (pages /markets/market-check
* and /solutions/solution-check): the page content audit of one scope,
* rendered by the React front end like the product check.
*
* Emitted under content.pagecheck:
*
* without query {mode: "overview", scope, scopeLabel, generatedAt, fields[], summary, pages[]}
* ?check=<pageUid> {mode: "detail", page: {…} | null}
* on failure {mode: "error", error}
*
* The scope (markets | solutions) comes from the element's FlexForm
* (settings.scope). Always USER_INT - the audit shows the database as it is
* right now; `check` is excluded from the cHash (ext_localconf.php, shared
* with the product check). The front end loads the detail variant
* client-side from /_json, one request per opened row.
*/
final class PageCheckJsonRenderer
{
protected ?ContentObjectRenderer $cObj = null;
public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
{
$this->cObj = $cObj;
}
#[AsAllowedCallable]
public function render(string $content, array $conf): string
{
if ($this->cObj !== null && $this->cObj->getUserObjectType() === ContentObjectRenderer::OBJECTTYPE_USER) {
$this->cObj->convertToUserIntObject();
return '';
}
try {
$scope = 'markets';
$flex = (string)($this->cObj?->data['pi_flexform'] ?? '');
if (trim($flex) !== '') {
$settings = GeneralUtility::makeInstance(FlexFormService::class)->convertFlexFormContentToArray($flex)['settings'] ?? [];
if (isset(PageCheckService::SCOPES[(string)($settings['scope'] ?? '')])) {
$scope = (string)$settings['scope'];
}
}
$service = GeneralUtility::makeInstance(PageCheckService::class);
$queryParams = $GLOBALS['TYPO3_REQUEST']?->getQueryParams() ?? [];
$check = (int)($queryParams['check'] ?? 0);
if ($check > 0) {
$payload = ['mode' => 'detail', 'scope' => $scope, 'page' => $service->detail($check)];
} else {
$payload = ['mode' => 'overview'] + $service->overview($scope);
}
} catch (\Throwable $e) {
$payload = ['mode' => 'error', 'error' => $e->getMessage()];
}
return (string)json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
}
}