From 65d1b84c5c6077507d39a4ac293676801503e209 Mon Sep 17 00:00:00 2001 From: Giuseppe Mazzapica Date: Fri, 19 Feb 2016 16:43:57 +0100 Subject: [PATCH] Ensure preview works by persisting preview url var Also adding 'cortex.matched-vars' filter to allow customize final vars array --- src/Cortex/Router/Router.php | 52 +++++++++++++++----- tests/src/Unit/Router/RouterTest.php | 71 ++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/src/Cortex/Router/Router.php b/src/Cortex/Router/Router.php index 161c6b1..db5439b 100644 --- a/src/Cortex/Router/Router.php +++ b/src/Cortex/Router/Router.php @@ -87,7 +87,7 @@ public function match(UriInterface $uri, $httpMethod) return $this->results; } - if (! count($this->routes) || !$this->parseRoutes($uri, $httpMethod)) { + if (! count($this->routes) || ! $this->parseRoutes($uri, $httpMethod)) { $this->results = new MatchingResult(['route' => null]); return $this->results; @@ -129,7 +129,7 @@ private function parseRoutes(UriInterface $uri, $httpMethod) /** @var \Brain\Cortex\Route\RouteInterface $route */ foreach ($iterator as $route) { $route = $this->sanitizeRouteMethod($this->groups->mergeGroup($route), $httpMethod); - if (!$this->validateRoute($route, $uri, $httpMethod)) { + if (! $this->validateRoute($route, $uri, $httpMethod)) { continue; } @@ -159,7 +159,7 @@ private function parseRoutes(UriInterface $uri, $httpMethod) */ private function sanitizeRouteMethod(RouteInterface $route, $httpMethod) { - if (empty($route['method']) || !(is_string($route['method']) || is_array($route['method']))) { + if (empty($route['method']) || ! (is_string($route['method']) || is_array($route['method']))) { $route['method'] = $httpMethod; } @@ -227,7 +227,9 @@ private function finalizeRoute(RouteInterface $route, array $vars, UriInterface { is_null($route['merge_query_string']) and $route['merge_query_string'] = true; $merge = filter_var($route['merge_query_string'], FILTER_VALIDATE_BOOLEAN); - $merge and $vars = array_merge($vars, $uri->vars()); + $vars = $merge + ? array_merge($vars, $uri->vars()) + : $this->ensurePreviewVar($vars, $uri, $route); $result = null; if (is_callable($route['vars'])) { $cb = $route['vars']; @@ -240,14 +242,38 @@ private function finalizeRoute(RouteInterface $route, array $vars, UriInterface } } - return $result instanceof MatchingResult ? $result : new MatchingResult([ - 'vars' => $vars, - 'route' => $route->id(), - 'path' => $route['path'], - 'handler' => $route['handler'], - 'before' => $route['before'], - 'after' => $route['after'], - 'template' => $route['template'], - ]); + $vars = $this->ensurePreviewVar($vars, $uri, $route); + $vars = apply_filters('cortex.matched-vars', $vars, $route, $uri); + + return $result instanceof MatchingResult + ? $result + : new MatchingResult([ + 'vars' => (array) $vars, + 'route' => $route->id(), + 'path' => $route['path'], + 'handler' => $route['handler'], + 'before' => $route['before'], + 'after' => $route['after'], + 'template' => $route['template'], + ]); + } + + /** + * We need this to ensure preview works. + * + * @param array $vars + * @param \Brain\Cortex\Uri\UriInterface $uri + * @param \Brain\Cortex\Route\RouteInterface $route + * @return array + */ + private function ensurePreviewVar(array $vars, UriInterface $uri, RouteInterface $route) + { + $uriVars = $uri->vars(); + + if (! isset($vars['preview']) && isset($uriVars['preview']) && is_user_logged_in()) { + $vars['preview'] = $uriVars['preview']; + } + + return $vars; } } diff --git a/tests/src/Unit/Router/RouterTest.php b/tests/src/Unit/Router/RouterTest.php index 497d8e4..0019390 100644 --- a/tests/src/Unit/Router/RouterTest.php +++ b/tests/src/Unit/Router/RouterTest.php @@ -19,6 +19,7 @@ use Brain\Cortex\Router\Router; use Brain\Cortex\Tests\TestCase; use Brain\Cortex\Uri\UriInterface; +use Brain\Monkey\Functions; use FastRoute\Dispatcher; use FastRoute\RouteCollector; @@ -222,7 +223,7 @@ public function testMatchMatchingExactMatch() $uri->shouldReceive('scheme')->andReturn('http'); $uri->shouldReceive('host')->andReturn('example.com'); $uri->shouldReceive('path')->andReturn('foo'); - $uri->shouldReceive('vars')->once()->andReturn(['c' => 'C']); + $uri->shouldReceive('vars')->atLeast()->once()->andReturn(['c' => 'C']); $uri->shouldReceive('chunks')->andReturn(['foo']); $collector = \Mockery::mock(RouteCollector::class); @@ -282,7 +283,7 @@ public function testMatchDynamicMatch() $uri->shouldReceive('scheme')->andReturn('http'); $uri->shouldReceive('host')->andReturn('example.com'); $uri->shouldReceive('path')->andReturn('foo/i-am-bar'); - $uri->shouldReceive('vars')->once()->andReturn(['c' => 'C']); + $uri->shouldReceive('vars')->atLeast()->once()->andReturn(['c' => 'C']); $uri->shouldReceive('chunks')->andReturn(['foo', 'meh']); $collector = \Mockery::mock(RouteCollector::class); @@ -352,6 +353,7 @@ public function testMatchMatchingExactMatchNoQueryVars() $uri->shouldReceive('host')->andReturn('example.com'); $uri->shouldReceive('path')->andReturn('foo'); $uri->shouldReceive('chunks')->andReturn(['foo']); + $uri->shouldReceive('vars')->andReturn(['foo' => 'no-way']); $collector = \Mockery::mock(RouteCollector::class); $collector->shouldReceive('addRoute')->never(); @@ -386,6 +388,69 @@ public function testMatchMatchingExactMatchNoQueryVars() assertSame($expected, $data); } + public function testMatchMatchingNoQueryVarsMaintainPreviewVar() + { + Functions::when('is_user_logged_in')->justReturn(true); + + $handler = function () { + return func_get_args(); + }; + + $route = new Route([ + 'id' => 'r1', + 'path' => '/foo', + 'handler' => $handler, + 'vars' => ['d' => 'D'], + 'method' => 'POST', + 'merge_query_string' => false, + ]); + $routes = new PriorityRouteCollection(); + + $routes->addRoute($route); + + $groups = \Mockery::mock(GroupCollectionInterface::class); + $groups->shouldReceive('mergeGroup')->once()->with($route)->andReturn($route); + + $uri = \Mockery::mock(UriInterface::class); + $uri->shouldReceive('scheme')->andReturn('http'); + $uri->shouldReceive('host')->andReturn('example.com'); + $uri->shouldReceive('path')->andReturn('foo'); + $uri->shouldReceive('chunks')->andReturn(['foo']); + $uri->shouldReceive('vars')->andReturn(['foo' => 'no-way', 'preview' => 1]); + + $collector = \Mockery::mock(RouteCollector::class); + $collector->shouldReceive('addRoute')->never(); + + $dispatcher = \Mockery::mock(Dispatcher::class); + $dispatcher->shouldReceive('dispatch')->never(); + + $factory = function (array $args) use ($dispatcher) { + assertSame($args, ['foo' => 'bar']); + + return $dispatcher; + }; + + $router = new Router($routes, $groups, $collector, $factory); + $result = $router->match($uri, 'POST'); + + $expected = [ + 'route' => 'r1', + 'path' => '/foo', + 'vars' => ['preview' => 1, 'd' => 'D'], + 'handler' => $handler, + 'before' => null, + 'after' => null, + 'template' => null, + ]; + + $proxy = new Proxy($result); + /** @noinspection PhpUndefinedFieldInspection */ + $data = $proxy->data; + + assertTrue($result->matched()); + assertSame($expected, $data); + } + public function testMatchMatchingExactMatchCallableVars() { $handler = function () { @@ -412,7 +477,7 @@ public function testMatchMatchingExactMatchCallableVars() $uri->shouldReceive('scheme')->andReturn('http'); $uri->shouldReceive('host')->andReturn('example.com'); $uri->shouldReceive('path')->andReturn('foo'); - $uri->shouldReceive('vars')->once()->andReturn(['c' => 'C']); + $uri->shouldReceive('vars')->atLeast()->once()->andReturn(['c' => 'C']); $uri->shouldReceive('chunks')->andReturn(['foo']); $collector = \Mockery::mock(RouteCollector::class);