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()); + } +} diff --git a/tests/Entries/CollectionTest.php b/tests/Entries/CollectionTest.php new file mode 100644 index 00000000..7040e1f7 --- /dev/null +++ b/tests/Entries/CollectionTest.php @@ -0,0 +1,68 @@ + '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']); + } + + #[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); + } +}