diff --git a/src/Routing/DispatcherFilter.php b/src/Routing/DispatcherFilter.php index f95da017a52..ef3e61e154e 100644 --- a/src/Routing/DispatcherFilter.php +++ b/src/Routing/DispatcherFilter.php @@ -149,7 +149,14 @@ public function matches(Event $event) { $request = $event->data['request']; $pass = true; if (!empty($this->_config['for'])) { - $pass = strpos($request->here(false), $this->_config['for']) === 0; + $len = strlen('preg:'); + $for = $this->_config['for']; + $url = $request->here(false); + if (substr($for, 0, $len) === 'preg:') { + $pass = (bool)preg_match(substr($for, $len), $url); + } else { + $pass = strpos($url, $for) === 0; + } } if ($pass && !empty($this->_config['when'])) { $response = $event->data['response']; diff --git a/tests/TestCase/Routing/DispatcherFilterTest.php b/tests/TestCase/Routing/DispatcherFilterTest.php index 086dbbb4e88..70af146be3f 100644 --- a/tests/TestCase/Routing/DispatcherFilterTest.php +++ b/tests/TestCase/Routing/DispatcherFilterTest.php @@ -85,6 +85,15 @@ public function testMatchesWithFor() { $request = new Request(['url' => '/blog/articles']); $event = new Event('Dispatcher.beforeDispatch', $this, compact('request')); $this->assertFalse($filter->matches($event), 'Does not start with /articles'); + + $request = new Request(['url' => '/articles/edit/1']); + $event = new Event('Dispatcher.beforeDispatch', $this, compact('request')); + $filter = new DispatcherFilter(['for' => 'preg:#^/articles/edit/\d+$#']); + $this->assertTrue($filter->matches($event)); + + $request = new Request(['url' => '/blog/articles/edit/1']); + $event = new Event('Dispatcher.beforeDispatch', $this, compact('request')); + $this->assertFalse($filter->matches($event), 'Does not start with /articles'); } /**