From a93ee2965a69701e146e2bdbbcbc6cd3a89a04fc Mon Sep 17 00:00:00 2001 From: Adam Copley Date: Sun, 21 Apr 2019 02:49:57 +0100 Subject: [PATCH 1/2] ensure slugs are still unique if we use soft deletes --- CHANGELOG.md | 4 ++ src/HasSlug.php | 20 +++++++-- tests/Integration/HasSlugTest.php | 11 +++++ tests/Integration/TestCase.php | 8 ++++ tests/Integration/TestModelSoftDeletes.php | 48 ++++++++++++++++++++++ 5 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 tests/Integration/TestModelSoftDeletes.php diff --git a/CHANGELOG.md b/CHANGELOG.md index bbb1b70..1e3e8ea 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to `laravel-sluggable` will be documented in this file +## 2.1.8 - 2019-04-21 + +- ensure slugs are still unique when soft deletes are in use on model + ## 2.1.7 - 2019-02-26 ❤️ - Add support for Laravel 5.8 diff --git a/src/HasSlug.php b/src/HasSlug.php index 26e1954..fa8a0ca 100644 --- a/src/HasSlug.php +++ b/src/HasSlug.php @@ -122,10 +122,24 @@ protected function otherRecordExistsWithSlug(string $slug): bool $key = $key ?? '0'; } - return static::where($this->slugOptions->slugField, $slug) + $query = static::where($this->slugOptions->slugField, $slug) ->where($this->getKeyName(), '!=', $key) - ->withoutGlobalScopes() - ->exists(); + ->withoutGlobalScopes(); + + if ($this->usesSoftDeletes()) { + $query->withTrashed(); + } + + return $query->exists(); + } + + protected function usesSoftDeletes() + { + if (in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this))) { + return true; + } + + return false; } protected function ensureValidSlugOptions() diff --git a/tests/Integration/HasSlugTest.php b/tests/Integration/HasSlugTest.php index 4e31a87..3b0c8b0 100644 --- a/tests/Integration/HasSlugTest.php +++ b/tests/Integration/HasSlugTest.php @@ -280,4 +280,15 @@ public function getSlugOptions(): SlugOptions $model->save(); $this->assertEquals('guete-nacht', $model->url); } + + /** @test */ + public function it_will_save_a_unique_slug_by_default_even_when_soft_deletes_are_on() + { + TestModelSoftDeletes::create(['name' => 'this is a test', 'deleted_at' => date('Y-m-d h:i:s')]); + + foreach (range(1, 10) as $i) { + $model = TestModelSoftDeletes::create(['name' => 'this is a test']); + $this->assertEquals("this-is-a-test-{$i}", $model->url); + } + } } diff --git a/tests/Integration/TestCase.php b/tests/Integration/TestCase.php index 9b57cf9..eb42fa7 100644 --- a/tests/Integration/TestCase.php +++ b/tests/Integration/TestCase.php @@ -47,6 +47,14 @@ protected function setUpDatabase(Application $app) $table->string('other_field')->nullable(); $table->string('url')->nullable(); }); + + $app['db']->connection()->getSchemaBuilder()->create('test_model_soft_deletes', function (Blueprint $table) { + $table->increments('id'); + $table->string('name')->nullable(); + $table->string('other_field')->nullable(); + $table->string('url')->nullable(); + $table->softDeletes(); + }); } protected function initializeDirectory(string $directory) diff --git a/tests/Integration/TestModelSoftDeletes.php b/tests/Integration/TestModelSoftDeletes.php new file mode 100644 index 0000000..55513a2 --- /dev/null +++ b/tests/Integration/TestModelSoftDeletes.php @@ -0,0 +1,48 @@ +slugOptions ?? $this->getDefaultSlugOptions(); + } + + /** + * Set the options for generating the slug. + */ + public function setSlugOptions(SlugOptions $slugOptions) : self + { + $this->slugOptions = $slugOptions; + + return $this; + } + + /** + * Get the default slug options used in the tests. + */ + public function getDefaultSlugOptions() : SlugOptions + { + return SlugOptions::create() + ->generateSlugsFrom('name') + ->saveSlugsTo('url'); + } +} From aac145df6217864ad9f0543829e81e45a1732174 Mon Sep 17 00:00:00 2001 From: Adam Copley Date: Sun, 21 Apr 2019 02:55:48 +0100 Subject: [PATCH 2/2] import ordering --- tests/Integration/TestModelSoftDeletes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Integration/TestModelSoftDeletes.php b/tests/Integration/TestModelSoftDeletes.php index 55513a2..9073845 100644 --- a/tests/Integration/TestModelSoftDeletes.php +++ b/tests/Integration/TestModelSoftDeletes.php @@ -2,10 +2,10 @@ namespace Spatie\Sluggable\Test\Integration; -use Illuminate\Database\Eloquent\SoftDeletes; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; class TestModelSoftDeletes extends Model {