Files
VITEC-website/packages/vitec/Classes/Service/RteResolver.php

57 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Evomedien\Vitec\Service;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**
* Turns raw richtext (RTE) database content into frontend-ready HTML.
*
* TYPO3 stores RTE fields with unresolved internal references: internal links as
* `<a href="t3://page?uid=12">`, legacy content as `<link>` tags, images with
* relative paths. Fluid resolves those through `parseFunc` when it renders; a
* headless UserFunc renderer that hands the raw column straight to JSON does
* not, and the frontend receives dead links.
*
* The two upstream packages already close this gap for the output they own:
* `friendsoftypo3/headless` applies `parseFunc =< lib.parseFunc_RTE` to the core
* text elements via TypoScript, and `nb-headless-content-blocks` calls
* `parseFunc($value, null, '< lib.parseFunc_RTE')` for every Content Block field
* whose TCA has `enableRichtext`. This class closes it for the VITEC UserFunc
* renderers, using exactly the same call.
*
* Static by design: the conversion is stateless, and the call sites are payload
* array literals where a `GeneralUtility::makeInstance(...)->` prefix would add
* only noise. Same rationale as `CropVariants::firstImage()` and
* `FormDefinitions::get()`.
*
* Fail-soft per architecture spec clause 9.5: when parsing is impossible — most
* notably outside a frontend request, where no TypoScript setup exists — the raw
* value is returned. Content is never lost; at worst it stays unresolved.
*/
final class RteResolver
{
/**
* @param mixed $value raw column value; null and non-strings are tolerated
*/
public static function html(mixed $value): string
{
$raw = (string)($value ?? '');
if (trim($raw) === '') {
return '';
}
try {
$parsed = GeneralUtility::makeInstance(ContentObjectRenderer::class)
->parseFunc($raw, null, '< lib.parseFunc_RTE');
return $parsed !== '' ? $parsed : $raw;
} catch (\Throwable $e) {
return $raw;
}
}
}