Skip to content

Commit 1a3609a

Browse files
committed
Allow model to provide custom route parameters
1 parent f6945e1 commit 1a3609a

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

src/Macros/LocalizedUrlMacro.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace CodeZero\LocalizedRoutes\Macros;
44

5+
use CodeZero\LocalizedRoutes\ProvidesRouteParameters;
6+
use Illuminate\Support\Collection;
57
use Illuminate\Support\Facades\Route;
68

79
class LocalizedUrlMacro
@@ -14,7 +16,16 @@ class LocalizedUrlMacro
1416
public static function register()
1517
{
1618
Route::macro('localizedUrl', function ($locale = null, $parameters = null, $absolute = true) {
17-
return route(Route::currentRouteName(), $parameters ?: Route::current()->parameters(), $absolute, $locale);
19+
if ( ! $parameters) {
20+
$parameters = Route::current()->parameters();
21+
$model = Collection::make($parameters)->first();
22+
23+
if ($model instanceof ProvidesRouteParameters) {
24+
$parameters = $model->getRouteParameters($locale);
25+
}
26+
}
27+
28+
return route(Route::currentRouteName(), $parameters, $absolute, $locale);
1829
});
1930
}
2031
}

src/ProvidesRouteParameters.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace CodeZero\LocalizedRoutes;
4+
5+
interface ProvidesRouteParameters
6+
{
7+
/**
8+
* Get the route parameters for this model.
9+
*
10+
* @param string|null $locale
11+
*
12+
* @return array
13+
*/
14+
public function getRouteParameters($locale = null);
15+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace CodeZero\LocalizedRoutes\Tests\Stubs;
4+
5+
use CodeZero\LocalizedRoutes\ProvidesRouteParameters;
6+
use Illuminate\Database\Eloquent\Model as BaseModel;
7+
use Illuminate\Support\Facades\App;
8+
9+
class ModelWithCustomRouteParameters extends BaseModel implements ProvidesRouteParameters
10+
{
11+
protected $guarded = [];
12+
13+
/**
14+
* Get the route parameters for this model.
15+
*
16+
* @param string|null $locale
17+
*
18+
* @return array
19+
*/
20+
public function getRouteParameters($locale = null)
21+
{
22+
return [
23+
$this->id,
24+
$this->attributes['slug'][$locale ?: App::getLocale()]
25+
];
26+
}
27+
28+
/**
29+
* Fake route model binding (avoid database for test purpose).
30+
*
31+
* @param int $id
32+
*
33+
* @return mixed
34+
*/
35+
public function resolveRouteBinding($id)
36+
{
37+
return $this;
38+
}
39+
}

tests/Unit/Macros/CurrentUrlMacroTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace CodeZero\LocalizedRoutes\Tests\Unit\Macros;
44

55
use CodeZero\LocalizedRoutes\Tests\Stubs\Model;
6+
use CodeZero\LocalizedRoutes\Tests\Stubs\ModelWithCustomRouteParameters;
67
use CodeZero\LocalizedRoutes\Tests\TestCase;
78
use Illuminate\Support\Facades\App;
89
use Illuminate\Support\Facades\Route;
@@ -42,6 +43,40 @@ public function it_automatically_generates_urls_with_localized_route_keys_for_th
4243
], $response->original);
4344
}
4445

46+
/** @test */
47+
public function you_can_implement_an_interface_and_let_your_model_return_custom_parameters_with_route_model_binding()
48+
{
49+
$this->setSupportedLocales(['en', 'nl']);
50+
51+
$model = (new ModelWithCustomRouteParameters([
52+
'id' => 1,
53+
'slug' => [
54+
'en' => 'en-slug',
55+
'nl' => 'nl-slug',
56+
],
57+
]))->setKeyName('id');
58+
59+
App::instance(ModelWithCustomRouteParameters::class, $model);
60+
61+
Route::localized(function () {
62+
Route::get('route/{model}/{slug}', function (ModelWithCustomRouteParameters $model, $slug) {
63+
return [
64+
'current' => Route::localizedUrl(),
65+
'en' => Route::localizedUrl('en'),
66+
'nl' => Route::localizedUrl('nl'),
67+
];
68+
})->middleware(['web']);
69+
});
70+
71+
$response = $this->call('GET', '/en/route/1/en-slug');
72+
$response->assertOk();
73+
$this->assertEquals([
74+
'current' => url('/en/route/1/en-slug'),
75+
'en' => url('/en/route/1/en-slug'),
76+
'nl' => url('/nl/route/1/nl-slug'),
77+
], $response->original);
78+
}
79+
4580
/** @test */
4681
public function it_cannot_guess_a_localized_route_key_without_route_model_binding()
4782
{

0 commit comments

Comments
 (0)