Skip to content

Commit

Permalink
Add DashedRoute class.
Browse files Browse the repository at this point in the history
  • Loading branch information
ADmad committed Sep 28, 2014
1 parent 3f1a3d8 commit 3bfa4ca
Show file tree
Hide file tree
Showing 2 changed files with 272 additions and 0 deletions.
107 changes: 107 additions & 0 deletions src/Routing/Route/DashedRoute.php
@@ -0,0 +1,107 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Routing\Route;

use Cake\Routing\Route\Route;
use Cake\Utility\Inflector;

/**
* This route class will transparently inflect the controller, action and plugin
* routing parameters, so that requesting `/my-plugin/my-controller/my-action`
* is parsed as `['plugin' => '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;
}

}
165 changes: 165 additions & 0 deletions tests/TestCase/Routing/Route/DashedRouteTest.php
@@ -0,0 +1,165 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Test\TestCase\Routing\Route;

use Cake\Core\App;
use Cake\Routing\Router;
use Cake\Routing\Route\DashedRoute;
use Cake\TestSuite\TestCase;

/**
* Test case for DashedRoute
*/
class DashedRouteTest extends TestCase {

/**
* test that routes match their pattern.
*
* @return void
*/
public function testMatchBasic() {
$route = new DashedRoute('/:controller/:action/:id', ['plugin' => 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']);
}

}

0 comments on commit 3bfa4ca

Please sign in to comment.