diff --git a/Classes/ContentObject/JsonContentContentObject.php b/Classes/ContentObject/JsonContentContentObject.php
index 3f717984..5437deeb 100755
--- a/Classes/ContentObject/JsonContentContentObject.php
+++ b/Classes/ContentObject/JsonContentContentObject.php
@@ -14,7 +14,10 @@
use FriendsOfTYPO3\Headless\Json\JsonEncoder;
use FriendsOfTYPO3\Headless\Json\JsonEncoderInterface;
use FriendsOfTYPO3\Headless\Utility\HeadlessUserInt;
+use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Backend\View\BackendLayoutView;
+use TYPO3\CMS\Core\Information\Typo3Version;
+use TYPO3\CMS\Core\TimeTracker\TimeTracker;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentContentObject;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
@@ -23,6 +26,7 @@
use function count;
use function is_array;
use function json_decode;
+use function json_encode;
use function str_contains;
use function trim;
@@ -102,11 +106,18 @@ class JsonContentContentObject extends ContentContentObject
{
private HeadlessUserInt $headlessUserInt;
private JsonEncoderInterface $jsonEncoder;
+ /**
+ * @var mixed|object|\Psr\Log\LoggerAwareInterface|\TYPO3\CMS\Core\SingletonInterface|TimeTracker|(TimeTracker&\Psr\Log\LoggerAwareInterface)|(TimeTracker&\TYPO3\CMS\Core\SingletonInterface)|null
+ */
+ private TimeTracker $timeTracker;
+ private EventDispatcherInterface $eventDispatcher;
public function __construct()
{
$this->headlessUserInt = GeneralUtility::makeInstance(HeadlessUserInt::class);
$this->jsonEncoder = GeneralUtility::makeInstance(JsonEncoder::class);
+ $this->timeTracker = GeneralUtility::makeInstance(TimeTracker::class);
+ $this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class);
}
/**
@@ -199,6 +210,8 @@ protected function groupContentElementsByColPos(array $contentElements, array $c
*/
private function prepareValue(array $conf): array
{
+ $t3v13andAbove = (new Typo3Version())->getMajorVersion() >= 13;
+
$frontendController = $this->getTypoScriptFrontendController();
$theValue = [];
$originalRec = $frontendController->currentRecord;
@@ -233,20 +246,44 @@ private function prepareValue(array $conf): array
$tmpValue = '';
do {
- $records = $this->cObj->getRecords($conf['table'], $conf['select.']);
+ if ($t3v13andAbove) {
+ $modifyRecordsEvent = $this->eventDispatcher->dispatch(
+ new \TYPO3\CMS\Frontend\ContentObject\Event\ModifyRecordsAfterFetchingContentEvent(
+ $this->cObj->getRecords($conf['table'], $conf['select.']),
+ json_encode($theValue, JSON_THROW_ON_ERROR),
+ $slide,
+ $slideCollect,
+ $slideCollectReverse,
+ $slideCollectFuzzy,
+ $conf
+ )
+ );
+
+ $records = $modifyRecordsEvent->getRecords();
+ $theValue = json_decode($modifyRecordsEvent->getFinalContent(), true, 512, JSON_THROW_ON_ERROR);
+ $slide = $modifyRecordsEvent->getSlide();
+ $slideCollect = $modifyRecordsEvent->getSlideCollect();
+ $slideCollectReverse = $modifyRecordsEvent->getSlideCollectReverse();
+ $slideCollectFuzzy = $modifyRecordsEvent->getSlideCollectFuzzy();
+ $conf = $modifyRecordsEvent->getConfiguration();
+ } else {
+ $records = $this->cObj->getRecords($conf['table'], $conf['select.']);
+ }
$cobjValue = [];
if (!empty($records)) {
- $this->getTimeTracker()->setTSlogMessage('NUMROWS: ' . count($records));
+ $this->timeTracker->setTSlogMessage('NUMROWS: ' . count($records));
$cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class, $frontendController);
$cObj->setParent($this->cObj->data, $this->cObj->currentRecord);
$this->cObj->currentRecordNumber = 0;
foreach ($records as $row) {
- // Call hook for possible manipulation of database row for cObj->data
- foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content_content.php']['modifyDBRow'] ?? [] as $className) {
- $_procObj = GeneralUtility::makeInstance($className);
- $_procObj->modifyDBRow($row, $conf['table']);
+ if (!$t3v13andAbove) {
+ // Call hook for possible manipulation of database row for cObj->data
+ foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content_content.php']['modifyDBRow'] ?? [] as $className) {
+ $_procObj = GeneralUtility::makeInstance($className);
+ $_procObj->modifyDBRow($row, $conf['table']);
+ }
}
$registerField = $conf['table'] . ':' . ($row['uid'] ?? 0);
if (!($frontendController->recordRegister[$registerField] ?? false)) {
@@ -282,7 +319,7 @@ private function prepareValue(array $conf): array
}
$again = (string)$conf['select.']['pidInList'] !== '';
}
- } while ($again && $slide && ((string)$tmpValue === '' && $slideCollectFuzzy || $slideCollect));
+ } while ($again && $slide && (((string)$tmpValue === '' && $slideCollectFuzzy) || $slideCollect));
$theValue = $this->groupContentElementsByColPos($theValue, $conf);
// Restore
diff --git a/Classes/Middleware/ShortcutAndMountPointRedirect.php b/Classes/Middleware/ShortcutAndMountPointRedirect.php
index 8c644bfa..0c8b15b9 100644
--- a/Classes/Middleware/ShortcutAndMountPointRedirect.php
+++ b/Classes/Middleware/ShortcutAndMountPointRedirect.php
@@ -12,29 +12,16 @@
namespace FriendsOfTYPO3\Headless\Middleware;
use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
+use FriendsOfTYPO3\Headless\Utility\UrlUtility;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
-use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LoggerAwareTrait;
-use TYPO3\CMS\Core\Domain\Repository\PageRepository;
-use TYPO3\CMS\Core\Http\ImmediateResponseException;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Http\RedirectResponse;
-use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Frontend\Controller\ErrorController;
-use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons;
-
-use function is_array;
-use function parse_url;
-
-class ShortcutAndMountPointRedirect implements MiddlewareInterface, LoggerAwareInterface
+class ShortcutAndMountPointRedirect extends \TYPO3\CMS\Frontend\Middleware\ShortcutAndMountPointRedirect
{
- use LoggerAwareTrait;
-
public function __construct(private readonly HeadlessMode $headlessMode) {}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
@@ -46,96 +33,18 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $handler->handle($request);
}
- $exposeInformation = $GLOBALS['TYPO3_CONF_VARS']['FE']['exposeRedirectInformation'] ?? false;
-
- // Check for shortcut page and mount point redirect
- try {
- $redirectToUri = $this->getRedirectUri($request);
- } catch (ImmediateResponseException $e) {
- return $e->getResponse();
- }
- if ($redirectToUri !== null && $redirectToUri !== (string)$request->getUri()) {
- /** @var PageArguments $pageArguments */
- $pageArguments = $request->getAttribute('routing', null);
- $message = 'TYPO3 Shortcut/Mountpoint' . ($exposeInformation ? ' at page with ID ' . $pageArguments->getPageId() : '');
-
- if ($this->isHeadlessEnabled($request)) {
- $parsed = parse_url($redirectToUri);
- if (is_array($parsed)) {
- $path = $parsed['path'] ?? '/';
- return new JsonResponse(['redirectUrl' => $path, 'statusCode' => 307]);
- }
- }
-
- return new RedirectResponse(
- $redirectToUri,
- 307,
- ['X-Redirect-By' => $message]
- );
- }
-
- // See if the current page is of doktype "External URL", if so, do a redirect as well.
- $controller = $request->getAttribute('frontend.controller');
- if ((int)$controller->page['doktype'] === PageRepository::DOKTYPE_LINK) {
- $externalUrl = $this->prefixExternalPageUrl(
- $controller->page['url'],
- $request->getAttribute('normalizedParams')->getSiteUrl()
- );
- $message = 'TYPO3 External URL' . ($exposeInformation ? ' at page with ID ' . $controller->page['uid'] : '');
- if (!empty($externalUrl)) {
- if ($this->isHeadlessEnabled($request)) {
- return new JsonResponse(['redirectUrl' => $externalUrl, 'statusCode' => 303]);
- }
+ $coreResponse = parent::process($request, $handler);
- return new RedirectResponse(
- $externalUrl,
- 303,
- ['X-Redirect-By' => $message]
- );
- }
- $this->logger->error(
- 'Page of type "External URL" could not be resolved properly',
- [
- 'page' => $controller->page,
- ]
- );
- return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
- $request,
- 'Page of type "External URL" could not be resolved properly',
- $controller->getPageAccessFailureReasons(PageAccessFailureReasons::INVALID_EXTERNAL_URL)
- );
+ if ($coreResponse instanceof RedirectResponse && $this->isHeadlessEnabled($request)) {
+ return new JsonResponse([
+ 'redirectUrl' => GeneralUtility::makeInstance(UrlUtility::class)
+ ->withRequest($request)
+ ->prepareRelativeUrlIfPossible($coreResponse->getHeader('location')[0] ?? ''),
+ 'statusCode' => $coreResponse->getStatusCode(),
+ ]);
}
- return $handler->handle($request);
- }
-
- protected function getRedirectUri(ServerRequestInterface $request): ?string
- {
- $controller = $request->getAttribute('frontend.controller');
- $redirectToUri = $controller->getRedirectUriForShortcut($request);
- return $redirectToUri ?? $controller->getRedirectUriForMountPoint($request);
- }
-
- /**
- * Returns the redirect URL for the input page row IF the doktype is set to 3.
- *
- * @param string $redirectTo The page row to return URL type for
- * @param string $sitePrefix if no protocol or relative path given, the site prefix is added
- * @return string The URL from based on the external page URL given with a prefix.
- */
- protected function prefixExternalPageUrl(string $redirectTo, string $sitePrefix): string
- {
- $uI = parse_url($redirectTo);
- // If relative path, prefix Site URL
- // If it's a valid email without protocol, add "mailto:"
- if (!($uI['scheme'] ?? false)) {
- if (GeneralUtility::validEmail($redirectTo)) {
- $redirectTo = 'mailto:' . $redirectTo;
- } elseif (!str_starts_with($redirectTo, '/')) {
- $redirectTo = $sitePrefix . $redirectTo;
- }
- }
- return $redirectTo;
+ return $coreResponse;
}
private function isHeadlessEnabled(ServerRequestInterface $request): bool
diff --git a/Classes/Seo/CanonicalGenerator.php b/Classes/Seo/CanonicalGenerator.php
index fafb93cc..e24f9cf6 100644
--- a/Classes/Seo/CanonicalGenerator.php
+++ b/Classes/Seo/CanonicalGenerator.php
@@ -12,73 +12,42 @@
namespace FriendsOfTYPO3\Headless\Seo;
use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
-use Psr\EventDispatcher\EventDispatcherInterface;
-use TYPO3\CMS\Core\Domain\Page;
-use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
-use TYPO3\CMS\Seo\Event\ModifyUrlForCanonicalTagEvent;
+use TYPO3\CMS\Seo\Canonical\CanonicalGenerator as CoreCanonicalGenerator;
use function htmlspecialchars;
use function json_encode;
/**
- * Overridden core version with headless implementation
+ * Decorate Core version with headless flavor
*
* @codeCoverageIgnore
*/
-class CanonicalGenerator extends \TYPO3\CMS\Seo\Canonical\CanonicalGenerator
+class CanonicalGenerator
{
- protected TypoScriptFrontendController $typoScriptFrontendController;
- protected PageRepository $pageRepository;
- protected EventDispatcherInterface $eventDispatcher;
-
public function handle(array &$params): string
{
- if ($this->typoScriptFrontendController->config['config']['disableCanonical'] ?? false) {
- return '';
- }
+ $canonical = GeneralUtility::makeInstance(CoreCanonicalGenerator::class)->generate($params);
- $event = new ModifyUrlForCanonicalTagEvent('', $params['request'], new Page($params['page']));
- $event = $this->eventDispatcher->dispatch($event);
- $href = $event->getUrl();
-
- if (empty($href) && (int)$this->typoScriptFrontendController->page['no_index'] === 1) {
+ if ($canonical === '') {
return '';
}
- if (empty($href)) {
- // 1) Check if page has canonical URL set
- $href = $this->checkForCanonicalLink();
- }
- if (empty($href)) {
- // 2) Check if page show content from other page
- $href = $this->checkContentFromPid();
- }
- if (empty($href)) {
- // 3) Fallback, create canonical URL
- $href = $this->checkDefaultCanonical();
- }
+ if (GeneralUtility::makeInstance(HeadlessMode::class)->withRequest($params['request'])->isEnabled()) {
+ $canonical = [
+ 'href' => $this->processCanonical($canonical),
+ 'rel' => 'canonical',
+ ];
- if (!empty($href)) {
- if (GeneralUtility::makeInstance(HeadlessMode::class)->withRequest($params['request'])->isEnabled()) {
- $canonical = [
- 'href' => htmlspecialchars($href),
- 'rel' => 'canonical',
- ];
+ $params['_seoLinks'][] = $canonical;
+ $canonical = json_encode($canonical);
+ }
- $params['_seoLinks'][] = $canonical;
- $canonical = json_encode($canonical);
- } else {
- $canonical = ' 'canonical',
- 'href' => $href,
- ], true) . '/>' . LF;
- $this->typoScriptFrontendController->additionalHeaderData[] = $canonical;
- }
+ return $canonical;
+ }
- return $canonical;
- }
- return '';
+ protected function processCanonical(string $canonical): string
+ {
+ return htmlspecialchars(GeneralUtility::get_tag_attributes($canonical)['href'] ?? '');
}
}
diff --git a/Classes/Seo/MetaHandler.php b/Classes/Seo/MetaHandler.php
index 7be45107..bf8a573c 100644
--- a/Classes/Seo/MetaHandler.php
+++ b/Classes/Seo/MetaHandler.php
@@ -35,7 +35,7 @@ public function process(ServerRequestInterface $request, TypoScriptFrontendContr
GeneralUtility::callUserFunction($_funcRef, $_params, $_ref);
}
- $content['seo']['title'] = $controller->generatePageTitle();
+ $content['seo']['title'] = $controller->generatePageTitle($request);
$this->generateMetaTagsFromTyposcript(
$controller->pSetup['meta.'] ?? [],
diff --git a/Classes/XClass/Controller/FormFrontendController.php b/Classes/XClass/Controller/FormFrontendController.php
index bc62fb04..64c13a8e 100644
--- a/Classes/XClass/Controller/FormFrontendController.php
+++ b/Classes/XClass/Controller/FormFrontendController.php
@@ -18,39 +18,34 @@
use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
use FriendsOfTYPO3\Headless\XClass\FormRuntime;
use Psr\Http\Message\ResponseInterface;
+use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface as ExtbaseConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Error\Error;
-use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
+use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
use TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory;
use TYPO3\CMS\Form\Domain\Model\FormDefinition;
use function array_merge;
use function array_pop;
use function base64_encode;
+use function class_exists;
use function count;
use function in_array;
+use function is_array;
use function json_decode;
use function serialize;
use function str_replace;
/**
- * The frontend controller
+ * Overridden form implementation with headless flavor
*
- * Scope: frontend
* @internal
* @codeCoverageIgnore
*/
class FormFrontendController extends \TYPO3\CMS\Form\Controller\FormFrontendController
{
- private Translator $jsonFormTranslator;
-
- public function __construct()
- {
- $this->hashService = GeneralUtility::makeInstance(HashService::class);
- $this->jsonFormTranslator = GeneralUtility::makeInstance(Translator::class);
- }
-
/**
* Take the form which should be rendered from the plugin settings
* and overlay the formDefinition with additional data from
@@ -64,13 +59,28 @@ public function renderAction(): ResponseInterface
{
$headlessMode = GeneralUtility::makeInstance(HeadlessMode::class);
- if (!$headlessMode->withRequest($GLOBALS['TYPO3_REQUEST'])->isEnabled()) {
+ if (!$headlessMode->withRequest($this->request)->isEnabled()) {
return parent::renderAction();
}
$formDefinition = [];
if (!empty($this->settings['persistenceIdentifier'])) {
- $formDefinition = $this->formPersistenceManager->load($this->settings['persistenceIdentifier']);
+ $formSettings = [];
+ $typoScriptSettings = [];
+
+ if ((new Typo3Version())->getMajorVersion() >= 13) {
+ $typoScriptSettings = $this->configurationManager->getConfiguration(
+ ExtbaseConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
+ 'form'
+ );
+ $formSettings = $this->extFormConfigurationManager->getYamlConfiguration($typoScriptSettings, true);
+ }
+
+ $formDefinition = $this->formPersistenceManager->load(
+ $this->settings['persistenceIdentifier'],
+ $formSettings,
+ $typoScriptSettings
+ );
$formDefinition['persistenceIdentifier'] = $this->settings['persistenceIdentifier'];
$formDefinition = $this->overrideByFlexFormSettings($formDefinition);
$formDefinition = ArrayUtility::setValueByPath(
@@ -80,10 +90,7 @@ public function renderAction(): ResponseInterface
'.'
);
- $formId = ($this->configurationManager->getContentObject() !== null ?
- ($this->configurationManager->getContentObject()->data['uid'] ?? 0) : 0);
-
- $formDefinition['identifier'] .= '-' . $formId;
+ $formDefinition['identifier'] .= '-' . ($this->request->getAttribute('currentContentObject')?->data['uid'] ?? '');
}
$i18n = [];
@@ -128,14 +135,21 @@ public function renderAction(): ResponseInterface
$honeyPot = array_pop($elements);
}
- $stateHash = $this->hashService->appendHmac(base64_encode(serialize($formState)));
+ $stateHash = $this->getHashService()->appendHmac(
+ base64_encode(serialize($formState)),
+ class_exists(\TYPO3\CMS\Form\Security\HashScope::class) ? \TYPO3\CMS\Form\Security\HashScope::FormState->prefix() : ''
+ );
$currentPageIndex = $formRuntime->getCurrentPage() ? $formRuntime->getCurrentPage()->getIndex() : 0;
$currentPageId = $currentPageIndex + 1;
$formFields = $formDefinition['renderables'][$currentPageIndex]['renderables'] ?? [];
// provides support for custom options providers (dynamic selects/radio/checkboxes)
- $formFieldsNames = $this->generateFieldNamesAndReplaceCustomOptions($formFields, $formDefinition['identifier'], $formRuntime);
+ $formFieldsNames = $this->generateFieldNamesAndReplaceCustomOptions(
+ $formFields,
+ $formDefinition['identifier'],
+ $formRuntime
+ );
if ($honeyPot) {
$formFields[] = [
@@ -188,7 +202,7 @@ public function renderAction(): ResponseInterface
$formDefinition['renderables'][$currentPageIndex]['renderables'] = $formFields;
$formDefinition['i18n'] = count($i18n) ? $i18n : null;
- $formDefinition = $this->jsonFormTranslator->translate(
+ $formDefinition = $this->getFormTranslator()->translate(
$formDefinition,
$formRuntime->getFormDefinition()->getRenderingOptions(),
$formRuntime->getFormState() ? $formRuntime->getFormState()->getFormValues() : []
@@ -260,8 +274,11 @@ private function getNextPage(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRun
* @param array $formFields
* @return array
*/
- private function generateFieldNamesAndReplaceCustomOptions(array &$formFields, string $identifier, FormRuntime $formRuntime): array
- {
+ private function generateFieldNamesAndReplaceCustomOptions(
+ array &$formFields,
+ string $identifier,
+ FormRuntime $formRuntime
+ ): array {
$formFieldsNames = [];
foreach ($formFields as &$field) {
@@ -274,7 +291,13 @@ private function generateFieldNamesAndReplaceCustomOptions(array &$formFields, s
);
} else {
if (!empty($field['properties']['customOptions'])) {
- $customOptions = GeneralUtility::makeInstance($field['properties']['customOptions'], $field, $formFields, $identifier, $formRuntime);
+ $customOptions = GeneralUtility::makeInstance(
+ $field['properties']['customOptions'],
+ $field,
+ $formFields,
+ $identifier,
+ $formRuntime
+ );
if ($customOptions instanceof CustomOptionsInterface) {
$field['properties']['options'] = $customOptions->get();
@@ -295,4 +318,18 @@ private function generateFieldNamesAndReplaceCustomOptions(array &$formFields, s
return $formFieldsNames;
}
+
+ private function getHashService(): \TYPO3\CMS\Extbase\Security\Cryptography\HashService|\TYPO3\CMS\Core\Crypto\HashService
+ {
+ if ((new Typo3Version())->getMajorVersion() >= 13) {
+ return GeneralUtility::makeInstance(\TYPO3\CMS\Core\Crypto\HashService::class);
+ }
+
+ return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Security\Cryptography\HashService::class);
+ }
+
+ private function getFormTranslator(): Translator
+ {
+ return GeneralUtility::makeInstance(Translator::class);
+ }
}
diff --git a/Classes/XClass/ResourceLocalDriver.php b/Classes/XClass/ResourceLocalDriver.php
index 285479af..a67207d5 100644
--- a/Classes/XClass/ResourceLocalDriver.php
+++ b/Classes/XClass/ResourceLocalDriver.php
@@ -16,6 +16,8 @@
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Http\ApplicationType;
use TYPO3\CMS\Core\Http\Uri;
+use TYPO3\CMS\Core\Information\Typo3Version;
+use TYPO3\CMS\Core\Resource\Capabilities;
use TYPO3\CMS\Core\Resource\Driver\LocalDriver;
use TYPO3\CMS\Core\Resource\ResourceStorage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -41,7 +43,7 @@ protected function determineBaseUrl(): void
return;
}
- if ($this->hasCapability(ResourceStorage::CAPABILITY_PUBLIC)) {
+ if ($this->hasCapability(((new Typo3Version())->getMajorVersion() < 13) ? ResourceStorage::CAPABILITY_PUBLIC : Capabilities::CAPABILITY_PUBLIC)) {
$urlUtility = GeneralUtility::makeInstance(UrlUtility::class)->withRequest($request);
$basePath = match (true) {
diff --git a/Configuration/SiteConfiguration/Overrides/site.php b/Configuration/SiteConfiguration/Overrides/site.php
index e3f14f98..03bfb80e 100644
--- a/Configuration/SiteConfiguration/Overrides/site.php
+++ b/Configuration/SiteConfiguration/Overrides/site.php
@@ -7,7 +7,6 @@
* LICENSE.md file that was distributed with this source code.
*/
-use FriendsOfTYPO3\Headless\Utility\Headless;
use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
use TYPO3\CMS\Core\Configuration\Features;
use TYPO3\CMS\Core\Utility\GeneralUtility;
diff --git a/composer.json b/composer.json
index 5d4f06ff..5be2f056 100644
--- a/composer.json
+++ b/composer.json
@@ -28,8 +28,8 @@
],
"require": {
"ext-json": "*",
- "typo3/cms-core": "^12.4 || ^13 ",
- "typo3/cms-install": "^12.4 || ^13"
+ "typo3/cms-core": "^12.4 || ^13.3",
+ "typo3/cms-install": "^12.4 || ^13.3"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.15.0",