Skip to content

Commit 669be07

Browse files
committed
Merge pull request #76 from symfony-cmf/event
optional event handling for dynamic router
2 parents e24b428 + b4bc402 commit 669be07

File tree

6 files changed

+109
-11
lines changed

6 files changed

+109
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Changelog
44
1.1
55
---
66

7+
* **2013-07-31**: DynamicRouter now accepts an EventDispatcher to trigger a RouteMatchEvent right before the matching starts
78
* **2013-07-29**: Renamed RouteAwareInterface to RouteReferrersInterface for naming consistency
89
* **2013-07-13**: NestedMatcher now expects a FinalMatcherInterface as second argument of the constructor
910
* **2013-04-30**: Dropped Symfony 2.1 support and got rid of ConfigurableUrlMatcher class

DynamicRouter.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
use Symfony\Component\Routing\Exception\RouteNotFoundException;
1414
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
1515
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
16-
1716
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
17+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
18+
use Symfony\Cmf\Component\Routing\Event\Events;
19+
use Symfony\Cmf\Component\Routing\Event\RouterMatchEvent;
1820

1921
/**
2022
* A flexible router accepting matcher and generator through injection and
@@ -35,6 +37,11 @@ class DynamicRouter implements RouterInterface, RequestMatcherInterface, Chained
3537
*/
3638
protected $generator;
3739

40+
/**
41+
* @var EventDispatcherInterface
42+
*/
43+
protected $eventDispatcher;
44+
3845
/**
3946
* @var RouteEnhancerInterface[]
4047
*/
@@ -64,15 +71,21 @@ class DynamicRouter implements RouterInterface, RequestMatcherInterface, Chained
6471
* @param RequestMatcherInterface|UrlMatcherInterface $matcher
6572
* @param UrlGeneratorInterface $generator
6673
* @param string $uriFilterRegexp
74+
* @param EventDispatcherInterface|null $eventDispatcher
6775
*/
68-
public function __construct(RequestContext $context, $matcher, UrlGeneratorInterface $generator, $uriFilterRegexp = '')
69-
{
76+
public function __construct(RequestContext $context,
77+
$matcher,
78+
UrlGeneratorInterface $generator,
79+
$uriFilterRegexp = '',
80+
EventDispatcherInterface $eventDispatcher = null
81+
) {
7082
$this->context = $context;
7183
if (! $matcher instanceof RequestMatcherInterface && ! $matcher instanceof UrlMatcherInterface) {
7284
throw new \InvalidArgumentException('Invalid $matcher');
7385
}
7486
$this->matcher = $matcher;
7587
$this->generator = $generator;
88+
$this->eventDispatcher = $eventDispatcher;
7689
$this->uriFilterRegexp = $uriFilterRegexp;
7790

7891
$this->generator->setContext($context);
@@ -167,6 +180,12 @@ public function supports($name)
167180
*/
168181
public function match($pathinfo)
169182
{
183+
$request = Request::create($pathinfo);
184+
if ($this->eventDispatcher) {
185+
$event = new RouterMatchEvent();
186+
$this->eventDispatcher->dispatch(Events::PRE_DYNAMIC_MATCH, $event);
187+
}
188+
170189
if (! empty($this->uriFilterRegexp) && ! preg_match($this->uriFilterRegexp, $pathinfo)) {
171190
throw new ResourceNotFoundException("$pathinfo does not match the '{$this->uriFilterRegexp}' pattern");
172191
}
@@ -178,7 +197,7 @@ public function match($pathinfo)
178197

179198
$defaults = $matcher->match($pathinfo);
180199

181-
return $this->applyRouteEnhancers($defaults, Request::create($pathinfo));
200+
return $this->applyRouteEnhancers($defaults, $request);
182201
}
183202

184203
/**
@@ -198,6 +217,11 @@ public function match($pathinfo)
198217
*/
199218
public function matchRequest(Request $request)
200219
{
220+
if ($this->eventDispatcher) {
221+
$event = new RouterMatchEvent($request);
222+
$this->eventDispatcher->dispatch(Events::PRE_DYNAMIC_MATCH_REQUEST, $event);
223+
}
224+
201225
if (! empty($this->uriFilterRegexp)
202226
&& ! preg_match($this->uriFilterRegexp, $request->getPathInfo())
203227
) {
@@ -206,12 +230,11 @@ public function matchRequest(Request $request)
206230

207231
$matcher = $this->getMatcher();
208232
if ($matcher instanceof UrlMatcherInterface) {
209-
// the match method will enhance the route $defaults
210-
return $this->match($request->getPathInfo());
233+
$defaults = $matcher->match($request->getPathInfo());
234+
} else {
235+
$defaults = $matcher->matchRequest($request);
211236
}
212237

213-
$defaults = $matcher->matchRequest($request);
214-
215238
return $this->applyRouteEnhancers($defaults, $request);
216239
}
217240

Event/Events.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Component\Routing\Event;
4+
5+
final class Events
6+
{
7+
/**
8+
* Fired before a path is matched in \Symfony\Cmf\Component\Routing\DynamicRouter#match
9+
*
10+
* The event object is RouteMatchEvent.
11+
*/
12+
const PRE_DYNAMIC_MATCH = 'cmf_routing.pre_dynamic_match';
13+
14+
/**
15+
* Fired before a Request is matched in \Symfony\Cmf\Component\Routing\DynamicRouter#match
16+
*
17+
* The event object is RouteMatchEvent.
18+
*/
19+
const PRE_DYNAMIC_MATCH_REQUEST = 'cmf_routing.pre_dynamic_match_request';
20+
}

Event/RouterMatchEvent.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Component\Routing\Event;
4+
5+
use Symfony\Component\EventDispatcher\Event;
6+
use Symfony\Component\HttpFoundation\Request;
7+
8+
class RouterMatchEvent extends Event
9+
{
10+
/**
11+
* @var Request
12+
*/
13+
protected $request;
14+
15+
/**
16+
* @param Request $request
17+
*/
18+
public function __construct(Request $request = null)
19+
{
20+
$this->request = $request;
21+
}
22+
23+
/**
24+
* @return Request | null
25+
*/
26+
public function getRequest()
27+
{
28+
return $this->request;
29+
}
30+
}

Tests/Routing/DynamicRouterTest.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Symfony\Cmf\Component\Routing\Tests\Routing;
44

5+
use Symfony\Cmf\Component\Routing\Event\Events;
6+
use Symfony\Cmf\Component\Routing\Event\RouterMatchEvent;
57
use Symfony\Component\HttpFoundation\Request;
68
use Symfony\Component\Routing\RouteCollection;
79

@@ -177,7 +179,7 @@ public function testMatchRequest()
177179
$expected = array('this' => 'that');
178180
$this->enhancer->expects($this->once())
179181
->method('enhance')
180-
->with($this->equalTo($routeDefaults), $this->equalTo($this->request)) // TODO: why do we not get the right thing?
182+
->with($this->equalTo($routeDefaults), $this->equalTo($this->request))
181183
->will($this->returnValue($expected))
182184
;
183185

@@ -262,4 +264,24 @@ public function testRouteDebugMessageNonversatile()
262264
$router = new DynamicRouter($this->context, $this->matcher, $generator);
263265
$this->assertInternalType('string', $router->getRouteDebugMessage('test'));
264266
}
267+
268+
public function testEventHandler()
269+
{
270+
$eventDispatcher = $this->buildMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
271+
$router = new DynamicRouter($this->context, $this->matcher, $this->generator, '', $eventDispatcher);
272+
273+
$eventDispatcher->expects($this->once())
274+
->method('dispatch')
275+
->with(Events::PRE_DYNAMIC_MATCH, $this->equalTo(new RouterMatchEvent()))
276+
;
277+
278+
$routeDefaults = array('foo' => 'bar');
279+
$this->matcher->expects($this->once())
280+
->method('match')
281+
->with($this->url)
282+
->will($this->returnValue($routeDefaults))
283+
;
284+
285+
$this->assertEquals($routeDefaults, $router->match($this->url));
286+
}
265287
}

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
},
2121
"require-dev": {
2222
"symfony/dependency-injection": "~2.0",
23-
"symfony/config": "~2.2"
23+
"symfony/config": "~2.2",
24+
"symfony/event-dispatcher": "~2.1"
2425
},
2526
"suggest": {
26-
"symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, ~2.2"
27+
"symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, ~2.2",
28+
"symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching, ~2.1"
2729
},
2830
"autoload": {
2931
"psr-0": { "Symfony\\Cmf\\Component\\Routing": "" }

0 commit comments

Comments
 (0)