@@ -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