Skip to content

Commit 2ef8150

Browse files
committed
Refactor LocalizedUrlGenerator
1 parent 62ace8b commit 2ef8150

File tree

1 file changed

+91
-37
lines changed

1 file changed

+91
-37
lines changed

src/LocalizedUrlGenerator.php

Lines changed: 91 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@ class LocalizedUrlGenerator
1818
*/
1919
protected $route;
2020

21+
/**
22+
* Supported locales config.
23+
*
24+
* @var array
25+
*/
26+
protected $supportedLocales;
27+
2128
/**
2229
* Create a new LocalizedUrlGenerator instance.
2330
*/
2431
public function __construct()
2532
{
2633
$this->route = Route::current();
34+
$this->supportedLocales = $this->getSupportedLocales();
2735
}
2836

2937
/**
@@ -97,35 +105,21 @@ protected function routeExists()
97105
protected function generateFromUrl($locale = null, $parameters = null, $absolute = true)
98106
{
99107
$locale = $locale ?: App::getLocale();
100-
$supportedLocales = $this->getSupportedLocales();
101-
$locales = $this->getLocaleKeys($supportedLocales);
102-
$domains = $this->getCustomDomains($supportedLocales);
103108
$currentUrl = Request::fullUrl();
104109
$urlParts = parse_url($currentUrl);
110+
$domains = $this->getCustomDomains();
105111

106-
if ($domains !== null) {
107-
$urlParts['host'] = $domains[$locale] ?? $urlParts['host'];
108-
}
112+
// Replace the host with a matching custom domain
113+
// or use the current host by default.
114+
$urlParts['host'] = $domains[$locale] ?? $urlParts['host'];
109115

110-
if ($domains === null) {
116+
if (empty($domains)) {
117+
// Localize the path if no custom domains are configured.
111118
$currentPath = $urlParts['path'] ?? '';
112-
$slugs = explode('/', trim($currentPath, '/'));
113-
$localeSlug = $slugs[0] ?? '';
114-
115-
if (in_array($localeSlug, $locales)) {
116-
$slugs[0] = $locale;
117-
} else {
118-
array_unshift($slugs, $locale);
119-
}
120-
121-
if ($slugs[0] === Config::get('localized-routes.omit_url_prefix_for_locale')) {
122-
$urlParts[0] = '';
123-
} else {
124-
$urlParts['path'] = '/' . join('/', $slugs);
125-
}
119+
$urlParts['path'] = $this->localizeUrlPath($currentPath, $locale);
126120
}
127121

128-
return $urlParts['scheme'] . '://' . $urlParts['host'] . ($urlParts['port'] ?? '') . ($urlParts['path'] ?? '');
122+
return $this->unparseUrl($urlParts);
129123
}
130124

131125
/**
@@ -158,45 +152,106 @@ protected function generateFromRoute($locale = null, $parameters = null, $absolu
158152
}
159153

160154
/**
161-
* Get the custom domains from the supported locales configuration.
155+
* Localize the URL path.
156+
*
157+
* @param string $path
158+
* @param string $requestedLocale
162159
*
163-
* @return array|null
160+
* @return string
164161
*/
165-
protected function getCustomDomains(array $locales)
162+
protected function localizeUrlPath($path, $requestedLocale)
166163
{
167-
return $this->hasCustomDomains($locales) ? $locales : null;
164+
$slugs = explode('/', trim($path, '/'));
165+
166+
if (isset($slugs[0]) && $this->localeIsSupported($slugs[0])) {
167+
// If the existing slug is a supported locale
168+
// replace it with the requested locale.
169+
$slugs[0] = $requestedLocale;
170+
} else {
171+
// If there is no slug, or it is not a supported locale
172+
// prepend the requested locale to the slugs array.
173+
array_unshift($slugs, $requestedLocale);
174+
}
175+
176+
if ($this->localeShouldBeOmitted($requestedLocale)) {
177+
array_shift($slugs);
178+
}
179+
180+
return '/' . join('/', $slugs);
168181
}
169182

170183
/**
171-
* Get the locale keys from the supported locales configuration.
184+
* Create a string from parsed URL parts.
172185
*
173-
* @param array $locales
186+
* @param array $parts
174187
*
175-
* @return array
188+
* @return string
176189
*/
177-
protected function getLocaleKeys(array $locales)
190+
protected function unparseUrl(array $parts)
178191
{
179-
return $this->hasCustomDomains($locales) ? array_keys($locales) : $locales;
192+
return $parts['scheme'] . '://' . $parts['host'] . ($parts['port'] ?? '') . ($parts['path'] ?? '');
180193
}
181194

182195
/**
183196
* Check if custom domains are configured.
184197
*
185-
* @param array $locales
186-
*
187198
* @return bool
188199
*/
189-
protected function hasCustomDomains(array $locales)
200+
protected function hasCustomDomains()
190201
{
191-
$keys = array_keys($locales);
202+
$keys = array_keys($this->supportedLocales);
192203

193-
if (empty($locales) || is_numeric($keys[0])) {
204+
if (empty($this->supportedLocales) || is_numeric($keys[0])) {
194205
return false;
195206
}
196207

197208
return true;
198209
}
199210

211+
/**
212+
* Get the custom domains from the supported locales configuration.
213+
*
214+
* @return array
215+
*/
216+
protected function getCustomDomains()
217+
{
218+
return $this->hasCustomDomains() ? $this->supportedLocales : [];
219+
}
220+
221+
/**
222+
* Get the locale keys from the supported locales configuration.
223+
*
224+
* @return array
225+
*/
226+
protected function getLocaleKeys()
227+
{
228+
return $this->hasCustomDomains() ? array_keys($this->supportedLocales) : $this->supportedLocales;
229+
}
230+
231+
/**
232+
* Check if the given locale should be omitted from the URL.
233+
*
234+
* @param string $locale
235+
*
236+
* @return bool
237+
*/
238+
protected function localeShouldBeOmitted($locale)
239+
{
240+
return $locale === Config::get('localized-routes.omit_url_prefix_for_locale');
241+
}
242+
243+
/**
244+
* Check if the given locale is supported.
245+
*
246+
* @param string $locale
247+
*
248+
* @return bool
249+
*/
250+
protected function localeIsSupported($locale)
251+
{
252+
return in_array($locale, $this->getLocaleKeys());
253+
}
254+
200255
/**
201256
* Get the supported locales and not the custom domains.
202257
*
@@ -205,6 +260,5 @@ protected function hasCustomDomains(array $locales)
205260
protected function getSupportedLocales()
206261
{
207262
return Config::get('localized-routes.supported-locales', []);
208-
209263
}
210264
}

0 commit comments

Comments
 (0)