2
2
3
3
namespace CodeZero \LocalizedRoutes ;
4
4
5
+ use Illuminate \Database \Eloquent \Model ;
5
6
use Illuminate \Support \Collection ;
6
7
use Illuminate \Support \Facades \App ;
7
8
use Illuminate \Support \Facades \Config ;
@@ -45,7 +46,7 @@ public function __construct()
45
46
*/
46
47
public function generateFromRequest ($ locale = null , $ parameters = null , $ absolute = true )
47
48
{
48
- return ($ this ->isDefault404 () || $ this ->isNonLocalizedFallback404 ())
49
+ return ($ this ->isDefault404 () || $ this ->isNonLocalizedFallback404 () || ! $ this -> routeHasName () )
49
50
? $ this ->generateFromUrl ($ locale , $ parameters , $ absolute )
50
51
: $ this ->generateFromRoute ($ locale , $ parameters , $ absolute );
51
52
}
@@ -113,6 +114,10 @@ protected function generateFromUrl($locale = null, $parameters = null, $absolute
113
114
// or use the current host by default.
114
115
$ urlParts ['host ' ] = $ domains [$ locale ] ?? $ urlParts ['host ' ];
115
116
117
+ if ($ this ->routeExists () && ! $ this ->route ->isFallback ) {
118
+ $ urlParts ['path ' ] = $ this ->replaceParameters ($ locale , $ this ->route ->uri (), $ this ->prepareParameters ($ locale , $ parameters ));
119
+ }
120
+
116
121
if (empty ($ domains )) {
117
122
// Localize the path if no custom domains are configured.
118
123
$ currentPath = $ urlParts ['path ' ] ?? '' ;
@@ -137,16 +142,7 @@ protected function generateFromRoute($locale = null, $parameters = null, $absolu
137
142
return URL ::current ();
138
143
}
139
144
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 );
150
146
151
147
return route ($ this ->route ->getName (), $ parameters , $ absolute , $ locale );
152
148
}
@@ -261,4 +257,102 @@ protected function getSupportedLocales()
261
257
{
262
258
return Config::get ('localized-routes.supported-locales ' , []);
263
259
}
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
+ }
264
358
}
0 commit comments