From 8f399884fc67819dc018f4636b2e64e543095b4d Mon Sep 17 00:00:00 2001 From: Torben Hansen Date: Sat, 12 Oct 2024 14:49:12 +0200 Subject: [PATCH] [TASK] Avoid TypoScriptFrontendController usage in MetaTagViewHelper Closes #1285 --- Classes/ViewHelpers/MetaTagViewHelper.php | 38 +++++++++++-------- .../ViewHelpers/MetaTagViewHelperTest.php | 32 ++++++++++++++-- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Classes/ViewHelpers/MetaTagViewHelper.php b/Classes/ViewHelpers/MetaTagViewHelper.php index 0296bcb9f..40c0dca28 100644 --- a/Classes/ViewHelpers/MetaTagViewHelper.php +++ b/Classes/ViewHelpers/MetaTagViewHelper.php @@ -12,9 +12,9 @@ namespace DERHANSEN\SfEventMgt\ViewHelpers; use Psr\Http\Message\ServerRequestInterface; -use TYPO3\CMS\Core\Page\PageRenderer; +use TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; +use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; /** @@ -27,36 +27,44 @@ public function initializeArguments(): void $this->registerArgument('property', 'string', 'Property of meta tag', false, '', false); $this->registerArgument('name', 'string', 'Content of meta tag using the name attribute', false, '', false); $this->registerArgument('content', 'string', 'Content of meta tag', true, null, false); + $this->registerArgument('replace', 'boolean', 'Replace potential existing tag', false, false); } public function render(): void { - $tsfe = $this->getTypoScriptFrontendController(); - - // Skip if current record is part of tt_content CType shortcut - if (!empty($tsfe->recordRegister) - && !empty($tsfe->currentRecord) - && str_contains($tsfe->currentRecord, 'tx_sfeventmgt_domain_model_event:') - && str_contains(array_keys($tsfe->recordRegister)[0], 'tt_content:') - ) { + // Skip if current record is rendered via tt_content CType shortcut + if ($this->isParentRecordShortcut()) { return; } $content = (string)$this->arguments['content']; if ($content !== '') { - $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); + $registry = GeneralUtility::makeInstance(MetaTagManagerRegistry::class); if ($this->arguments['property']) { - $pageRenderer->setMetaTag('property', $this->arguments['property'], $content); + $manager = $registry->getManagerForProperty($this->arguments['property']); + $manager->addProperty($this->arguments['property'], $content, [], $this->arguments['replace'], 'property'); } elseif ($this->arguments['name']) { - $pageRenderer->setMetaTag('property', $this->arguments['name'], $content); + $manager = $registry->getManagerForProperty($this->arguments['name']); + $manager->addProperty($this->arguments['name'], $content, [], $this->arguments['replace'], 'name'); } } } - private function getTypoScriptFrontendController(): TypoScriptFrontendController + private function isParentRecordShortcut(): bool + { + $contentObjectRenderer = $this->getContentObjectRenderer(); + + return $contentObjectRenderer->parentRecord !== [] && + isset($contentObjectRenderer->parentRecord['currentRecord']) && + isset($contentObjectRenderer->parentRecord['data']['CType']) && + str_starts_with($contentObjectRenderer->parentRecord['currentRecord'], 'tt_content:') && + $contentObjectRenderer->parentRecord['data']['CType'] === 'shortcut'; + } + + private function getContentObjectRenderer(): ContentObjectRenderer { return $this->renderingContext->getAttribute(ServerRequestInterface::class) - ->getAttribute('frontend.controller'); + ->getAttribute('currentContentObject'); } } diff --git a/Tests/Functional/ViewHelpers/MetaTagViewHelperTest.php b/Tests/Functional/ViewHelpers/MetaTagViewHelperTest.php index fbc2cf716..3e5ecb55b 100644 --- a/Tests/Functional/ViewHelpers/MetaTagViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/MetaTagViewHelperTest.php @@ -19,7 +19,7 @@ use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters; use TYPO3\CMS\Extbase\Mvc\Request; use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; +use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; use TYPO3Fluid\Fluid\View\TemplateView; @@ -42,7 +42,7 @@ public function metaTagForNameIsSetByViewHelper(): void $extbaseRequestParameters = new ExtbaseRequestParameters(); $serverRequest = new ServerRequest(); $serverRequest = $serverRequest->withAttribute('extbase', $extbaseRequestParameters) - ->withAttribute('frontend.controller', new TypoScriptFrontendController()) + ->withAttribute('currentContentObject', new ContentObjectRenderer()) ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE); $extbaseRequest = (new Request($serverRequest)); $context = $this->get(RenderingContextFactory::class)->create([], $extbaseRequest); @@ -60,7 +60,7 @@ public function metaTagForPropertyIsSetByViewHelper(): void $extbaseRequestParameters = new ExtbaseRequestParameters(); $serverRequest = new ServerRequest(); $serverRequest = $serverRequest->withAttribute('extbase', $extbaseRequestParameters) - ->withAttribute('frontend.controller', new TypoScriptFrontendController()) + ->withAttribute('currentContentObject', new ContentObjectRenderer()) ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE); $extbaseRequest = (new Request($serverRequest)); $context = $this->get(RenderingContextFactory::class)->create([], $extbaseRequest); @@ -71,4 +71,30 @@ public function metaTagForPropertyIsSetByViewHelper(): void $metaTag = $this->pageRenderer->getMetaTag('property', 'og:title'); self::assertEquals('The og:title', $metaTag['content']); } + + #[Test] + public function metaTagIsNotRenderedWhenViewHelperUsedInShortcutRecord(): void + { + $contentObjectRenderer = new ContentObjectRenderer(); + $contentObjectRenderer->parentRecord = [ + 'currentRecord' => 'tt_content:123', + 'data' => [ + 'CType' => 'shortcut', + ], + ]; + + $extbaseRequestParameters = new ExtbaseRequestParameters(); + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withAttribute('extbase', $extbaseRequestParameters) + ->withAttribute('currentContentObject', $contentObjectRenderer) + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE); + $extbaseRequest = (new Request($serverRequest)); + $context = $this->get(RenderingContextFactory::class)->create([], $extbaseRequest); + $context->getViewHelperResolver()->addNamespace('e', 'DERHANSEN\\SfEventMgt\\ViewHelpers'); + $context->getTemplatePaths()->setTemplateSource(''); + self::assertEquals('', (new TemplateView($context))->render()); + + $metaTag = $this->pageRenderer->getMetaTag('property', 'og:title'); + self::assertEmpty($metaTag); + } }