From 3bfa4ca2177af7e3fda3a7e104dbfe0f33a48d4e Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 29 Sep 2014 03:08:48 +0530 Subject: [PATCH] Add DashedRoute class. --- src/Routing/Route/DashedRoute.php | 107 ++++++++++++ .../Routing/Route/DashedRouteTest.php | 165 ++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 src/Routing/Route/DashedRoute.php create mode 100644 tests/TestCase/Routing/Route/DashedRouteTest.php diff --git a/src/Routing/Route/DashedRoute.php b/src/Routing/Route/DashedRoute.php new file mode 100644 index 00000000000..c73d6ecea6f --- /dev/null +++ b/src/Routing/Route/DashedRoute.php @@ -0,0 +1,107 @@ + 'MyPlugin', 'controller' => 'MyController', 'action' => 'myAction']` + */ +class DashedRoute extends Route { + +/** + * Flag for tracking whether or not the defaults have been inflected. + * + * Default values need to be inflected so that they match the inflections that + * match() will create. + * + * @var bool + */ + protected $_inflectedDefaults = false; + +/** + * Parses a string URL into an array. If it mathes, it will convert the + * controller, action and plugin keys to their camelized form. + * + * @param string $url The URL to parse + * @return mixed false on failure, or an array of request parameters + */ + public function parse($url) { + $params = parent::parse($url); + if (!$params) { + return false; + } + if (!empty($params['controller'])) { + $params['controller'] = Inflector::camelize(str_replace( + '-', + '_', + $params['controller'] + )); + } + if (!empty($params['plugin'])) { + $params['plugin'] = Inflector::camelize(str_replace( + '-', + '_', + $params['plugin'] + )); + } + if (!empty($params['action'])) { + $params['action'] = Inflector::variable(str_replace( + '-', + '_', + $params['action'] + )); + } + return $params; + } + +/** + * Dasherizes the controller, action and plugin params before passing them on + * to the parent class. + * + * @param array $url Array of parameters to convert to a string. + * @param array $context An array of the current request context. + * Contains information such as the current host, scheme, port, and base + * directory. + * @return mixed either false or a string URL. + */ + public function match(array $url, array $context = array()) { + $url = $this->_dasherize($url); + if (!$this->_inflectedDefaults) { + $this->_inflectedDefaults = true; + $this->defaults = $this->_dasherize($this->defaults); + } + return parent::match($url, $context); + } + +/** + * Helper method for dasherizing keys in a URL array. + * + * @param array $url An array of URL keys. + * @return array + */ + protected function _dasherize($url) { + foreach (['controller', 'plugin', 'action'] as $element) { + if (!empty($url[$element])) { + $url[$element] = Inflector::dasherize($url[$element]); + } + } + return $url; + } + +} diff --git a/tests/TestCase/Routing/Route/DashedRouteTest.php b/tests/TestCase/Routing/Route/DashedRouteTest.php new file mode 100644 index 00000000000..65d27074dcf --- /dev/null +++ b/tests/TestCase/Routing/Route/DashedRouteTest.php @@ -0,0 +1,165 @@ + null]); + $result = $route->match(['controller' => 'Posts', 'action' => 'myView', 'plugin' => null]); + $this->assertFalse($result); + + $result = $route->match([ + 'plugin' => null, + 'controller' => 'Posts', + 'action' => 'myView', + 0 + ]); + $this->assertFalse($result); + + $result = $route->match([ + 'plugin' => null, + 'controller' => 'MyPosts', + 'action' => 'myView', + 'id' => 1 + ]); + $this->assertEquals('/my-posts/my-view/1', $result); + + $route = new DashedRoute('/', ['controller' => 'Pages', 'action' => 'myDisplay', 'home']); + $result = $route->match(['controller' => 'Pages', 'action' => 'myDisplay', 'home']); + $this->assertEquals('/', $result); + + $result = $route->match(['controller' => 'Pages', 'action' => 'display', 'about']); + $this->assertFalse($result); + + $route = new DashedRoute('/blog/:action', ['controller' => 'Posts']); + $result = $route->match(['controller' => 'Posts', 'action' => 'myView']); + $this->assertEquals('/blog/my-view', $result); + + $result = $route->match(['controller' => 'Posts', 'action' => 'myView', 'id' => 2]); + $this->assertEquals('/blog/my-view?id=2', $result); + + $result = $route->match(['controller' => 'Posts', 'action' => 'myView', 1]); + $this->assertFalse($result); + + $route = new DashedRoute('/foo/:controller/:action', ['action' => 'index']); + $result = $route->match(['controller' => 'Posts', 'action' => 'myView']); + $this->assertEquals('/foo/posts/my-view', $result); + + $route = new DashedRoute('/:plugin/:id/*', ['controller' => 'Posts', 'action' => 'myView']); + $result = $route->match([ + 'plugin' => 'TestPlugin', + 'controller' => 'Posts', + 'action' => 'myView', + 'id' => '1' + ]); + $this->assertEquals('/test-plugin/1/', $result); + + $result = $route->match([ + 'plugin' => 'TestPlugin', + 'controller' => 'Posts', + 'action' => 'myView', + 'id' => '1', + '0' + ]); + $this->assertEquals('/test-plugin/1/0', $result); + + $result = $route->match([ + 'plugin' => 'TestPlugin', + 'controller' => 'Nodes', + 'action' => 'myView', + 'id' => 1 + ]); + $this->assertFalse($result); + + $result = $route->match([ + 'plugin' => 'TestPlugin', + 'controller' => 'Posts', + 'action' => 'edit', + 'id' => 1 + ]); + $this->assertFalse($result); + + $route = new DashedRoute('/admin/subscriptions/:action/*', [ + 'controller' => 'Subscribe', 'prefix' => 'admin' + ]); + $result = $route->match([ + 'controller' => 'Subscribe', + 'prefix' => 'admin', + 'action' => 'editAdminE', + 1 + ]); + $expected = '/admin/subscriptions/edit-admin-e/1'; + $this->assertEquals($expected, $result); + } + +/** + * test the parse method of DashedRoute. + * + * @return void + */ + public function testParse() { + $route = new DashedRoute( + '/:controller/:action/:id', + ['controller' => 'Testing4', 'id' => null], + ['id' => Router::ID] + ); + $route->compile(); + $result = $route->parse('/my-posts/my-view/1'); + $this->assertEquals('MyPosts', $result['controller']); + $this->assertEquals('myView', $result['action']); + $this->assertEquals('1', $result['id']); + + $route = new DashedRoute( + '/admin/:controller', + ['prefix' => 'admin', 'admin' => 1, 'action' => 'index'] + ); + $route->compile(); + $result = $route->parse('/admin/'); + $this->assertFalse($result); + + $result = $route->parse('/admin/my-posts'); + $this->assertEquals('MyPosts', $result['controller']); + $this->assertEquals('index', $result['action']); + + $route = new DashedRoute( + '/media/search/*', + ['controller' => 'Media', 'action' => 'searchIt'] + ); + $result = $route->parse('/media/search'); + $this->assertEquals('Media', $result['controller']); + $this->assertEquals('searchIt', $result['action']); + $this->assertEquals([], $result['pass']); + + $result = $route->parse('/media/search/tv_shows'); + $this->assertEquals('Media', $result['controller']); + $this->assertEquals('searchIt', $result['action']); + $this->assertEquals(['tv_shows'], $result['pass']); + } + +}