diff --git a/src/Commands/ImportRevisions.php b/src/Commands/ImportRevisions.php index 0eeaf5b1..83df023f 100644 --- a/src/Commands/ImportRevisions.php +++ b/src/Commands/ImportRevisions.php @@ -7,6 +7,7 @@ use Illuminate\Support\Facades\File; use Statamic\Console\RunsInPlease; use Statamic\Eloquent\Revisions\Revision; +use Statamic\Facades\Stache; use Statamic\Facades\YAML; class ImportRevisions extends Command @@ -45,7 +46,7 @@ public function handle(): int private function importRevisions(): void { - $this->withProgressBar(File::allFiles(config('statamic.stache.stores.revisions.directory')), function ($file) { + $this->withProgressBar(File::allFiles(Stache::store('revisions')->directory()), function ($file) { $yaml = YAML::file($file->getPathname())->parse(); $revision = (new Revision) diff --git a/src/Revisions/Revision.php b/src/Revisions/Revision.php index 0d0161ac..30e198c9 100644 --- a/src/Revisions/Revision.php +++ b/src/Revisions/Revision.php @@ -3,11 +3,7 @@ namespace Statamic\Eloquent\Revisions; use Illuminate\Database\Eloquent\Model; -use Statamic\Events\RevisionDeleted; -use Statamic\Events\RevisionSaved; -use Statamic\Events\RevisionSaving; use Statamic\Revisions\Revision as FileEntry; -use Statamic\Revisions\WorkingCopy; class Revision extends FileEntry { @@ -33,11 +29,10 @@ public static function fromModel(Model $model) { return (new static) ->key($model->key) - ->action($model->action ?? false) - ->id($model->created_at->timestamp) + ->action($model->action ?? null) ->date($model->created_at) - ->user($model->user ?? false) - ->message($model->message ?? '') + ->user($model->user ?? null) + ->message($model->message ?? null) ->attributes($model->attributes ?? []) ->model($model); } @@ -59,10 +54,10 @@ public function fromRevisionOrWorkingCopy($item) { return (new static) ->key($item->key()) - ->action($item instanceof WorkingCopy ? 'working' : $item->action()) + ->action($item->isWorkingCopy() ? 'working' : $item->action()) ->date($item->date()) - ->user($item->user()?->id() ?? false) - ->message($item->message() ?? '') + ->user($item->user()?->id() ?? null) + ->message($item->message() ?? null) ->attributes($item->attributes() ?? []); } @@ -76,22 +71,4 @@ public function model($model = null) return $this; } - - public function save() - { - if (RevisionSaving::dispatch($this) === false) { - return false; - } - - $this->model->save(); - - RevisionSaved::dispatch($this); - } - - public function delete() - { - $this->model->delete(); - - RevisionDeleted::dispatch($this); - } } diff --git a/src/Revisions/RevisionQueryBuilder.php b/src/Revisions/RevisionQueryBuilder.php new file mode 100644 index 00000000..5b556967 --- /dev/null +++ b/src/Revisions/RevisionQueryBuilder.php @@ -0,0 +1,46 @@ +map(function ($model) use ($columns) { + return app(RevisionContract::class)::fromModel($model) + ->selectedQueryColumns($this->selectedQueryColumns ?? $columns); + }); + } + + protected function column($column) + { + if (! is_string($column)) { + return $column; + } + + if (! in_array($column, self::COLUMNS)) { + if (! Str::startsWith($column, 'attributes->')) { + $column = 'attributes->'.$column; + } + } + + return $column; + } + + public function with($relations, $callback = null) + { + return $this; + } +} diff --git a/src/Revisions/RevisionRepository.php b/src/Revisions/RevisionRepository.php index c5f2366e..a2dedfa3 100644 --- a/src/Revisions/RevisionRepository.php +++ b/src/Revisions/RevisionRepository.php @@ -3,28 +3,11 @@ namespace Statamic\Eloquent\Revisions; use Statamic\Contracts\Revisions\Revision as RevisionContract; +use Statamic\Contracts\Revisions\RevisionQueryBuilder as QueryBuilderContract; use Statamic\Revisions\RevisionRepository as StacheRepository; -use Statamic\Revisions\WorkingCopy; class RevisionRepository extends StacheRepository { - public function make(): RevisionContract - { - return new (app('statamic.eloquent.revisions.model')); - } - - public function whereKey($key) - { - return app('statamic.eloquent.revisions.model')::where('key', $key) - ->orderBy('created_at') - ->get() - ->map(function ($revision) use ($key) { - return $this->makeRevisionFromFile($key, $revision); - })->keyBy(function ($revision) { - return $revision->date()->timestamp; - }); - } - public function findWorkingCopyByKey($key) { $class = app('statamic.eloquent.revisions.model'); @@ -37,14 +20,14 @@ public function findWorkingCopyByKey($key) public function save(RevisionContract $copy) { - if ($copy instanceof WorkingCopy) { + if ($copy->isWorkingCopy()) { app('statamic.eloquent.revisions.model')::where([ 'key' => $copy->key(), 'action' => 'working', ])->delete(); } - $revision = (new Revision) + (new Revision) ->fromRevisionOrWorkingCopy($copy) ->toModel() ->save(); @@ -52,13 +35,7 @@ public function save(RevisionContract $copy) public function delete(RevisionContract $revision) { - if ($revision instanceof WorkingCopy) { - $this->findWorkingCopyByKey($revision->key())?->delete(); - - return; - } - - $revision->model?->delete(); + $revision->model()?->delete(); } protected function makeRevisionFromFile($key, $model) @@ -70,6 +47,7 @@ public static function bindings(): array { return [ RevisionContract::class => Revision::class, + QueryBuilderContract::class => RevisionQueryBuilder::class, ]; } } diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 98ac68d6..c6eaf040 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -33,6 +33,7 @@ use Statamic\Eloquent\Forms\SubmissionRepository; use Statamic\Eloquent\Globals\GlobalRepository; use Statamic\Eloquent\Globals\GlobalVariablesRepository; +use Statamic\Eloquent\Revisions\RevisionQueryBuilder; use Statamic\Eloquent\Revisions\RevisionRepository; use Statamic\Eloquent\Structures\CollectionTreeRepository; use Statamic\Eloquent\Structures\NavigationRepository; @@ -485,6 +486,12 @@ private function registerRevisions() return config('statamic.eloquent-driver.revisions.model'); }); + $this->app->bind(RevisionQueryBuilder::class, function ($app) { + return new RevisionQueryBuilder( + $app['statamic.eloquent.revisions.model']::query() + ); + }); + Statamic::repository(RevisionRepositoryContract::class, RevisionRepository::class); } diff --git a/tests/Repositories/RevisionRepositoryTest.php b/tests/Repositories/RevisionRepositoryTest.php new file mode 100644 index 00000000..be78e818 --- /dev/null +++ b/tests/Repositories/RevisionRepositoryTest.php @@ -0,0 +1,113 @@ +sites(['en', 'fr']); + $this->app->instance(Stache::class, $stache); + $this->repo = new RevisionRepository($stache); + + \Statamic\Facades\User::shouldReceive('find')->andReturnNull(); + \Statamic\Facades\User::shouldReceive('current')->andReturnNull(); + + \Statamic\Facades\Revision::make() + ->key('123') + ->action('working') + ->date(now()) + ->save(); + + \Statamic\Facades\Revision::make() + ->key('123') + ->action('other') + ->date(now()->subHour()) + ->save(); + + \Statamic\Facades\Revision::make() + ->key('123') + ->action('other') + ->date(now()->subHours(2)) + ->save(); + + \Statamic\Facades\Revision::make() + ->key('456') + ->action('working') + ->date(now()) + ->save(); + + \Statamic\Facades\Revision::make() + ->key('456') + ->action('other') + ->date(now()->subHour()) + ->save(); + } + + #[Test] + public function it_gets_revisions_and_excludes_working_copies() + { + $revisions = $this->repo->whereKey('123'); + + $this->assertInstanceOf(Collection::class, $revisions); + $this->assertCount(2, $revisions); + $this->assertContainsOnlyInstancesOf(Revision::class, $revisions); + } + + #[Test] + public function it_can_call_to_array_on_a_revision_collection() + { + User::shouldReceive('find')->andReturnNull(); + + $revisions = $this->repo->whereKey('123'); + + $this->assertIsArray($revisions->toArray()); + } + + #[Test] + public function it_returns_a_query_builder() + { + $builder = $this->repo->query(); + + $this->assertInstanceOf(RevisionQueryBuilder::class, $builder); + } + + #[Test] + public function it_gets_and_filters_items_using_query_builder() + { + $builder = $this->repo->query(); + + $revisions = $builder->get(); + $this->assertInstanceOf(Collection::class, $revisions); + $this->assertCount(5, $revisions); + $this->assertContainsOnlyInstancesOf(Revision::class, $revisions); + + $revisions = $builder->where('key', '123')->get(); + $this->assertInstanceOf(Collection::class, $revisions); + $this->assertCount(3, $revisions); + $this->assertContainsOnlyInstancesOf(Revision::class, $revisions); + + $revisions = $builder->where('key', '123')->where('action', '!=', 'working')->get(); + $this->assertInstanceOf(Collection::class, $revisions); + $this->assertCount(2, $revisions); + $this->assertContainsOnlyInstancesOf(Revision::class, $revisions); + + $revisions = $builder->where('key', '1234')->get(); + $this->assertInstanceOf(Collection::class, $revisions); + $this->assertCount(0, $revisions); + } +}