Skip to content

Commit

Permalink
[TASK] Add request object to Canonical Tag generation link
Browse files Browse the repository at this point in the history
The PSR-14 ModifyUrlForCanonicalTagEvent was one of the first PSR-14
events to be added to TYPO3 Core, and was rather useless, as it
did not contain the context to deal with creating a URl for the
canonical tag.

In order to make it useful, some more information is added to
the Event object.

This is a pre-cursor for a breaking change, for issue #99807.

Resolves: #102001
Related: #99807
Releases: main, 12.4
Change-Id: Iebab3af3e9408ea82c95e1ad2cfdadc4a72c4a1d
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/82021
Tested-by: core-ci <typo3@b13.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
  • Loading branch information
bmack committed Dec 4, 2023
1 parent f381d0e commit 8ae8f35
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 5 deletions.
2 changes: 1 addition & 1 deletion typo3/sysext/frontend/Classes/Http/RequestHandler.php
Expand Up @@ -683,7 +683,7 @@ protected function processHtmlBasedRenderingSettings(TypoScriptFrontendControlle
$controller->generatePageTitle();

// @internal hook for EXT:seo, will be gone soon, do not use it in your own extensions
$_params = ['page' => $controller->page];
$_params = ['page' => $controller->page, 'request' => $request];
$_ref = null;
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['TYPO3\CMS\Frontend\Page\PageGenerator']['generateMetaTags'] ?? [] as $_funcRef) {
GeneralUtility::callUserFunction($_funcRef, $_params, $_ref);
Expand Down
6 changes: 4 additions & 2 deletions typo3/sysext/seo/Classes/Canonical/CanonicalGenerator.php
Expand Up @@ -18,6 +18,7 @@
namespace TYPO3\CMS\Seo\Canonical;

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\Core\Utility\RootlineUtility;
Expand All @@ -43,13 +44,14 @@ public function __construct(TypoScriptFrontendController $typoScriptFrontendCont
$this->pageRepository = GeneralUtility::makeInstance(PageRepository::class);
}

public function generate(): string
public function generate(array $params): string
{
if ($this->typoScriptFrontendController->config['config']['disableCanonical'] ?? false) {
return '';
}

$event = $this->eventDispatcher->dispatch(new ModifyUrlForCanonicalTagEvent(''));
$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) {
Expand Down
21 changes: 19 additions & 2 deletions typo3/sysext/seo/Classes/Event/ModifyUrlForCanonicalTagEvent.php
Expand Up @@ -17,12 +17,19 @@

namespace TYPO3\CMS\Seo\Event;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Domain\Page;

/**
* PSR-14 to alter (or empty) a canonical URL for the href="" attribute of a canonical URL.
* PSR-14 event to alter (or empty) a canonical URL for the href="" attribute of a canonical URL.
*/
final class ModifyUrlForCanonicalTagEvent
{
public function __construct(private string $url) {}
public function __construct(
private string $url,
private readonly ServerRequestInterface $request,
private readonly Page $page
) {}

public function getUrl(): string
{
Expand All @@ -33,4 +40,14 @@ public function setUrl(string $url): void
{
$this->url = $url;
}

public function getRequest(): ServerRequestInterface
{
return $this->request;
}

public function getPage(): Page
{
return $this->page;
}
}
Expand Up @@ -17,7 +17,13 @@

namespace TYPO3\CMS\Seo\Tests\Functional\Canonical;

use Symfony\Component\DependencyInjection\Container;
use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3\CMS\Seo\Canonical\CanonicalGenerator;
use TYPO3\CMS\Seo\Event\ModifyUrlForCanonicalTagEvent;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\TypoScriptInstruction;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
Expand Down Expand Up @@ -146,6 +152,37 @@ public function generate(string $targetUri, string $expectedCanonicalUrl): void
}
}

/**
* @test
*/
public function afterContentObjectRendererInitializedEventIsCalled(): void
{
$modifyUrlForCanonicalTagEvent = null;

/** @var Container $container */
$container = $this->getContainer();
$container->set(
'modify-url-for-canonical-tag-listener',
static function (ModifyUrlForCanonicalTagEvent $event) use (&$modifyUrlForCanonicalTagEvent) {
$modifyUrlForCanonicalTagEvent = $event;
}
);

$eventListener = $container->get(ListenerProvider::class);
$eventListener->addListener(ModifyUrlForCanonicalTagEvent::class, 'modify-url-for-canonical-tag-listener');

$GLOBALS['TSFE'] = $this->createMock(TypoScriptFrontendController::class);
$GLOBALS['TSFE']->id = 123;
$GLOBALS['TSFE']->page['no_index'] = 1;

(new CanonicalGenerator())->generate(['request' => new ServerRequest('https://example.com'), 'page' => ['uid' => 123]]);

self::assertInstanceOf(ModifyUrlForCanonicalTagEvent::class, $modifyUrlForCanonicalTagEvent);
self::assertEmpty('', $modifyUrlForCanonicalTagEvent->getUrl());
self::assertEquals('https://example.com', (string)$modifyUrlForCanonicalTagEvent->getRequest()->getUri());
self::assertEquals(123, $modifyUrlForCanonicalTagEvent->getPage()->getPageId());
}

private function buildPageTypoScript(): TypoScriptInstruction
{
return (new TypoScriptInstruction())
Expand Down
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Seo\Tests\Unit\Event;

use TYPO3\CMS\Core\Domain\Page;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Seo\Event\ModifyUrlForCanonicalTagEvent;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

final class ModifyUrlForCanonicalTagEventTest extends UnitTestCase
{
/**
* @test
*/
public function gettersReturnInitializedObjects(): void
{
$url = (string)new Uri('https://example.com');
$request = (new ServerRequest($url));
$page = new Page(['uid' => 123]);
$event = new ModifyUrlForCanonicalTagEvent($url, $request, $page);

self::assertEquals($url, $event->getUrl());
self::assertEquals($request, $event->getRequest());
self::assertEquals($page, $event->getPage());
}
}

0 comments on commit 8ae8f35

Please sign in to comment.