Skip to content

Commit

Permalink
Extract parameter binding into its own class.
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Dec 21, 2016
1 parent 9d3ff16 commit c906ed9
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 95 deletions.
97 changes: 2 additions & 95 deletions src/Illuminate/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,105 +403,12 @@ public function bind(Request $request)
{
$this->compileRoute();

$this->bindParameters($request);
$this->parameters = (new RouteParameterBinder($this))
->parameters($request);

return $this;
}

/**
* Extract the parameter list from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function bindParameters(Request $request)
{
// If the route has a regular expression for the host part of the URI, we will
// compile that and get the parameter matches for this domain. We will then
// merge them into this parameters array so that this array is completed.
$params = $this->matchToKeys(
array_slice($this->bindPathParameters($request), 1)
);

// If the route has a regular expression for the host part of the URI, we will
// compile that and get the parameter matches for this domain. We will then
// merge them into this parameters array so that this array is completed.
if (! is_null($this->compiled->getHostRegex())) {
$params = $this->bindHostParameters(
$request, $params
);
}

return $this->parameters = $this->replaceDefaults($params);
}

/**
* Get the parameter matches for the path portion of the URI.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function bindPathParameters(Request $request)
{
preg_match($this->compiled->getRegex(), '/'.$request->decodedPath(), $matches);

return $matches;
}

/**
* Extract the parameter list from the host part of the request.
*
* @param \Illuminate\Http\Request $request
* @param array $parameters
* @return array
*/
protected function bindHostParameters(Request $request, $parameters)
{
preg_match($this->compiled->getHostRegex(), $request->getHost(), $matches);

return array_merge($this->matchToKeys(array_slice($matches, 1)), $parameters);
}

/**
* Combine a set of parameter matches with the route's keys.
*
* @param array $matches
* @return array
*/
protected function matchToKeys(array $matches)
{
if (empty($parameterNames = $this->parameterNames())) {
return [];
}

$parameters = array_intersect_key($matches, array_flip($parameterNames));

return array_filter($parameters, function ($value) {
return is_string($value) && strlen($value) > 0;
});
}

/**
* Replace null parameters with their defaults.
*
* @param array $parameters
* @return array
*/
protected function replaceDefaults(array $parameters)
{
foreach ($parameters as $key => $value) {
$parameters[$key] = isset($value) ? $value : Arr::get($this->defaults, $key);
}

foreach ($this->defaults as $key => $value) {
if (! isset($parameters[$key])) {
$parameters[$key] = $value;
}
}

return $parameters;
}

/**
* Parse the route action into a standard array.
*
Expand Down
115 changes: 115 additions & 0 deletions src/Illuminate/Routing/RouteParameterBinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace Illuminate\Routing;

class RouteParameterBinder
{
/**
* The route instance.
*
* @var \Illuminate\Routing\Route
*/
protected $route;

/**
* Create a new Route parameter binder instance.
*
* @param \Illuminate\Routing\Route $route
* @return void
*/
public function __construct($route)
{
$this->route = $route;
}

/**
* Get the parameters for the route.
*
* @return array
*/
public function parameters($request)
{
// If the route has a regular expression for the host part of the URI, we will
// compile that and get the parameter matches for this domain. We will then
// merge them into this parameters array so that this array is completed.
$parameters = $this->bindPathParameters($request);

// If the route has a regular expression for the host part of the URI, we will
// compile that and get the parameter matches for this domain. We will then
// merge them into this parameters array so that this array is completed.
if (! is_null($this->route->compiled->getHostRegex())) {
$parameters = $this->bindHostParameters(
$request, $parameters
);
}

return $this->replaceDefaults($parameters);
}

/**
* Get the parameter matches for the path portion of the URI.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function bindPathParameters($request)
{
preg_match($this->route->compiled->getRegex(), '/'.$request->decodedPath(), $matches);

return $this->matchToKeys(array_slice($matches, 1));
}

/**
* Extract the parameter list from the host part of the request.
*
* @param \Illuminate\Http\Request $request
* @param array $parameters
* @return array
*/
protected function bindHostParameters($request, $parameters)
{
preg_match($this->route->compiled->getHostRegex(), $request->getHost(), $matches);

return array_merge($this->matchToKeys(array_slice($matches, 1)), $parameters);
}

/**
* Combine a set of parameter matches with the route's keys.
*
* @param array $matches
* @return array
*/
protected function matchToKeys(array $matches)
{
if (empty($parameterNames = $this->route->parameterNames())) {
return [];
}

$parameters = array_intersect_key($matches, array_flip($parameterNames));

return array_filter($parameters, function ($value) {
return is_string($value) && strlen($value) > 0;
});
}

/**
* Replace null parameters with their defaults.
*
* @param array $parameters
* @return array
*/
protected function replaceDefaults(array $parameters)
{
foreach ($parameters as $key => $value) {
$parameters[$key] = isset($value) ? $value : Arr::get($this->route->defaults, $key);
}

foreach ($this->route->defaults as $key => $value) {
if (! isset($parameters[$key])) {
$parameters[$key] = $value;
}
}

return $parameters;
}
}

0 comments on commit c906ed9

Please sign in to comment.