Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Fix generating links to sitemap #696

Merged
merged 3 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions Classes/Event/Listener/AfterLinkIsGeneratedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@
use FriendsOfTYPO3\Headless\Utility\HeadlessFrontendUrlInterface;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Core\Site\Entity\NullSite;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Frontend\Event\AfterLinkIsGeneratedEvent;

use function is_numeric;
use function is_string;
use function str_starts_with;

final class AfterLinkIsGeneratedListener
{
public function __construct(
Expand All @@ -39,16 +44,26 @@ public function __invoke(AfterLinkIsGeneratedEvent $event): void

$urlUtility = $this->urlUtility->withRequest($event->getContentObjectRenderer()->getRequest());

if ($pageId) {
if (is_numeric($pageId) && ((int)$pageId) > 0) {
$href = $urlUtility->getFrontendUrlForPage(
$event->getLinkResult()->getUrl(),
(int)$pageId
);
} else {
/**
* @var Site $site
*/
$site = $event->getContentObjectRenderer()->getRequest()->getAttribute('site');
$key = 'frontendBase';

$sitemapConfig = $site->getConfiguration()['settings']['headless']['sitemap'] ?? [];

if (is_string($pageId) && str_starts_with($pageId, 't3://page?uid=current&type=' . ($sitemapConfig['type'] ?? '1533906435'))) {
$key = $sitemapConfig['key'] ?? 'frontendApiProxy';
}

if (!$site instanceof NullSite) {
$href = $urlUtility->getFrontendUrlWithSite($event->getLinkResult()->getUrl(), $site);
$href = $urlUtility->getFrontendUrlWithSite($event->getLinkResult()->getUrl(), $site, $key);
}
}

Expand Down
5 changes: 5 additions & 0 deletions Classes/Utility/UrlUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use TYPO3\CMS\Core\Utility\GeneralUtility;

use function array_merge;
use function ltrim;
use function rtrim;
use function str_contains;

Expand Down Expand Up @@ -96,11 +97,15 @@ public function getFrontendUrlWithSite($url, SiteInterface $site, string $return

$frontendBase = GeneralUtility::makeInstance(Uri::class, $this->sanitizeBaseUrl($frontendBaseUrl));
$frontBase = $frontendBase->getHost();
$frontExtraPath = $frontendBase->getPath();
$frontPort = $frontendBase->getPort();
$targetUri = new Uri($this->sanitizeBaseUrl($url));

if (str_contains($url, $base)) {
$targetUri = $targetUri->withHost($frontBase);
if ($frontExtraPath) {
$targetUri = $targetUri->withPath($frontExtraPath . ($targetUri->getPath() !== '' ? '/' . ltrim($targetUri->getPath(), '/') : ''));
}
}

if ($port === $frontPort) {
Expand Down
79 changes: 72 additions & 7 deletions Tests/Unit/Event/Listener/AfterLinkIsGeneratedListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ public function test__construct()
$resolver->evaluate(Argument::any())->willReturn(true);
$siteFinder = $this->prophesize(SiteFinder::class);

$listener = new AfterLinkIsGeneratedListener(new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()), $this->prophesize(LinkService::class)->reveal());
$listener = new AfterLinkIsGeneratedListener(
new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()),
$this->prophesize(LinkService::class)->reveal()
);

self::assertInstanceOf(AfterLinkIsGeneratedListener::class, $listener);
}
Expand All @@ -44,7 +47,10 @@ public function test__invokeNotModifingAnything()
$resolver->evaluate(Argument::any())->willReturn(true);
$siteFinder = $this->prophesize(SiteFinder::class);

$listener = new AfterLinkIsGeneratedListener(new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()), $this->prophesize(LinkService::class)->reveal());
$listener = new AfterLinkIsGeneratedListener(
new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()),
$this->prophesize(LinkService::class)->reveal()
);

$site = new Site('test', 1, []);
$cObj = $this->prophesize(ContentObjectRenderer::class);
Expand Down Expand Up @@ -73,8 +79,15 @@ public function test__invokeModifingFromPageUid()
$resolver->evaluate(Argument::any())->willReturn(true);

$urlUtility = $this->prophesize(UrlUtility::class);
$urlUtility->getFrontendUrlForPage(Argument::is('/'), Argument::is(2))->willReturn('https://frontend-domain.tld/page');
$urlUtility->getFrontendUrlWithSite(Argument::is('/'), Argument::any())->willReturn('https://frontend-domain.tld/page');
$urlUtility->getFrontendUrlForPage(
Argument::is('/'),
Argument::is(2)
)->willReturn('https://frontend-domain.tld/page');
$urlUtility->getFrontendUrlWithSite(
Argument::is('/'),
Argument::any(),
Argument::is('frontendBase')
)->willReturn('https://frontend-domain.tld/page');

$site = new Site('test', 1, []);
$cObj = $this->prophesize(ContentObjectRenderer::class);
Expand All @@ -83,7 +96,10 @@ public function test__invokeModifingFromPageUid()

$urlUtility->withRequest($request)->willReturn($urlUtility->reveal());

$listener = new AfterLinkIsGeneratedListener($urlUtility->reveal(), $this->prophesize(LinkService::class)->reveal());
$listener = new AfterLinkIsGeneratedListener(
$urlUtility->reveal(),
$this->prophesize(LinkService::class)->reveal()
);

$linkResult = new LinkResult('page', '/');
$linkResult = $linkResult->withLinkText('t3://page?uid=2');
Expand All @@ -102,15 +118,22 @@ public function test__invokeModifingWithoutPageId()
$site = new Site('test', 1, []);

$urlUtility = $this->prophesize(UrlUtility::class);
$urlUtility->getFrontendUrlWithSite(Argument::is('/'), Argument::is($site))->willReturn('https://front.typo3.tld');
$urlUtility->getFrontendUrlWithSite(
Argument::is('/'),
Argument::is($site),
Argument::is('frontendBase')
)->willReturn('https://front.typo3.tld');

$cObj = $this->prophesize(ContentObjectRenderer::class);
$request = (new ServerRequest())->withAttribute('site', $site);
$cObj->getRequest()->willReturn($request);

$urlUtility->withRequest($request)->willReturn($urlUtility->reveal());

$listener = new AfterLinkIsGeneratedListener($urlUtility->reveal(), $this->prophesize(LinkService::class)->reveal());
$listener = new AfterLinkIsGeneratedListener(
$urlUtility->reveal(),
$this->prophesize(LinkService::class)->reveal()
);
$linkResult = new LinkResult('page', '/');
$linkResult = $linkResult->withLinkText('|');

Expand Down Expand Up @@ -149,4 +172,46 @@ public function test__invokeModifingExternalSite()

self::assertSame('https://front.typo3.tld', $event->getLinkResult()->getUrl());
}

public function test__SitemapLink()
{
$resolver = $this->prophesize(Resolver::class);
$resolver->evaluate(Argument::any())->willReturn(true);

$site = new Site('test', 1, []);

$urlUtility = $this->prophesize(UrlUtility::class);
$urlUtility->getFrontendUrlWithSite(
Argument::is('https://typo3.tld/sitemap-type/pages/sitemap.xml'),
Argument::is($site),
Argument::is('frontendApiProxy')
)
->willReturn('https://front.typo3.tld/headless/sitemap-type/pages/sitemap.xml');

$linkService = $this->prophesize(LinkService::class);
$linkService->resolve(Argument::any())->willReturn(['pageuid' => 5]);

$cObj = $this->prophesize(ContentObjectRenderer::class);
$request = (new ServerRequest())->withAttribute('site', $site);
$cObj->getRequest()->willReturn($request);

$urlUtility->withRequest($request)->willReturn($urlUtility->reveal());

$listener = new AfterLinkIsGeneratedListener($urlUtility->reveal(), $linkService->reveal());

$linkResult = new LinkResult('page', 'https://typo3.tld/sitemap-type/pages/sitemap.xml');
$linkResult = $linkResult->withLinkConfiguration([
'parameter' => 't3://page?uid=current&type=1533906435&sitemap=pages',
'forceAbsoluteUrl' => true,
'additionalParams' => '&sitemap=pages',
]);

$event = new AfterLinkIsGeneratedEvent($linkResult, $cObj->reveal(), []);
$listener($event);

self::assertSame(
'https://front.typo3.tld/headless/sitemap-type/pages/sitemap.xml',
$event->getLinkResult()->getUrl()
);
}
}
3 changes: 3 additions & 0 deletions Tests/Unit/Utility/UrlUtilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,16 @@ public function testFrontendUrls(): void

$siteFinder = $this->prophesize(SiteFinder::class);

$site->getBase()->shouldBeCalled(2)->willReturn(new Uri('https://test-backend3-api.tld'));

$urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode);
$urlUtility = $urlUtility->withSite($site->reveal());

self::assertSame('https://test-frontend3.tld', $urlUtility->getFrontendUrl());
self::assertSame('https://test-frontend-api3.tld/headless', $urlUtility->getProxyUrl());
self::assertSame('https://test-frontend-api3.tld/headless/fileadmin', $urlUtility->getStorageProxyUrl());
self::assertSame('https://test-frontend3.tld/sitemap', $urlUtility->resolveKey('SpecialSitemapKey'));
self::assertSame('https://test-frontend-api3.tld/headless', $urlUtility->getFrontendUrlWithSite('https://test-backend3-api.tld', $site->reveal(), 'frontendApiProxy'));
}

public function testFrontendUrlsWithBaseProductionAndLocalOverride(): void
Expand Down