Skip to content

Commit

Permalink
Extract route compiler.
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Dec 21, 2016
1 parent b75aca6 commit 9d3ff16
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 147 deletions.
223 changes: 91 additions & 132 deletions src/Illuminate/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Illuminate\Routing\Matching\MethodValidator;
use Illuminate\Routing\Matching\SchemeValidator;
use Illuminate\Http\Exception\HttpResponseException;
use Symfony\Component\Routing\Route as SymfonyRoute;

class Route
{
Expand All @@ -27,63 +26,63 @@ class Route
*
* @var string
*/
protected $uri;
public $uri;

/**
* The HTTP methods the route responds to.
*
* @var array
*/
protected $methods;
public $methods;

/**
* The route action array.
*
* @var array
*/
protected $action;
public $action;

/**
* The controller instance.
*
* @var mixed
*/
protected $controller;
public $controller;

/**
* The default values for the route.
*
* @var array
*/
protected $defaults = [];
public $defaults = [];

/**
* The regular expression requirements.
*
* @var array
*/
protected $wheres = [];
public $wheres = [];

/**
* The array of matched parameters.
*
* @var array
*/
protected $parameters;
public $parameters;

/**
* The parameter names for the route.
*
* @var array|null
*/
protected $parameterNames;
public $parameterNames;

/**
* The compiled version of the route.
*
* @var \Symfony\Component\Routing\CompiledRoute
*/
protected $compiled;
public $compiled;

/**
* The router instance used by the route.
Expand Down Expand Up @@ -166,13 +165,11 @@ protected function isControllerAction()
*/
protected function runCallable()
{
$parameters = $this->resolveMethodDependencies(
$this->parametersWithoutNulls(), new ReflectionFunction($this->action['uses'])
);

$callable = $this->action['uses'];

return $callable(...array_values($parameters));
return $callable(...array_values($this->resolveMethodDependencies(
$this->parametersWithoutNulls(), new ReflectionFunction($this->action['uses'])
)));
}

/**
Expand Down Expand Up @@ -246,101 +243,11 @@ public function matches(Request $request, $includingMethod = true)
*/
protected function compileRoute()
{
if ($this->compiled) {
return;
}

$optionals = $this->extractOptionalParameters();

$uri = preg_replace('/\{(\w+?)\?\}/', '{$1}', $this->uri);

$this->compiled = (
new SymfonyRoute($uri, $optionals, $this->wheres, [], $this->domain() ?: '')
)->compile();
}

/**
* Get the optional parameters for the route.
*
* @return array
*/
protected function extractOptionalParameters()
{
preg_match_all('/\{(\w+?)\?\}/', $this->uri, $matches);

return isset($matches[1]) ? array_fill_keys($matches[1], null) : [];
}

/**
* Get all middleware, including the ones from the controller.
*
* @return array
*/
public function gatherMiddleware()
{
return array_unique(array_merge($this->middleware(), $this->controllerMiddleware()), SORT_REGULAR);
}

/**
* Get or set the middlewares attached to the route.
*
* @param array|string|null $middleware
* @return $this|array
*/
public function middleware($middleware = null)
{
if (is_null($middleware)) {
return (array) Arr::get($this->action, 'middleware', []);
}

if (is_string($middleware)) {
$middleware = func_get_args();
}

$this->action['middleware'] = array_merge(
(array) Arr::get($this->action, 'middleware', []), $middleware
);

return $this;
}

/**
* Get the middleware for the route's controller.
*
* @return array
*/
public function controllerMiddleware()
{
if (! $this->isControllerAction()) {
return [];
if (! $this->compiled) {
$this->compiled = (new RouteCompiler($this))->compile();
}

return ControllerDispatcher::getMiddleware(
$this->getController(), $this->getControllerMethod()
);
}

/**
* Get the parameters that are listed in the route / controller signature.
*
* @param string|null $subClass
* @return array
*/
public function signatureParameters($subClass = null)
{
$action = $this->getAction();

if (is_string($action['uses'])) {
list($class, $method) = explode('@', $action['uses']);

$parameters = (new ReflectionMethod($class, $method))->getParameters();
} else {
$parameters = (new ReflectionFunction($action['uses']))->getParameters();
}

return is_null($subClass) ? $parameters : array_filter($parameters, function ($p) use ($subClass) {
return $p->getClass() && $p->getClass()->isSubclassOf($subClass);
});
return $this->compiled;
}

/**
Expand Down Expand Up @@ -368,18 +275,6 @@ public function hasParameter($name)
return array_key_exists($name, $this->parameters());
}

/**
* Get a given parameter from the route.
*
* @param string $name
* @param mixed $default
* @return string|object
*/
public function getParameter($name, $default = null)
{
return $this->parameter($name, $default);
}

/**
* Get a given parameter from the route.
*
Expand Down Expand Up @@ -475,6 +370,29 @@ protected function compileParameterNames()
}, $matches[1]);
}

/**
* Get the parameters that are listed in the route / controller signature.
*
* @param string|null $subClass
* @return array
*/
public function signatureParameters($subClass = null)
{
$action = $this->getAction();

if (is_string($action['uses'])) {
list($class, $method) = explode('@', $action['uses']);

$parameters = (new ReflectionMethod($class, $method))->getParameters();
} else {
$parameters = (new ReflectionFunction($action['uses']))->getParameters();
}

return is_null($subClass) ? $parameters : array_filter($parameters, function ($p) use ($subClass) {
return $p->getClass() && $p->getClass()->isSubclassOf($subClass);
});
}

/**
* Bind the route to a given request for execution.
*
Expand Down Expand Up @@ -756,16 +674,6 @@ public function getPath()
return $this->uri();
}

/**
* Get the URI associated with the route.
*
* @return string
*/
public function uri()
{
return $this->uri;
}

/**
* Get the HTTP verbs the route responds to.
*
Expand Down Expand Up @@ -828,11 +736,11 @@ public function domain()
}

/**
* Get the URI that the route responds to.
* Get the URI associated with the route.
*
* @return string
*/
public function getUri()
public function uri()
{
return $this->uri;
}
Expand Down Expand Up @@ -949,6 +857,57 @@ public function setAction(array $action)
return $this;
}

/**
* Get all middleware, including the ones from the controller.
*
* @return array
*/
public function gatherMiddleware()
{
return array_unique(array_merge(
$this->middleware(), $this->controllerMiddleware()
), SORT_REGULAR);
}

/**
* Get or set the middlewares attached to the route.
*
* @param array|string|null $middleware
* @return $this|array
*/
public function middleware($middleware = null)
{
if (is_null($middleware)) {
return (array) Arr::get($this->action, 'middleware', []);
}

if (is_string($middleware)) {
$middleware = func_get_args();
}

$this->action['middleware'] = array_merge(
(array) Arr::get($this->action, 'middleware', []), $middleware
);

return $this;
}

/**
* Get the middleware for the route's controller.
*
* @return array
*/
public function controllerMiddleware()
{
if (! $this->isControllerAction()) {
return [];
}

return ControllerDispatcher::getMiddleware(
$this->getController(), $this->getControllerMethod()
);
}

/**
* Get the compiled version of the route.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Routing/RouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function add(Route $route)
*/
protected function addToCollections($route)
{
$domainAndUri = $route->domain().$route->getUri();
$domainAndUri = $route->domain().$route->uri();

foreach ($route->methods() as $method) {
$this->routes[$method][$domainAndUri] = $route;
Expand Down
Loading

0 comments on commit 9d3ff16

Please sign in to comment.