Skip to content

Commit 00ef707

Browse files
committed
Merge pull request #474 from ezsystems/siteAccessSymfonyRoutes
Fix EZP-21354: Siteaccess part missing in generated symfony routes
2 parents e625523 + 31f98de commit 00ef707

File tree

13 files changed

+328
-12
lines changed

13 files changed

+328
-12
lines changed

eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/ChainRoutingPass.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ public function process( ContainerBuilder $container )
3333
if ( $container->hasDefinition( 'router.default' ) )
3434
{
3535
$defaultRouter = $container->getDefinition( 'router.default' );
36+
$defaultRouter->addMethodCall(
37+
'setNonSiteAccessAwareRoutes',
38+
array( '%ezpublish.default_router.non_siteaccess_aware_routes%' )
39+
);
3640
if ( !$defaultRouter->hasTag( 'router' ) )
3741
{
3842
$defaultRouter->addTag(

eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function getConfigTreeBuilder()
4040
$this->addHttpCacheSection( $rootNode );
4141
$this->addSystemSection( $rootNode );
4242
$this->addPageSection( $rootNode );
43+
$this->addRouterSection( $rootNode );
4344

4445
return $treeBuilder;
4546
}
@@ -294,4 +295,31 @@ private function addPageSection( ArrayNodeDefinition $rootNode )
294295
->end();
295296

296297
}
298+
299+
private function addRouterSection( ArrayNodeDefinition $rootNode )
300+
{
301+
$nonSAAwareInfo = <<<EOT
302+
Route names that are not supposed to be SiteAccess aware, i.e. Routes pointing to asset generation (like assetic).
303+
Note that you can just specify a prefix to match a selection of routes.
304+
e.g. "_assetic_" will match "_assetic_*"
305+
Defaults to ['_assetic_', '_wdt', '_profiler', '_configurator_']
306+
EOT;
307+
$rootNode
308+
->children()
309+
->arrayNode( 'router' )
310+
->children()
311+
->arrayNode( 'default_router' )
312+
->children()
313+
->arrayNode( 'non_siteaccess_aware_routes' )
314+
->prototype( 'scalar' )->end()
315+
->info( $nonSAAwareInfo )
316+
->example( array( 'my_route_name', 'some_prefix_' ) )
317+
->end()
318+
->end()
319+
->end()
320+
->end()
321+
->info( 'Router related settings' )
322+
->end()
323+
->end();
324+
}
297325
}

eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function load( array $configs, ContainerBuilder $container )
6464
$this->registerPageConfiguration( $config, $container );
6565

6666
// Routing
67-
$this->handleRouting( $container, $loader );
67+
$this->handleRouting( $config, $container, $loader );
6868
// Public API loading
6969
$this->handleApiLoading( $container, $loader );
7070
$this->handleTemplating( $container, $loader );
@@ -174,13 +174,25 @@ private function registerPageConfiguration( array $config, ContainerBuilder $con
174174
/**
175175
* Handle routing parameters
176176
*
177+
* @param array $config
177178
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
178179
* @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
179180
*/
180-
private function handleRouting( ContainerBuilder $container, FileLoader $loader )
181+
private function handleRouting( array $config, ContainerBuilder $container, FileLoader $loader )
181182
{
182183
$loader->load( 'routing.yml' );
183184
$container->setAlias( 'router', 'ezpublish.chain_router' );
185+
186+
if ( isset( $config['router']['default_router']['non_siteaccess_aware_routes'] ) )
187+
{
188+
$container->setParameter(
189+
'ezpublish.default_router.non_siteaccess_aware_routes',
190+
array_merge(
191+
$container->getParameter( 'ezpublish.default_router.non_siteaccess_aware_routes' ),
192+
$config['router']['default_router']['non_siteaccess_aware_routes']
193+
)
194+
);
195+
}
184196
}
185197

186198
/**

eZ/Bundle/EzPublishCoreBundle/EventListener/SiteAccessListener.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
use eZ\Publish\Core\MVC\Symfony\MVCEvents;
1313
use eZ\Publish\Core\MVC\Symfony\Event\PostSiteAccessMatchEvent;
14+
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
15+
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware;
1416
use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer;
1517
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1618
use Symfony\Component\DependencyInjection\ContainerInterface;
19+
use Symfony\Component\Routing\RouterInterface;
1720

1821
/**
1922
* SiteAccess match listener.
@@ -25,9 +28,21 @@ class SiteAccessListener implements EventSubscriberInterface
2528
*/
2629
private $container;
2730

28-
public function __construct( ContainerInterface $container )
31+
/**
32+
* @var \Symfony\Component\Routing\RouterInterface
33+
*/
34+
private $defaultRouter;
35+
36+
/**
37+
* @var \eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator
38+
*/
39+
private $urlAliasGenerator;
40+
41+
public function __construct( ContainerInterface $container, RouterInterface $defaultRouter, UrlAliasGenerator $urlAliasGenerator )
2942
{
3043
$this->container = $container;
44+
$this->defaultRouter = $defaultRouter;
45+
$this->urlAliasGenerator = $urlAliasGenerator;
3146
}
3247

3348
public static function getSubscribedEvents()
@@ -42,7 +57,10 @@ public function onSiteAccessMatch( PostSiteAccessMatchEvent $event )
4257
$request = $event->getRequest();
4358
$siteAccess = $event->getSiteAccess();
4459
$this->container->set( 'ezpublish.siteaccess', $siteAccess );
45-
$this->container->get( 'ezpublish.urlalias_generator' )->setSiteAccess( $siteAccess );
60+
if ( $this->urlAliasGenerator instanceof SiteAccessAware )
61+
$this->urlAliasGenerator->setSiteAccess( $siteAccess );
62+
if ( $this->defaultRouter instanceof SiteAccessAware )
63+
$this->defaultRouter->setSiteAccess( $siteAccess );
4664

4765
// We already have semanticPathinfo (sub-request)
4866
if ( $request->attributes->has( 'semanticPathinfo' ) )

eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
parameters:
22
# Redefining the default router class to implement the RequestMatcherInterface
33
router.class: eZ\Bundle\EzPublishCoreBundle\Routing\DefaultRouter
4+
ezpublish.default_router.non_siteaccess_aware_routes: ['_assetic_', '_wdt', '_profiler', '_configurator_']
5+
46
ezpublish.chain_router.class: Symfony\Cmf\Component\Routing\ChainRouter
57
ezpublish.url_generator.base.class: eZ\Publish\Core\MVC\Symfony\Routing\Generator
68
ezpublish.urlalias_router.class: eZ\Bundle\EzPublishCoreBundle\Routing\UrlAliasRouter
@@ -60,7 +62,7 @@ services:
6062

6163
ezpublish.siteaccess_listener:
6264
class: %ezpublish.siteaccess_listener.class%
63-
arguments: [@service_container]
65+
arguments: [@service_container, @router.default, @ezpublish.urlalias_generator]
6466
tags:
6567
- { name: kernel.event_subscriber }
6668

eZ/Bundle/EzPublishCoreBundle/Routing/DefaultRouter.php

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,41 @@
99

1010
namespace eZ\Bundle\EzPublishCoreBundle\Routing;
1111

12+
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
13+
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware;
14+
use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer;
1215
use Symfony\Bundle\FrameworkBundle\Routing\Router;
1316
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
1417
use Symfony\Component\HttpFoundation\Request;
1518

1619
/**
1720
* Extension of Symfony default router implementing RequestMatcherInterface
1821
*/
19-
class DefaultRouter extends Router implements RequestMatcherInterface
22+
class DefaultRouter extends Router implements RequestMatcherInterface, SiteAccessAware
2023
{
24+
/**
25+
* @var SiteAccess
26+
*/
27+
protected $siteAccess;
28+
29+
protected $nonSiteAccessAwareRoutes = array();
30+
31+
public function setSiteAccess( SiteAccess $siteAccess = null )
32+
{
33+
$this->siteAccess = $siteAccess;
34+
}
35+
36+
/**
37+
* Injects route names that are not supposed to be SiteAccess aware.
38+
* i.e. Routes pointing to asset generation (like assetic).
39+
*
40+
* @param array $routes
41+
*/
42+
public function setNonSiteAccessAwareRoutes( array $routes )
43+
{
44+
$this->nonSiteAccessAwareRoutes = $routes;
45+
}
46+
2147
/**
2248
* @param \Symfony\Component\HttpFoundation\Request $request The request to match
2349
*
@@ -35,4 +61,58 @@ public function matchRequest( Request $request )
3561

3662
return $this->match( $request->getPathInfo() );
3763
}
64+
65+
public function generate( $name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH )
66+
{
67+
$url = parent::generate( $name, $parameters, $referenceType );
68+
if ( $this->isSiteAccessAwareRoute( $name ) && isset( $this->siteAccess ) && $this->siteAccess->matcher instanceof URILexer )
69+
{
70+
$context = $this->getContext();
71+
if ( $referenceType == self::ABSOLUTE_URL || $referenceType == self::NETWORK_PATH )
72+
{
73+
$scheme = $context->getScheme();
74+
$port = '';
75+
if ( $scheme === 'http' && $this->context->getHttpPort() != 80 )
76+
{
77+
$port = ':' . $this->context->getHttpPort();
78+
}
79+
else if ( $scheme === 'https' && $this->context->getHttpsPort() != 443 )
80+
{
81+
$port = ':' . $this->context->getHttpsPort();
82+
}
83+
84+
$base = $context->getHost() . $port . $context->getBaseUrl();
85+
}
86+
else
87+
{
88+
$base = $context->getBaseUrl();
89+
}
90+
91+
$linkUri = $base ? substr( $url, strpos( $url, $base ) + strlen( $base ) ) : $url;
92+
$url = str_replace( $linkUri, $this->siteAccess->matcher->analyseLink( $linkUri ), $url );
93+
}
94+
95+
return $url;
96+
}
97+
98+
/**
99+
* Checks if $routeName is a siteAccess aware route, and thus needs to have siteAccess URI prepended.
100+
* Will be used for link generation, only in the case of URI SiteAccess matching.
101+
*
102+
* @param $routeName
103+
*
104+
* @return bool
105+
*/
106+
protected function isSiteAccessAwareRoute( $routeName )
107+
{
108+
foreach ( $this->nonSiteAccessAwareRoutes as $ignoredPrefix )
109+
{
110+
if ( strpos( $routeName, $ignoredPrefix ) === 0 )
111+
{
112+
return false;
113+
}
114+
}
115+
116+
return true;
117+
}
38118
}

0 commit comments

Comments
 (0)