22
33namespace CodeZero \LocalizedRoutes ;
44
5+ use Illuminate \Database \Eloquent \Model ;
56use Illuminate \Support \Collection ;
67use Illuminate \Support \Facades \App ;
78use Illuminate \Support \Facades \Config ;
@@ -45,7 +46,7 @@ public function __construct()
4546 */
4647 public function generateFromRequest ($ locale = null , $ parameters = null , $ absolute = true )
4748 {
48- return ($ this ->isDefault404 () || $ this ->isNonLocalizedFallback404 ())
49+ return ($ this ->isDefault404 () || $ this ->isNonLocalizedFallback404 () || ! $ this -> routeHasName () )
4950 ? $ this ->generateFromUrl ($ locale , $ parameters , $ absolute )
5051 : $ this ->generateFromRoute ($ locale , $ parameters , $ absolute );
5152 }
@@ -113,6 +114,10 @@ protected function generateFromUrl($locale = null, $parameters = null, $absolute
113114 // or use the current host by default.
114115 $ urlParts ['host ' ] = $ domains [$ locale ] ?? $ urlParts ['host ' ];
115116
117+ if ($ this ->routeExists () && ! $ this ->route ->isFallback ) {
118+ $ urlParts ['path ' ] = $ this ->replaceParameters ($ locale , $ this ->route ->uri (), $ this ->prepareParameters ($ locale , $ parameters ));
119+ }
120+
116121 if (empty ($ domains )) {
117122 // Localize the path if no custom domains are configured.
118123 $ currentPath = $ urlParts ['path ' ] ?? '' ;
@@ -137,16 +142,7 @@ protected function generateFromRoute($locale = null, $parameters = null, $absolu
137142 return URL ::current ();
138143 }
139144
140- $ parameters = $ parameters ?: $ this ->route ->parameters ();
141- $ model = Collection::make ($ parameters )->first ();
142-
143- if ($ model instanceof ProvidesRouteParameters) {
144- $ parameters = $ model ->getRouteParameters ($ locale );
145- }
146-
147- if (is_callable ($ parameters )) {
148- $ parameters = $ parameters ($ locale );
149- }
145+ $ parameters = $ this ->prepareParameters ($ locale , $ parameters );
150146
151147 return route ($ this ->route ->getName (), $ parameters , $ absolute , $ locale );
152148 }
@@ -261,4 +257,102 @@ protected function getSupportedLocales()
261257 {
262258 return Config::get ('localized-routes.supported-locales ' , []);
263259 }
260+
261+ /**
262+ * Check if the route has a name.
263+ *
264+ * @return bool
265+ */
266+ protected function routeHasName ()
267+ {
268+ return $ this ->routeExists () && $ this ->stripLocaleFromRouteName ($ this ->route ->getName ()) !== '' ;
269+ }
270+
271+ /**
272+ * Strip the locale from the beginning of a route name.
273+ *
274+ * @param string $name
275+ *
276+ * @return string
277+ */
278+ protected function stripLocaleFromRouteName ($ name )
279+ {
280+ $ parts = explode ('. ' , $ name );
281+
282+ // If there is no dot in the route name,
283+ // there is no locale in the route name.
284+ if (count ($ parts ) === 1 ) {
285+ return $ name ;
286+ }
287+
288+ $ locales = $ this ->getLocaleKeys ();
289+
290+ // If the first part of the route name is a valid
291+ // locale, then remove it from the array.
292+ if (in_array ($ parts [0 ], $ locales )) {
293+ array_shift ($ parts );
294+ }
295+
296+ // Rebuild the normalized route name.
297+ $ name = join ('. ' , $ parts );
298+
299+ return $ name ;
300+ }
301+
302+ /**
303+ * Prepare any route parameters.
304+ *
305+ * @param string $locale
306+ * @param mixed $parameters
307+ *
308+ * @return array
309+ */
310+ protected function prepareParameters ($ locale , $ parameters )
311+ {
312+ if ($ this ->routeExists () && $ parameters === null ) {
313+ $ parameters = $ this ->route ->parameters ();
314+ }
315+
316+ $ model = Collection::make ($ parameters )->first ();
317+
318+ if ($ model instanceof ProvidesRouteParameters) {
319+ $ parameters = $ model ->getRouteParameters ($ locale );
320+ }
321+
322+ if (is_callable ($ parameters )) {
323+ $ parameters = $ parameters ($ locale );
324+ }
325+
326+ return $ parameters ;
327+ }
328+
329+ /**
330+ * Replace parameter placeholders with their value.
331+ *
332+ * @param string $locale
333+ * @param string $uri
334+ * @param array $parameters
335+ *
336+ * @return string
337+ */
338+ protected function replaceParameters ($ locale , $ uri , array $ parameters )
339+ {
340+ preg_match_all ('/{([a-z_.-]+)}/ ' , $ uri , $ matches );
341+ $ paramKeys = $ matches [1 ] ?? [];
342+
343+ foreach ($ paramKeys as $ index => $ key ) {
344+ $ value = $ parameters [$ key ] ?? $ parameters [$ index ];
345+
346+ if ($ value instanceof Model) {
347+ $ originalLocale = App::getLocale ();
348+ App::setLocale ($ locale );
349+ $ value = $ value ->getRouteKey ();
350+ App::setLocale ($ originalLocale );
351+ }
352+
353+ $ uri = str_replace ("{ {$ key }} " , $ value , $ uri );
354+ }
355+
356+ return $ uri ;
357+ }
264358}
0 commit comments