{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); } }