Skip to content

Commit e4f20e4

Browse files
committed
Refactor UrlGenerator (#78)
1 parent 30caefa commit e4f20e4

File tree

2 files changed

+92
-52
lines changed

2 files changed

+92
-52
lines changed

src/Illuminate/Routing/UrlGenerator.php

Lines changed: 90 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,83 +21,104 @@ class UrlGenerator extends BaseUrlGenerator
2121
*/
2222
public function route($name, $parameters = [], $absolute = true, $locale = null)
2323
{
24-
// If the route exists and we're not requesting a translation,
25-
// let the base class resolve the route.
26-
if (Route::has($name) && $locale === null) {
27-
return parent::route($name, $parameters, $absolute);
28-
}
29-
30-
// Cache the current locale so we can change it
31-
// to automatically resolve any translatable
32-
// route parameters such as slugs.
24+
// Cache the current locale, so we can change it to automatically
25+
// resolve any translatable route parameters such as slugs.
3326
$currentLocale = App::getLocale();
3427

35-
// Use the specified or current locale
36-
// as a prefix for the route name.
37-
$locale = $locale ?: $currentLocale;
28+
$resolvedName = $this->resolveLocalizedRouteName($name, $locale, $currentLocale);
3829

39-
// Check if the locale is supported
40-
if ( ! in_array($locale, $this->getSupportedLocales())) {
41-
// Use a fallback locale if provided
42-
$locale = Config::get('localized-routes.fallback_locale') ?: $locale;
30+
// Update the current locale if needed.
31+
if ($locale !== null && $locale !== $currentLocale) {
32+
App::setLocale($locale);
4333
}
4434

45-
// Normalize the route name by removing any locale prefix.
46-
// We will prepend the applicable locale manually.
47-
$baseName = $this->stripLocaleFromRouteName($name);
35+
$url = parent::route($resolvedName, $parameters, $absolute);
4836

49-
// If the route has a name (not just the locale prefix)
50-
// add the requested locale prefix.
51-
$newName = $baseName ? "{$locale}.{$baseName}" : '';
52-
53-
// If the new localized name does not exist, but the unprefixed route name does,
54-
// someone might be calling "route($name, [], true, $locale)" on a non localized route.
55-
// In that case, resolve the unprefixed route name.
56-
if (Route::has($baseName) && ! Route::has($newName)) {
57-
$newName = $baseName;
37+
// Restore the current locale if needed.
38+
if ($locale !== null && $locale !== $currentLocale) {
39+
App::setLocale($currentLocale);
5840
}
5941

42+
return $url;
43+
}
44+
45+
/**
46+
* Create a signed route URL for a named route.
47+
*
48+
* @param string $name
49+
* @param mixed $parameters
50+
* @param \DateInterval|\DateTimeInterface|int|null $expiration
51+
* @param bool $absolute
52+
* @param string|null $locale
53+
*
54+
* @return string
55+
*/
56+
public function signedRoute($name, $parameters = [], $expiration = null, $absolute = true, $locale = null)
57+
{
58+
// Cache the current locale, so we can change it to automatically
59+
// resolve any translatable route parameters such as slugs.
60+
$currentLocale = App::getLocale();
61+
62+
$resolvedName = $this->resolveLocalizedRouteName($name, $locale, $currentLocale);
63+
6064
// Update the current locale if needed.
61-
if ($locale !== $currentLocale) {
65+
if ($locale !== null && $locale !== $currentLocale) {
6266
App::setLocale($locale);
6367
}
6468

65-
$url = parent::route($newName, $parameters, $absolute);
69+
$url = parent::signedRoute($resolvedName, $parameters, $expiration, $absolute);
6670

6771
// Restore the current locale if needed.
68-
if ($locale !== $currentLocale) {
72+
if ($locale !== null && $locale !== $currentLocale) {
6973
App::setLocale($currentLocale);
7074
}
7175

7276
return $url;
7377
}
7478

7579
/**
76-
* Create a signed route URL for a named route.
80+
* Resolve a localized version of the route name in the given locale.
7781
*
7882
* @param string $name
79-
* @param array $parameters
80-
* @param \DateTimeInterface|\DateInterval|int $expiration
81-
* @param bool $absolute
8283
* @param string|null $locale
84+
* @param string $currentLocale
8385
*
8486
* @return string
8587
*/
86-
public function signedRoute($name, $parameters = [], $expiration = null, $absolute = true, $locale = null)
88+
protected function resolveLocalizedRouteName($name, $locale, $currentLocale)
8789
{
88-
$parameters = $this->formatParameters($parameters);
90+
// If the route exists, and we're not requesting a specific locale,
91+
// let the base class resolve the route.
92+
if (Route::has($name) && $locale === null) {
93+
return $name;
94+
}
8995

90-
if ($expiration) {
91-
$parameters = $parameters + ['expires' => $this->availableAt($expiration)];
96+
// Use the specified or current locale
97+
// as a prefix for the route name.
98+
$locale = $locale ?: $currentLocale;
99+
100+
// If the locale is not supported, use a fallback
101+
// locale if one is configured.
102+
if ( ! $this->isSupportedLocale($locale)) {
103+
$locale = $this->getFallbackLocale() ?: $locale;
92104
}
93105

94-
ksort($parameters);
106+
// Normalize the route name by removing any locale prefix.
107+
// We will prepend the applicable locale manually.
108+
$baseName = $this->stripLocaleFromRouteName($name);
95109

96-
$key = call_user_func($this->keyResolver);
110+
// If the route has a name (not just the locale prefix)
111+
// add the requested locale prefix.
112+
$newName = $baseName ? "{$locale}.{$baseName}" : '';
97113

98-
return $this->route($name, $parameters + [
99-
'signature' => hash_hmac('sha256', $this->route($name, $parameters, $absolute, $locale), $key),
100-
], $absolute, $locale);
114+
// If the new localized route name does not exist, but the unprefixed route name does,
115+
// someone is calling "route($name, [], true, $locale)" on a non localized route.
116+
// In that case, resolve the unprefixed route name.
117+
if (Route::has($baseName) && ! Route::has($newName)) {
118+
$newName = $baseName;
119+
}
120+
121+
return $newName;
101122
}
102123

103124
/**
@@ -117,11 +138,9 @@ protected function stripLocaleFromRouteName($name)
117138
return $name;
118139
}
119140

120-
$locales = $this->getSupportedLocales();
121-
122141
// If the first part of the route name is a valid
123142
// locale, then remove it from the array.
124-
if (in_array($parts[0], $locales)) {
143+
if ($this->isSupportedLocale($parts[0])) {
125144
array_shift($parts);
126145
}
127146

@@ -132,19 +151,40 @@ protected function stripLocaleFromRouteName($name)
132151
}
133152

134153
/**
135-
* Get the supported locales and not the custom domains.
154+
* Check if the given locale is supported.
155+
*
156+
* @param string $locale
157+
*
158+
* @return bool
159+
*/
160+
protected function isSupportedLocale($locale)
161+
{
162+
return in_array($locale, $this->getSupportedLocales());
163+
}
164+
165+
/**
166+
* Get the supported locales and not the custom slugs or domains.
136167
*
137168
* @return array
138169
*/
139170
protected function getSupportedLocales()
140171
{
141172
$locales = Config::get('localized-routes.supported_locales', []);
142-
$keys = array_keys($locales);
143173

144174
if (is_numeric(key($locales))) {
145175
return $locales;
146176
}
147177

148-
return $keys;
178+
return array_keys($locales);
179+
}
180+
181+
/**
182+
* Get the fallback locale.
183+
*
184+
* @return string|null
185+
*/
186+
protected function getFallbackLocale()
187+
{
188+
return Config::get('localized-routes.fallback_locale');
149189
}
150190
}

src/helpers.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<?php
22

3-
if (! function_exists('route')) {
3+
if ( ! function_exists('route')) {
44
/**
55
* Generate the URL to a named route.
66
*
77
* @param string $name
88
* @param array $parameters
99
* @param bool $absolute
10-
* @param null|string $locale
10+
* @param string|null $locale
1111
*
1212
* @return string
1313
*/

0 commit comments

Comments
 (0)