diff --git a/composer.json b/composer.json index 6e5d3c5b4b6..07b83b55e84 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "liip/imagine-bundle": "^2.1", "oneup/flysystem-bundle": "^3.0", "friendsofsymfony/http-cache-bundle": "^1.3.13 | ^2.5.1", + "friendsofsymfony/jsrouting-bundle": "^1.6.3", "sensio/framework-extra-bundle": "^5.2", "jms/translation-bundle": "^1.4", "twig/twig": "^2.10", diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing/js_routing.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing/js_routing.yml index d22cd90f622..4056252ba9f 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing/js_routing.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing/js_routing.yml @@ -4,4 +4,4 @@ services: decorates: 'fos_js_routing.extractor' arguments: - '@ezpublish.js_routing.extractor.inner' - - '@=service("request_stack").getMasterRequest()' + - '@request_stack' diff --git a/eZ/Bundle/EzPublishCoreBundle/Routing/JsRouting/ExposedRoutesExtractor.php b/eZ/Bundle/EzPublishCoreBundle/Routing/JsRouting/ExposedRoutesExtractor.php index 0e7786aafd8..6641fdf0f5f 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Routing/JsRouting/ExposedRoutesExtractor.php +++ b/eZ/Bundle/EzPublishCoreBundle/Routing/JsRouting/ExposedRoutesExtractor.php @@ -8,24 +8,26 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess; use FOS\JsRoutingBundle\Extractor\ExposedRoutesExtractorInterface; -use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; /** * Decorator of FOSJsRouting routes extractor. * Ensures that base URL contains the SiteAccess part when applicable. + * + * @internal */ class ExposedRoutesExtractor implements ExposedRoutesExtractorInterface { - /** @var ExposedRoutesExtractorInterface */ + /** @var \FOS\JsRoutingBundle\Extractor\ExposedRoutesExtractorInterface */ private $innerExtractor; - /** @var Request */ - private $masterRequest; + /** @var \Symfony\Component\HttpFoundation\RequestStack */ + private $requestStack; - public function __construct(ExposedRoutesExtractorInterface $innerExtractor, Request $masterRequest) + public function __construct(ExposedRoutesExtractorInterface $innerExtractor, RequestStack $requestStack) { $this->innerExtractor = $innerExtractor; - $this->masterRequest = $masterRequest; + $this->requestStack = $requestStack; } public function getRoutes() @@ -43,7 +45,12 @@ public function getRoutes() public function getBaseUrl() { $baseUrl = $this->innerExtractor->getBaseUrl(); - $siteAccess = $this->masterRequest->attributes->get('siteaccess'); + $request = $this->requestStack->getMasterRequest(); + if ($request === null) { + return $baseUrl; + } + + $siteAccess = $request->attributes->get('siteaccess'); if ($siteAccess instanceof SiteAccess && $siteAccess->matcher instanceof SiteAccess\URILexer) { $baseUrl .= $siteAccess->matcher->analyseLink(''); } diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/JsRouting/ExposedRoutesExtractorTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/JsRouting/ExposedRoutesExtractorTest.php new file mode 100644 index 00000000000..e4964f4c212 --- /dev/null +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/JsRouting/ExposedRoutesExtractorTest.php @@ -0,0 +1,76 @@ + [ + // no master request in a stack + null, + self::BASE_URL, + ]; + + yield 'No SiteAccess' => [ + new Request(), + self::BASE_URL, + ]; + + $siteAccess = new SiteAccess( + 'test', + SiteAccess\Matcher\HostText::class, + new SiteAccess\Matcher\HostText([]) + ); + yield 'SiteAccess w/o URI Lexer matcher' => [ + new Request([], [], ['siteaccess' => $siteAccess]), + self::BASE_URL, + ]; + + $siteAccess = new SiteAccess( + 'test', + SiteAccess\Matcher\URIText::class, + new SiteAccess\Matcher\URIText(['prefix' => 'bar']) + ); + yield 'SiteAccess with URI Lexer matcher' => [ + new Request([], [], ['siteaccess' => $siteAccess]), + self::BASE_URL . '/bar/', + ]; + } + + /** + * @dataProvider getDataForTestGetBaseUrl + */ + public function testGetBaseUrl(?Request $masterRequest, string $expectedBaseUrl): void + { + $innerExtractor = $this->createMock(ExposedRoutesExtractorInterface::class); + $requestStack = $this->createMock(RequestStack::class); + + $innerExtractor->method('getBaseUrl')->willReturn(self::BASE_URL); + $requestStack->method('getMasterRequest')->willReturn($masterRequest); + + $extractor = new ExposedRoutesExtractor($innerExtractor, $requestStack); + + self::assertSame($expectedBaseUrl, $extractor->getBaseUrl()); + } +}