Skip to content

Commit

Permalink
[BUGFIX] Fix issue with preview of workspaces in headless mode
Browse files Browse the repository at this point in the history
Resolves #695
  • Loading branch information
twoldanski authored and lukaszuznanski committed Feb 5, 2024
1 parent bbd0574 commit a710126
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 19 deletions.
14 changes: 4 additions & 10 deletions Classes/Event/Listener/AfterPagePreviewUriGeneratedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@

namespace FriendsOfTYPO3\Headless\Event\Listener;

use FriendsOfTYPO3\Headless\Utility\Headless;
use FriendsOfTYPO3\Headless\Utility\HeadlessFrontendUrlInterface;
use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
use TYPO3\CMS\Backend\Routing\Event\AfterPagePreviewUriGeneratedEvent;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;

final class AfterPagePreviewUriGeneratedListener
{
Expand All @@ -31,16 +31,10 @@ public function __invoke(AfterPagePreviewUriGeneratedEvent $event): void

try {
$site = $this->siteFinder->getSiteByPageId($event->getPageId());
$mode = (int)($site->getConfiguration()['headless'] ?? HeadlessMode::NONE);

if ($mode === HeadlessMode::MIXED) {
// in BE context we override it to force generate url
$mode = HeadlessMode::FULL;
}

$request = $GLOBALS['TYPO3_REQUEST'];
$request = $request->withAttribute('language', $site->getLanguageById($event->getLanguageId()));
$request = $request->withAttribute('headless', new Headless($mode));
$headlessMode = GeneralUtility::makeInstance(HeadlessMode::class);
$headlessMode = $headlessMode->withRequest($GLOBALS['TYPO3_REQUEST']);
$request = $headlessMode->overrideBackendRequestBySite($site, $site->getLanguageById($event->getLanguageId()));

$urlUtility = $this->urlUtility->withRequest($request);
$event->setPreviewUri(new Uri($urlUtility->getFrontendUrlWithSite($event->getPreviewUri()->__toString(), $site)));
Expand Down
20 changes: 20 additions & 0 deletions Classes/Utility/HeadlessMode.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
namespace FriendsOfTYPO3\Headless\Utility;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Site\Entity\SiteInterface;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

final class HeadlessMode
{
Expand Down Expand Up @@ -41,4 +43,22 @@ public function isEnabled(): bool
return $headless->getMode() === self::FULL ||
($headless->getMode() === self::MIXED && ($this->request->getHeader('Accept')[0] ?? '') === 'application/json');
}

public function overrideBackendRequestBySite(SiteInterface $site, ?SiteLanguage $language = null): ServerRequestInterface
{
$mode = (int)($site->getConfiguration()['headless'] ?? self::NONE);

if ($mode === self::MIXED) {
// in BE context we override
$mode = self::NONE;
}

$request = clone $this->request;

if ($language) {
$request = $request->withAttribute('language', $language);
}

return $request->withAttribute('headless', new Headless($mode));
}
}
12 changes: 11 additions & 1 deletion Classes/XClass/Controller/PreviewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace FriendsOfTYPO3\Headless\XClass\Controller;

use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
use FriendsOfTYPO3\Headless\Utility\UrlUtility;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Utility\GeneralUtility;
Expand All @@ -25,6 +26,15 @@ class PreviewController extends \TYPO3\CMS\Workspaces\Controller\PreviewControll
protected function generateUrl(Site $site, int $pageUid, array $parameters): string
{
$url = (string)$site->getRouter()->generateUri($pageUid, $parameters);
return GeneralUtility::makeInstance(UrlUtility::class)->getFrontendUrlForPage($url, $pageUid);

if (!isset($GLOBALS['TYPO3_REQUEST'])) {
return $url;
}

$headlessMode = GeneralUtility::makeInstance(HeadlessMode::class);
$headlessMode = $headlessMode->withRequest($GLOBALS['TYPO3_REQUEST']);
$request = $headlessMode->overrideBackendRequestBySite($site, $parameters['_language'] ?? null);

return GeneralUtility::makeInstance(UrlUtility::class)->withRequest($request)->getFrontendUrlForPage($url, $pageUid);
}
}
9 changes: 8 additions & 1 deletion Classes/XClass/Preview/PreviewUriBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace FriendsOfTYPO3\Headless\XClass\Preview;

use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
use FriendsOfTYPO3\Headless\Utility\UrlUtility;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
Expand Down Expand Up @@ -46,7 +47,13 @@ public function buildUriForPage(int $uid, int $languageId = 0): string
$language = $site->getDefaultLanguage();
}

return GeneralUtility::makeInstance(UrlUtility::class)->getFrontendUrlForPage((string)$site->getRouter()->generateUri($uid, ['ADMCMD_prev' => $previewKeyword, '_language' => $language], ''), $uid);
$headlessMode = GeneralUtility::makeInstance(HeadlessMode::class);
$headlessMode = $headlessMode->withRequest($GLOBALS['TYPO3_REQUEST']);
$request = $headlessMode->overrideBackendRequestBySite($site, $language);

return GeneralUtility::makeInstance(UrlUtility::class)
->withRequest($request)
->getFrontendUrlForPage((string)$site->getRouter()->generateUri($uid, ['ADMCMD_prev' => $previewKeyword, '_language' => $language], ''), $uid);
} catch (SiteNotFoundException | InvalidRouteArgumentsException $e) {
throw new UnableToLinkToPageException('The page ' . $uid . ' had no proper connection to a site, no link could be built.', 1559794916);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function testLink()
$resolver = $this->prophesize(Resolver::class);
$resolver->evaluate(Argument::any())->willReturn(true);
$siteFinder = $this->prophesize(SiteFinder::class);
$siteFinder->getSiteByPageId(Argument::any())->willReturn($site = new Site('test', 1, ['headless' => HeadlessMode::MIXED, 'frontendBase' => 'https://front.test.tld']));
$siteFinder->getSiteByPageId(Argument::any())->willReturn($site = new Site('test', 1, ['headless' => HeadlessMode::MIXED, 'frontendBase' => 'https://front.test.tld', 'base' => 'https://test.tld']));

$listener = new AfterPagePreviewUriGeneratedListener(new UrlUtility(
null,
Expand All @@ -71,11 +71,11 @@ public function testLink()
$GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
$listener->__invoke($event);

self::assertSame('https://front.test.tld/page', (string)$event->getPreviewUri());
self::assertSame('https://test.tld/page', (string)$event->getPreviewUri());

$GLOBALS['BE_USER'] = new BackendUserAuthentication();
$listener->__invoke($event);
self::assertSame('https://front.test.tld/page', (string)$event->getPreviewUri());
self::assertSame('https://test.tld/page', (string)$event->getPreviewUri());
}

public function testSiteNotFound()
Expand Down
42 changes: 38 additions & 4 deletions Tests/Unit/Utility/HeadlessModeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
use FriendsOfTYPO3\Headless\Utility\HeadlessMode;
use PHPUnit\Framework\TestCase;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

class HeadlessModeTest extends TestCase
{
public function testMixedModeWithoutHeader(): void
{
$mode = new HeadlessMode();

$request = new ServerRequest();
$request = new ServerRequest();
$request = $request->withAttribute('headless', new Headless(HeadlessMode::MIXED));

$mode = $mode->withRequest($request);
Expand All @@ -32,7 +35,7 @@ public function testMixedModeWithHeader(): void
{
$mode = new HeadlessMode();

$request = new ServerRequest();
$request = new ServerRequest();
$request = $request->withHeader('Accept', 'application/json');
$request = $request->withAttribute('headless', new Headless(HeadlessMode::MIXED));

Expand All @@ -45,7 +48,7 @@ public function testDisabled(): void
{
$mode = new HeadlessMode();

$request = new ServerRequest();
$request = new ServerRequest();
$request = $request->withHeader('Accept', 'application/json');
$request = $request->withAttribute('headless', new Headless(HeadlessMode::NONE));

Expand All @@ -58,7 +61,7 @@ public function testNotSet(): void
{
$mode = new HeadlessMode();

$request = new ServerRequest();
$request = new ServerRequest();
$request = $request->withHeader('Accept', 'application/json');

$mode = $mode->withRequest($request);
Expand All @@ -79,4 +82,35 @@ public function testFullMode(): void

self::assertTrue($mode->isEnabled());
}

public function testBackendRequestOverride(): void
{
$mode = new HeadlessMode();

$request = new ServerRequest();

$mode = $mode->withRequest($request);

self::assertNull($request->getAttribute('headless'));

$request = $mode->overrideBackendRequestBySite(new Site('test', 1, ['headless' => HeadlessMode::FULL]));

self::assertSame(HeadlessMode::FULL, $request->getAttribute('headless')->getMode());

$request = $mode->overrideBackendRequestBySite(new Site('test', 1, ['headless' => HeadlessMode::MIXED]));

self::assertSame(HeadlessMode::NONE, $request->getAttribute('headless')->getMode());

$request = $mode->overrideBackendRequestBySite(
new Site('test', 1, ['headless' => HeadlessMode::MIXED]),
new SiteLanguage(
1,
'en_US',
new Uri('/'),
[]
)
);

self::assertSame(HeadlessMode::NONE, $request->getAttribute('headless')->getMode());
}
}

0 comments on commit a710126

Please sign in to comment.