diff --git a/src/Illuminate/Routing/RouteUrlGenerator.php b/src/Illuminate/Routing/RouteUrlGenerator.php index 833726a723f1..cbfd6d5fbe73 100644 --- a/src/Illuminate/Routing/RouteUrlGenerator.php +++ b/src/Illuminate/Routing/RouteUrlGenerator.php @@ -77,8 +77,11 @@ 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); @@ -86,9 +89,16 @@ public function to($route, $parameters = [], $absolute = false) 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; } /** @@ -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() + ); } /** @@ -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); } /** @@ -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); } /** @@ -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. * diff --git a/src/Illuminate/Routing/UrlGenerator.php b/src/Illuminate/Routing/UrlGenerator.php index 6a0a003d339b..d9ccd4161fa9 100755 --- a/src/Illuminate/Routing/UrlGenerator.php +++ b/src/Illuminate/Routing/UrlGenerator.php @@ -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; } /** @@ -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); } /** @@ -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. *