Skip to content
This repository was archived by the owner on Sep 19, 2022. It is now read-only.

Better RESTful routing #19

Merged
merged 1 commit into from
Jan 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,28 @@ Minimal bootstrap file for this example

## Configuration

### RESTful Routing

You can define the http method that routes use by adding it to the beginning of the route and separating the http method and the path by a space (or any whitespace char(s) [space, tab, newline]).

$app->addRoutes(array(
'/' => 'Home:index',
'get /posts' => 'Posts:index',
'get /posts/:id' => 'Posts:show',
'post /posts' => 'Posts:create'
));

Leading spaces in routes are ignored and all spaces in between the http method and the route are ignored so that you can have sexy indenting like this:

$app->addRoutes(array(
' /' => 'Home:index',
'get /posts' => 'Posts:index',
'get /posts/:id' => 'Posts:show',
'post /posts' => 'Posts:create'
));

If you don't specify an http method then that route will work with any http method.

### controller.class_prefix

Optional class prefix for controller classes. Will be prepended to routes.
Expand Down Expand Up @@ -162,9 +184,8 @@ Defaults to `twig`. Will be appended to template name given in `render()` method
error_log("ADDITIONAL MIDDLWARE FOR SINGLE ROUTE");
}
),
'/hello/:name' => array(
'post /hello/:name' => array(
'Home:hello',
'post',
function() {
error_log("THIS ROUTE IS ONLY POST");
}
Expand Down
23 changes: 12 additions & 11 deletions src/SlimController/Slim.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,17 @@ public function addRoutes(array $routes, $middlewares = null)
array_shift($args);
$middlewares = $args;

foreach ($routes as $path => $routeArgs) {
$httpMethod = 'any';
foreach ($routes as $p => $routeArgs) {
$path = $p;
$httpMethod = null;

if (preg_match('/^\s*(?P<method>[\S]+)\s+(?P<path>.+)$/', $path, $matches)) {
$httpMethod = strtoupper($matches['method']);
$path = $matches['path'];
if (!in_array($httpMethod, static::$ALLOWED_HTTP_METHODS)) {
throw new \InvalidArgumentException("Http method '$httpMethod' is not supported.");
}
}

// simple
if (!is_array($routeArgs)) {
Expand All @@ -79,18 +88,10 @@ public function addRoutes(array $routes, $middlewares = null)

$classRoute = array_shift($routeArgs);

// specific HTTP method
if (count($routeArgs) > 0 && is_string($routeArgs[0])) {
$httpMethod = strtoupper(array_shift($routeArgs));
if (!in_array($httpMethod, static::$ALLOWED_HTTP_METHODS)) {
throw new \InvalidArgumentException("Http method '$httpMethod' is not supported.");
}
}

$routeMiddlewares = array_merge($routeArgs, $middlewares);
$route = $this->addControllerRoute($path, $classRoute, $routeMiddlewares)->name($classRoute);

if ('any' === $httpMethod) {
if (is_null($httpMethod)) {
call_user_func_array(array($route, 'via'), static::$ALLOWED_HTTP_METHODS);
} else {
$route->via($httpMethod);
Expand Down
17 changes: 14 additions & 3 deletions tests/SlimController/Tests/SlimTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,22 @@ public function testAddRoutesWithVariables()
$this->assertEquals(1, count($this->app->router()->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
}

public function testAddRoutesInExtendedFormat()
public function testAddRoutesInRestFormat()
{
$this->setUrl('/bla');
$this->app->addRoutes(array(
'/bla' => array('Controller:index', 'get')
'get /bla' => 'Controller:index'
));
$this->assertEquals(1, count($this->app->router()->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
}

public function testAddRoutesInRestFormatWithMultipleWhiteSpaceChars()
{
$this->setUrl('/bla');
$this->app->addRoutes(array(
' get

/bla' => 'Controller:index'
));
$this->assertEquals(1, count($this->app->router()->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
}
Expand Down Expand Up @@ -124,7 +135,7 @@ public function testFailToAddRouteForUnsupportedHttpMethod()
{
$this->setUrl('/bla');
$this->app->addRoutes(array(
'/bla' => array('Controller:index', 'foo')
'foo /bla' => 'Controller:index'
));
}

Expand Down