refactoring. added default controller. added uri class.

This commit is contained in:
Taylor Otwell
2011-10-24 21:00:51 -05:00
parent 320653e832
commit d4ddb05abb
13 changed files with 200 additions and 134 deletions

View File

@@ -122,11 +122,16 @@ class Router {
foreach ($routes as $keys => $callback)
{
// Formats are appended to the route key as a regular expression.
// It will look something like: "(\.(json|xml|html))?"
$formats = $this->provides($callback);
// Only check routes that have multiple URIs or wildcards since other
// routes would have been caught by the check for literal matches.
if (strpos($keys, '(') !== false or strpos($keys, ',') !== false)
// We also need to check routes with "provides" clauses.
if ($this->fuzzy($keys) or ! is_null($formats))
{
if ( ! is_null($route = $this->match($destination, $keys, $callback)))
if ( ! is_null($route = $this->match($destination, $keys, $callback, $formats)))
{
return Request::$route = $route;
}
@@ -136,6 +141,21 @@ class Router {
return Request::$route = $this->controller($method, $uri, $destination);
}
/**
* Determine if the route contains elements that forbid literal matches.
*
* Any route key containing a regular expression, wildcard, or multiple
* URIs cannot be matched using a literal string check, but must be
* checked using regular expressions.
*
* @param string $keys
* @return bool
*/
protected function fuzzy($keys)
{
return strpos($keys, '(') !== false or strpos($keys, ',') !== false;
}
/**
* Attempt to match a given route destination to a given route.
*
@@ -146,20 +166,18 @@ class Router {
* @param string $destination
* @param array $keys
* @param mixed $callback
* @param array $formats
* @return mixed
*/
protected function match($destination, $keys, $callback)
protected function match($destination, $keys, $callback, $formats)
{
// Append the provided formats to the route as an optional regular expression.
// This should make the route look something like: "user(\.(json|xml|html))?"
$formats = ( ! is_null($formats)) ? '(\.('.implode('|', $formats).'))?' : '';
foreach (explode(', ', $keys) as $key)
{
// Append the provided formats to the route as an optional regular expression.
// This should make the route look something like: "user(\.(json|xml|html))?"
if ( ! is_null($formats = $this->provides($callback)))
{
$key .= '(\.('.implode('|', $formats).'))?';
}
if (preg_match('#^'.$this->wildcards($key).'$#', $destination))
if (preg_match('#^'.$this->wildcards($key).$formats.'$#', $destination))
{
return new Route($keys, $callback, $this->parameters($destination, $key));
}
@@ -185,19 +203,13 @@ class Router {
if ( ! is_null($key = $this->controller_key($segments)))
{
// Create the controller name for the current request. This controller
// name will be returned by the anonymous route we will create. Instead
// of using directory slashes, dots will be used to specify the controller
// location with the controllers directory.
// Extract the controller name from the URI segments.
$controller = implode('.', array_slice($segments, 0, $key));
// Now that we have the controller path and name, we can slice the controller
// section of the URI from the array of segments.
// Remove the controller name from the URI.
$segments = array_slice($segments, $key);
// Extract the controller method from the URI segments. If no more segments
// are remaining after slicing off the controller, the "index" method will
// be used as the default controller method.
// Extract the controller method from the remaining segments.
$method = (count($segments) > 0) ? array_shift($segments) : 'index';
return new Route($destination, $controller.'@'.$method, $segments);
@@ -206,12 +218,12 @@ class Router {
/**
* Search the controllers for the application and determine if an applicable
* controller exists for the current request.
* controller exists for the current request to the application.
*
* If a controller is found, the array key for the controller name in the URI
* segments will be returned by the method, otherwise NULL will be returned.
* The deepest possible matching controller will be considered the controller
* that should handle the request.
* The deepest possible controller will be considered the controller that
* should handle the request.
*
* @param array $segments
* @return int
@@ -276,7 +288,21 @@ class Router {
*/
protected function parameters($uri, $route)
{
return array_values(array_intersect_key(explode('/', $uri), preg_grep('/\(.+\)/', explode('/', $route))));
list($uri, $route) = array(explode('/', $uri), explode('/', $route));
$count = count($route);
$parameters = array();
for ($i = 0; $i < $count; $i++)
{
if (preg_match('/\(.+\)/', $route[$i]))
{
$parameters[] = $uri[$i];
}
}
return $parameters;
}
}