From 2926f161ad05e93b0c73f1a9f92d0d8bc9762651 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Thu, 11 Nov 2021 03:30:43 +0100 Subject: [PATCH 01/20] Adds support for implicit route model binding with translated slugs --- src/HasTranslatableSlug.php | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index 4abdd81..517dc2d 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -2,6 +2,9 @@ namespace Spatie\Sluggable; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Illuminate\Support\Traits\Localizable; @@ -120,4 +123,45 @@ protected function hasCustomSlugBeenUsed(): bool return $originalSlug !== $newSlug; } + + public function resolveRouteBinding($value, $field = null): Model|null + { + if ($field ?? $this->getRouteKeyName() !== $this->getSlugOptions()->slugField) { + return parent::resolveRouteBinding($value, $field); + } + + return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) + ->first(); + } + + public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null + { + if ($field ?? $this->getRouteKeyName() !== $this->getSlugOptions()->slugField) { + return $this->where($field ?? $this->getRouteKeyName(), $value)->withTrashed()->first(); + } + + return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) + ->withTrashed()->first(); + } + + public function resolveChildRouteBindingQuery($childType, $value, $field): Model|null + { + if ($field !== $this->getSlugOptions()->slugField) { + return parent::resolveChildRouteBindingQuery($childType, $value, $field); + } + + $relationship = $this->{Str::plural(Str::camel($childType))}(); + + $field = $field ?: $relationship->getRelated()->getRouteKeyName(); + + if ($relationship instanceof HasManyThrough || + $relationship instanceof BelongsToMany) { + return $relationship->whereJsonContains( + $relationship->getRelated()->getTable() . '.' . $field . '->' . $this->getLocale(), + $value + ); + } else { + return $relationship->whereJsonContains($field . '->' . $this->getLocale(), $value); + } + } } From 58659f3e111d7738a99f501343a80dc2c1158ea4 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Thu, 11 Nov 2021 22:49:54 +0100 Subject: [PATCH 02/20] Fixes runtime exception being thrown when database doesn't support json operations Fixes invalid model binding when field is set --- src/HasTranslatableSlug.php | 46 ++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index 517dc2d..5c03f52 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -126,22 +126,34 @@ protected function hasCustomSlugBeenUsed(): bool public function resolveRouteBinding($value, $field = null): Model|null { - if ($field ?? $this->getRouteKeyName() !== $this->getSlugOptions()->slugField) { + if (($field ?? $this->getRouteKeyName()) !== $this->getSlugOptions()->slugField) { return parent::resolveRouteBinding($value, $field); } - return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) - ->first(); + // Only some database types support json operations. + // If the database doesn't support it, null is returned as default method would do the same + try { + return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) + ->first(); + } catch (\RuntimeException $exception) { + return null; + } } public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null { - if ($field ?? $this->getRouteKeyName() !== $this->getSlugOptions()->slugField) { + if (($field ?? $this->getRouteKeyName()) !== $this->getSlugOptions()->slugField) { return $this->where($field ?? $this->getRouteKeyName(), $value)->withTrashed()->first(); } - return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) - ->withTrashed()->first(); + // Only some database types support json operations. + // If the database doesn't support it, null is returned as default method would do the same + try { + return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) + ->withTrashed()->first(); + } catch (\RuntimeException $exception) { + return null; + } } public function resolveChildRouteBindingQuery($childType, $value, $field): Model|null @@ -154,14 +166,20 @@ public function resolveChildRouteBindingQuery($childType, $value, $field): Model $field = $field ?: $relationship->getRelated()->getRouteKeyName(); - if ($relationship instanceof HasManyThrough || - $relationship instanceof BelongsToMany) { - return $relationship->whereJsonContains( - $relationship->getRelated()->getTable() . '.' . $field . '->' . $this->getLocale(), - $value - ); - } else { - return $relationship->whereJsonContains($field . '->' . $this->getLocale(), $value); + // Only some database types support json operations. + // If the database doesn't support it, null is returned as default method would do the same + try { + if ($relationship instanceof HasManyThrough || + $relationship instanceof BelongsToMany) { + return $relationship->whereJsonContains( + $relationship->getRelated()->getTable() . '.' . $field . '->' . $this->getLocale(), + $value + ); + } else { + return $relationship->whereJsonContains($field . '->' . $this->getLocale(), $value); + } + } catch (\RuntimeException $exception) { + return null; } } } From fdd966204657e20568a91e1d96cbb70712a90d8c Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Thu, 11 Nov 2021 23:06:08 +0100 Subject: [PATCH 03/20] Updates README.md --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 22e4db4..e6c69ed 100644 --- a/README.md +++ b/README.md @@ -339,6 +339,43 @@ class YourEloquentModel extends Model } } ``` +You canb also use laravels [implicip route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use the feature make sure that the slug column matches the `routeNameKey`. +Currently only some database types support json opterations. Further information about which databases support json can be fund in the [laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). +```php +namespace App; + +use Spatie\Sluggable\HasSlug; +use Spatie\Sluggable\SlugOptions; +use Illuminate\Database\Eloquent\Model; + +class YourEloquentModel extends Model +{ + use HasTranslations, HasTranslatableSlug; + + public $translatable = ['name', 'slug']; + + /** + * Get the options for generating the slug. + */ + public function getSlugOptions() : SlugOptions + { + return SlugOptions::create() + ->generateSlugsFrom('name') + ->saveSlugsTo('slug'); + } + + /** + * Get the route key for the model. + * + * @return string + */ + public function getRouteKeyName() + { + return 'slug'; + } +} +``` + ## Changelog From a955f761ff72f8bdf3ea45966934f927bcfe4c3c Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Thu, 11 Nov 2021 23:30:39 +0100 Subject: [PATCH 04/20] Fixed style issue --- src/HasTranslatableSlug.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index 5c03f52..c396a4d 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -97,7 +97,7 @@ protected function slugIsBasedOnTitle(): bool $slugSeparator = $currentSlug[strlen($titleSlug)]; $slugIdentifier = substr($currentSlug, strlen($titleSlug) + 1); - return $slugSeparator === $this->slugOptions->slugSeparator && is_numeric($slugIdentifier); + return $slugSeparator === $this->slugOptions->slugSeparator && is_numeric($slugIdentifier); } protected function getOriginalSourceString(): string From fe4189cc131ccc812ff3b0482dc4484d8df4b2c9 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Mon, 15 Nov 2021 00:56:48 +0100 Subject: [PATCH 05/20] Adds support for SQLite databases --- src/HasTranslatableSlug.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index c396a4d..d23a917 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -133,7 +133,7 @@ public function resolveRouteBinding($value, $field = null): Model|null // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { - return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) + return $this->where($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) ->first(); } catch (\RuntimeException $exception) { return null; @@ -143,13 +143,13 @@ public function resolveRouteBinding($value, $field = null): Model|null public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null { if (($field ?? $this->getRouteKeyName()) !== $this->getSlugOptions()->slugField) { - return $this->where($field ?? $this->getRouteKeyName(), $value)->withTrashed()->first(); + return parent::resolveSoftDeletableRouteBinding($value, $field); } // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { - return $this->whereJsonContains($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) + return $this->where($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) ->withTrashed()->first(); } catch (\RuntimeException $exception) { return null; @@ -171,12 +171,12 @@ public function resolveChildRouteBindingQuery($childType, $value, $field): Model try { if ($relationship instanceof HasManyThrough || $relationship instanceof BelongsToMany) { - return $relationship->whereJsonContains( + return $relationship->where( $relationship->getRelated()->getTable() . '.' . $field . '->' . $this->getLocale(), $value ); } else { - return $relationship->whereJsonContains($field . '->' . $this->getLocale(), $value); + return $relationship->where($field . '->' . $this->getLocale(), $value); } } catch (\RuntimeException $exception) { return null; From 2618a5ac5920b44c37b70776f9c3c3d0ed319e50 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Mon, 15 Nov 2021 00:57:33 +0100 Subject: [PATCH 06/20] Adds tests --- tests/HasTranslatableSlugTest.php | 52 ++++++++++++++++++++++++++ tests/TestCase.php | 9 +++++ tests/TranslatableModelSoftDeletes.php | 37 ++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 tests/TranslatableModelSoftDeletes.php diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index f62afcd..2ac1ebe 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -302,4 +302,56 @@ public function it_can_update_slug_with_non_unique_names_multiple() $this->assertSame($expectedSlug, $model->getTranslation('slug', 'en')); } } + + + /** @test */ + public function it_can_resolve_route_binding() + { + $model = new TranslatableModel(); + + $model->setTranslation('name', 'en', 'Test value EN'); + $model->setTranslation('name', 'nl', 'Test value NL'); + $model->setTranslation('slug', 'en', 'updated-value-en'); + $model->setTranslation('slug', 'nl', 'updated-value-nl'); + $model->save(); + + // Test for em locale + $result = (new TranslatableModel())->resolveRouteBinding('updated-value-en', 'slug'); + + $this->assertNotNull($result); + $this->assertEquals($model->id, $result->id); + + // Test for nl locale + $this->app->setLocale('nl'); + + $result = (new TranslatableModel())->resolveRouteBinding('updated-value-nl', 'slug'); + + $this->assertNotNull($result); + $this->assertEquals($model->id, $result->id); + + // Test for fr locale - should fail + $this->app->setLocale('fr'); + $result = (new TranslatableModel())->resolveRouteBinding('updated-value-nl', 'slug'); + $this->assertNull($result); + } + + /** @test */ + public function it_can_resolve_route_binding_even_when_soft_deletes_are_on() + { + foreach (range(1, 10) as $i) { + $model = new TranslatableModelSoftDeletes(); + $model->setTranslation('name', 'en', 'Test value EN'); + $model->setTranslation('slug', 'en', 'updated-value-en-' . $i); + $model->save(); + $model->delete(); + + $result = (new TranslatableModelSoftDeletes())->resolveSoftDeletableRouteBinding( + 'updated-value-en-' . $i, + 'slug' + ); + + $this->assertNotNull($result); + $this->assertEquals($model->id, $result->id); + } + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 6884953..6c36d85 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -64,6 +64,15 @@ protected function setUpDatabase(Application $app) $table->text('slug')->nullable(); }); + $app['db']->connection()->getSchemaBuilder()->create('translatable_model_soft_deletes', function (Blueprint $table) { + $table->increments('id'); + $table->text('name')->nullable(); + $table->text('other_field')->nullable(); + $table->text('non_translatable_field')->nullable(); + $table->text('slug')->nullable(); + $table->softDeletes(); + }); + $app['db']->connection()->getSchemaBuilder()->create('scopeable_models', function (Blueprint $table) { $table->increments('id'); $table->text('name')->nullable(); diff --git a/tests/TranslatableModelSoftDeletes.php b/tests/TranslatableModelSoftDeletes.php new file mode 100644 index 0000000..bc4f397 --- /dev/null +++ b/tests/TranslatableModelSoftDeletes.php @@ -0,0 +1,37 @@ +customSlugOptions = $slugOptions; + } + + public function getSlugOptions(): SlugOptions + { + return $this->customSlugOptions ?: SlugOptions::create() + ->generateSlugsFrom('name') + ->saveSlugsTo('slug'); + } +} From 46345125c042e43538cf78b63d53b06a26bfa798 Mon Sep 17 00:00:00 2001 From: Freek Van der Herten Date: Mon, 15 Nov 2021 08:41:50 +0100 Subject: [PATCH 07/20] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e6c69ed..4e2c3b7 100644 --- a/README.md +++ b/README.md @@ -339,8 +339,9 @@ class YourEloquentModel extends Model } } ``` -You canb also use laravels [implicip route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use the feature make sure that the slug column matches the `routeNameKey`. -Currently only some database types support json opterations. Further information about which databases support json can be fund in the [laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). +You can also use Laravels [implicip route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use the feature make sure that the slug column matches the `routeNameKey`. +Currently only some database types support JSON opterations. Further information about which databases support JSON can be fund in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). + ```php namespace App; From d127805379149eb3f071052a0a5918857e30744e Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Mon, 15 Nov 2021 10:26:56 +0100 Subject: [PATCH 08/20] Adds full route test --- tests/HasTranslatableSlugTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index 2ac1ebe..9230e35 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -2,6 +2,7 @@ namespace Spatie\Sluggable\Tests; +use Illuminate\Support\Facades\Route; use Spatie\Sluggable\SlugOptions; class HasTranslatableSlugTest extends TestCase @@ -354,4 +355,23 @@ public function it_can_resolve_route_binding_even_when_soft_deletes_are_on() $this->assertEquals($model->id, $result->id); } } + /** @test */ + public function it_can_bind_route_model_implicit() + { + $model = new TranslatableModel(); + $model->setTranslation('name', 'en', 'Test value EN'); + $model->setTranslation('slug', 'en', 'updated-value-en'); + $model->save(); + + Route::get( + '/translatable-model/{test:slug}', + function (TranslatableModel $test) use ($model) { + $this->assertNotNull($test); + $this->assertEquals($model->id, $test->id); + } + )->middleware('bindings'); + + $result = $this->get("/translatable-model/updated-value-en"); + $this->assertEquals(200, $result->status()); + } } From 23b28008326dde7aa113b10ec781424090d00429 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Mon, 15 Nov 2021 10:59:52 +0100 Subject: [PATCH 09/20] Updates style Fixes typo --- src/HasTranslatableSlug.php | 17 +++++++---------- tests/HasTranslatableSlugTest.php | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index d23a917..0326ec9 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -129,12 +129,11 @@ public function resolveRouteBinding($value, $field = null): Model|null if (($field ?? $this->getRouteKeyName()) !== $this->getSlugOptions()->slugField) { return parent::resolveRouteBinding($value, $field); } - // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { - return $this->where($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) - ->first(); + return $this + ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->first(); } catch (\RuntimeException $exception) { return null; } @@ -149,8 +148,8 @@ public function resolveSoftDeletableRouteBinding($value, $field = null): Model|n // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { - return $this->where($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) - ->withTrashed()->first(); + return $this + ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->withTrashed()->first(); } catch (\RuntimeException $exception) { return null; } @@ -171,12 +170,10 @@ public function resolveChildRouteBindingQuery($childType, $value, $field): Model try { if ($relationship instanceof HasManyThrough || $relationship instanceof BelongsToMany) { - return $relationship->where( - $relationship->getRelated()->getTable() . '.' . $field . '->' . $this->getLocale(), - $value - ); + return $relationship + ->where("{$relationship->getRelated()->getTable()}.{$field}->{$this->getLocale()}", $value); } else { - return $relationship->where($field . '->' . $this->getLocale(), $value); + return $relationship->where("{$field}->{$this->getLocale()}", $value); } } catch (\RuntimeException $exception) { return null; diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index 9230e35..fa580c4 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -316,7 +316,7 @@ public function it_can_resolve_route_binding() $model->setTranslation('slug', 'nl', 'updated-value-nl'); $model->save(); - // Test for em locale + // Test for en locale $result = (new TranslatableModel())->resolveRouteBinding('updated-value-en', 'slug'); $this->assertNotNull($result); From 10fb7ee218b5de7e83ed0f3f66a6ee0391732529 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Mon, 15 Nov 2021 10:59:52 +0100 Subject: [PATCH 10/20] Updates style Fixes typo --- src/HasTranslatableSlug.php | 38 +++++++++++++++---------------- tests/HasTranslatableSlugTest.php | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index d23a917..7cb9b55 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -8,6 +8,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\Str; use Illuminate\Support\Traits\Localizable; +use RuntimeException; trait HasTranslatableSlug { @@ -126,59 +127,58 @@ protected function hasCustomSlugBeenUsed(): bool public function resolveRouteBinding($value, $field = null): Model|null { - if (($field ?? $this->getRouteKeyName()) !== $this->getSlugOptions()->slugField) { + $field = $field ?? $this->getRouteKeyName(); + if ($field !== $this->getSlugOptions()->slugField) { return parent::resolveRouteBinding($value, $field); } - // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { - return $this->where($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) - ->first(); - } catch (\RuntimeException $exception) { + return $this + ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->first(); + } catch (RuntimeException $exception) { return null; } } public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null { - if (($field ?? $this->getRouteKeyName()) !== $this->getSlugOptions()->slugField) { + $field = $field ?? $this->getRouteKeyName(); + if ($field !== $this->getSlugOptions()->slugField) { return parent::resolveSoftDeletableRouteBinding($value, $field); } // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { - return $this->where($this->getSlugOptions()->slugField . '->' . $this->getLocale(), $value) - ->withTrashed()->first(); - } catch (\RuntimeException $exception) { + return $this + ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->withTrashed()->first(); + } catch (RuntimeException $exception) { return null; } } public function resolveChildRouteBindingQuery($childType, $value, $field): Model|null { - if ($field !== $this->getSlugOptions()->slugField) { - return parent::resolveChildRouteBindingQuery($childType, $value, $field); - } - $relationship = $this->{Str::plural(Str::camel($childType))}(); $field = $field ?: $relationship->getRelated()->getRouteKeyName(); + if ($field !== $this->getSlugOptions()->slugField) { + return parent::resolveChildRouteBindingQuery($childType, $value, $field); + } + // Only some database types support json operations. // If the database doesn't support it, null is returned as default method would do the same try { if ($relationship instanceof HasManyThrough || $relationship instanceof BelongsToMany) { - return $relationship->where( - $relationship->getRelated()->getTable() . '.' . $field . '->' . $this->getLocale(), - $value - ); + return $relationship + ->where("{$relationship->getRelated()->getTable()}.{$field}->{$this->getLocale()}", $value); } else { - return $relationship->where($field . '->' . $this->getLocale(), $value); + return $relationship->where("{$field}->{$this->getLocale()}", $value); } - } catch (\RuntimeException $exception) { + } catch (RuntimeException $exception) { return null; } } diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index 9230e35..fa580c4 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -316,7 +316,7 @@ public function it_can_resolve_route_binding() $model->setTranslation('slug', 'nl', 'updated-value-nl'); $model->save(); - // Test for em locale + // Test for en locale $result = (new TranslatableModel())->resolveRouteBinding('updated-value-en', 'slug'); $this->assertNotNull($result); From e232cbda4ea2a635e41f82dfd51c302b160a43ae Mon Sep 17 00:00:00 2001 From: Freek Van der Herten Date: Tue, 16 Nov 2021 09:00:32 +0100 Subject: [PATCH 11/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e2c3b7..bb93a11 100644 --- a/README.md +++ b/README.md @@ -339,7 +339,7 @@ class YourEloquentModel extends Model } } ``` -You can also use Laravels [implicip route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use the feature make sure that the slug column matches the `routeNameKey`. +You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use the feature make sure that the slug column matches the `routeNameKey`. Currently only some database types support JSON opterations. Further information about which databases support JSON can be fund in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). ```php From f1a74d95ec594510dd4dac6b355d46946923c637 Mon Sep 17 00:00:00 2001 From: Freek Van der Herten Date: Tue, 16 Nov 2021 09:01:24 +0100 Subject: [PATCH 12/20] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bb93a11..eeee86f 100644 --- a/README.md +++ b/README.md @@ -339,8 +339,8 @@ class YourEloquentModel extends Model } } ``` -You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use the feature make sure that the slug column matches the `routeNameKey`. -Currently only some database types support JSON opterations. Further information about which databases support JSON can be fund in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). +You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use this feature, make sure that the slug column matches the `routeNameKey`. +Currently, only some database types support JSON opterations. Further information about which databases support JSON can be found in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). ```php namespace App; From f3a06c6cae874f4c5d55253e296338033472d3ee Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Wed, 17 Nov 2021 21:08:14 +0100 Subject: [PATCH 13/20] Updates database setup to Facades --- tests/TestCase.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 6c36d85..a9264c6 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,6 +5,8 @@ use File; use Illuminate\Database\Schema\Blueprint; use Illuminate\Foundation\Application; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Schema; use Orchestra\Testbench\TestCase as Orchestra; abstract class TestCase extends Orchestra @@ -26,29 +28,29 @@ protected function getEnvironmentSetUp($app) { $this->initializeDirectory($this->getTempDirectory()); - $app['config']->set('database.default', 'sqlite'); - $app['config']->set('database.connections.sqlite', [ + Config::set('database.default', 'sqlite'); + Config::set('database.connections.sqlite', [ 'driver' => 'sqlite', - 'database' => $this->getTempDirectory().'/database.sqlite', + 'database' => $this->getTempDirectory() . '/database.sqlite', 'prefix' => '', ]); } /** - * @param $app + * @param Application $app */ protected function setUpDatabase(Application $app) { - file_put_contents($this->getTempDirectory().'/database.sqlite', null); + file_put_contents($this->getTempDirectory() . '/database.sqlite', null); - $app['db']->connection()->getSchemaBuilder()->create('test_models', function (Blueprint $table) { + Schema::create('test_models', function (Blueprint $table) { $table->increments('id'); $table->string('name')->nullable(); $table->string('other_field')->nullable(); $table->string('url')->nullable(); }); - $app['db']->connection()->getSchemaBuilder()->create('test_model_soft_deletes', function (Blueprint $table) { + Schema::create('test_model_soft_deletes', function (Blueprint $table) { $table->increments('id'); $table->string('name')->nullable(); $table->string('other_field')->nullable(); @@ -56,7 +58,7 @@ protected function setUpDatabase(Application $app) $table->softDeletes(); }); - $app['db']->connection()->getSchemaBuilder()->create('translatable_models', function (Blueprint $table) { + Schema::create('translatable_models', function (Blueprint $table) { $table->increments('id'); $table->text('name')->nullable(); $table->text('other_field')->nullable(); @@ -64,7 +66,7 @@ protected function setUpDatabase(Application $app) $table->text('slug')->nullable(); }); - $app['db']->connection()->getSchemaBuilder()->create('translatable_model_soft_deletes', function (Blueprint $table) { + Schema::create('translatable_model_soft_deletes', function (Blueprint $table) { $table->increments('id'); $table->text('name')->nullable(); $table->text('other_field')->nullable(); @@ -73,7 +75,7 @@ protected function setUpDatabase(Application $app) $table->softDeletes(); }); - $app['db']->connection()->getSchemaBuilder()->create('scopeable_models', function (Blueprint $table) { + Schema::create('scopeable_models', function (Blueprint $table) { $table->increments('id'); $table->text('name')->nullable(); $table->text('slug')->nullable(); @@ -91,6 +93,6 @@ protected function initializeDirectory(string $directory) public function getTempDirectory(): string { - return __DIR__.'/temp'; + return __DIR__ . '/temp'; } } From 57a5acce97bcababf6192a0f5f1005dda6e867a2 Mon Sep 17 00:00:00 2001 From: Marvin Wittschen Date: Sun, 21 Nov 2021 19:29:56 +0100 Subject: [PATCH 14/20] Updates style --- src/HasTranslatableSlug.php | 4 ++-- tests/TranslatableModel.php | 4 ++-- tests/TranslatableModelSoftDeletes.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index 7cb9b55..0ed6c00 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -175,9 +175,9 @@ public function resolveChildRouteBindingQuery($childType, $value, $field): Model $relationship instanceof BelongsToMany) { return $relationship ->where("{$relationship->getRelated()->getTable()}.{$field}->{$this->getLocale()}", $value); - } else { - return $relationship->where("{$field}->{$this->getLocale()}", $value); } + + return $relationship->where("{$field}->{$this->getLocale()}", $value); } catch (RuntimeException $exception) { return null; } diff --git a/tests/TranslatableModel.php b/tests/TranslatableModel.php index 09ec19d..aa6fb74 100644 --- a/tests/TranslatableModel.php +++ b/tests/TranslatableModel.php @@ -17,9 +17,9 @@ class TranslatableModel extends Model protected $guarded = []; public $timestamps = false; - public $translatable = ['name', 'other_field', 'slug']; + protected $translatable = ['name', 'other_field', 'slug']; - private $customSlugOptions; + protected $customSlugOptions; public function useSlugOptions($slugOptions) { diff --git a/tests/TranslatableModelSoftDeletes.php b/tests/TranslatableModelSoftDeletes.php index bc4f397..154a7aa 100644 --- a/tests/TranslatableModelSoftDeletes.php +++ b/tests/TranslatableModelSoftDeletes.php @@ -19,9 +19,9 @@ class TranslatableModelSoftDeletes extends Model protected $guarded = []; public $timestamps = false; - public $translatable = ['name', 'other_field', 'slug']; + protected $translatable = ['name', 'other_field', 'slug']; - private $customSlugOptions; + protected $customSlugOptions; public function useSlugOptions($slugOptions) { From cf73d3838d7c61df2b993ea57f05932b445616fd Mon Sep 17 00:00:00 2001 From: Freek Van der Herten Date: Mon, 22 Nov 2021 08:34:35 +0100 Subject: [PATCH 15/20] Update HasTranslatableSlug.php --- src/HasTranslatableSlug.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index 0ed6c00..f11380d 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -128,6 +128,7 @@ protected function hasCustomSlugBeenUsed(): bool public function resolveRouteBinding($value, $field = null): Model|null { $field = $field ?? $this->getRouteKeyName(); + if ($field !== $this->getSlugOptions()->slugField) { return parent::resolveRouteBinding($value, $field); } @@ -135,7 +136,8 @@ public function resolveRouteBinding($value, $field = null): Model|null // If the database doesn't support it, null is returned as default method would do the same try { return $this - ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->first(); + ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value) + ->first(); } catch (RuntimeException $exception) { return null; } @@ -144,6 +146,7 @@ public function resolveRouteBinding($value, $field = null): Model|null public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null { $field = $field ?? $this->getRouteKeyName(); + if ($field !== $this->getSlugOptions()->slugField) { return parent::resolveSoftDeletableRouteBinding($value, $field); } @@ -152,7 +155,8 @@ public function resolveSoftDeletableRouteBinding($value, $field = null): Model|n // If the database doesn't support it, null is returned as default method would do the same try { return $this - ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->withTrashed()->first(); + ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->withTrashed() + ->first(); } catch (RuntimeException $exception) { return null; } From b055b63531ff45ea61dfdeeef312ef1b0af520a0 Mon Sep 17 00:00:00 2001 From: marvin-wtt <31454580+marvin-wtt@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:22:43 +0100 Subject: [PATCH 16/20] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index eeee86f..bde1d80 100644 --- a/README.md +++ b/README.md @@ -338,7 +338,11 @@ class YourEloquentModel extends Model ->saveSlugsTo('slug'); } } + ``` + +#### Implicit route model binding + You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use this feature, make sure that the slug column matches the `routeNameKey`. Currently, only some database types support JSON opterations. Further information about which databases support JSON can be found in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). From da14983e2fe5dffab6a42b8b6b8d29acaec298cf Mon Sep 17 00:00:00 2001 From: marvin-wtt <31454580+marvin-wtt@users.noreply.github.com> Date: Thu, 9 Dec 2021 15:58:50 +0100 Subject: [PATCH 17/20] Fix child model binding resolution --- src/HasTranslatableSlug.php | 60 ++++++++----------------------- tests/HasTranslatableSlugTest.php | 33 ++++++++++++++++- tests/TestCase.php | 6 ++-- tests/TestModel.php | 6 ++++ tests/TranslatableModel.php | 6 ++++ 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index f11380d..ad1b95a 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -2,13 +2,12 @@ namespace Spatie\Sluggable; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Relations\BelongsToMany; -use Illuminate\Database\Eloquent\Relations\HasManyThrough; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Illuminate\Support\Traits\Localizable; -use RuntimeException; trait HasTranslatableSlug { @@ -125,65 +124,36 @@ protected function hasCustomSlugBeenUsed(): bool return $originalSlug !== $newSlug; } - public function resolveRouteBinding($value, $field = null): Model|null + public function resolveRouteBindingQuery($query, $value, $field = null): Builder|Relation { $field = $field ?? $this->getRouteKeyName(); - + if ($field !== $this->getSlugOptions()->slugField) { - return parent::resolveRouteBinding($value, $field); - } - // Only some database types support json operations. - // If the database doesn't support it, null is returned as default method would do the same - try { - return $this - ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value) - ->first(); - } catch (RuntimeException $exception) { - return null; + return parent::resolveRouteBindingQuery($query, $value, $field); } + + return $query->where("{$field}->{$this->getLocale()}", $value); } - public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null + public function resolveRouteBinding($value, $field = null): Model|null { $field = $field ?? $this->getRouteKeyName(); - + if ($field !== $this->getSlugOptions()->slugField) { - return parent::resolveSoftDeletableRouteBinding($value, $field); + return parent::resolveRouteBinding($value, $field); } - // Only some database types support json operations. - // If the database doesn't support it, null is returned as default method would do the same - try { - return $this - ->where("{$this->getSlugOptions()->slugField}->{$this->getLocale()}", $value)->withTrashed() - ->first(); - } catch (RuntimeException $exception) { - return null; - } + return $this->resolveRouteBindingQuery($this, $value, $field)->first(); } - public function resolveChildRouteBindingQuery($childType, $value, $field): Model|null + public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null { - $relationship = $this->{Str::plural(Str::camel($childType))}(); - - $field = $field ?: $relationship->getRelated()->getRouteKeyName(); + $field = $field ?? $this->getRouteKeyName(); if ($field !== $this->getSlugOptions()->slugField) { - return parent::resolveChildRouteBindingQuery($childType, $value, $field); + return parent::resolveSoftDeletableRouteBinding($value, $field); } - // Only some database types support json operations. - // If the database doesn't support it, null is returned as default method would do the same - try { - if ($relationship instanceof HasManyThrough || - $relationship instanceof BelongsToMany) { - return $relationship - ->where("{$relationship->getRelated()->getTable()}.{$field}->{$this->getLocale()}", $value); - } - - return $relationship->where("{$field}->{$this->getLocale()}", $value); - } catch (RuntimeException $exception) { - return null; - } + return $this->resolveRouteBindingQuery($this, $value, $field)->withTrashed()->first(); } } diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index fa580c4..b48803f 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -304,7 +304,6 @@ public function it_can_update_slug_with_non_unique_names_multiple() } } - /** @test */ public function it_can_resolve_route_binding() { @@ -374,4 +373,36 @@ function (TranslatableModel $test) use ($model) { $result = $this->get("/translatable-model/updated-value-en"); $this->assertEquals(200, $result->status()); } + + /** @test */ + public function it_can_bind_child_route_model_implicit() + { + if (version_compare("8.75.0", app()->version()) === 1) { + $this->markTestSkipped("Implicit child model resolution not supported with framework version <= 08.75.0"); + } + + $model = new TranslatableModel(); + $model->setTranslation('name', 'en', 'Test value EN'); + $model->setTranslation('slug', 'en', 'updated-value-en'); + $model->test_model_id = 1; + $model->save(); + + $parent = new TestModel(); + $parent->name = 'parent'; + $parent->save(); + + Route::get( + '/test-model/{test_model:url}/translatable-model/{translatable_model:slug}', + function (TestModel $testModel, TranslatableModel $translatableModel) use ($parent, $model) { + $this->assertNotNull($parent); + $this->assertNotNull($translatableModel); + $this->assertEquals($parent->id, $testModel->id); + $this->assertEquals($model->id, $translatableModel->id); + } + )->middleware('bindings'); + + $result = $this->get("/test-model/parent/translatable-model/updated-value-en"); + + $this->assertEquals(200, $result->status()); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index a9264c6..3f77600 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,7 +5,6 @@ use File; use Illuminate\Database\Schema\Blueprint; use Illuminate\Foundation\Application; -use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Schema; use Orchestra\Testbench\TestCase as Orchestra; @@ -28,8 +27,8 @@ protected function getEnvironmentSetUp($app) { $this->initializeDirectory($this->getTempDirectory()); - Config::set('database.default', 'sqlite'); - Config::set('database.connections.sqlite', [ + config()->set('database.default', 'sqlite'); + config()->set('database.connections.sqlite', [ 'driver' => 'sqlite', 'database' => $this->getTempDirectory() . '/database.sqlite', 'prefix' => '', @@ -64,6 +63,7 @@ protected function setUpDatabase(Application $app) $table->text('other_field')->nullable(); $table->text('non_translatable_field')->nullable(); $table->text('slug')->nullable(); + $table->foreignId('test_model_id')->nullable()->index(); }); Schema::create('translatable_model_soft_deletes', function (Blueprint $table) { diff --git a/tests/TestModel.php b/tests/TestModel.php index 8dc1570..0bc1436 100644 --- a/tests/TestModel.php +++ b/tests/TestModel.php @@ -3,6 +3,7 @@ namespace Spatie\Sluggable\Tests; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; @@ -43,4 +44,9 @@ public function getDefaultSlugOptions(): SlugOptions ->generateSlugsFrom('name') ->saveSlugsTo('url'); } + + public function translatableModels(): HasMany + { + return $this->hasMany(TranslatableModel::class); + } } diff --git a/tests/TranslatableModel.php b/tests/TranslatableModel.php index aa6fb74..ef5ac50 100644 --- a/tests/TranslatableModel.php +++ b/tests/TranslatableModel.php @@ -3,6 +3,7 @@ namespace Spatie\Sluggable\Tests; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Spatie\Sluggable\HasTranslatableSlug; use Spatie\Sluggable\SlugOptions; use Spatie\Translatable\HasTranslations; @@ -32,4 +33,9 @@ public function getSlugOptions(): SlugOptions ->generateSlugsFrom('name') ->saveSlugsTo('slug'); } + + public function testModel(): BelongsTo + { + return $this->belongsTo(TestModel::class); + } } From 04412c9b0a60059d1c4458281cb16b1610d4ab20 Mon Sep 17 00:00:00 2001 From: marvin-wtt <31454580+marvin-wtt@users.noreply.github.com> Date: Thu, 9 Dec 2021 16:04:41 +0100 Subject: [PATCH 18/20] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bde1d80..b78c252 100644 --- a/README.md +++ b/README.md @@ -346,6 +346,8 @@ class YourEloquentModel extends Model You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use this feature, make sure that the slug column matches the `routeNameKey`. Currently, only some database types support JSON opterations. Further information about which databases support JSON can be found in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). +**NOTE:** Implicit route model binding for child model ís only supported with laravel framework version `> v.8.75.0` + ```php namespace App; From bc082063d1d3e1d580e044fca321a30f074fc27a Mon Sep 17 00:00:00 2001 From: marvin-wtt <31454580+marvin-wtt@users.noreply.github.com> Date: Fri, 10 Dec 2021 11:31:01 +0100 Subject: [PATCH 19/20] Update test syntax --- tests/HasTranslatableSlugTest.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index b48803f..3e8bbe9 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -370,8 +370,9 @@ function (TranslatableModel $test) use ($model) { } )->middleware('bindings'); - $result = $this->get("/translatable-model/updated-value-en"); - $this->assertEquals(200, $result->status()); + $response = $this->get("/translatable-model/updated-value-en"); + + $response->assertStatus(200); } /** @test */ @@ -401,8 +402,8 @@ function (TestModel $testModel, TranslatableModel $translatableModel) use ($pare } )->middleware('bindings'); - $result = $this->get("/test-model/parent/translatable-model/updated-value-en"); + $response = $this->get("/test-model/parent/translatable-model/updated-value-en"); - $this->assertEquals(200, $result->status()); + $response->assertStatus(200); } } From 2207cf8ea53524675014e005d494289aaf59e8aa Mon Sep 17 00:00:00 2001 From: marvin-wtt <31454580+marvin-wtt@users.noreply.github.com> Date: Tue, 14 Dec 2021 21:31:33 +0100 Subject: [PATCH 20/20] Update laravel version --- .github/workflows/run-tests.yml | 2 +- README.md | 2 -- composer.json | 4 ++-- src/HasTranslatableSlug.php | 23 ----------------------- tests/HasTranslatableSlugTest.php | 4 ---- 5 files changed, 3 insertions(+), 32 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index eaf30b2..ae9a48b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,7 @@ jobs: fail-fast: false matrix: php: [8.0] - laravel: [7, 8] + laravel: [8.76.1] dependency-version: [prefer-lowest, prefer-stable] name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} diff --git a/README.md b/README.md index b78c252..bde1d80 100644 --- a/README.md +++ b/README.md @@ -346,8 +346,6 @@ class YourEloquentModel extends Model You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use this feature, make sure that the slug column matches the `routeNameKey`. Currently, only some database types support JSON opterations. Further information about which databases support JSON can be found in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses). -**NOTE:** Implicit route model binding for child model ís only supported with laravel framework version `> v.8.75.0` - ```php namespace App; diff --git a/composer.json b/composer.json index e6b68d8..c60577b 100644 --- a/composer.json +++ b/composer.json @@ -17,8 +17,8 @@ ], "require": { "php": "^8.0", - "illuminate/database": "^7.30|^8.0", - "illuminate/support": "^7.30|^8.0" + "illuminate/database": "^8.76.1", + "illuminate/support": "^8.0" }, "require-dev": { "orchestra/testbench": "^5.16|^6.11", diff --git a/src/HasTranslatableSlug.php b/src/HasTranslatableSlug.php index ad1b95a..2fdec7e 100644 --- a/src/HasTranslatableSlug.php +++ b/src/HasTranslatableSlug.php @@ -3,7 +3,6 @@ namespace Spatie\Sluggable; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Collection; use Illuminate\Support\Str; @@ -134,26 +133,4 @@ public function resolveRouteBindingQuery($query, $value, $field = null): Builder return $query->where("{$field}->{$this->getLocale()}", $value); } - - public function resolveRouteBinding($value, $field = null): Model|null - { - $field = $field ?? $this->getRouteKeyName(); - - if ($field !== $this->getSlugOptions()->slugField) { - return parent::resolveRouteBinding($value, $field); - } - - return $this->resolveRouteBindingQuery($this, $value, $field)->first(); - } - - public function resolveSoftDeletableRouteBinding($value, $field = null): Model|null - { - $field = $field ?? $this->getRouteKeyName(); - - if ($field !== $this->getSlugOptions()->slugField) { - return parent::resolveSoftDeletableRouteBinding($value, $field); - } - - return $this->resolveRouteBindingQuery($this, $value, $field)->withTrashed()->first(); - } } diff --git a/tests/HasTranslatableSlugTest.php b/tests/HasTranslatableSlugTest.php index 3e8bbe9..37fcdca 100644 --- a/tests/HasTranslatableSlugTest.php +++ b/tests/HasTranslatableSlugTest.php @@ -378,10 +378,6 @@ function (TranslatableModel $test) use ($model) { /** @test */ public function it_can_bind_child_route_model_implicit() { - if (version_compare("8.75.0", app()->version()) === 1) { - $this->markTestSkipped("Implicit child model resolution not supported with framework version <= 08.75.0"); - } - $model = new TranslatableModel(); $model->setTranslation('name', 'en', 'Test value EN'); $model->setTranslation('slug', 'en', 'updated-value-en');