From 6f7fd9ff007609132daeae790a91d04d17150b4c Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Mon, 18 Nov 2024 17:29:47 +0000 Subject: [PATCH 1/3] Update entry URIs when collection route is changed --- src/Collections/CollectionRepository.php | 18 ++++++++++++++++++ src/Jobs/UpdateCollectionEntryUris.php | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/Jobs/UpdateCollectionEntryUris.php diff --git a/src/Collections/CollectionRepository.php b/src/Collections/CollectionRepository.php index 136ca2e0..f87a58fc 100644 --- a/src/Collections/CollectionRepository.php +++ b/src/Collections/CollectionRepository.php @@ -4,6 +4,7 @@ use Illuminate\Support\Collection as IlluminateCollection; use Statamic\Contracts\Entries\Collection as CollectionContract; +use Statamic\Eloquent\Jobs\UpdateCollectionEntryUris; use Statamic\Facades\Blink; use Statamic\Stache\Repositories\CollectionRepository as StacheRepository; @@ -33,8 +34,25 @@ public function findByHandle($handle): ?CollectionContract public function save($entry) { $model = $entry->toModel(); + $original = $model->getOriginal(); + $model->save(); + if ( + $model->wasChanged('settings') + && ($model->settings['routes'] ?? null) !== ($original['settings']['routes'] ?? null) + ) { + $dispatch = UpdateCollectionEntryUris::dispatch($entry->handle()); + + $connection = config('statamic.eloquent-driver.collections.update_entry_uris_connection', 'default'); + + if ($connection != 'default') { + $dispatch->onConnection($connection); + } + + $dispatch->onQueue(config('statamic.eloquent-driver.collections.update_entry_uris_queue', 'default')); + } + Blink::forget("eloquent-collection-{$model->handle}"); Blink::forget('eloquent-collections'); diff --git a/src/Jobs/UpdateCollectionEntryUris.php b/src/Jobs/UpdateCollectionEntryUris.php new file mode 100644 index 00000000..9245d759 --- /dev/null +++ b/src/Jobs/UpdateCollectionEntryUris.php @@ -0,0 +1,23 @@ +where('collection', $this->collection) + ->chunk(100, fn ($entries) => $entries->each->save()); + } +} From 13fe7561d97f37d3112a894e1c4b001965b9efef Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Mon, 18 Nov 2024 17:30:22 +0000 Subject: [PATCH 2/3] Add minimal test coverage around collections --- tests/Entries/CollectionTest.php | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/Entries/CollectionTest.php diff --git a/tests/Entries/CollectionTest.php b/tests/Entries/CollectionTest.php new file mode 100644 index 00000000..101e1db0 --- /dev/null +++ b/tests/Entries/CollectionTest.php @@ -0,0 +1,43 @@ + 'Blog', + 'handle' => 'blog', + 'settings' => [], + ]); + + $find = CollectionFacade::find('blog'); + + $this->assertTrue($model->is($find->model())); + $this->assertEquals('blog', $find->handle()); + $this->assertEquals('Blog', $find->title()); + } + + #[Test] + public function it_saves_to_collection_model() + { + $collection = (new Collection)->handle('test'); + + $this->assertDatabaseMissing('collections', ['handle' => 'test']); + + $collection->save(); + + $this->assertDatabaseHas('collections', ['handle' => 'test']); + } +} From 099061aa840c47d508d7fb55fb324ef0b6cc8edc Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Mon, 18 Nov 2024 17:37:33 +0000 Subject: [PATCH 3/3] Add test --- tests/Entries/CollectionTest.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/Entries/CollectionTest.php b/tests/Entries/CollectionTest.php index 101e1db0..7040e1f7 100644 --- a/tests/Entries/CollectionTest.php +++ b/tests/Entries/CollectionTest.php @@ -3,10 +3,13 @@ namespace Entries; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\Queue; use PHPUnit\Framework\Attributes\Test; use Statamic\Eloquent\Collections\Collection; use Statamic\Eloquent\Collections\CollectionModel; +use Statamic\Eloquent\Jobs\UpdateCollectionEntryUris; use Statamic\Facades\Collection as CollectionFacade; +use Statamic\Facades\Entry as EntryFacade; use Tests\TestCase; class CollectionTest extends TestCase @@ -40,4 +43,26 @@ public function it_saves_to_collection_model() $this->assertDatabaseHas('collections', ['handle' => 'test']); } + + #[Test] + public function changing_a_collections_route_updates_entry_uris() + { + Queue::fake(); + + $collection = (new Collection)->handle('test'); + $collection->save(); + + EntryFacade::make()->collection('test')->slug('one'); + EntryFacade::make()->collection('test')->slug('two'); + EntryFacade::make()->collection('test')->slug('three'); + + $collection->routes(['en' => '/blog/{slug}'])->save(); + $collection->routes(['en' => '/{slug}'])->save(); + $collection->routes(['en' => '/{slug}'])->save(); + $collection->routes(['en' => null])->save(); + + // The job should only be dispatched three times. + // It shouldn't be dispatched when the route is null or hasn't changed since the last save. + Queue::assertPushed(UpdateCollectionEntryUris::class, 3); + } }