Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Remove Router::resourceMap() and update internals of mapResources()
* Remove Router::resourceMap() as the new options added to
  RouterBuilder::resources() replace most of the important functionality
  this method exposed in a simpler to use format.
* Update the internals of mapResources() to use the RouterBuilder
  primitives and not contain any duplicated code with that class.
  • Loading branch information
markstory committed Jul 14, 2014
1 parent 0273d9f commit 4b499f6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 176 deletions.
170 changes: 29 additions & 141 deletions src/Routing/Router.php
Expand Up @@ -124,20 +124,6 @@ class Router {
'UUID' => Router::UUID
);

/**
* Default HTTP request method => controller action map.
*
* @var array
*/
protected static $_resourceMap = array(
array('action' => 'index', 'method' => 'GET', 'id' => false),
array('action' => 'view', 'method' => 'GET', 'id' => true),
array('action' => 'add', 'method' => 'POST', 'id' => false),
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
array('action' => 'edit', 'method' => 'POST', 'id' => true)
);

/**
* Maintains the request object stack for the current request.
* This will contain more than one request object when requestAction is used.
Expand Down Expand Up @@ -173,83 +159,10 @@ public static function getNamedExpressions() {
return static::$_namedExpressions;
}

/**
* Resource map getter & setter.
*
* Allows you to define the default route configuration for REST routing and
* Router::mapResources()
*
* @param array $resourceMap Resource map
* @return mixed
* @see Router::$_resourceMap
*/
public static function resourceMap($resourceMap = null) {
if ($resourceMap === null) {
return static::$_resourceMap;
}
static::$_resourceMap = $resourceMap;
}

/**
* Connects a new Route in the router.
*
* Routes are a way of connecting request URLs to objects in your application.
* At their core routes are a set or regular expressions that are used to
* match requests to destinations.
*
* Examples:
*
* `Router::connect('/:controller/:action/*');`
*
* The first parameter will be used as a controller name while the second is
* used as the action name. The '/*' syntax makes this route greedy in that
* it will match requests like `/posts/index` as well as requests
* like `/posts/edit/1/foo/bar`.
*
* `Router::connect('/home-page', ['controller' => 'pages', 'action' => 'display', 'home']);`
*
* The above shows the use of route parameter defaults. And providing routing
* parameters for a static route.
*
* {{{
* Router::connect(
* '/:lang/:controller/:action/:id',
* [],
* ['id' => '[0-9]+', 'lang' => '[a-z]{3}']
* );
* }}}
*
* Shows connecting a route with custom route parameters as well as
* providing patterns for those parameters. Patterns for routing parameters
* do not need capturing groups, as one will be added for each route params.
*
* $options offers several 'special' keys that have special meaning
* in the $options array.
*
* - `pass` is used to define which of the routed parameters should be shifted
* into the pass array. Adding a parameter to pass will remove it from the
* regular route array. Ex. `'pass' => array('slug')`.
* - `routeClass` is used to extend and change how individual routes parse requests
* and handle reverse routing, via a custom routing class.
* Ex. `'routeClass' => 'SlugRoute'`
* - `_name` is used to define a specific name for routes. This can be used to optimize
* reverse routing lookups. If undefined a name will be generated for each
* connected route.
* - `_ext` is an array of filename extensions that will be parsed out of the url if present.
* See {@link Route::parseExtensions()}.
*
* You can also add additional conditions for matching routes to the $defaults array.
* The following conditions can be used:
*
* - `[type]` Only match requests for specific content types.
* - `[method]` Only match requests with specific HTTP verbs.
* - `[server]` Only match when $_SERVER['SERVER_NAME'] matches the given value.
*
* Example of using the `[method]` condition:
*
* `Router::connect('/tasks', array('controller' => 'tasks', 'action' => 'index', '[method]' => 'GET'));`
*
* The above route will only be matched for GET requests. POST requests will fail to match this route.
* Compatibility proxy to \Cake\Routing\RouteBuilder::connect() in the `/` scope.
*
* @param string $route A string describing the template of the route
* @param array $defaults An array describing the default route parameters. These parameters will be used by default
Expand All @@ -258,9 +171,10 @@ public static function resourceMap($resourceMap = null) {
* element should match. Also contains additional parameters such as which routed parameters should be
* shifted into the passed arguments, supplying patterns for routing parameters and supplying the name of a
* custom routing class.
* @see routes
* @return void
* @throws \Cake\Error\Exception
* @see \Cake\Routing\RouteBuilder::connect()
* @see \Cake\Routing\Router::scope()
*/
public static function connect($route, $defaults = [], $options = []) {
static::$initialized = true;
Expand All @@ -272,34 +186,15 @@ public static function connect($route, $defaults = [], $options = []) {
/**
* Connects a new redirection Route in the router.
*
* Redirection routes are different from normal routes as they perform an actual
* header redirection if a match is found. The redirection can occur within your
* application or redirect to an outside location.
*
* Examples:
*
* `Router::redirect('/home/*', array('controller' => 'posts', 'action' => 'view'));`
*
* Redirects /home/* to /posts/view and passes the parameters to /posts/view. Using an array as the
* redirect destination allows you to use other routes to define where an URL string should be redirected to.
*
* `Router::redirect('/posts/*', 'http://google.com', array('status' => 302));`
*
* Redirects /posts/* to http://google.com with a HTTP status of 302
*
* ### Options:
*
* - `status` Sets the HTTP status (default 301)
* - `persist` Passes the params to the redirected route, if it can. This is useful with greedy routes,
* routes that end in `*` are greedy. As you can remap URLs and not loose any passed args.
* Compatibility proxy to \Cake\Routing\RouteBuilder::redirect() in the `/` scope.
*
* @param string $route A string describing the template of the route
* @param array $url An URL to redirect to. Can be a string or a Cake array-based URL
* @param array $options An array matching the named elements in the route to regular expressions which that
* element should match. Also contains additional parameters such as which routed parameters should be
* shifted into the passed arguments. As well as supplying patterns for routing parameters.
* @see routes
* @return array Array of routes
* @see \Cake\Routing\RouteBuilder::redirect()
*/
public static function redirect($route, $url, $options = []) {
$options['routeClass'] = 'Cake\Routing\Route\RedirectRoute';
Expand All @@ -312,6 +207,9 @@ public static function redirect($route, $url, $options = []) {
/**
* Generate REST resource routes for the given controller(s).
*
* Compatibility proxy to \Cake\Routing\RouteBuilder::resources(). Additional, compatibility
* around prefixes and plugins and prefixes is handled by this method.
*
* A quick way to generate a default routes to a set of REST resources (controller(s)).
*
* ### Usage
Expand Down Expand Up @@ -354,46 +252,36 @@ public static function redirect($route, $url, $options = []) {
* @return void
*/
public static function mapResources($controller, $options = []) {
$options += array(
'connectOptions' => [],
'id' => static::ID . '|' . static::UUID
);

$connectOptions = $options['connectOptions'];
unset($options['connectOptions']);

foreach ((array)$controller as $name) {
list($plugin, $name) = pluginSplit($name);
$urlName = Inflector::underscore($name);
$pluginUrl = $plugin ? Inflector::underscore($plugin) : null;
$prefix = $ext = null;

$prefix = $pluginUrl = false;
if (!empty($options['prefix'])) {
$prefix = $options['prefix'];
}
if (!empty($options['_ext'])) {
$ext = $options['_ext'];
if ($plugin) {
$pluginUrl = Inflector::underscore($plugin);
}

foreach (static::$_resourceMap as $params) {
$id = $params['id'] ? ':id' : '';
$url = '/' . implode('/', array_filter(array($prefix, $pluginUrl, $urlName, $id)));
$params = array(
'plugin' => $plugin,
'controller' => $name,
'action' => $params['action'],
'[method]' => $params['method'],
'_ext' => $ext
);
if ($prefix) {
$params['prefix'] = $prefix;
}
$routeOptions = array_merge(array(
'id' => $options['id'],
'pass' => array('id')
), $connectOptions);
static::connect($url, $params, $routeOptions);
$callback = function($routes) use ($name, $options) {
$routes->resources($name, $options);
};

if ($plugin && $prefix) {
$path = '/' . implode('/', [$prefix, $pluginUrl]);
$params = ['prefix' => $prefix, 'plugin' => $plugin];
return static::scope($path, $params, $callback);
}

if ($prefix) {
return static::prefix($prefix, $callback);
}

if ($plugin) {
return static::plugin($plugin, $callback);
}

return static::scope('/', $callback);
}
}

Expand Down
39 changes: 4 additions & 35 deletions tests/TestCase/Routing/RouterTest.php
Expand Up @@ -154,7 +154,7 @@ public function testMapResources() {
'controller' => 'Posts',
'action' => 'edit',
'id' => '13',
'[method]' => 'PUT',
'[method]' => ['PUT', 'PATCH'],
'_ext' => null
];
$result = Router::parse('/posts/13');
Expand All @@ -166,7 +166,7 @@ public function testMapResources() {
'controller' => 'Posts',
'action' => 'edit',
'id' => '475acc39-a328-44d3-95fb-015000000000',
'[method]' => 'PUT',
'[method]' => ['PUT', 'PATCH'],
'_ext' => null
];
$result = Router::parse('/posts/475acc39-a328-44d3-95fb-015000000000');
Expand Down Expand Up @@ -208,7 +208,7 @@ public function testMapResources() {
'controller' => 'Posts',
'action' => 'edit',
'id' => 'name',
'[method]' => 'PUT',
'[method]' => ['PUT', 'PATCH'],
'_ext' => null
];
$result = Router::parse('/posts/name');
Expand Down Expand Up @@ -425,7 +425,7 @@ public function testGenerateUrlResourceRoute() {
$expected = '/posts/10';
$this->assertEquals($expected, $result);

$result = Router::url(['controller' => 'Posts', 'action' => 'edit', '[method]' => 'POST', 'id' => 10]);
$result = Router::url(['controller' => 'Posts', 'action' => 'edit', '[method]' => 'PATCH', 'id' => 10]);
$expected = '/posts/10';
$this->assertEquals($expected, $result);
}
Expand Down Expand Up @@ -2508,37 +2508,6 @@ public function testRedirect() {
$this->assertInstanceOf('Cake\Routing\Route\RedirectRoute', $route);
}

/**
* Tests resourceMap as getter and setter.
*
* @return void
*/
public function testResourceMap() {
$default = Router::resourceMap();
$expected = array(
array('action' => 'index', 'method' => 'GET', 'id' => false),
array('action' => 'view', 'method' => 'GET', 'id' => true),
array('action' => 'add', 'method' => 'POST', 'id' => false),
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
array('action' => 'edit', 'method' => 'POST', 'id' => true)
);
$this->assertEquals($expected, $default);

$custom = array(
array('action' => 'index', 'method' => 'GET', 'id' => false),
array('action' => 'view', 'method' => 'GET', 'id' => true),
array('action' => 'add', 'method' => 'POST', 'id' => false),
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
array('action' => 'update', 'method' => 'POST', 'id' => true)
);
Router::resourceMap($custom);
$this->assertEquals(Router::resourceMap(), $custom);

Router::resourceMap($default);
}

/**
* Test that the compatibility method for incoming urls works.
*
Expand Down

0 comments on commit 4b499f6

Please sign in to comment.