Skip to content

Commit

Permalink
finish cleaning url generation
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Dec 22, 2016
1 parent 39e8c83 commit 098da0d
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 142 deletions.
162 changes: 75 additions & 87 deletions src/Illuminate/Routing/RouteUrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,28 @@ public function to($route, $parameters = [], $absolute = false)
{
$domain = $this->getRouteDomain($route, $parameters);

// First we will construct the entire URI including the root and query string. Once it
// has been constructed, we'll make sure we don't have any missing parameters or we
// will need to throw the exception to let the developers know one was not given.
$uri = $this->addQueryString($this->url->format(
$root = $this->replaceRoot($route, $domain, $parameters),
$root = $this->replaceRootParameters($route, $domain, $parameters),
$this->replaceRouteParameters($route->uri(), $parameters)
), $parameters);

if (preg_match('/\{.*?\}/', $uri)) {
throw UrlGenerationException::forMissingParameters($route);
}

// Once we have ensured that there are no missing parameters in the URI we will encode
// the URI and prepare it for returning to the developer. If the URI is supposed to
// be absolute, we will return it as-is. Otherwise we will remove the URL's root.
$uri = strtr(rawurlencode($uri), $this->dontEncode);

return $absolute ? $uri : '/'.ltrim(str_replace($root, '', $uri), '/');
if (! $absolute) {
return '/'.ltrim(str_replace($root, '', $uri), '/');
}

return $uri;
}

/**
Expand All @@ -112,18 +122,9 @@ protected function getRouteDomain($route, &$parameters)
*/
protected function formatDomain($route, &$parameters)
{
return $this->addPortToDomain($this->getDomainAndScheme($route));
}

/**
* Get the domain and scheme for the route.
*
* @param \Illuminate\Routing\Route $route
* @return string
*/
protected function getDomainAndScheme($route)
{
return $this->getRouteScheme($route).$route->domain();
return $this->addPortToDomain(
$this->getRouteScheme($route).$route->domain()
);
}

/**
Expand All @@ -138,9 +139,9 @@ protected function getRouteScheme($route)
return 'http://';
} elseif ($route->httpsOnly()) {
return 'https://';
} else {
return $this->url->formatScheme(null);
}

return $this->url->formatScheme(null);
}

/**
Expand All @@ -155,11 +156,65 @@ protected function addPortToDomain($domain)

$port = (int) $this->request->getPort();

if (($secure && $port === 443) || (! $secure && $port === 80)) {
return $domain;
}
return ($secure && $port === 443) || (! $secure && $port === 80)
? $domain : $domain.':'.$port;
}

/**
* Replace the parameters on the root path.
*
* @param \Illuminate\Routing\Route $route
* @param string $domain
* @param array $parameters
* @return string
*/
protected function replaceRootParameters($route, $domain, &$parameters)
{
$scheme = $this->getRouteScheme($route);

return $this->replaceRouteParameters(
$this->url->formatRoot($scheme, $domain), $parameters
);
}

/**
* Replace all of the wildcard parameters for a route path.
*
* @param string $path
* @param array $parameters
* @return string
*/
protected function replaceRouteParameters($path, array &$parameters)
{
$path = $this->replaceNamedParameters($path, $parameters);

$path = preg_replace_callback('/\{.*?\}/', function ($match) use (&$parameters) {
return (empty($parameters) && ! Str::endsWith($match[0], '?}'))
? $match[0]
: array_shift($parameters);
}, $path);

return trim(preg_replace('/\{.*?\?\}/', '', $path), '/');
}

return $domain.':'.$port;
/**
* Replace all of the named parameters in the path.
*
* @param string $path
* @param array $parameters
* @return string
*/
protected function replaceNamedParameters($path, &$parameters)
{
return preg_replace_callback('/\{(.*?)\??\}/', function ($m) use (&$parameters) {
if (isset($parameters[$m[1]])) {
return Arr::pull($parameters, $m[1]);
} elseif (isset($this->defaultParameters[$m[1]])) {
return $this->defaultParameters[$m[1]];
} else {
return $m[0];
}
}, $path);
}

/**
Expand Down Expand Up @@ -236,73 +291,6 @@ protected function getNumericParameters(array $parameters)
return array_filter($parameters, 'is_numeric', ARRAY_FILTER_USE_KEY);
}

/**
* Replace the parameters on the root path.
*
* @param \Illuminate\Routing\Route $route
* @param string $domain
* @param array $parameters
* @return string
*/
protected function replaceRoot($route, $domain, &$parameters)
{
return $this->replaceRouteParameters(
$this->formatRouteRoot($route, $domain), $parameters
);
}

/**
* Get the root of the route URL.
*
* @param \Illuminate\Routing\Route $route
* @param string $domain
* @return string
*/
protected function formatRouteRoot($route, $domain)
{
return $this->url->formatRoot($this->getRouteScheme($route), $domain);
}

/**
* Replace all of the wildcard parameters for a route path.
*
* @param string $path
* @param array $parameters
* @return string
*/
protected function replaceRouteParameters($path, array &$parameters)
{
$path = $this->replaceNamedParameters($path, $parameters);

$path = preg_replace_callback('/\{.*?\}/', function ($match) use (&$parameters) {
return (empty($parameters) && ! Str::endsWith($match[0], '?}'))
? $match[0]
: array_shift($parameters);
}, $path);

return trim(preg_replace('/\{.*?\?\}/', '', $path), '/');
}

/**
* Replace all of the named parameters in the path.
*
* @param string $path
* @param array $parameters
* @return string
*/
protected function replaceNamedParameters($path, &$parameters)
{
return preg_replace_callback('/\{(.*?)\??\}/', function ($m) use (&$parameters) {
if (isset($parameters[$m[1]])) {
return Arr::pull($parameters, $m[1]);
} elseif (isset($this->defaultParameters[$m[1]])) {
return $this->defaultParameters[$m[1]];
} else {
return $m[0];
}
}, $path);
}

/**
* Set the default named parameters used by the URL generator.
*
Expand Down
119 changes: 64 additions & 55 deletions src/Illuminate/Routing/UrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -324,69 +324,56 @@ protected function toRoute($route, $parameters, $absolute)
}

/**
* Format the array of URL parameters.
* Get the URL to a controller action.
*
* @param mixed|array $parameters
* @return array
* @param string $action
* @param mixed $parameters
* @param bool $absolute
* @return string
*
* @throws \InvalidArgumentException
*/
public function formatParameters($parameters)
public function action($action, $parameters = [], $absolute = true)
{
$parameters = is_array($parameters) ? $parameters : [$parameters];

foreach ($parameters as $key => $parameter) {
if ($parameter instanceof UrlRoutable) {
$parameters[$key] = $parameter->getRouteKey();
}
if (is_null($route = $this->routes->getByAction($action = $this->formatAction($action)))) {
throw new InvalidArgumentException("Action {$action} not defined.");
}

return $parameters;
return $this->toRoute($route, $parameters, $absolute);
}

/**
* Get the URL to a controller action.
* Format the given controller action.
*
* @param string $action
* @param mixed $parameters
* @param bool $absolute
* @return string
*
* @throws \InvalidArgumentException
*/
public function action($action, $parameters = [], $absolute = true)
protected function formatAction($action)
{
if ($this->rootNamespace && ! (strpos($action, '\\') === 0)) {
$action = $this->rootNamespace.'\\'.$action;
return $this->rootNamespace.'\\'.$action;
} else {
$action = trim($action, '\\');
}

if (! is_null($route = $this->routes->getByAction($action))) {
return $this->toRoute($route, $parameters, $absolute);
return trim($action, '\\');
}

throw new InvalidArgumentException("Action {$action} not defined.");
}

/**
* Get the base URL for the request.
* Format the array of URL parameters.
*
* @param string $scheme
* @param string $root
* @return string
* @param mixed|array $parameters
* @return array
*/
public function formatRoot($scheme, $root = null)
public function formatParameters($parameters)
{
if (is_null($root)) {
if (is_null($this->cachedRoot)) {
$this->cachedRoot = $this->forcedRoot ?: $this->request->root();
}
$parameters = is_array($parameters) ? $parameters : [$parameters];

$root = $this->cachedRoot;
foreach ($parameters as $key => $parameter) {
if ($parameter instanceof UrlRoutable) {
$parameters[$key] = $parameter->getRouteKey();
}
}

$start = Str::startsWith($root, 'http://') ? 'http://' : 'https://';

return preg_replace('~'.$start.'~', $scheme, $root, 1);
return $parameters;
}

/**
Expand All @@ -408,29 +395,25 @@ protected function extractQueryString($path)
}

/**
* Force the scheme for URLs.
* Get the base URL for the request.
*
* @param string $schema
* @return void
* @param string $scheme
* @param string $root
* @return string
*/
public function forceScheme($schema)
public function formatRoot($scheme, $root = null)
{
$this->cachedSchema = null;
if (is_null($root)) {
if (is_null($this->cachedRoot)) {
$this->cachedRoot = $this->forcedRoot ?: $this->request->root();
}

$this->forceScheme = $schema.'://';
}
$root = $this->cachedRoot;
}

/**
* Set the forced root URL.
*
* @param string $root
* @return void
*/
public function forceRootUrl($root)
{
$this->forcedRoot = rtrim($root, '/');
$start = Str::startsWith($root, 'http://') ? 'http://' : 'https://';

$this->cachedRoot = null;
return preg_replace('~'.$start.'~', $scheme, $root, 1);
}

/**
Expand Down Expand Up @@ -495,6 +478,32 @@ public function defaults(array $defaults)
$this->routeUrl()->defaults($defaults);
}

/**
* Force the scheme for URLs.
*
* @param string $schema
* @return void
*/
public function forceScheme($schema)
{
$this->cachedSchema = null;

$this->forceScheme = $schema.'://';
}

/**
* Set the forced root URL.
*
* @param string $root
* @return void
*/
public function forceRootUrl($root)
{
$this->forcedRoot = rtrim($root, '/');

$this->cachedRoot = null;
}

/**
* Set a callback to be used to format the host of generated URLs.
*
Expand Down

0 comments on commit 098da0d

Please sign in to comment.