From 12323af2f4be9ebeff9995f8e9f2514e4b24f2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 28 Mar 2014 10:56:17 +0100 Subject: [PATCH 01/23] Removed useless @covers in SiteAccess matcher tests --- .../Tests/Compound/CompoundAndTest.php | 4 ---- .../SiteAccess/Tests/Compound/CompoundOrTest.php | 7 +------ .../SiteAccess/Tests/RouterHostElementTest.php | 13 ------------- .../SiteAccess/Tests/RouterHostPortURITest.php | 9 --------- .../SiteAccess/Tests/RouterHostRegexTest.php | 14 -------------- .../SiteAccess/Tests/RouterHostTextTest.php | 14 -------------- .../SiteAccess/Tests/RouterMapURITest.php | 2 -- .../SiteAccess/Tests/RouterPortHostURITest.php | 12 ------------ .../SiteAccess/Tests/RouterSpecialPortsTest.php | 12 ------------ .../MVC/Symfony/SiteAccess/Tests/RouterTest.php | 12 ------------ .../SiteAccess/Tests/RouterURIElement2Test.php | 16 ---------------- .../SiteAccess/Tests/RouterURIElementTest.php | 15 --------------- .../SiteAccess/Tests/RouterURIRegexTest.php | 14 -------------- .../SiteAccess/Tests/RouterURITextTest.php | 14 -------------- 14 files changed, 1 insertion(+), 157 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php index 60c830a28ac..e4eab87c13f 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php @@ -29,7 +29,6 @@ protected function setUp() } /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound::__construct * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalAnd */ public function testConstruct() @@ -71,8 +70,6 @@ private function buildMatcher() /** * @depends testConstruct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound::setMatcherBuilder - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound::getSubMatchers */ public function testSetMatcherBuilder( Compound $compoundMatcher ) { @@ -94,7 +91,6 @@ public function testSetMatcherBuilder( Compound $compoundMatcher ) /** * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalAnd::match * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request * @param $expectedMatch diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php index d4e5817d7c9..03c60cdef0b 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php @@ -29,7 +29,6 @@ protected function setUp() } /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound::__construct * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalAnd */ public function testConstruct() @@ -64,8 +63,6 @@ private function buildMatcher() /** * @depends testConstruct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound::setMatcherBuilder - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound::getSubMatchers */ public function testSetMatcherBuilder( Compound $compoundMatcher ) { @@ -86,11 +83,9 @@ public function testSetMatcherBuilder( Compound $compoundMatcher ) /** * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalOr::match * - * @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound $compoundMatcher * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * @param $expectedMatch + * @param string $expectedMatch */ public function testMatch( SimplifiedRequest $request, $expectedMatch ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php index 2d2ebb04ab8..40495aca50d 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -56,13 +53,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostElement::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostElement::match */ public function testMatch( $request, $siteAccess, $router ) { @@ -129,9 +119,6 @@ public function matchProvider() ); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::getName - */ public function testGetName() { $matcher = new HostMapMatcher( array( 'host' => 'foo' ), array() ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php index 5d48cf35f73..27ff99a32c3 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php @@ -27,9 +27,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -62,12 +59,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port::__construct */ public function testMatch( $request, $siteAccess, $router ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostRegexTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostRegexTest.php index e0b0a927a96..d268a5552c4 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostRegexTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostRegexTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -57,14 +54,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex\Host::__construct */ public function testMatch( $request, $siteAccess, $router ) { @@ -132,9 +121,6 @@ public function matchProvider() ); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex\Host::getName - */ public function testGetName() { $matcher = new HostRegexMatcher( array( 'host' => 'foo' ), array() ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php index 26cecb5af12..bc03c0bbbdc 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -58,14 +55,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostText::__construct */ public function testMatch( $request, $siteAccess, $router ) { @@ -132,9 +121,6 @@ public function matchProvider() ); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostText::getName - */ public function testGetName() { $matcher = new HostTextMatcher( array( 'host' => 'foo' ), array() ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php index c9c6a1436bd..1edf606a6ac 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php @@ -20,7 +20,6 @@ class RouterMapURITest extends PHPUnit_Framework_TestCase * @param string $expectedFixedUpURI * * @dataProvider fixupURIProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::analyseURI */ public function testAnalyseURI( $uri, $expectedFixedUpURI ) { @@ -36,7 +35,6 @@ public function testAnalyseURI( $uri, $expectedFixedUpURI ) * @param string $linkUri * * @dataProvider fixupURIProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::analyseLink */ public function testAnalyseLink( $fullUri, $linkUri ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterPortHostURITest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterPortHostURITest.php index 268321c5992..33bb246f66b 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterPortHostURITest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterPortHostURITest.php @@ -27,9 +27,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -62,15 +59,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::setRequest - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::setRequest - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port::setRequest */ public function testMatch( $request, $siteAccess, $router ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterSpecialPortsTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterSpecialPortsTest.php index 43eec17552b..1329a3cd752 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterSpecialPortsTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterSpecialPortsTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -63,12 +60,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port::__construct */ public function testMatch( $request, $siteAccess, $router ) { @@ -139,9 +130,6 @@ public function matchProvider() ); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port::getName - */ public function testGetName() { $matcher = new PortMatcher( array( 'port' => '8080', 'scheme' => 'http' ), array() ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php index cf15f140ed1..634f30a3f9d 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php @@ -34,9 +34,6 @@ protected function tearDown() parent::tearDown(); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -83,12 +80,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port::__construct */ public function testMatch( $request, $siteAccess, $router ) { @@ -103,7 +94,6 @@ public function testMatch( $request, $siteAccess, $router ) /** * @depends testConstruct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match * @expectedException \eZ\Publish\Core\MVC\Exception\InvalidSiteAccessException */ public function testMatchWithEnvFail( $router ) @@ -115,7 +105,6 @@ public function testMatchWithEnvFail( $router ) /** * @depends testConstruct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match */ public function testMatchWithEnv( $router ) { @@ -132,7 +121,6 @@ public function testMatchWithEnv( $router ) * @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router $router * * @depends testConstruct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match */ public function testMatchWithRequestHeader( $router ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php index ee5c4ea753e..10d9678fe9f 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -55,15 +52,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::setRequest - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::getURIElements */ public function testMatch( $request, $siteAccess, $router ) { @@ -130,9 +118,6 @@ public function matchProvider() * @param string $expectedFixedUpURI * * @dataProvider analyseProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::analyseURI - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::setRequest - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::getURIElements */ public function testAnalyseURI( $level, $uri, $expectedFixedUpURI ) { @@ -149,7 +134,6 @@ public function testAnalyseURI( $level, $uri, $expectedFixedUpURI ) * @param string $linkUri * * @dataProvider analyseProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::analyseLink */ public function testAnalyseLink( $level, $fullUri, $linkUri ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php index 565f35e79ef..47e7f6280ab 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -55,13 +52,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::match */ public function testMatch( $request, $siteAccess, $router ) { @@ -122,9 +112,6 @@ public function matchProvider() ); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::getName - */ public function testGetName() { $matcher = new URIElementMatcher( array(), array() ); @@ -136,7 +123,6 @@ public function testGetName() * @param string $expectedFixedUpURI * * @dataProvider analyseProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::analyseURI */ public function testAnalyseURI( $uri, $expectedFixedUpURI ) { @@ -152,7 +138,6 @@ public function testAnalyseURI( $uri, $expectedFixedUpURI ) * @param string $linkUri * * @dataProvider analyseProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement::analyseLink */ public function testAnalyseLink( $fullUri, $linkUri ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIRegexTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIRegexTest.php index b4e20962470..bb105ffa59e 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIRegexTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIRegexTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -57,14 +54,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex\URI::__construct */ public function testMatch( $request, $siteAccess, $router ) { @@ -132,9 +121,6 @@ public function matchProvider() ); } - /** - * @covers eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex\URI::getName - */ public function testGetName() { $matcher = new RegexMatcher( array(), array() ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php index a31f35ee271..90650cc9ad5 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php @@ -28,9 +28,6 @@ protected function setUp() $this->matcherBuilder = new MatcherBuilder; } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::__construct - */ public function testConstruct() { return new Router( @@ -58,14 +55,6 @@ public function testConstruct() /** * @depends testConstruct * @dataProvider matchProvider - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Router::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::__construct - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex::match - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIText::__construct */ public function testMatch( $request, $siteAccess, $router ) { @@ -133,9 +122,6 @@ public function matchProvider() ); } - /** - * @covers \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIText::getName - */ public function testGetName() { $matcher = new URITextMatcher( array(), array() ); From 72b75e9cff98f163228cb4aaea50198d553e6f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 28 Mar 2014 10:57:03 +0100 Subject: [PATCH 02/23] EZP-20305: Fixed phpDoc in MatcherBuilder --- eZ/Publish/Core/MVC/Symfony/SiteAccess/MatcherBuilder.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/MatcherBuilder.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/MatcherBuilder.php index 1dbd54bfd08..fc5b5ff50e4 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/MatcherBuilder.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/MatcherBuilder.php @@ -25,7 +25,7 @@ class MatcherBuilder implements MatcherBuilderInterface * @param mixed $matchingConfiguration Configuration to pass to the matcher. Can be anything the matcher supports. * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request The request to match against. * - * @return \eZ\Bundle\EzPublishCoreBundle\SiteAccess\Matcher + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher */ public function buildMatcher( $matcherIdentifier, $matchingConfiguration, SimplifiedRequest $request ) { @@ -34,6 +34,7 @@ public function buildMatcher( $matcherIdentifier, $matchingConfiguration, Simpli if ( $matcherIdentifier[0] !== '\\' ) $matcherIdentifier = __NAMESPACE__ . "\\Matcher\\$matcherIdentifier"; + /** @var $matcher \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher */ $matcher = new $matcherIdentifier( $matchingConfiguration ); $matcher->setRequest( $request ); From c3424ecddefe191226626b34d690b022694897cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 28 Mar 2014 15:08:06 +0100 Subject: [PATCH 03/23] EZP-20305: Introduced SiteAccessRouterInterface --- .../Core/MVC/Symfony/SiteAccess/Router.php | 7 ++--- .../SiteAccess/SiteAccessRouterInterface.php | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php index e3ae9aadde8..e014bd69203 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php @@ -14,8 +14,9 @@ use eZ\Publish\Core\MVC\Exception\InvalidSiteAccessException; use Psr\Log\LoggerInterface; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\CompoundInterface; +use InvalidArgumentException; -class Router +class Router implements SiteAccessRouterInterface, SiteAccessAware { /** * Name of the default siteaccess @@ -95,7 +96,7 @@ public function __construct( MatcherBuilderInterface $matcherBuilder, LoggerInte $this->defaultSiteAccess = $defaultSiteAccess; $this->siteAccessesConfiguration = $siteAccessesConfiguration; $this->siteAccessList = array_fill_keys( $siteAccessList, true ); - $this->siteAccessClass = $siteAccessClass; + $this->siteAccessClass = $siteAccessClass ?: 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess'; } /** @@ -112,7 +113,7 @@ public function match( SimplifiedRequest $request ) if ( isset( $this->siteAccess ) ) return $this->siteAccess; - $siteAccessClass = $this->siteAccessClass ?: 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess'; + $siteAccessClass = $this->siteAccessClass; $this->siteAccess = new $siteAccessClass(); // Request header always have precedence diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php new file mode 100644 index 00000000000..0322f5aa9bb --- /dev/null +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php @@ -0,0 +1,26 @@ + Date: Fri, 28 Mar 2014 15:09:35 +0100 Subject: [PATCH 04/23] EZP-20305: Introduced VersatileMatcher interface This interface makes it possible to do a reverse match, from a SiteAccess name. If a reverse match is performed, a clone of the used matcher is returned --- .../Symfony/SiteAccess/VersatileMatcher.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php new file mode 100644 index 00000000000..6c0b532d029 --- /dev/null +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php @@ -0,0 +1,38 @@ + Date: Fri, 28 Mar 2014 15:11:20 +0100 Subject: [PATCH 05/23] EZP-20305: Made Map matchers implement VersatileMatcher --- .../MVC/Symfony/SiteAccess/Matcher/Map.php | 68 +++++++++++++++- .../Symfony/SiteAccess/Matcher/Map/Host.php | 14 +++- .../Symfony/SiteAccess/Matcher/Map/Port.php | 14 +++- .../Symfony/SiteAccess/Matcher/Map/URI.php | 17 +++- .../Tests/RouterHostPortURITest.php | 77 ++++++++++++++++++- .../SiteAccess/Tests/RouterMapURITest.php | 36 +++++++++ 6 files changed, 219 insertions(+), 7 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php index 8ea51422605..be1a20c4d60 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php @@ -9,9 +9,10 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; +use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; -abstract class Map implements Matcher +abstract class Map implements VersatileMatcher { /** * String that will be looked up in the map. @@ -27,6 +28,18 @@ abstract class Map implements Matcher */ protected $map; + /** + * Map used for reverse matching. + * + * @var array + */ + protected $reverseMap; + + /** + * @var \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest + */ + protected $request; + /** * Constructor. * @@ -34,7 +47,27 @@ abstract class Map implements Matcher */ public function __construct( array $map ) { + foreach ( $map as $mapKey => &$value ) + { + // $value can be true in the case of the use of a Compound matcher + if ( $value === true ) + { + $value = $mapKey; + } + } + $this->map = $map; + $this->reverseMap = array_flip( $map ); + } + + public function setRequest( SimplifiedRequest $request ) + { + $this->request = $request; + } + + public function getRequest() + { + return $this->request; } /** @@ -47,6 +80,14 @@ public function setMapKey( $key ) $this->key = $key; } + /** + * @return string + */ + public function getMapKey() + { + return $this->key; + } + /** * Returns matching Siteaccess. * @@ -58,4 +99,27 @@ public function match() ? $this->map[$this->key] : false; } + + /** + * @param string $siteAccessName + * + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher|Map|null + */ + public function reverseMatch( $siteAccessName ) + { + if ( !isset( $this->reverseMap[$siteAccessName] ) ) + { + return null; + } + + $mapKey = $this->reverseMap[$siteAccessName]; + $matcher = clone $this; + $matcher->setMapKey( $mapKey ); + return $matcher; + } + + public function __clone() + { + $this->request = clone $this->request; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php index 2d4518e5b8c..3f5d14003a6 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php @@ -13,7 +13,7 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; -class Host extends Map implements Matcher +class Host extends Map { public function getName() { @@ -30,5 +30,17 @@ public function getName() public function setRequest( SimplifiedRequest $request ) { $this->setMapKey( $request->host ); + parent::setRequest( $request ); + } + + public function reverseMatch( $siteAccessName ) + { + $matcher = parent::reverseMatch( $siteAccessName ); + if ( $matcher instanceof Host ) + { + $matcher->getRequest()->setHost( $matcher->getMapKey() ); + } + + return $matcher; } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php index c5d08fd4a91..dc87ed7b57b 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php @@ -13,7 +13,7 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; -class Port extends Map implements Matcher +class Port extends Map { public function getName() { @@ -48,5 +48,17 @@ public function setRequest( SimplifiedRequest $request ) } $this->setMapKey( $key ); + parent::setRequest( $request ); + } + + public function reverseMatch( $siteAccessName ) + { + $matcher = parent::reverseMatch( $siteAccessName ); + if ( $matcher instanceof Port ) + { + $matcher->getRequest()->setPort( $matcher->getMapKey() ); + } + + return $matcher; } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php index b2ed29d1af5..d82d6a873b9 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php @@ -9,12 +9,11 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; -class URI extends Map implements Matcher, URILexer +class URI extends Map implements URILexer { /** * Injects the request object to match against. @@ -27,6 +26,7 @@ public function setRequest( SimplifiedRequest $request ) { sscanf( $request->pathinfo, "/%[^/]", $key ); $this->setMapKey( $key ); + parent::setRequest( $request ); } public function getName() @@ -70,4 +70,17 @@ public function analyseLink( $linkUri ) return "/{$this->key}{$joiningSlash}{$linkUri}{$queryString}"; } + public function reverseMatch( $siteAccessName ) + { + $matcher = parent::reverseMatch( $siteAccessName ); + if ( $matcher instanceof URI ) + { + $request = $matcher->getRequest(); + // Clean up "old" siteaccess prefix and add the new prefix. + $cleanedUpPathinfo = $this->analyseURI( $request->pathinfo ); + $request->setPathinfo( $matcher->analyseLink( $cleanedUpPathinfo ) ); + } + + return $matcher; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php index 27ff99a32c3..c590c33bef7 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostPortURITest.php @@ -9,6 +9,8 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Tests; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port; use PHPUnit_Framework_TestCase; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Router; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; @@ -60,7 +62,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -135,4 +137,77 @@ public function matchProvider() array( SimplifiedRequest::fromUrl( "https://example.com:82/foo" ), "fourth_sa" ), ); } + + public function testSetGetRequestMapHost() + { + $mapKey = 'phoenix-rises.fm'; + $request = new SimplifiedRequest( array( 'host' => $mapKey ) ); + $matcher = new Host( array( 'foo' => $mapKey ) ); + $matcher->setRequest( $request ); + $this->assertSame( $request, $matcher->getRequest() ); + $this->assertSame( $mapKey, $matcher->getMapKey() ); + } + + public function testReverseHostMatchFail() + { + $config = array( 'foo' => 'bar' ); + $matcher = new Host( $config ); + $this->assertNull( $matcher->reverseMatch( 'non_existent' ) ); + } + + public function testReverseMatchHost() + { + $config = array( + 'ez.no' => 'some_siteaccess', + 'something_else' => 'another_siteaccess', + 'phoenix-rises.fm' => 'ezdemo_site', + ); + $request = new SimplifiedRequest( array( 'host' => 'ez.no' ) ); + $matcher = new Host( $config ); + $matcher->setRequest( $request ); + $this->assertSame( 'ez.no', $matcher->getMapKey() ); + + $result = $matcher->reverseMatch( 'ezdemo_site' ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host', $result ); + $this->assertSame( $request, $matcher->getRequest() ); + $this->assertSame( 'phoenix-rises.fm', $result->getMapKey() ); + $this->assertSame( 'phoenix-rises.fm', $result->getRequest()->host ); + } + + public function testSetGetRequestMapPort() + { + $mapKey = '8000'; + $request = new SimplifiedRequest( array( 'port' => $mapKey ) ); + $matcher = new Port( array( 'foo' => $mapKey ) ); + $matcher->setRequest( $request ); + $this->assertSame( $request, $matcher->getRequest() ); + $this->assertSame( $mapKey, $matcher->getMapKey() ); + } + + public function testReversePortMatchFail() + { + $config = array( 'foo' => '8080' ); + $matcher = new Port( $config ); + $this->assertNull( $matcher->reverseMatch( 'non_existent' ) ); + } + + public function testReverseMatchPort() + { + $config = array( + '80' => 'some_siteaccess', + '443' => 'another_siteaccess', + 8000 => 'ezdemo_site', + ); + $request = new SimplifiedRequest( array( 'scheme' => 'http', 'host' => 'ez.no' ) ); + $matcher = new Port( $config ); + $matcher->setRequest( $request ); + $this->assertSame( 80, $matcher->getMapKey() ); + + $result = $matcher->reverseMatch( 'ezdemo_site' ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Port', $result ); + $this->assertSame( $request, $matcher->getRequest() ); + $this->assertSame( 8000, $result->getMapKey() ); + $this->assertSame( 8000, $result->getRequest()->port ); + $this->assertSame( 'http', $result->getRequest()->scheme ); + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php index 1edf606a6ac..92d49fa9a8f 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php @@ -15,6 +15,16 @@ class RouterMapURITest extends PHPUnit_Framework_TestCase { + public function testSetGetRequest() + { + $request = new SimplifiedRequest( array( 'pathinfo' => '/bar/baz' ) ); + $mapKey = 'bar'; + $matcher = new URIMapMatcher( array( 'foo' => $mapKey ) ); + $matcher->setRequest( $request ); + $this->assertSame( $request, $matcher->getRequest() ); + $this->assertSame( $mapKey, $matcher->getMapKey() ); + } + /** * @param string $uri * @param string $expectedFixedUpURI @@ -55,4 +65,30 @@ public function fixupURIProvider() array( '/ezdemo_site/some/thing?foo=ezdemo_site&bar=toto', '/some/thing?foo=ezdemo_site&bar=toto' ) ); } + + public function testReverseMatchFail() + { + $config = array( 'foo' => 'bar' ); + $matcher = new URIMapMatcher( $config ); + $this->assertNull( $matcher->reverseMatch( 'non_existent' ) ); + } + + public function testReverseMatch() + { + $config = array( + 'some_uri' => 'some_siteaccess', + 'something_else' => 'another_siteaccess', + 'toutouyoutou' => 'ezdemo_site', + ); + $request = new SimplifiedRequest( array( 'pathinfo' => '/some_uri/foo' ) ); + $matcher = new URIMapMatcher( $config ); + $matcher->setRequest( $request ); + $this->assertSame( 'some_uri', $matcher->getMapKey() ); + + $result = $matcher->reverseMatch( 'ezdemo_site' ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI', $result ); + $this->assertSame( $request, $matcher->getRequest() ); + $this->assertSame( 'toutouyoutou', $result->getMapKey() ); + $this->assertSame( '/toutouyoutou/foo', $result->getRequest()->pathinfo ); + } } From 01930e2a1ee2994b9c3b0c19e3cf2ae93a54239d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 28 Mar 2014 15:12:07 +0100 Subject: [PATCH 06/23] EZP-20305: Added setters to SimplifiedRequest This is to be able to modify it for usage in Versatile matchers. --- .../MVC/Symfony/Routing/SimplifiedRequest.php | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/SimplifiedRequest.php b/eZ/Publish/Core/MVC/Symfony/Routing/SimplifiedRequest.php index 6691a38589e..033061aa8e7 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/SimplifiedRequest.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/SimplifiedRequest.php @@ -73,6 +73,62 @@ class SimplifiedRequest extends ValueObject */ protected $headers; + /** + * @param array $headers + */ + public function setHeaders( array $headers ) + { + $this->headers = $headers; + } + + /** + * @param string $host + */ + public function setHost( $host ) + { + $this->host = $host; + } + + /** + * @param array $languages + */ + public function setLanguages( array $languages ) + { + $this->languages = $languages; + } + + /** + * @param string $pathinfo + */ + public function setPathinfo( $pathinfo ) + { + $this->pathinfo = $pathinfo; + } + + /** + * @param string $port + */ + public function setPort( $port ) + { + $this->port = $port; + } + + /** + * @param array $queryParams + */ + public function setQueryParams( array $queryParams ) + { + $this->queryParams = $queryParams; + } + + /** + * @param string $scheme + */ + public function setScheme( $scheme ) + { + $this->scheme = $scheme; + } + /** * Constructs a SimplifiedRequest object from a standard URL (http://www.example.com/foo/bar?queryParam=value) * From c6a89ccc241f9bbc559f926480fb788465adb455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 28 Mar 2014 15:12:31 +0100 Subject: [PATCH 07/23] EZP-20305: Made URIElement matcher implement VersatileMatcher --- .../Symfony/SiteAccess/Matcher/URIElement.php | 46 +++++++++++++++++-- .../Tests/RouterURIElement2Test.php | 33 ++++++++++++- .../SiteAccess/Tests/RouterURIElementTest.php | 27 ++++++++++- 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php index b0baca2b63d..46b4dbd15ff 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php @@ -9,12 +9,12 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; use LogicException; -class URIElement implements Matcher, URILexer +class URIElement implements VersatileMatcher, URILexer { /** * @var \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest @@ -91,14 +91,20 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { $this->request = $request; } + /** + * @return \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest + */ + public function getRequest() + { + return $this->request; + } + /** * Analyses $uri and removes the siteaccess part, if needed. * @@ -135,4 +141,36 @@ public function analyseLink( $linkUri ) $uriElements = implode( '/', $this->getURIElements() ); return "/{$uriElements}{$joiningSlash}{$linkUri}"; } + + /** + * Returns matcher object corresponding to $siteAccessName or null if non applicable. + * + * Limitation: If the element number is > 1, we cannot predict how URI segments are expected to be built. + * So we expect "_" will be reversed to "/" + * e.g. foo_bar => foo/bar with elementNumber == 2 + * Hence if number of elements is different than the element number, we report as non matched. + * + * @param string $siteAccessName + * + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement|null + */ + public function reverseMatch( $siteAccessName ) + { + $elements = $this->elementNumber > 1 ? explode( '_', $siteAccessName ) : array( $siteAccessName ); + if ( count( $elements ) !== $this->elementNumber ) + { + return null; + } + + $matcher = clone $this; + $request = $matcher->getRequest(); + $pathinfo = '/' . implode( '/', $elements ) . '/' . ltrim( $this->analyseURI( $request->pathinfo ), '/' ); + $request->setPathinfo( $pathinfo ); + return $matcher; + } + + public function __clone() + { + $this->request = clone $this->request; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php index 10d9678fe9f..26c32fdfecb 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php @@ -53,7 +53,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -161,4 +161,35 @@ public function analyseProvider() array( 2, '/prefix/siteaccess/', '/' ), ); } + + /** + * @dataProvider reverseMatchProvider + */ + public function testReverseMatch( $siteAccessName, $originalPathinfo ) + { + $expectedSiteAccessPath = implode( '/', explode( '_', $siteAccessName ) ); + $matcher = new URIElementMatcher( 2 ); + $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => "/my/siteaccess{$originalPathinfo}" ) ) ); + + $result = $matcher->reverseMatch( $siteAccessName ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement', $result ); + $this->assertSame( "/{$expectedSiteAccessPath}{$originalPathinfo}", $result->getRequest()->pathinfo ); + $this->assertSame( "/$expectedSiteAccessPath/some/linked/uri", $result->analyseLink( '/some/linked/uri' ) ); + $this->assertSame( "/foo/bar/baz", $result->analyseURI( "/$expectedSiteAccessPath/foo/bar/baz" ) ); + } + + public function reverseMatchProvider() + { + return array( + array( 'some_thing', '/foo/bar' ), + array( 'another_siteaccess', '/foo/bar' ), + ); + } + + public function testReverseMatchFail() + { + $matcher = new URIElementMatcher( 2 ); + $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => "/my/siteaccess/foo/bar" ) ) ); + $this->assertNull( $matcher->reverseMatch( 'another_siteaccess_again_dont_tell_me' ) ); + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php index 47e7f6280ab..40cc3865208 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php @@ -53,7 +53,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -155,4 +155,29 @@ public function analyseProvider() array( '/vive/le/sucre', '/le/sucre' ) ); } + + /** + * @dataProvider reverseMatchProvider + */ + public function testReverseMatch( $siteAccessName, $originalPathinfo ) + { + $matcher = new URIElementMatcher( 1 ); + $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => "/my_siteaccess{$originalPathinfo}" ) ) ); + $result = $matcher->reverseMatch( $siteAccessName ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement', $result ); + $this->assertSame( "/{$siteAccessName}{$originalPathinfo}", $result->getRequest()->pathinfo ); + $this->assertSame( "/$siteAccessName/some/linked/uri", $result->analyseLink( '/some/linked/uri' ) ); + $this->assertSame( "/foo/bar/baz", $result->analyseURI( "/$siteAccessName/foo/bar/baz" ) ); + } + + public function reverseMatchProvider() + { + return array( + array( 'something', '/foo/bar' ), + array( 'something', '/' ), + array( 'some_thing', '/foo/bar' ), + array( 'another_siteaccess', '/foo/bar' ), + array( 'another_siteaccess_again_dont_tell_me', '/foo/bar' ), + ); + } } From d6297e7a6257a287122407a07e75dd8a5c6549a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Mon, 31 Mar 2014 11:06:15 +0200 Subject: [PATCH 08/23] EZP-20305: Made HostElement matcher implement VersatileMatcher --- .../SiteAccess/Matcher/HostElement.php | 43 ++++++++++++++++++- .../Tests/RouterHostElementTest.php | 35 ++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php index b3ff1865163..0686e2cb564 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php @@ -9,10 +9,10 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; -class HostElement implements Matcher +class HostElement implements VersatileMatcher { /** * @var \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest @@ -64,4 +64,43 @@ public function setRequest( SimplifiedRequest $request ) { $this->request = $request; } + + /** + * @return \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest + */ + public function getRequest() + { + return $this->request; + } + + /** + * Returns matcher object corresponding to $siteAccessName or null if non applicable. + * + * @note Limitation: Will only work correctly if HostElement is used for all siteaccesses, as host cannot be guessed. + * + * @param string $siteAccessName + * + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostElement|null Typically a clone of current matcher, with appropriate config. + */ + public function reverseMatch( $siteAccessName ) + { + $request = clone $this->request; + $hostElements = explode( '.', $request->host ); + $elementNumber = $this->elementNumber - 1; + if ( !isset( $hostElements[$elementNumber] ) ) + { + return null; + } + + $hostElements[$elementNumber] = $siteAccessName; + $matcher = clone $this; + $matcher->getRequest()->setHost( implode( '.', $hostElements ) ); + + return $matcher; + } + + public function __clone() + { + $this->request = clone $this->request; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php index 40495aca50d..e9a4713e5be 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostElementTest.php @@ -9,6 +9,7 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Tests; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostElement; use PHPUnit_Framework_TestCase; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Router; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\Host as HostMapMatcher; @@ -54,7 +55,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -123,5 +124,37 @@ public function testGetName() { $matcher = new HostMapMatcher( array( 'host' => 'foo' ), array() ); $this->assertSame( 'host:map', $matcher->getName() ); + + $matcherHostElement = new HostElement( 1 ); + $this->assertSame( 'host:element', $matcherHostElement->getName() ); + } + + /** + * @dataProvider reverseMatchProvider + */ + public function testReverseMatch( $siteAccessName, $elementNumber, SimplifiedRequest $request, $expectedHost ) + { + $matcher = new HostElement( $elementNumber ); + $matcher->setRequest( $request ); + $result = $matcher->reverseMatch( $siteAccessName ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostElement', $result ); + $this->assertSame( $expectedHost, $result->getRequest()->host ); + } + + public function reverseMatchProvider() + { + return array( + array( 'foo', 1, SimplifiedRequest::fromUrl( 'http://bar.example.com/' ), 'foo.example.com' ), + array( 'ezdemo_site', 1, SimplifiedRequest::fromUrl( 'http://ezflow_site.ez.no/' ), 'ezdemo_site.ez.no' ), + array( 'metalfrance', 2, SimplifiedRequest::fromUrl( 'http://www.lolart.net/' ), 'www.metalfrance.net' ), + array( 'fm', 3, SimplifiedRequest::fromUrl( 'http://www.phoenix-rises.fr/' ), 'www.phoenix-rises.fm' ), + ); + } + + public function testReverseMatchFail() + { + $matcher = new HostElement( 3 ); + $matcher->setRequest( new SimplifiedRequest( array( 'host' => 'ez.no' ) ) ); + $this->assertNull( $matcher->reverseMatch( 'foo' ) ); } } From a52afaf9e2e03f670b74561fb02f796b06ed4505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Tue, 1 Apr 2014 18:23:12 +0200 Subject: [PATCH 09/23] EZP-20305: Refactored URL generators Moved generic methods to abstract class --- .../Resources/config/routing.yml | 6 ++-- .../Resources/config/services.yml | 2 -- .../Routing/UrlGenerator.php | 20 +---------- .../Core/MVC/Symfony/Routing/Generator.php | 33 ++++++++++++++++++- .../Routing/Generator/UrlAliasGenerator.php | 32 ++---------------- .../Routing/Tests/UrlAliasGeneratorTest.php | 13 +++----- 6 files changed, 42 insertions(+), 64 deletions(-) diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml index 4ffb3c3f2e6..943da828fd7 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml @@ -33,6 +33,8 @@ services: abstract: true calls: - [setRequestContext, [@router.request_context]] + - [setSiteAccess, [@?ezpublish.siteaccess=]] + - [setLogger, [@?logger]] ezpublish.urlalias_router: class: %ezpublish.urlalias_router.class% @@ -49,10 +51,8 @@ services: ezpublish.urlalias_generator: class: %ezpublish.urlalias_generator.class% - arguments: [@ezpublish.api.repository, @router.default, @?logger] + arguments: [@ezpublish.api.repository, @router.default] parent: ezpublish.url_generator.base - calls: - - [setSiteAccess, [@ezpublish.siteaccess]] ezpublish.siteaccess.matcher_builder: class: %ezpublish.siteaccess.matcher_builder.class% diff --git a/eZ/Bundle/EzPublishLegacyBundle/Resources/config/services.yml b/eZ/Bundle/EzPublishLegacyBundle/Resources/config/services.yml index afdfafccc14..129326767a7 100644 --- a/eZ/Bundle/EzPublishLegacyBundle/Resources/config/services.yml +++ b/eZ/Bundle/EzPublishLegacyBundle/Resources/config/services.yml @@ -167,8 +167,6 @@ services: class: %ezpublish_legacy.url_generator.class% arguments: [@ezpublish_legacy.kernel] parent: ezpublish.url_generator.base - calls: - - [setSiteAccess, [@ezpublish.siteaccess]] ezpublish_legacy.siteaccess_mapper: class: %ezpublish_legacy.siteaccess_mapper.class% diff --git a/eZ/Bundle/EzPublishLegacyBundle/Routing/UrlGenerator.php b/eZ/Bundle/EzPublishLegacyBundle/Routing/UrlGenerator.php index b9f8b63f570..606b073d79c 100644 --- a/eZ/Bundle/EzPublishLegacyBundle/Routing/UrlGenerator.php +++ b/eZ/Bundle/EzPublishLegacyBundle/Routing/UrlGenerator.php @@ -9,34 +9,21 @@ namespace eZ\Bundle\EzPublishLegacyBundle\Routing; -use eZ\Publish\Core\MVC\Symfony\SiteAccess; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; use eZModule; use eZ\Publish\Core\MVC\Symfony\Routing\Generator; -class UrlGenerator extends Generator implements SiteAccessAware +class UrlGenerator extends Generator { /** * @var \Closure */ private $legacyKernelClosure; - /** - * @var SiteAccess - */ - private $siteAccess; - public function __construct( \Closure $legacyKernelClosure ) { $this->legacyKernelClosure = $legacyKernelClosure; } - public function setSiteAccess( SiteAccess $siteAccess = null ) - { - $this->siteAccess = $siteAccess; - } - /** * @return \eZ\Publish\Core\MVC\Legacy\Kernel */ @@ -88,11 +75,6 @@ function () use ( $legacyModuleUri, $moduleName, $viewName, $parameters, $siteAc $unorderedParams .= "/($paramName)/$paramValue"; } - if ( isset( $siteAccess ) && $siteAccess->matcher instanceof URILexer ) - { - $legacyModuleUri = trim( $siteAccess->matcher->analyseLink( "/$legacyModuleUri" ), '/' ); - } - return "/$legacyModuleUri$unorderedParams"; }, false diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php b/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php index 81aba93b489..e8e6c96416b 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php @@ -9,18 +9,32 @@ namespace eZ\Publish\Core\MVC\Symfony\Routing; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware; +use eZ\Publish\Core\MVC\Symfony\SiteAccess; +use Psr\Log\LoggerInterface; use Symfony\Component\Routing\RequestContext; /** * Base class for eZ Publish Url generation. */ -abstract class Generator +abstract class Generator implements SiteAccessAware { /** * @var \Symfony\Component\Routing\RequestContext */ protected $requestContext; + /** + /** + * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess + */ + protected $siteAccess; + + /** + * @var \Psr\Log\LoggerInterface + */ + protected $logger; + /** * @param \Symfony\Component\Routing\RequestContext $requestContext */ @@ -29,6 +43,23 @@ public function setRequestContext( RequestContext $requestContext ) $this->requestContext = $requestContext; } + /** + /** + * @param SiteAccess $siteAccess + */ + public function setSiteAccess( SiteAccess $siteAccess = null ) + { + $this->siteAccess = $siteAccess; + } + + /** + * @param LoggerInterface $logger + */ + public function setLogger( LoggerInterface $logger = null ) + { + $this->logger = $logger; + } + /** * Triggers URL generation for $urlResource and $parameters. * diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/Generator/UrlAliasGenerator.php b/eZ/Publish/Core/MVC/Symfony/Routing/Generator/UrlAliasGenerator.php index 4fd0b70fc1e..bce254ccc8d 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/Generator/UrlAliasGenerator.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/Generator/UrlAliasGenerator.php @@ -10,19 +10,15 @@ namespace eZ\Publish\Core\MVC\Symfony\Routing\Generator; use eZ\Publish\API\Repository\Repository; -use Psr\Log\LoggerInterface; use eZ\Publish\Core\MVC\Symfony\Routing\Generator; use Symfony\Component\Routing\RouterInterface; -use eZ\Publish\Core\MVC\Symfony\SiteAccess; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; /** * URL generator for UrlAlias based links * * @see \eZ\Publish\Core\MVC\Symfony\Routing\UrlAliasRouter */ -class UrlAliasGenerator extends Generator implements SiteAccessAware +class UrlAliasGenerator extends Generator { const INTERNAL_LOCATION_ROUTE = '_ezpublishLocation'; @@ -38,11 +34,6 @@ class UrlAliasGenerator extends Generator implements SiteAccessAware */ private $defaultRouter; - /** - * @var \Psr\Log\LoggerInterface - */ - private $logger; - /** * @var int */ @@ -58,24 +49,10 @@ class UrlAliasGenerator extends Generator implements SiteAccessAware */ private $pathPrefixMap = array(); - /** - * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess - */ - private $siteAccess; - - public function __construct( Repository $repository, RouterInterface $defaultRouter, LoggerInterface $logger = null ) + public function __construct( Repository $repository, RouterInterface $defaultRouter ) { $this->repository = $repository; $this->defaultRouter = $defaultRouter; - $this->logger = $logger; - } - - /** - * @param SiteAccess $siteAccess - */ - public function setSiteAccess( SiteAccess $siteAccess = null ) - { - $this->siteAccess = $siteAccess; } /** @@ -125,11 +102,6 @@ public function doGenerate( $location, array $parameters ) ); } - if ( isset( $this->siteAccess ) && $this->siteAccess->matcher instanceof URILexer ) - { - $path = $this->siteAccess->matcher->analyseLink( $path ); - } - $path = $path ?: '/'; return $path . $queryString; } diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php b/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php index 365b24d2e18..55a916d5472 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php @@ -76,9 +76,10 @@ protected function setUp() $this->urlAliasGenerator = new UrlAliasGenerator( $this->repository, - $this->router, - $this->logger + $this->router ); + $this->urlAliasGenerator->setLogger( $this->logger ); + $this->urlAliasGenerator->setSiteAccessRouter( $this->siteAccessRouter ); } public function testGetPathPrefixByRootLocationId() @@ -160,13 +161,7 @@ public function testDoGenerate( URLAlias $urlAlias, array $parameters, $expected ->with( $location, false ) ->will( $this->returnValue( array( $urlAlias ) ) ); - $siteAccessMatcher = $this->getMock( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess\\URILexer' ); - $siteAccessMatcher - ->expects( $this->once() ) - ->method( 'analyseLink' ) - ->with( $urlAlias->path ) - ->will( $this->returnArgument( 0 ) ); - $this->urlAliasGenerator->setSiteAccess( new SiteAccess( 'test', 'fake', $siteAccessMatcher ) ); + $this->urlAliasGenerator->setSiteAccess( new SiteAccess( 'test', 'fake', $this->getMock( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess\\URILexer' ) ) ); $this->assertSame( $expected, $this->urlAliasGenerator->doGenerate( $location, $parameters ) ); } From 3921cb5d94b226225b743b6f12e0edc61053e253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Tue, 1 Apr 2014 18:27:06 +0200 Subject: [PATCH 10/23] EZP-20305: Implemented cross-SA linking at UrlGenerator level - Added matchByName() method in SiteAccessRouterInterface - Implemented matchByName() in SiteAccess router - Implemented reverse matching mechanism in base URL Generator class. - Added tests --- .../Resources/config/routing.yml | 1 + .../Core/MVC/Symfony/Routing/Generator.php | 94 ++++++++++-- .../Symfony/Routing/Tests/GeneratorTest.php | 135 ++++++++++++++++++ .../Routing/Tests/UrlAliasGeneratorTest.php | 6 + .../Core/MVC/Symfony/SiteAccess/Router.php | 67 +++++++++ .../SiteAccess/SiteAccessRouterInterface.php | 13 ++ .../Symfony/SiteAccess/Tests/RouterTest.php | 88 +++++++++++- 7 files changed, 390 insertions(+), 14 deletions(-) create mode 100644 eZ/Publish/Core/MVC/Symfony/Routing/Tests/GeneratorTest.php diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml index 943da828fd7..71422d42b42 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/routing.yml @@ -34,6 +34,7 @@ services: calls: - [setRequestContext, [@router.request_context]] - [setSiteAccess, [@?ezpublish.siteaccess=]] + - [setSiteAccessRouter, [@ezpublish.siteaccess_router]] - [setLogger, [@?logger]] ezpublish.urlalias_router: diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php b/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php index e8e6c96416b..08d3e9a00c9 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/Generator.php @@ -10,6 +10,7 @@ namespace eZ\Publish\Core\MVC\Symfony\Routing; use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface; use eZ\Publish\Core\MVC\Symfony\SiteAccess; use Psr\Log\LoggerInterface; use Symfony\Component\Routing\RequestContext; @@ -25,6 +26,10 @@ abstract class Generator implements SiteAccessAware protected $requestContext; /** + * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface + */ + protected $siteAccessRouter; + /** * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess */ @@ -44,6 +49,13 @@ public function setRequestContext( RequestContext $requestContext ) } /** + * @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface $siteAccessRouter + */ + public function setSiteAccessRouter( SiteAccessRouterInterface $siteAccessRouter ) + { + $this->siteAccessRouter = $siteAccessRouter; + } + /** * @param SiteAccess $siteAccess */ @@ -64,17 +76,45 @@ public function setLogger( LoggerInterface $logger = null ) * Triggers URL generation for $urlResource and $parameters. * * @param mixed $urlResource Type can be anything, depending on the context. It's up to the router to pass the appropriate value to the implementor. - * @param array $parameters + * @param array $parameters Arbitrary hash of parameters to generate a link. + * SiteAccess name can be provided as 'siteaccess' to generate a link to it (cross siteaccess link). * @param boolean $absolute * * @return string */ public function generate( $urlResource, array $parameters, $absolute = false ) { - $url = $this->requestContext->getBaseUrl() . $this->doGenerate( $urlResource, $parameters ); + $siteAccess = $this->siteAccess; + $requestContext = $this->requestContext; + + // Retrieving the appropriate SiteAccess to generate the link for. + if ( isset( $parameters['siteaccess'] ) ) + { + $siteAccess = $this->siteAccessRouter->matchByName( $parameters['siteaccess'] ); + if ( $siteAccess instanceof SiteAccess && $siteAccess->matcher instanceof SiteAccess\VersatileMatcher ) + { + $requestContext = $this->getContextBySimplifiedRequest( $siteAccess->matcher->getRequest() ); + } + else if ( $this->logger ) + { + $siteAccess = $this->siteAccess; + $this->logger->notice( "Could not generate a link using provided 'siteaccess' parameter: {$parameters['siteaccess']}. Generating using current context." ); + } + + unset( $parameters['siteaccess'] ); + } + + $url = $requestContext->getBaseUrl() . $this->doGenerate( $urlResource, $parameters ); + + // Add the SiteAccess URI back if needed. + if ( $siteAccess && $siteAccess->matcher instanceof SiteAccess\URILexer ) + { + $url = $siteAccess->matcher->analyseLink( $url ); + } + if ( $absolute ) { - $url = $this->generateAbsoluteUrl( $url ); + $url = $this->generateAbsoluteUrl( $url, $requestContext ); } return $url; @@ -94,22 +134,56 @@ abstract public function doGenerate( $urlResource, array $parameters ); * Generates an absolute URL from $uri and the request context * * @param string $uri + * @param \Symfony\Component\Routing\RequestContext $requestContext * * @return string */ - protected function generateAbsoluteUrl( $uri ) + protected function generateAbsoluteUrl( $uri, RequestContext $requestContext ) { - $scheme = $this->requestContext->getScheme(); + $scheme = $requestContext->getScheme(); $port = ''; - if ( $scheme === 'http' && $this->requestContext->getHttpPort() != 80 ) + if ( $scheme === 'http' && $requestContext->getHttpPort() != 80 ) + { + $port = ':' . $requestContext->getHttpPort(); + } + else if ( $scheme === 'https' && $requestContext->getHttpsPort() != 443 ) + { + $port = ':' . $requestContext->getHttpsPort(); + } + + return $scheme . '://' . $requestContext->getHost() . $port . $uri; + } + + /** + * Merges context from $simplifiedRequest into a clone of the current context. + * + * @param SimplifiedRequest $simplifiedRequest + * + * @return RequestContext + */ + private function getContextBySimplifiedRequest( SimplifiedRequest $simplifiedRequest ) + { + $context = clone $this->requestContext; + if ( $simplifiedRequest->scheme ) + { + $context->setScheme( $simplifiedRequest->scheme ); + } + + if ( $simplifiedRequest->port ) { - $port = ':' . $this->requestContext->getHttpPort(); + $context->setHttpPort( $simplifiedRequest->port ); } - else if ( $scheme === 'https' && $this->requestContext->getHttpsPort() != 443 ) + + if ( $simplifiedRequest->host ) + { + $context->setHost( $simplifiedRequest->host ); + } + + if ( $simplifiedRequest->pathinfo ) { - $port = ':' . $this->requestContext->getHttpsPort(); + $context->setPathInfo( $simplifiedRequest->pathinfo ); } - return $scheme . '://' . $this->requestContext->getHost() . $port . $uri; + return $context; } } diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/Tests/GeneratorTest.php b/eZ/Publish/Core/MVC/Symfony/Routing/Tests/GeneratorTest.php new file mode 100644 index 00000000000..077056df013 --- /dev/null +++ b/eZ/Publish/Core/MVC/Symfony/Routing/Tests/GeneratorTest.php @@ -0,0 +1,135 @@ +siteAccessRouter = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface' ); + $this->logger = $this->getMock( 'Psr\\Log\\LoggerInterface' ); + $this->generator = $this->getMockForAbstractClass( 'eZ\Publish\Core\MVC\Symfony\Routing\Generator' ); + $this->generator->setSiteAccessRouter( $this->siteAccessRouter ); + $this->generator->setLogger( $this->logger ); + } + + public function generateProvider() + { + return array( + array( 'foo_bar', array(), false ), + array( 'foo_bar', array(), true ), + array( 'foo_bar', array( 'some' => 'thing' ), true ), + array( new Location(), array(), false ), + array( new Location(), array(), true ), + array( new Location(), array( 'some' => 'thing' ), true ), + array( new \stdClass(), array(), false ), + array( new \stdClass(), array(), true ), + array( new \stdClass(), array( 'some' => 'thing' ), true ), + ); + } + + /** + * @dataProvider generateProvider + */ + public function testSimpleGenerate( $urlResource, array $parameters, $absolute ) + { + $matcher = $this->getMock( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess\\URILexer' ); + $this->generator->setSiteAccess( new SiteAccess( 'test', 'fake', $matcher ) ); + + $baseUrl = '/base/url'; + $requestContext = new RequestContext( $baseUrl ); + $this->generator->setRequestContext( $requestContext ); + + $uri = '/some/thing'; + $this->generator + ->expects( $this->once() ) + ->method( 'doGenerate' ) + ->with( $urlResource, $parameters ) + ->will( $this->returnValue( $uri ) ); + + $fullUri = $baseUrl . $uri; + $matcher + ->expects( $this->once() ) + ->method( 'analyseLink' ) + ->with( $fullUri ) + ->will( $this->returnValue( $fullUri ) ); + + if ( $absolute ) + { + $fullUri = $requestContext->getScheme() . '://' . $requestContext->getHost() . $baseUrl . $uri; + } + + $this->assertSame( $fullUri, $this->generator->generate( $urlResource, $parameters, $absolute ) ); + } + + /** + * @dataProvider generateProvider + */ + public function testGenerateWithSiteAccessNoReverseMatch( $urlResource, array $parameters, $absolute ) + { + $matcher = $this->getMock( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess\\URILexer' ); + $this->generator->setSiteAccess( new SiteAccess( 'test', 'test', $matcher ) ); + + $baseUrl = '/base/url'; + $requestContext = new RequestContext( $baseUrl ); + $this->generator->setRequestContext( $requestContext ); + + $uri = '/some/thing'; + $this->generator + ->expects( $this->once() ) + ->method( 'doGenerate' ) + ->with( $urlResource, $parameters ) + ->will( $this->returnValue( $uri ) ); + + $fullUri = $baseUrl . $uri; + $matcher + ->expects( $this->once() ) + ->method( 'analyseLink' ) + ->with( $fullUri ) + ->will( $this->returnValue( $fullUri ) ); + + if ( $absolute ) + { + $fullUri = $requestContext->getScheme() . '://' . $requestContext->getHost() . $baseUrl . $uri; + } + + $siteAccessName = 'fake'; + $this->siteAccessRouter + ->expects( $this->once() ) + ->method( 'matchByName' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( null ) ); + $this->logger + ->expects( $this->once() ) + ->method( 'notice' ); + $this->assertSame( $fullUri, $this->generator->generate( $urlResource, $parameters + array( 'siteaccess' => $siteAccessName ), $absolute ) ); + } +} diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php b/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php index 55a916d5472..69a33c1bf4a 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/Tests/UrlAliasGeneratorTest.php @@ -47,11 +47,17 @@ class UrlAliasGeneratorTest extends PHPUnit_Framework_TestCase */ private $urlAliasGenerator; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $siteAccessRouter; + protected function setUp() { parent::setUp(); $this->router = $this->getMock( 'Symfony\\Component\\Routing\\RouterInterface' ); $this->logger = $this->getMock( 'Psr\\Log\\LoggerInterface' ); + $this->siteAccessRouter = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface' ); $repositoryClass = 'eZ\\Publish\\Core\\Repository\\Repository'; $this->repository = $repository = $this ->getMockBuilder( $repositoryClass ) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php index e014bd69203..33542bd3c73 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php @@ -79,6 +79,11 @@ class Router implements SiteAccessRouterInterface, SiteAccessAware */ protected $matcherBuilder; + /** + * @var \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest + */ + protected $request; + /** * Constructor. * @@ -97,6 +102,15 @@ public function __construct( MatcherBuilderInterface $matcherBuilder, LoggerInte $this->siteAccessesConfiguration = $siteAccessesConfiguration; $this->siteAccessList = array_fill_keys( $siteAccessList, true ); $this->siteAccessClass = $siteAccessClass ?: 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess'; + $this->request = new SimplifiedRequest(); + } + + /** + * @return \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest + */ + public function getRequest() + { + return $this->request; } /** @@ -110,6 +124,8 @@ public function __construct( MatcherBuilderInterface $matcherBuilder, LoggerInte */ public function match( SimplifiedRequest $request ) { + $this->request = $request; + if ( isset( $this->siteAccess ) ) return $this->siteAccess; @@ -184,6 +200,57 @@ private function doMatch( SimplifiedRequest $request ) return $this->siteAccess; } + /** + * Matches a SiteAccess by name. + * Returns corresponding SiteAccess object, according to configuration, with corresponding matcher. + * Returns null if no matcher can be found (e.g. non versatile). + * + * @param string $siteAccessName + * + * @throws \InvalidArgumentException If $siteAccessName is invalid (i.e. not present in configured list). + * + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess|null + */ + public function matchByName( $siteAccessName ) + { + if ( !isset( $this->siteAccessList[$siteAccessName] ) ) + { + throw new InvalidArgumentException( "Invalid SiteAccess name provided for reverse matching: $siteAccessName" ); + } + + foreach ( $this->siteAccessesConfiguration as $matchingClass => $matchingConfiguration ) + { + $matcher = $this->matcherBuilder->buildMatcher( $matchingClass, $matchingConfiguration, $this->request ); + if ( !$matcher instanceof VersatileMatcher ) + { + continue; + } + + if ( $matcher instanceof CompoundInterface ) + { + $matcher->setMatcherBuilder( $this->matcherBuilder ); + } + + $reverseMatcher = $matcher->reverseMatch( $siteAccessName ); + if ( !$reverseMatcher instanceof Matcher ) + { + continue; + } + + $siteAccessClass = $this->siteAccessClass; + /** @var \eZ\Publish\Core\MVC\Symfony\SiteAccess $siteAccess */ + $siteAccess = new $siteAccessClass(); + $siteAccess->name = $siteAccessName; + $siteAccess->matcher = $reverseMatcher; + $siteAccess->matchingType = $reverseMatcher->getName(); + return $siteAccess; + } + + // No VersatileMatcher configured for $siteAccessName. + $this->logger->notice( "Siteaccess '$siteAccessName' could not be reverse-matched against configuration. No VersatileMatcher found." ); + return null; + } + /** * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess|null */ diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php index 0322f5aa9bb..67716989942 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/SiteAccessRouterInterface.php @@ -23,4 +23,17 @@ interface SiteAccessRouterInterface * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess */ public function match( SimplifiedRequest $request ); + + /** + * Matches a SiteAccess by name. + * Returns corresponding SiteAccess object, according to configuration, with corresponding matcher. + * If no matcher can be found (e.g. non versatile), matcher property will be "default". + * + * @param string $siteAccessName + * + * @throws \InvalidArgumentException If $siteAccessName is invalid (i.e. not present in configured list). + * + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess + */ + public function matchByName( $siteAccessName ); } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php index 634f30a3f9d..0cc9babad62 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php @@ -81,7 +81,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -96,7 +96,7 @@ public function testMatch( $request, $siteAccess, $router ) * @depends testConstruct * @expectedException \eZ\Publish\Core\MVC\Exception\InvalidSiteAccessException */ - public function testMatchWithEnvFail( $router ) + public function testMatchWithEnvFail( Router $router ) { $saName = 'foobar_sa'; putenv( "EZPUBLISH_SITEACCESS=$saName" ); @@ -106,7 +106,7 @@ public function testMatchWithEnvFail( $router ) /** * @depends testConstruct */ - public function testMatchWithEnv( $router ) + public function testMatchWithEnv( Router $router ) { $saName = 'first_sa'; putenv( "EZPUBLISH_SITEACCESS=$saName" ); @@ -122,7 +122,7 @@ public function testMatchWithEnv( $router ) * * @depends testConstruct */ - public function testMatchWithRequestHeader( $router ) + public function testMatchWithRequestHeader( Router $router ) { $saName = 'headerbased_sa'; $request = Request::create( '/foo/bar' ); @@ -203,4 +203,84 @@ public function matchProvider() array( SimplifiedRequest::fromUrl( 'http://us.ezpublish.dev/fre' ), 'fr_us' ), ); } + + /** + * @expectedException \InvalidArgumentException + */ + public function testMatchByNameInvalidSiteAccess() + { + $matcherBuilder = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\MatcherBuilderInterface' ); + $logger = $this->getMock( 'Psr\Log\LoggerInterface' ); + $router = new Router( $matcherBuilder, $logger, 'default_sa', array(), array( 'foo', 'default_sa' ) ); + $router->matchByName( 'bar' ); + } + + public function testMatchByName() + { + $matcherBuilder = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\MatcherBuilderInterface' ); + $logger = $this->getMock( 'Psr\Log\LoggerInterface' ); + $matcherClass = 'Map\Host'; + $matchedSiteAccess = 'foo'; + $matcherConfig = array( + 'phoenix-rises.fm' => $matchedSiteAccess, + ); + $config = array( + $matcherClass => $matcherConfig, + 'Map\URI' => array( 'default' => 'default_sa' ) + ); + + $router = new Router( $matcherBuilder, $logger, 'default_sa', $config, array( $matchedSiteAccess, 'default_sa' ) ); + $request = $router->getRequest(); + $matcher = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcherBuilder + ->expects( $this->once() ) + ->method( 'buildMatcher' ) + ->with( $matcherClass, $matcherConfig, $request ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', array( 'default' => 'default_sa' ), $request, $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ) ), + array( $matcherClass, $matcherConfig, $request, $matcher ), + ) + ) + ); + + $reverseMatchedMatcher = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $matchedSiteAccess ) + ->will( $this->returnValue( $reverseMatchedMatcher ) ); + + $siteAccess = $router->matchByName( $matchedSiteAccess ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess', $siteAccess ); + $this->assertSame( $reverseMatchedMatcher, $siteAccess->matcher ); + $this->assertSame( $matchedSiteAccess, $siteAccess->name ); + } + + public function testMatchByNameNoVersatileMatcher() + { + $matcherBuilder = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\MatcherBuilderInterface' ); + $logger = $this->getMock( 'Psr\Log\LoggerInterface' ); + $matcherClass = 'Map\Host'; + $matchedSiteAccess = 'foo'; + $matcherConfig = array( + 'phoenix-rises.fm' => $matchedSiteAccess, + 'ez.no' => 'default_sa', + ); + $config = array( $matcherClass => $matcherConfig ); + + $router = new Router( $matcherBuilder, $logger, 'default_sa', $config, array( $matchedSiteAccess, 'default_sa' ) ); + $request = $router->getRequest(); + $matcherBuilder + ->expects( $this->once() ) + ->method( 'buildMatcher' ) + ->with( $matcherClass, $matcherConfig, $request ) + ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ) ) ); + + $logger + ->expects( $this->once() ) + ->method( 'notice' ); + $this->assertNull( $router->matchByName( $matchedSiteAccess ) ); + } } From ee355f7de887542a442fba619caee2d386758054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Thu, 3 Apr 2014 11:06:03 +0200 Subject: [PATCH 11/23] Removed @return void in SiteAccess matchers --- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php | 2 -- eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php | 2 -- 9 files changed, 18 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher.php index 4537e361931..1b3d222a801 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher.php @@ -20,8 +20,6 @@ interface Matcher * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php index 0686e2cb564..dda19576ea8 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php @@ -57,8 +57,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php index ae427874de8..f4cb9d80293 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php @@ -40,8 +40,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php index 3f5d14003a6..3e55004b219 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php @@ -24,8 +24,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php index dc87ed7b57b..ad96e5a5383 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php @@ -24,8 +24,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php index d82d6a873b9..04cee24dc66 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php @@ -19,8 +19,6 @@ class URI extends Map implements URILexer * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php index 1cf913fdff2..8b2603c2696 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php @@ -37,8 +37,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php index 00e3a042d44..73d2de7c1e4 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php @@ -37,8 +37,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php index 418241f85ed..4edaed09a89 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php @@ -39,8 +39,6 @@ public function getName() * Injects the request object to match against. * * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request - * - * @return void */ public function setRequest( SimplifiedRequest $request ) { From 38883350c02c95cca7e1926ec05a3e06ac0fe9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Thu, 3 Apr 2014 15:34:28 +0200 Subject: [PATCH 12/23] EZP-20305: Fixed phpDoc in Compound siteaccess abstract matcher --- .../Core/MVC/Symfony/SiteAccess/Matcher/Compound.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php index 331c9e82b40..d76f8cdeba3 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php @@ -26,7 +26,10 @@ abstract class Compound implements CompoundInterface, URILexer protected $config; /** - * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher[] + * Matchers map. + * Consists of an array of matchers, grouped by ruleset (so array of array of matchers). + * + * @var array */ protected $matchersMap = array(); @@ -94,11 +97,6 @@ public function analyseLink( $linkUri ) return $linkUri; } - /** - * Returns all used sub-matchers. - * - * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher[] - */ public function getSubMatchers() { return $this->subMatchers; From ac43b86923a9aa762b189d38c72d51606f34ba52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Thu, 3 Apr 2014 15:37:12 +0200 Subject: [PATCH 13/23] EZP-20305: Ensure match element is not modified each time a SiteAccess matcher gets a request --- .../Symfony/SiteAccess/Matcher/HostText.php | 7 ++++- .../Symfony/SiteAccess/Matcher/Map/Host.php | 6 +++- .../Symfony/SiteAccess/Matcher/Map/Port.php | 30 +++++++++++-------- .../Symfony/SiteAccess/Matcher/Map/URI.php | 8 +++-- .../MVC/Symfony/SiteAccess/Matcher/Regex.php | 22 ++++++++++++-- .../Symfony/SiteAccess/Matcher/Regex/Host.php | 7 ++++- .../Symfony/SiteAccess/Matcher/Regex/URI.php | 7 ++++- .../Symfony/SiteAccess/Matcher/URIText.php | 7 ++++- 8 files changed, 71 insertions(+), 23 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php index f4cb9d80293..97d0edbab20 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php @@ -43,6 +43,11 @@ public function getName() */ public function setRequest( SimplifiedRequest $request ) { - $this->setMatchElement( $request->host ); + if ( !$this->element ) + { + $this->setMatchElement( $request->host ); + } + + parent::setRequest( $request ); } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php index 3e55004b219..0885e5e700c 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Host.php @@ -27,7 +27,11 @@ public function getName() */ public function setRequest( SimplifiedRequest $request ) { - $this->setMapKey( $request->host ); + if ( !$this->key ) + { + $this->setMapKey( $request->host ); + } + parent::setRequest( $request ); } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php index ad96e5a5383..a0ae3f5e4f7 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/Port.php @@ -27,25 +27,29 @@ public function getName() */ public function setRequest( SimplifiedRequest $request ) { - if ( !empty( $request->port ) ) + if ( !$this->key ) { - $key = $request->port; - } - else - { - switch ( $request->scheme ) + if ( !empty( $request->port ) ) { - case "https": - $key = 443; - break; + $key = $request->port; + } + else + { + switch ( $request->scheme ) + { + case "https": + $key = 443; + break; - case "http": - default: - $key = 80; + case "http": + default: + $key = 80; + } } + + $this->setMapKey( $key ); } - $this->setMapKey( $key ); parent::setRequest( $request ); } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php index 04cee24dc66..833ee48d58d 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php @@ -22,8 +22,12 @@ class URI extends Map implements URILexer */ public function setRequest( SimplifiedRequest $request ) { - sscanf( $request->pathinfo, "/%[^/]", $key ); - $this->setMapKey( $key ); + if ( !$this->key ) + { + sscanf( $request->pathinfo, "/%[^/]", $key ); + $this->setMapKey( $key ); + } + parent::setRequest( $request ); } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex.php index 4ab5f2f37ca..c4dc1421145 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex.php @@ -9,6 +9,7 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; +use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; abstract class Regex implements Matcher @@ -18,21 +19,26 @@ abstract class Regex implements Matcher * * @var string */ - private $element; + protected $element; /** * Regular expression used for matching. * * @var string */ - private $regex; + protected $regex; /** * Item number to pick in regex. * * @var string */ - private $itemNumber; + protected $itemNumber; + + /** + * @var \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest + */ + protected $request; /** * Constructor. @@ -62,6 +68,16 @@ public function match() return isset( $match[$this->itemNumber] ) ? $match[$this->itemNumber] : false; } + /** + * Injects the request object to match against. + * + * @param \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest $request + */ + public function setRequest( SimplifiedRequest $request ) + { + $this->request = $request; + } + /** * Injects element to match against with the regexp * diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php index 8b2603c2696..5fed9e52f52 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php @@ -40,6 +40,11 @@ public function getName() */ public function setRequest( SimplifiedRequest $request ) { - $this->setMatchElement( $request->host ); + if ( !$this->element ) + { + $this->setMatchElement( $request->host ); + } + + parent::setRequest( $request ); } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php index 73d2de7c1e4..5077b7bcb3d 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php @@ -40,6 +40,11 @@ public function getName() */ public function setRequest( SimplifiedRequest $request ) { - $this->setMatchElement( $request->pathinfo ); + if ( !$this->element ) + { + $this->setMatchElement( $request->pathinfo ); + } + + parent::setRequest( $request ); } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php index 4edaed09a89..a629668f04f 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php @@ -42,6 +42,11 @@ public function getName() */ public function setRequest( SimplifiedRequest $request ) { - $this->setMatchElement( $request->pathinfo ); + if ( !$this->element ) + { + $this->setMatchElement( $request->pathinfo ); + } + + parent::setRequest( $request ); } } From d6b37004066972ed7eab9e0e813fb556e1acaddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Thu, 3 Apr 2014 15:39:34 +0200 Subject: [PATCH 14/23] EZP-20305: Made Compound\LogicalAnd matcher implement VersatileMatcher --- .../Symfony/SiteAccess/Matcher/Compound.php | 32 +++ .../Matcher/Compound/LogicalAnd.php | 34 ++- .../SiteAccess/Matcher/CompoundInterface.php | 10 +- .../Tests/Compound/CompoundAndTest.php | 221 ++++++++++++++++++ 4 files changed, 295 insertions(+), 2 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php index d76f8cdeba3..caf7d32535a 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php @@ -69,6 +69,18 @@ public function setMatcherBuilder( MatcherBuilderInterface $matcherBuilder ) public function setRequest( SimplifiedRequest $request ) { $this->request = $request; + foreach ( $this->matchersMap as $ruleset ) + { + foreach ( $ruleset as $matcher ) + { + $matcher->setRequest( $request ); + } + } + } + + public function getRequest() + { + return $this->request; } public function analyseURI( $uri ) @@ -102,6 +114,11 @@ public function getSubMatchers() return $this->subMatchers; } + public function setSubMatchers( array $subMatchers ) + { + $this->subMatchers = $subMatchers; + } + /** * Returns the matcher's name. * This information will be stored in the SiteAccess object itself to quickly be able to identify the matcher type. @@ -129,4 +146,19 @@ public function __sleep() // We don't need the whole matcher map and the matcher builder once serialized. return array( 'config', 'subMatchers', 'request' ); } + + public function __clone() + { + $this->request = clone $this->request; + if ( $this->subMatchers ) + { + $clonedSubMatchers = array(); + foreach ( $this->subMatchers as $matcher ) + { + $clonedSubMatchers[] = clone $matcher; + } + + $this->subMatchers = $clonedSubMatchers; + } + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php index 4dd2867305f..2550dfb484f 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php @@ -10,11 +10,12 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; /** * Siteaccess matcher that allows a combination of matchers, with a logical AND */ -class LogicalAnd extends Compound +class LogicalAnd extends Compound implements VersatileMatcher { const NAME = 'logicalAnd'; @@ -37,4 +38,35 @@ public function match() return false; } + + public function reverseMatch( $siteAccessName ) + { + foreach ( $this->config as $i => $rule ) + { + if ( $rule['match'] === $siteAccessName ) + { + $matcher = clone $this; + $subMatchers = array(); + foreach ( $this->matchersMap[$i] as $subMatcher ) + { + if ( !$subMatcher instanceof VersatileMatcher ) + { + return null; + } + + $subMatcher->setRequest( $matcher->getRequest() ); + $reverseMatcher = $subMatcher->reverseMatch( $siteAccessName ); + if ( !$reverseMatcher ) + { + return null; + } + + $subMatchers[] = $subMatcher; + } + + $matcher->setSubMatchers( $subMatchers ); + return $matcher; + } + } + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/CompoundInterface.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/CompoundInterface.php index 628214a36ab..9e0150cbe43 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/CompoundInterface.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/CompoundInterface.php @@ -11,8 +11,9 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; use eZ\Publish\Core\MVC\Symfony\SiteAccess\MatcherBuilderInterface; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; -interface CompoundInterface extends Matcher +interface CompoundInterface extends VersatileMatcher { /** * Injects the matcher builder, to allow the Compound matcher to properly build the underlying matchers. @@ -27,4 +28,11 @@ public function setMatcherBuilder( MatcherBuilderInterface $matcherBuilder ); * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher[] */ public function getSubMatchers(); + + /** + * Replaces sub-matchers + * + * @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher[] $subMatchers + */ + public function setSubMatchers( array $subMatchers ); } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php index e4eab87c13f..b8b874cb6dd 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php @@ -103,6 +103,42 @@ public function testMatch( SimplifiedRequest $request, $expectedMatch ) $this->assertSame( $expectedMatch, $compoundMatcher->match() ); } + public function testSetRequest() + { + $compoundMatcher = new LogicalAnd( + array( + array( + 'matchers' => array( + 'Map\\URI' => array( 'eng' => true ), + 'Map\\Host' => array( 'fr.ezpublish.dev' => true ) + ), + 'match' => 'fr_eng' + ), + ) + ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( $this->onConsecutiveCalls( $matcher1, $matcher2 ) ); + + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher2 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + + $compoundMatcher->setRequest( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ) ); + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $compoundMatcher->setRequest( $request ); + } + public function matchProvider() { return array( @@ -116,4 +152,189 @@ public function matchProvider() array( SimplifiedRequest::fromUrl( 'http://jp.ezpublish.dev/de' ), 'de_jp' ), ); } + + public function testReverseMatchSiteAccessNotConfigured() + { + $compoundMatcher = $this->buildMatcher(); + $this->matcherBuilder + ->expects( $this->any() ) + ->method( 'buildMatcher' ) + ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ) ) ); + + $compoundMatcher->setRequest( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ) ); + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $this->assertNull( $compoundMatcher->reverseMatch( 'not_configured_sa' ) ); + } + + public function testReverseMatchNotVersatile() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalAnd( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher1 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ) ) ); + $matcher2 + ->expects( $this->never() ) + ->method( 'setRequest' ); + $matcher2 + ->expects( $this->never() ) + ->method( 'reverseMatch' ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $this->assertNull( $compoundMatcher->reverseMatch( $siteAccessName ) ); + } + + public function testReverseMatchFail() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalAnd( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher1 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ) ) ); + $matcher2 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher2 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( null ) ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $this->assertNull( $compoundMatcher->reverseMatch( $siteAccessName ) ); + } + + public function testReverseMatch() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalAnd( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $reverseMatchedMatcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher1 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( $reverseMatchedMatcher1 ) ); + $matcher2 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $reverseMatchedMatcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( $reverseMatchedMatcher2 ) ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $result = $compoundMatcher->reverseMatch( $siteAccessName ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalAnd', $result ); + foreach ( $result->getSubMatchers() as $subMatcher ) + { + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher', $subMatcher ); + } + } } From 19cf4a2f5a21925930fa3cd5e4a44edb56a50914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Thu, 3 Apr 2014 16:13:29 +0200 Subject: [PATCH 15/23] EZP-20305: Made Compound\LogicalOr matcher implement VersatileMatcher --- .../SiteAccess/Matcher/Compound/LogicalOr.php | 29 +++ .../Tests/Compound/CompoundOrTest.php | 240 ++++++++++++++++++ 2 files changed, 269 insertions(+) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php index ae52e29ef11..90f15aa15c2 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php @@ -10,6 +10,7 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; /** * Siteaccess matcher that allows a combination of matchers, with a logical OR @@ -34,4 +35,32 @@ public function match() return false; } + + public function reverseMatch( $siteAccessName ) + { + foreach ( $this->config as $i => $rule ) + { + if ( $rule['match'] === $siteAccessName ) + { + $matcher = clone $this; + foreach ( $this->matchersMap[$i] as $subMatcher ) + { + if ( !$subMatcher instanceof VersatileMatcher ) + { + continue; + } + + $subMatcher->setRequest( $matcher->getRequest() ); + $reverseMatcher = $subMatcher->reverseMatch( $siteAccessName ); + if ( !$reverseMatcher ) + { + continue; + } + + $matcher->setSubMatchers( array( $subMatcher ) ); + return $matcher; + } + } + } + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php index 03c60cdef0b..026491eebda 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php @@ -109,4 +109,244 @@ public function matchProvider() array( SimplifiedRequest::fromUrl( 'http://ezpublish.dev/fr' ), false ), ); } + + public function testReverseMatchSiteAccessNotConfigured() + { + $compoundMatcher = $this->buildMatcher(); + $this->matcherBuilder + ->expects( $this->any() ) + ->method( 'buildMatcher' ) + ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ) ) ); + + $compoundMatcher->setRequest( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ) ); + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $this->assertNull( $compoundMatcher->reverseMatch( 'not_configured_sa' ) ); + } + + public function testReverseMatchNotVersatile() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalOr( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->never() ) + ->method( 'setRequest' ); + $matcher1 + ->expects( $this->never() ) + ->method( 'reverseMatch' ); + $matcher2 + ->expects( $this->never() ) + ->method( 'setRequest' ); + $matcher2 + ->expects( $this->never() ) + ->method( 'reverseMatch' ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $this->assertNull( $compoundMatcher->reverseMatch( $siteAccessName ) ); + } + + public function testReverseMatchFail() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalOr( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher1 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( null ) ); + $matcher2 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher2 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( null ) ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $this->assertNull( $compoundMatcher->reverseMatch( $siteAccessName ) ); + } + + public function testReverseMatch1() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalOr( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $reverseMatchedMatcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher1 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( $reverseMatchedMatcher1 ) ); + $matcher2 + ->expects( $this->never() ) + ->method( 'setRequest' ); + $matcher2 + ->expects( $this->never() ) + ->method( 'reverseMatch' ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $result = $compoundMatcher->reverseMatch( $siteAccessName ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalOr', $result ); + foreach ( $result->getSubMatchers() as $subMatcher ) + { + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher', $subMatcher ); + } + } + + public function testReverseMatch2() + { + $request = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest' ); + $siteAccessName = 'fr_eng'; + $mapUriConfig = array( 'eng' => true ); + $mapHostConfig = array( 'fr.ezpublish.dev' => true ); + $compoundMatcher = new LogicalOr( + array( + array( + 'matchers' => array( + 'Map\URI' => $mapUriConfig, + 'Map\Host' => $mapHostConfig + ), + 'match' => $siteAccessName + ), + ) + ); + $compoundMatcher->setRequest( $request ); + + $matcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $this->matcherBuilder + ->expects( $this->exactly( 2 ) ) + ->method( 'buildMatcher' ) + ->will( + $this->returnValueMap( + array( + array( 'Map\URI', $mapUriConfig, $request, $matcher1 ), + array( 'Map\Host', $mapHostConfig, $request, $matcher2 ), + ) + ) + ); + + $matcher1 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $matcher1 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( null ) ); + $matcher2 + ->expects( $this->once() ) + ->method( 'setRequest' ) + ->with( $request ); + $reverseMatchedMatcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $matcher2 + ->expects( $this->once() ) + ->method( 'reverseMatch' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( $reverseMatchedMatcher2 ) ); + + $compoundMatcher->setMatcherBuilder( $this->matcherBuilder ); + $result = $compoundMatcher->reverseMatch( $siteAccessName ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Compound\LogicalOr', $result ); + foreach ( $result->getSubMatchers() as $subMatcher ) + { + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher', $subMatcher ); + } + } } From 77e6a9f86c789bec482a14bc99175398bbd277e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Thu, 10 Apr 2014 17:25:44 +0200 Subject: [PATCH 16/23] EZP-20305: Removed matcher cloning --- .../Symfony/SiteAccess/Matcher/Compound.php | 15 ---------- .../Matcher/Compound/LogicalAnd.php | 6 ++-- .../SiteAccess/Matcher/Compound/LogicalOr.php | 6 ++-- .../SiteAccess/Matcher/HostElement.php | 26 ++--------------- .../MVC/Symfony/SiteAccess/Matcher/Map.php | 11 ++----- .../Symfony/SiteAccess/Matcher/Map/URI.php | 4 +-- .../Symfony/SiteAccess/Matcher/URIElement.php | 13 ++------- .../Core/MVC/Symfony/SiteAccess/Router.php | 3 +- .../Tests/Compound/CompoundAndTest.php | 23 --------------- .../Tests/Compound/CompoundOrTest.php | 29 ------------------- .../Symfony/SiteAccess/Tests/RouterTest.php | 14 ++++----- .../Symfony/SiteAccess/VersatileMatcher.php | 2 +- 12 files changed, 22 insertions(+), 130 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php index caf7d32535a..dd4a1f9f4f4 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound.php @@ -146,19 +146,4 @@ public function __sleep() // We don't need the whole matcher map and the matcher builder once serialized. return array( 'config', 'subMatchers', 'request' ); } - - public function __clone() - { - $this->request = clone $this->request; - if ( $this->subMatchers ) - { - $clonedSubMatchers = array(); - foreach ( $this->subMatchers as $matcher ) - { - $clonedSubMatchers[] = clone $matcher; - } - - $this->subMatchers = $clonedSubMatchers; - } - } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php index 2550dfb484f..0bce51a8003 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalAnd.php @@ -45,7 +45,6 @@ public function reverseMatch( $siteAccessName ) { if ( $rule['match'] === $siteAccessName ) { - $matcher = clone $this; $subMatchers = array(); foreach ( $this->matchersMap[$i] as $subMatcher ) { @@ -54,7 +53,6 @@ public function reverseMatch( $siteAccessName ) return null; } - $subMatcher->setRequest( $matcher->getRequest() ); $reverseMatcher = $subMatcher->reverseMatch( $siteAccessName ); if ( !$reverseMatcher ) { @@ -64,8 +62,8 @@ public function reverseMatch( $siteAccessName ) $subMatchers[] = $subMatcher; } - $matcher->setSubMatchers( $subMatchers ); - return $matcher; + $this->setSubMatchers( $subMatchers ); + return $this; } } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php index 90f15aa15c2..2ba8060d5fb 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Compound/LogicalOr.php @@ -42,7 +42,6 @@ public function reverseMatch( $siteAccessName ) { if ( $rule['match'] === $siteAccessName ) { - $matcher = clone $this; foreach ( $this->matchersMap[$i] as $subMatcher ) { if ( !$subMatcher instanceof VersatileMatcher ) @@ -50,15 +49,14 @@ public function reverseMatch( $siteAccessName ) continue; } - $subMatcher->setRequest( $matcher->getRequest() ); $reverseMatcher = $subMatcher->reverseMatch( $siteAccessName ); if ( !$reverseMatcher ) { continue; } - $matcher->setSubMatchers( array( $subMatcher ) ); - return $matcher; + $this->setSubMatchers( array( $subMatcher ) ); + return $this; } } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php index dda19576ea8..1aab5ca9325 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostElement.php @@ -63,27 +63,14 @@ public function setRequest( SimplifiedRequest $request ) $this->request = $request; } - /** - * @return \eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest - */ public function getRequest() { return $this->request; } - /** - * Returns matcher object corresponding to $siteAccessName or null if non applicable. - * - * @note Limitation: Will only work correctly if HostElement is used for all siteaccesses, as host cannot be guessed. - * - * @param string $siteAccessName - * - * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostElement|null Typically a clone of current matcher, with appropriate config. - */ public function reverseMatch( $siteAccessName ) { - $request = clone $this->request; - $hostElements = explode( '.', $request->host ); + $hostElements = explode( '.', $this->request->host ); $elementNumber = $this->elementNumber - 1; if ( !isset( $hostElements[$elementNumber] ) ) { @@ -91,14 +78,7 @@ public function reverseMatch( $siteAccessName ) } $hostElements[$elementNumber] = $siteAccessName; - $matcher = clone $this; - $matcher->getRequest()->setHost( implode( '.', $hostElements ) ); - - return $matcher; - } - - public function __clone() - { - $this->request = clone $this->request; + $this->request->setHost( implode( '.', $hostElements ) ); + return $this; } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php index be1a20c4d60..e8140f42210 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php @@ -112,14 +112,7 @@ public function reverseMatch( $siteAccessName ) return null; } - $mapKey = $this->reverseMap[$siteAccessName]; - $matcher = clone $this; - $matcher->setMapKey( $mapKey ); - return $matcher; - } - - public function __clone() - { - $this->request = clone $this->request; + $this->setMapKey( $this->reverseMap[$siteAccessName] ); + return $this; } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php index 833ee48d58d..39328a80abc 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php @@ -74,13 +74,13 @@ public function analyseLink( $linkUri ) public function reverseMatch( $siteAccessName ) { + $mapKey = $this->getMapKey(); $matcher = parent::reverseMatch( $siteAccessName ); if ( $matcher instanceof URI ) { $request = $matcher->getRequest(); // Clean up "old" siteaccess prefix and add the new prefix. - $cleanedUpPathinfo = $this->analyseURI( $request->pathinfo ); - $request->setPathinfo( $matcher->analyseLink( $cleanedUpPathinfo ) ); + $request->setPathinfo( str_replace( $mapKey, $this->reverseMap[$siteAccessName], $request->pathinfo ) ); } return $matcher; diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php index 46b4dbd15ff..5d92228861b 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php @@ -162,15 +162,8 @@ public function reverseMatch( $siteAccessName ) return null; } - $matcher = clone $this; - $request = $matcher->getRequest(); - $pathinfo = '/' . implode( '/', $elements ) . '/' . ltrim( $this->analyseURI( $request->pathinfo ), '/' ); - $request->setPathinfo( $pathinfo ); - return $matcher; - } - - public function __clone() - { - $this->request = clone $this->request; + $pathinfo = '/' . implode( '/', $elements ) . '/' . ltrim( $this->analyseURI( $this->request->pathinfo ), '/' ); + $this->request->setPathinfo( $pathinfo ); + return $this; } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php index 33542bd3c73..05cd7ae11f2 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php @@ -218,9 +218,10 @@ public function matchByName( $siteAccessName ) throw new InvalidArgumentException( "Invalid SiteAccess name provided for reverse matching: $siteAccessName" ); } + $request = clone $this->request; foreach ( $this->siteAccessesConfiguration as $matchingClass => $matchingConfiguration ) { - $matcher = $this->matcherBuilder->buildMatcher( $matchingClass, $matchingConfiguration, $this->request ); + $matcher = $this->matcherBuilder->buildMatcher( $matchingClass, $matchingConfiguration, $request ); if ( !$matcher instanceof VersatileMatcher ) { continue; diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php index b8b874cb6dd..dede7b431a4 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundAndTest.php @@ -199,18 +199,11 @@ public function testReverseMatchNotVersatile() ) ); - $matcher1 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $matcher1 ->expects( $this->once() ) ->method( 'reverseMatch' ) ->with( $siteAccessName ) ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ) ) ); - $matcher2 - ->expects( $this->never() ) - ->method( 'setRequest' ); $matcher2 ->expects( $this->never() ) ->method( 'reverseMatch' ); @@ -252,19 +245,11 @@ public function testReverseMatchFail() ) ); - $matcher1 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $matcher1 ->expects( $this->once() ) ->method( 'reverseMatch' ) ->with( $siteAccessName ) ->will( $this->returnValue( $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ) ) ); - $matcher2 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $matcher2 ->expects( $this->once() ) ->method( 'reverseMatch' ) @@ -308,20 +293,12 @@ public function testReverseMatch() ) ); - $matcher1 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $reverseMatchedMatcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); $matcher1 ->expects( $this->once() ) ->method( 'reverseMatch' ) ->with( $siteAccessName ) ->will( $this->returnValue( $reverseMatchedMatcher1 ) ); - $matcher2 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $reverseMatchedMatcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); $matcher2 ->expects( $this->once() ) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php index 026491eebda..c3d4fd72abc 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/Compound/CompoundOrTest.php @@ -156,15 +156,9 @@ public function testReverseMatchNotVersatile() ) ); - $matcher1 - ->expects( $this->never() ) - ->method( 'setRequest' ); $matcher1 ->expects( $this->never() ) ->method( 'reverseMatch' ); - $matcher2 - ->expects( $this->never() ) - ->method( 'setRequest' ); $matcher2 ->expects( $this->never() ) ->method( 'reverseMatch' ); @@ -206,19 +200,11 @@ public function testReverseMatchFail() ) ); - $matcher1 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $matcher1 ->expects( $this->once() ) ->method( 'reverseMatch' ) ->with( $siteAccessName ) ->will( $this->returnValue( null ) ); - $matcher2 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $matcher2 ->expects( $this->once() ) ->method( 'reverseMatch' ) @@ -262,19 +248,12 @@ public function testReverseMatch1() ) ); - $matcher1 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $reverseMatchedMatcher1 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); $matcher1 ->expects( $this->once() ) ->method( 'reverseMatch' ) ->with( $siteAccessName ) ->will( $this->returnValue( $reverseMatchedMatcher1 ) ); - $matcher2 - ->expects( $this->never() ) - ->method( 'setRequest' ); $matcher2 ->expects( $this->never() ) ->method( 'reverseMatch' ); @@ -321,19 +300,11 @@ public function testReverseMatch2() ) ); - $matcher1 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $matcher1 ->expects( $this->once() ) ->method( 'reverseMatch' ) ->with( $siteAccessName ) ->will( $this->returnValue( null ) ); - $matcher2 - ->expects( $this->once() ) - ->method( 'setRequest' ) - ->with( $request ); $reverseMatchedMatcher2 = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); $matcher2 ->expects( $this->once() ) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php index 0cc9babad62..eb66025c665 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php @@ -225,23 +225,19 @@ public function testMatchByName() 'phoenix-rises.fm' => $matchedSiteAccess, ); $config = array( + 'Map\URI' => array( 'default' => 'default_sa' ), $matcherClass => $matcherConfig, - 'Map\URI' => array( 'default' => 'default_sa' ) ); $router = new Router( $matcherBuilder, $logger, 'default_sa', $config, array( $matchedSiteAccess, 'default_sa' ) ); - $request = $router->getRequest(); $matcher = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); $matcherBuilder - ->expects( $this->once() ) + ->expects( $this->exactly( 2 ) ) ->method( 'buildMatcher' ) - ->with( $matcherClass, $matcherConfig, $request ) ->will( - $this->returnValueMap( - array( - array( 'Map\URI', array( 'default' => 'default_sa' ), $request, $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ) ), - array( $matcherClass, $matcherConfig, $request, $matcher ), - ) + $this->onConsecutiveCalls( + $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ), + $matcher ) ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php index 6c0b532d029..8295cd06e1a 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php @@ -22,7 +22,7 @@ interface VersatileMatcher extends Matcher * * @param string $siteAccessName * - * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher|null Typically a clone of current matcher, with appropriate config. + * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher|null Typically the current matcher, with updated request. */ public function reverseMatch( $siteAccessName ); From aac5a67c7bad542495f0a7913d4b07f2b80ee4e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 11 Apr 2014 11:43:07 +0200 Subject: [PATCH 17/23] EZP-20305: Simplified reverse map building in Map matchers --- .../MVC/Symfony/SiteAccess/Matcher/Map.php | 36 ++++++++++++------- .../Symfony/SiteAccess/Matcher/Map/URI.php | 2 +- .../Symfony/SiteAccess/Matcher/URIElement.php | 2 +- .../Core/MVC/Symfony/SiteAccess/Router.php | 6 ++++ .../SiteAccess/Tests/RouterMapURITest.php | 3 +- .../Symfony/SiteAccess/Tests/RouterTest.php | 8 +++++ .../Tests/RouterURIElement2Test.php | 2 +- .../SiteAccess/Tests/RouterURIElementTest.php | 2 +- .../Symfony/SiteAccess/VersatileMatcher.php | 2 ++ 9 files changed, 45 insertions(+), 18 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php index e8140f42210..a335e296ac0 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map.php @@ -47,17 +47,7 @@ abstract class Map implements VersatileMatcher */ public function __construct( array $map ) { - foreach ( $map as $mapKey => &$value ) - { - // $value can be true in the case of the use of a Compound matcher - if ( $value === true ) - { - $value = $mapKey; - } - } - $this->map = $map; - $this->reverseMap = array_flip( $map ); } public function setRequest( SimplifiedRequest $request ) @@ -107,12 +97,34 @@ public function match() */ public function reverseMatch( $siteAccessName ) { - if ( !isset( $this->reverseMap[$siteAccessName] ) ) + $reverseMap = $this->getReverseMap( $siteAccessName ); + + if ( !isset( $reverseMap[$siteAccessName] ) ) { return null; } - $this->setMapKey( $this->reverseMap[$siteAccessName] ); + $this->setMapKey( $reverseMap[$siteAccessName] ); return $this; } + + private function getReverseMap( $defaultSiteAccess ) + { + if ( !empty( $this->reverseMap ) ) + { + return $this->reverseMap; + } + + $map = $this->map; + foreach ( $map as &$value ) + { + // $value can be true in the case of the use of a Compound matcher + if ( $value === true ) + { + $value = $defaultSiteAccess; + } + } + + return $this->reverseMap = array_flip( $map ); + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php index 39328a80abc..abb477768f5 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Map/URI.php @@ -80,7 +80,7 @@ public function reverseMatch( $siteAccessName ) { $request = $matcher->getRequest(); // Clean up "old" siteaccess prefix and add the new prefix. - $request->setPathinfo( str_replace( $mapKey, $this->reverseMap[$siteAccessName], $request->pathinfo ) ); + $request->setPathinfo( $this->analyseLink( $request->pathinfo ) ); } return $matcher; diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php index 5d92228861b..45a47be6c8b 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIElement.php @@ -162,7 +162,7 @@ public function reverseMatch( $siteAccessName ) return null; } - $pathinfo = '/' . implode( '/', $elements ) . '/' . ltrim( $this->analyseURI( $this->request->pathinfo ), '/' ); + $pathinfo = '/' . implode( '/', $elements ) . '/' . ltrim( $this->request->pathinfo, '/' ); $this->request->setPathinfo( $pathinfo ); return $this; } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php index 05cd7ae11f2..b064ebdf9e9 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Router.php @@ -219,6 +219,12 @@ public function matchByName( $siteAccessName ) } $request = clone $this->request; + // Be sure to have a clean pathinfo, without SiteAccess part in it. + if ( $this->siteAccess->matcher instanceof URILexer ) + { + $request->setPathinfo( $this->siteAccess->matcher->analyseURI( $request->pathinfo ) ); + } + foreach ( $this->siteAccessesConfiguration as $matchingClass => $matchingConfiguration ) { $matcher = $this->matcherBuilder->buildMatcher( $matchingClass, $matchingConfiguration, $request ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php index 92d49fa9a8f..8cdffbda33c 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterMapURITest.php @@ -80,10 +80,9 @@ public function testReverseMatch() 'something_else' => 'another_siteaccess', 'toutouyoutou' => 'ezdemo_site', ); - $request = new SimplifiedRequest( array( 'pathinfo' => '/some_uri/foo' ) ); + $request = new SimplifiedRequest( array( 'pathinfo' => '/foo' ) ); $matcher = new URIMapMatcher( $config ); $matcher->setRequest( $request ); - $this->assertSame( 'some_uri', $matcher->getMapKey() ); $result = $matcher->reverseMatch( 'ezdemo_site' ); $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Map\URI', $result ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php index eb66025c665..f71e19be8d2 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterTest.php @@ -9,6 +9,7 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Tests; +use eZ\Publish\Core\MVC\Symfony\SiteAccess; use PHPUnit_Framework_TestCase; use eZ\Publish\Core\MVC\Symfony\SiteAccess\Router; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; @@ -230,6 +231,12 @@ public function testMatchByName() ); $router = new Router( $matcherBuilder, $logger, 'default_sa', $config, array( $matchedSiteAccess, 'default_sa' ) ); + $matcherInitialSA = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer' ); + $router->setSiteAccess( new SiteAccess( 'test', 'test', $matcherInitialSA ) ); + $matcherInitialSA + ->expects( $this->once() ) + ->method( 'analyseURI' ); + $matcher = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); $matcherBuilder ->expects( $this->exactly( 2 ) ) @@ -267,6 +274,7 @@ public function testMatchByNameNoVersatileMatcher() $config = array( $matcherClass => $matcherConfig ); $router = new Router( $matcherBuilder, $logger, 'default_sa', $config, array( $matchedSiteAccess, 'default_sa' ) ); + $router->setSiteAccess( new SiteAccess( 'test', 'test' ) ); $request = $router->getRequest(); $matcherBuilder ->expects( $this->once() ) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php index 26c32fdfecb..7edd98e5ded 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElement2Test.php @@ -169,7 +169,7 @@ public function testReverseMatch( $siteAccessName, $originalPathinfo ) { $expectedSiteAccessPath = implode( '/', explode( '_', $siteAccessName ) ); $matcher = new URIElementMatcher( 2 ); - $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => "/my/siteaccess{$originalPathinfo}" ) ) ); + $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => $originalPathinfo ) ) ); $result = $matcher->reverseMatch( $siteAccessName ); $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement', $result ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php index 40cc3865208..974996a71d9 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURIElementTest.php @@ -162,7 +162,7 @@ public function analyseProvider() public function testReverseMatch( $siteAccessName, $originalPathinfo ) { $matcher = new URIElementMatcher( 1 ); - $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => "/my_siteaccess{$originalPathinfo}" ) ) ); + $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => $originalPathinfo ) ) ); $result = $matcher->reverseMatch( $siteAccessName ); $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIElement', $result ); $this->assertSame( "/{$siteAccessName}{$originalPathinfo}", $result->getRequest()->pathinfo ); diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php index 8295cd06e1a..f808091661a 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/VersatileMatcher.php @@ -20,6 +20,8 @@ interface VersatileMatcher extends Matcher /** * Returns matcher object corresponding to $siteAccessName or null if non applicable. * + * @note VersatileMatcher objects always receive a request with cleaned up pathinfo (i.e. no SiteAccess part inside). + * * @param string $siteAccessName * * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher|null Typically the current matcher, with updated request. From 7ce756e049e8730941e50f8ee2f7f86183cf7b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 11 Apr 2014 16:01:34 +0200 Subject: [PATCH 18/23] Fix EZP-22634: URIText SiteAccess matcher doesn't implement URILexer --- .../Symfony/SiteAccess/Matcher/URIText.php | 50 ++++++++++++++++--- .../SiteAccess/Tests/RouterURITextTest.php | 32 +++++++++++- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php index a629668f04f..8fc9c9b2ac5 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php @@ -11,9 +11,20 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; -class URIText extends Regex implements Matcher +class URIText extends Regex implements Matcher, URILexer { + /** + * @var string + */ + private $prefix; + + /** + * @var string + */ + private $suffix; + /** * Constructor. * @@ -21,12 +32,12 @@ class URIText extends Regex implements Matcher */ public function __construct( array $siteAccessesConfiguration ) { + $this->prefix = isset( $siteAccessesConfiguration['prefix'] ) ? $siteAccessesConfiguration['prefix'] : ''; + $this->suffix = isset( $siteAccessesConfiguration['suffix'] ) ? $siteAccessesConfiguration['suffix'] : ''; + parent::__construct( - "^/" . - ( isset( $siteAccessesConfiguration["prefix"] ) ? preg_quote( $siteAccessesConfiguration["prefix"], "@" ) : "" ) . - "(\w+)" . - ( isset( $siteAccessesConfiguration["suffix"] ) ? preg_quote( $siteAccessesConfiguration["suffix"], "@" ) : "" ), - 1 + '^(/' . preg_quote( $this->prefix, '@' ) . '(\w+)' . preg_quote( $this->suffix, '@' ) . ')', + 2 ); } @@ -49,4 +60,31 @@ public function setRequest( SimplifiedRequest $request ) parent::setRequest( $request ); } + + /** + * Analyses $uri and removes the siteaccess part, if needed. + * + * @param string $uri The original URI + * + * @return string The modified URI + */ + public function analyseURI( $uri ) + { + $uri = '/' . ltrim( $uri, '/' ); + return preg_replace( "@$this->regex@", '', $uri ); + } + + /** + * Analyses $linkUri when generating a link to a route, in order to have the siteaccess part back in the URI. + * + * @param string $linkUri + * + * @return string The modified link URI + */ + public function analyseLink( $linkUri ) + { + $linkUri = '/' . ltrim( $linkUri, '/' ); + $siteAccessUri = "/$this->prefix" . $this->match() . $this->suffix; + return $siteAccessUri . $linkUri; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php index 90650cc9ad5..427f5ca7da0 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php @@ -56,7 +56,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -127,4 +127,34 @@ public function testGetName() $matcher = new URITextMatcher( array(), array() ); $this->assertSame( 'uri:text', $matcher->getName() ); } + + public function testAnalyseURI() + { + $siteAccessURI = "/footestbar"; + $semanticURI = "/something/hoho"; + $matcher = new URITextMatcher( + array( + "prefix" => "foo", + "suffix" => "bar", + ) + ); + $matcher->setRequest( SimplifiedRequest::fromUrl( "http://phoenix-rises.fm/footestbar/blabla" ) ); + + $this->assertSame( $semanticURI, $matcher->analyseURI( $siteAccessURI . $semanticURI ) ); + } + + public function testAnalyseLink() + { + $siteAccessURI = "/footestbar"; + $semanticURI = "/something/hoho"; + $matcher = new URITextMatcher( + array( + "prefix" => "foo", + "suffix" => "bar", + ) + ); + $matcher->setRequest( SimplifiedRequest::fromUrl( "http://phoenix-rises.fm/footestbar/blabla" ) ); + + $this->assertSame( $siteAccessURI . $semanticURI, $matcher->analyseLink( $semanticURI ) ); + } } From 3d31489a88e203316ffd2fc1fbcd68f0b69043b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 11 Apr 2014 16:14:03 +0200 Subject: [PATCH 19/23] EZP-20305: Made URIText matcher implement VersatileMatcher --- .../MVC/Symfony/SiteAccess/Matcher/URIText.php | 15 +++++++++++++-- .../SiteAccess/Tests/RouterURITextTest.php | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php index 8fc9c9b2ac5..cfafe18a75b 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/URIText.php @@ -9,11 +9,11 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; -class URIText extends Regex implements Matcher, URILexer +class URIText extends Regex implements VersatileMatcher, URILexer { /** * @var string @@ -87,4 +87,15 @@ public function analyseLink( $linkUri ) $siteAccessUri = "/$this->prefix" . $this->match() . $this->suffix; return $siteAccessUri . $linkUri; } + + public function reverseMatch( $siteAccessName ) + { + $this->request->setPathinfo( "/{$this->prefix}{$siteAccessName}{$this->suffix}{$this->request->pathinfo}" ); + return $this; + } + + public function getRequest() + { + return $this->request; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php index 427f5ca7da0..a77e2811976 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterURITextTest.php @@ -157,4 +157,22 @@ public function testAnalyseLink() $this->assertSame( $siteAccessURI . $semanticURI, $matcher->analyseLink( $semanticURI ) ); } + + public function testReverseMatch() + { + $semanticURI = "/hihi/hoho"; + $matcher = new URITextMatcher( + array( + "prefix" => "foo", + "suffix" => "bar", + ) + ); + $matcher->setRequest( new SimplifiedRequest( array( 'pathinfo' => $semanticURI ) ) ); + + $result = $matcher->reverseMatch( 'something' ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\URIText', $result ); + $request = $result->getRequest(); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest', $request ); + $this->assertSame( "/foosomethingbar{$semanticURI}", $request->pathinfo ); + } } From 4fc68173edf99ff1c3c7f750c9a8f19ab636327a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Fri, 11 Apr 2014 16:52:30 +0200 Subject: [PATCH 20/23] EZP-20305: Made HostText matcher implement VersatileMatcher --- .../Symfony/SiteAccess/Matcher/HostText.php | 27 ++++++++++++++----- .../SiteAccess/Tests/RouterHostTextTest.php | 20 +++++++++++++- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php index 97d0edbab20..0eb39c488df 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php @@ -9,11 +9,15 @@ namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; -use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher; -class HostText extends Regex implements Matcher +class HostText extends Regex implements VersatileMatcher { + private $prefix; + + private $suffix; + /** * Constructor. * @@ -21,12 +25,10 @@ class HostText extends Regex implements Matcher */ public function __construct( array $siteAccessesConfiguration ) { + $this->prefix = isset( $siteAccessesConfiguration['prefix'] ) ? $siteAccessesConfiguration['prefix'] : ''; + $this->suffix = isset( $siteAccessesConfiguration['suffix'] ) ? $siteAccessesConfiguration['suffix'] : ''; parent::__construct( - "^" . - ( isset( $siteAccessesConfiguration["prefix"] ) ? preg_quote( $siteAccessesConfiguration["prefix"], "@" ) : "" ) . - "(\w+)" . - ( isset( $siteAccessesConfiguration["suffix"] ) ? preg_quote( $siteAccessesConfiguration["suffix"], "@" ) : "" ) . - '$', + "^" . preg_quote( $this->prefix, "@" ) . "(\w+)" . preg_quote( $this->suffix, "@" ) . '$', 1 ); } @@ -50,4 +52,15 @@ public function setRequest( SimplifiedRequest $request ) parent::setRequest( $request ); } + + public function reverseMatch( $siteAccessName ) + { + $this->request->setHost( $this->prefix . $siteAccessName . $this->suffix ); + return $this; + } + + public function getRequest() + { + return $this->request; + } } diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php index bc03c0bbbdc..69a888180ca 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Tests/RouterHostTextTest.php @@ -56,7 +56,7 @@ public function testConstruct() * @depends testConstruct * @dataProvider matchProvider */ - public function testMatch( $request, $siteAccess, $router ) + public function testMatch( SimplifiedRequest $request, $siteAccess, Router $router ) { $sa = $router->match( $request ); $this->assertInstanceOf( 'eZ\\Publish\\Core\\MVC\\Symfony\\SiteAccess', $sa ); @@ -126,4 +126,22 @@ public function testGetName() $matcher = new HostTextMatcher( array( 'host' => 'foo' ), array() ); $this->assertSame( 'host:text', $matcher->getName() ); } + + public function testReverseMatch() + { + $matcher = new HostTextMatcher( + array( + "prefix" => "www.", + "suffix" => ".com", + ) + ); + + $matcher->setRequest( new SimplifiedRequest( array( 'host' => 'www.my_siteaccess.com' ) ) ); + + $result = $matcher->reverseMatch( 'foobar' ); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\HostText', $result ); + $request = $result->getRequest(); + $this->assertInstanceOf( 'eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest', $request ); + $this->assertSame( "www.foobar.com", $request->host ); + } } From e5377295630b58baea9fce237d299f4b1d776d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Mon, 14 Apr 2014 11:06:37 +0200 Subject: [PATCH 21/23] Fix EZP-22560: Deprecate the Regex SiteAccess matchers --- doc/bc/changes-5.3.md | 2 ++ eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php | 3 +++ eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php | 3 +++ 3 files changed, 8 insertions(+) diff --git a/doc/bc/changes-5.3.md b/doc/bc/changes-5.3.md index cd965e15246..38203819422 100644 --- a/doc/bc/changes-5.3.md +++ b/doc/bc/changes-5.3.md @@ -86,6 +86,8 @@ Changes affecting version compatibility with former or future versions. * In semantic configuration, `ezpublish.system..session_name` is deprecated. Use `ezpublish.system..session.name` instead. +* `Regex\URI` and `Regex\Host` SiteAccess matchers are deprecated as reverse match is not possible with them (i.e. see `VersatileMatcher` interface). + * All Location based SortClauses, as well as PriorityCriterion and DepthCriterion has been deprecated for content search use since their behaviour is unpredictable by design when content has several locations. Instead use same functionality on new Location Search API. diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php index 5fed9e52f52..64d0a45f3e1 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/Host.php @@ -13,6 +13,9 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; +/** + * @deprecated since 5.3 as it cannot be reverted. + */ class Host extends Regex implements Matcher { /** diff --git a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php index 5077b7bcb3d..5252e4ce9ec 100644 --- a/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php +++ b/eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/Regex/URI.php @@ -13,6 +13,9 @@ use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher\Regex; use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; +/** + * @deprecated since 5.3 as it cannot be reverted. + */ class URI extends Regex implements Matcher { /** From 835d979a9d13bc10de9f60c32ec9255f7f941d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Mon, 14 Apr 2014 15:06:05 +0200 Subject: [PATCH 22/23] EZP-20305: Implement reverse matching on the DefaultRouter --- .../Compiler/ChainRoutingPass.php | 4 + .../Routing/DefaultRouter.php | 80 ++++++++++++++++++- .../Compiler/ChainRoutingPassTest.php | 5 ++ .../Tests/Routing/DefaultRouterTest.php | 65 ++++++++++++++- 4 files changed, 150 insertions(+), 4 deletions(-) diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/ChainRoutingPass.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/ChainRoutingPass.php index f14e9e8765e..b1471f09152 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/ChainRoutingPass.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/ChainRoutingPass.php @@ -43,6 +43,10 @@ public function process( ContainerBuilder $container ) 'setLegacyAwareRoutes', array( '%ezpublish.default_router.legacy_aware_routes%' ) ); + $defaultRouter->addMethodCall( + 'setSiteAccessRouter', + array( new Reference( 'ezpublish.siteaccess_router' ) ) + ); if ( !$defaultRouter->hasTag( 'router' ) ) { $defaultRouter->addTag( diff --git a/eZ/Bundle/EzPublishCoreBundle/Routing/DefaultRouter.php b/eZ/Bundle/EzPublishCoreBundle/Routing/DefaultRouter.php index ba6a9c426fd..83e547b5cf0 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Routing/DefaultRouter.php +++ b/eZ/Bundle/EzPublishCoreBundle/Routing/DefaultRouter.php @@ -10,8 +10,10 @@ namespace eZ\Bundle\EzPublishCoreBundle\Routing; use eZ\Publish\Core\MVC\ConfigResolverInterface; +use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; use eZ\Publish\Core\MVC\Symfony\SiteAccess; use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware; +use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface; use eZ\Publish\Core\MVC\Symfony\SiteAccess\URILexer; use Symfony\Bundle\FrameworkBundle\Routing\Router; use Symfony\Component\Routing\Exception\ResourceNotFoundException; @@ -37,6 +39,11 @@ class DefaultRouter extends Router implements RequestMatcherInterface, SiteAcces */ protected $configResolver; + /** + * @var \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface + */ + protected $siteAccessRouter; + public function setConfigResolver( ConfigResolverInterface $configResolver ) { $this->configResolver = $configResolver; @@ -68,6 +75,14 @@ public function setLegacyAwareRoutes( array $routes ) $this->legacyAwareRoutes = $routes; } + /** + * @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface $siteAccessRouter + */ + public function setSiteAccessRouter( SiteAccessRouterInterface $siteAccessRouter ) + { + $this->siteAccessRouter = $siteAccessRouter; + } + /** * @param \Symfony\Component\HttpFoundation\Request $request The request to match * @@ -101,10 +116,34 @@ public function matchRequest( Request $request ) public function generate( $name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH ) { + $siteAccess = $this->siteAccess; + $originalContext = $context = $this->getContext(); + $isSiteAccessAware = $this->isSiteAccessAwareRoute( $name ); + + // Retrieving the appropriate SiteAccess to generate the link for. + if ( isset( $parameters['siteaccess'] ) && $isSiteAccessAware ) + { + $siteAccess = $this->siteAccessRouter->matchByName( $parameters['siteaccess'] ); + if ( $siteAccess instanceof SiteAccess && $siteAccess->matcher instanceof SiteAccess\VersatileMatcher ) + { + // Switch request context for link generation. + $context = $this->getContextBySimplifiedRequest( $siteAccess->matcher->getRequest() ); + $this->setContext( $context ); + } + else if ( $this->logger ) + { + $siteAccess = $this->siteAccess; + $this->logger->notice( "Could not generate a link using provided 'siteaccess' parameter: {$parameters['siteaccess']}. Generating using current context." ); + } + + unset( $parameters['siteaccess'] ); + } + $url = parent::generate( $name, $parameters, $referenceType ); - if ( $this->isSiteAccessAwareRoute( $name ) && isset( $this->siteAccess ) && $this->siteAccess->matcher instanceof URILexer ) + + // Now putting back SiteAccess URI if needed. + if ( $isSiteAccessAware && $siteAccess && $siteAccess->matcher instanceof URILexer ) { - $context = $this->getContext(); if ( $referenceType == self::ABSOLUTE_URL || $referenceType == self::NETWORK_PATH ) { $scheme = $context->getScheme(); @@ -126,9 +165,11 @@ public function generate( $name, $parameters = array(), $referenceType = self::A } $linkUri = $base ? substr( $url, strpos( $url, $base ) + strlen( $base ) ) : $url; - $url = str_replace( $linkUri, $this->siteAccess->matcher->analyseLink( $linkUri ), $url ); + $url = str_replace( $linkUri, $siteAccess->matcher->analyseLink( $linkUri ), $url ); } + // Switch back to original context, for next links generation. + $this->setContext( $originalContext ); return $url; } @@ -172,4 +213,37 @@ protected function isLegacyAwareRoute( $routeName ) return false; } + + /** + * Merges context from $simplifiedRequest into a clone of the current context. + * + * @param SimplifiedRequest $simplifiedRequest + * + * @return \Symfony\Component\Routing\RequestContext + */ + public function getContextBySimplifiedRequest( SimplifiedRequest $simplifiedRequest ) + { + $context = clone $this->context; + if ( $simplifiedRequest->scheme ) + { + $context->setScheme( $simplifiedRequest->scheme ); + } + + if ( $simplifiedRequest->port ) + { + $context->setHttpPort( $simplifiedRequest->port ); + } + + if ( $simplifiedRequest->host ) + { + $context->setHost( $simplifiedRequest->host ); + } + + if ( $simplifiedRequest->pathinfo ) + { + $context->setPathInfo( $simplifiedRequest->pathinfo ); + } + + return $context; + } } diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/ChainRoutingPassTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/ChainRoutingPassTest.php index 12972963c4d..1f89edb6fd5 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/ChainRoutingPassTest.php +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/ChainRoutingPassTest.php @@ -111,6 +111,11 @@ public function testAddRouterWithDefaultRouter( $declaredPriority, $expectedPrio 'setLegacyAwareRoutes', array( '%ezpublish.default_router.legacy_aware_routes%' ) ); + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'router.default', + 'setSiteAccessRouter', + array( new Reference( 'ezpublish.siteaccess_router' ) ) + ); $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( 'ezpublish.chain_router', 'add', diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/DefaultRouterTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/DefaultRouterTest.php index ddf185c9659..5a4aeee4ba1 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/DefaultRouterTest.php +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/DefaultRouterTest.php @@ -10,9 +10,11 @@ namespace eZ\Bundle\EzPublishCoreBundle\Tests\Routing; use eZ\Bundle\EzPublishCoreBundle\Routing\DefaultRouter; +use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest; use eZ\Publish\Core\MVC\Symfony\SiteAccess; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\RequestContext; +use ReflectionObject; class DefaultRouterTest extends \PHPUnit_Framework_TestCase { @@ -26,11 +28,17 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase */ private $configResolver; + /** + * @var \Symfony\Component\Routing\RequestContext + */ + private $requestContext; + protected function setUp() { parent::setUp(); $this->container = $this->getMock( 'Symfony\\Component\\DependencyInjection\\ContainerInterface' ); $this->configResolver = $this->getMock( 'eZ\\Publish\\Core\\MVC\\ConfigResolverInterface' ); + $this->requestContext = new RequestContext(); } /** @@ -40,9 +48,10 @@ protected function setUp() */ private function generateRouter( array $mockedMethods = array() ) { + /** @var \PHPUnit_Framework_MockObject_MockObject|DefaultRouter $router */ $router = $this ->getMockBuilder( 'eZ\\Bundle\\EzPublishCoreBundle\\Routing\\DefaultRouter' ) - ->setConstructorArgs( array( $this->container, 'foo' ) ) + ->setConstructorArgs( array( $this->container, 'foo', array(), $this->requestContext ) ) ->setMethods( array_merge( $mockedMethods ) ) ->getMock(); $router->setConfigResolver( $this->configResolver ); @@ -266,4 +275,58 @@ public function providerGenerateWithSiteAccess() array( '/foo/bar/baz', '/foo/bar/baz', '/foo/bar/baz', 'test_siteaccess', true, false, '_dontwantsiteaccess' ), ); } + + public function testGenerateReverseSiteAccessMatch() + { + $routeName = 'some_route_name'; + $urlGenerated = 'http://phoenix-rises.fm/foo/bar'; + + $siteAccessName = 'foo_test'; + $siteAccessRouter = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface' ); + $versatileMatcher = $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher' ); + $simplifiedRequest = new SimplifiedRequest( + array( + 'host' => 'phoenix-rises.fm', + 'scheme' => 'http' + ) + ); + $versatileMatcher + ->expects( $this->once() ) + ->method( 'getRequest' ) + ->will( $this->returnValue( $simplifiedRequest ) ); + $siteAccessRouter + ->expects( $this->once() ) + ->method( 'matchByName' ) + ->with( $siteAccessName ) + ->will( $this->returnValue( new SiteAccess( $siteAccessName, 'foo', $versatileMatcher ) ) ); + + $generator = $this->getMock( 'Symfony\Component\Routing\Generator\UrlGeneratorInterface' ); + $generator + ->expects( $this->at( 0 ) ) + ->method( 'setContext' ) + ->with( $this->isInstanceOf( 'Symfony\Component\Routing\RequestContext' ) ); + $generator + ->expects( $this->at( 1 ) ) + ->method( 'generate' ) + ->with( $routeName ) + ->will( $this->returnValue( $urlGenerated ) ); + $generator + ->expects( $this->at( 2 ) ) + ->method( 'setContext' ) + ->with( $this->requestContext ); + + $router = new DefaultRouter( $this->container, 'foo', array(), $this->requestContext ); + $router->setConfigResolver( $this->configResolver ); + $router->setSiteAccess( new SiteAccess( 'test', 'test', $this->getMock( 'eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher' ) ) ); + $router->setSiteAccessRouter( $siteAccessRouter ); + $refRouter = new ReflectionObject( $router ); + $refGenerator = $refRouter->getProperty( 'generator' ); + $refGenerator->setAccessible( true ); + $refGenerator->setValue( $router, $generator ); + + $this->assertSame( + $urlGenerated, + $router->generate( $routeName, array( 'siteaccess' => $siteAccessName ), DefaultRouter::ABSOLUTE_PATH ) + ); + } } From baba021253cea2b9adad876ea209c693cdc3cdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Vieilledent?= Date: Mon, 14 Apr 2014 16:11:28 +0200 Subject: [PATCH 23/23] EZP-20305: Added specifications --- .../siteaccess/cross_siteaccess_links.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 doc/specifications/siteaccess/cross_siteaccess_links.md diff --git a/doc/specifications/siteaccess/cross_siteaccess_links.md b/doc/specifications/siteaccess/cross_siteaccess_links.md new file mode 100644 index 00000000000..8980f061dde --- /dev/null +++ b/doc/specifications/siteaccess/cross_siteaccess_links.md @@ -0,0 +1,67 @@ +# Cross SiteAccess links + +## Description +When using the *multisite* feature, it is sometimes useful to be able to **generate cross-links** between the different sites. +This allows to link different resources referenced in a same content repository, but configured independently with different +tree roots. + +## Solution +To implement this feature, a new `VersatileMatcher` was added to allow SiteAccess matchers to be able to *reverse-match*. +All existing matchers implement this new interface, except the Regexp based matchers which have been deprecated. + +The SiteAccess router has been added a `matchByName()` method to reflect this addition. + +> **Note:** SiteAccess router public methods have also been extracted to a new interface, `SiteAccessRouterInterface`. + +Abstract URLGenerator and `DefaultRouter` have been updated as well. + +## Usage +*Twig example* +```jinja +{# Linking a location #} +{{ ez_content_name( content ) }} + +{# Linking a regular route #} +Hello world! +``` + +*PHP example* +```php +namespace Acme\TestBundle\Controller; + +use eZ\Bundle\EzPublishCoreBundle\Controller as BaseController; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +class MyController extends BaseController +{ + public function fooAction() + { + // ... + + $location = $this->getRepository()->getLocationService()->loadLocation( 123 ); + $locationUrl = $this->generateUrl( + $location, + array( 'siteaccess' => 'some_siteaccess_name' ), + UrlGeneratorInterface::ABSOLUTE_PATH + ); + + $regularRouteUrl = $this->generateUrl( + 'some_route_name', + array( 'siteaccess' => 'some_siteaccess_name' ), + UrlGeneratorInterface::ABSOLUTE_PATH + ); + + // ... + } +} +``` + +> **Important**: As SiteAccess matchers can involve hosts and ports, it is **highly recommended** to generate cross-siteaccess +> links in the absolute form (e.g. using `url()` Twig helper). + +## Troubleshooting +* The first matcher succeeding always wins, so be careful when using *catch-all* matchers like `URIElement`. +* If passed SiteAccess name is not a valid one, an `InvalidArgumentException` will be thrown. +* If matcher used to match provided SiteAccess doesn't implement `VersatileMatcher`, the link will be generated for the current SiteAccess. +* When using `Compound\LogicalAnd`, all inner matchers **must match**. If at least one matcher doesn't implement `VersatileMatcher`, it will fail. +* When using `Compound\LogicalOr`, the first inner matcher succeeding will win.