Skip to content

Commit

Permalink
Add the actions and only options to resources().
Browse files Browse the repository at this point in the history
These options let you limit which routes are connected for a resource
set, and re-map the controller methods used.

Refs #3962
  • Loading branch information
markstory committed Jul 13, 2014
1 parent 48e457e commit 5b40e2d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 13 deletions.
37 changes: 25 additions & 12 deletions src/Routing/RouteBuilder.php
Expand Up @@ -47,14 +47,13 @@ class RouteBuilder {
*
* @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)
);
protected static $_resourceMap = [
'index' => ['action' => 'index', 'method' => 'GET', 'id' => false],
'create' => ['action' => 'add', 'method' => 'POST', 'id' => false],
'view' => ['action' => 'view', 'method' => 'GET', 'id' => true],
'update' => ['action' => 'edit', 'method' => ['PUT', 'PATCH'], 'id' => true],
'delete' => ['action' => 'delete', 'method' => 'DELETE', 'id' => true],
];

/**
* The extensions that should be set into the routes connected.
Expand Down Expand Up @@ -187,6 +186,8 @@ public function params() {
*
* - 'id' - The regular expression fragment to use when matching IDs. By default, matches
* integer values and UUIDs.
* - 'only' - Only connect the specific list of actions.
* - 'actions' - Override the method names used for connecting actions.
*
* @param string|array $name A controller name or array of controller names (i.e. "Posts" or "ListItems")
* @param array $options Options to use when generating REST routes
Expand All @@ -201,10 +202,13 @@ public function resources($name, $options = [], $callback = null) {
}
$options += array(
'connectOptions' => [],
'id' => static::ID . '|' . static::UUID
'id' => static::ID . '|' . static::UUID,
'only' => ['index', 'update', 'create', 'view', 'delete'],
'actions' => [],
);
$options['only'] = (array)$options['only'];

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

$urlName = Inflector::underscore($name);

Expand All @@ -213,12 +217,21 @@ public function resources($name, $options = [], $callback = null) {
$ext = $options['_ext'];
}

foreach (static::$_resourceMap as $params) {
foreach (static::$_resourceMap as $method => $params) {
if (!in_array($method, $options['only'], true)) {
continue;
}

$action = $params['action'];
if (isset($options['actions'][$method])) {
$action = $options['actions'][$method];
}

$id = $params['id'] ? ':id' : '';
$url = '/' . implode('/', array_filter(array($urlName, $id)));
$params = array(
'controller' => $name,
'action' => $params['action'],
'action' => $action,
'[method]' => $params['method'],
'_ext' => $ext
);
Expand Down
57 changes: 56 additions & 1 deletion tests/TestCase/Routing/RouteBuilderTest.php
Expand Up @@ -250,13 +250,68 @@ public function testResources() {
$routes->resources('Articles', ['_ext' => 'json']);

$all = $this->collection->routes();
$this->assertCount(6, $all);
$this->assertCount(5, $all);

$this->assertEquals('/api/articles', $all[0]->template);
$this->assertEquals('json', $all[0]->defaults['_ext']);
$this->assertEquals('Articles', $all[0]->defaults['controller']);
}

/**
* Test the only option of RouteBuilder.
*
* @return void
*/
public function testResourcesOnlyString() {
$routes = new RouteBuilder($this->collection, '/');
$routes->resources('Articles', ['only' => 'index']);

$result = $this->collection->routes();
$this->assertCount(1, $result);
$this->assertEquals('/articles', $result[0]->template);
}

/**
* Test the only option of RouteBuilder.
*
* @return void
*/
public function testResourcesOnlyArray() {
$routes = new RouteBuilder($this->collection, '/');
$routes->resources('Articles', ['only' => ['index', 'delete']]);

$result = $this->collection->routes();
$this->assertCount(2, $result);
$this->assertEquals('/articles', $result[0]->template);
$this->assertEquals('index', $result[0]->defaults['action']);
$this->assertEquals('GET', $result[0]->defaults['[method]']);

$this->assertEquals('/articles/:id', $result[1]->template);
$this->assertEquals('delete', $result[1]->defaults['action']);
$this->assertEquals('DELETE', $result[1]->defaults['[method]']);
}

/**
* Test the actions option of RouteBuilder.
*
* @return void
*/
public function testResourcesActions() {
$routes = new RouteBuilder($this->collection, '/');
$routes->resources('Articles', [
'only' => ['index', 'delete'],
'actions' => ['index' => 'showList']
]);

$result = $this->collection->routes();
$this->assertCount(2, $result);
$this->assertEquals('/articles', $result[0]->template);
$this->assertEquals('showList', $result[0]->defaults['action']);

$this->assertEquals('/articles/:id', $result[1]->template);
$this->assertEquals('delete', $result[1]->defaults['action']);
}

/**
* Test nesting resources
*
Expand Down

0 comments on commit 5b40e2d

Please sign in to comment.