Skip to content

Commit e0f6a14

Browse files
authored
Taxonomy wheres should use entry query builder, not stache (#432)
* Taxonomy wheres should use entry query builder, not stache * 🍺 * Scope to the right collections * only taxonomize if we are stache * Add some test coverage
1 parent d200806 commit e0f6a14

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

src/Entries/EntryQueryBuilder.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Statamic\Facades\Blink;
1010
use Statamic\Facades\Collection;
1111
use Statamic\Facades\Entry;
12+
use Statamic\Facades\Taxonomy;
1213
use Statamic\Query\EloquentQueryBuilder;
1314
use Statamic\Stache\Query\QueriesEntryStatus;
1415
use Statamic\Stache\Query\QueriesTaxonomizedEntries;
@@ -222,4 +223,56 @@ private function getCollectionsForStatusQuery(): \Illuminate\Support\Collection
222223
->flatMap(fn ($where) => $where['values'] ?? [$where['value']])
223224
->map(fn ($handle) => Collection::find($handle));
224225
}
226+
227+
private function getKeysForTaxonomyWhereBasic($where)
228+
{
229+
$term = $where['value'];
230+
231+
[$taxonomy, $slug] = explode('::', $term);
232+
233+
if (! $taxonomy = Taxonomy::find($taxonomy)) {
234+
return collect();
235+
}
236+
237+
return app('statamic.eloquent.entries.model')::query()
238+
->select(['id'])
239+
->whereIn('collection', $taxonomy->collections()->map->handle()->all())
240+
->whereJsonContains($this->column($taxonomy->handle()), $term)
241+
->get()
242+
->pluck('id');
243+
}
244+
245+
private function getKeysForTaxonomyWhereIn($where)
246+
{
247+
// Get the terms grouped by taxonomy.
248+
// [tags::foo, categories::baz, tags::bar]
249+
// becomes [tags => [foo, bar], categories => [baz]]
250+
$taxonomies = collect($where['values'])
251+
->map(function ($value) {
252+
[$taxonomy, $term] = explode('::', $value);
253+
254+
return compact('taxonomy', 'term');
255+
})
256+
->groupBy->taxonomy
257+
->map(function ($group) {
258+
return collect($group)->map->term;
259+
});
260+
261+
return $taxonomies->flatMap(function ($terms, $taxonomy) {
262+
if (! $taxonomy = Taxonomy::find($taxonomy)) {
263+
return collect();
264+
}
265+
266+
return app('statamic.eloquent.entries.model')::query()
267+
->select(['id'])
268+
->whereIn('collection', $taxonomy->collections()->map->handle()->all())
269+
->where(function ($query) use ($taxonomy, $terms) {
270+
foreach ($terms as $term) {
271+
$query->orWhereJsonContains($this->column($taxonomy->handle()), $term);
272+
}
273+
})
274+
->get()
275+
->pluck('id');
276+
});
277+
}
225278
}

src/Entries/EntryRepository.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,13 @@ public function updateParents($collection, $ids = null)
115115
$dispatch->onQueue(config('statamic.eloquent-driver.collections.update_entry_parent_queue', 'default'));
116116
});
117117
}
118+
119+
public function taxonomize($entry)
120+
{
121+
if (config('statamic.eloquent-driver.taxonomies.driver') === 'eloquent') {
122+
return;
123+
}
124+
125+
parent::taxonomize($entry);
126+
}
118127
}

tests/Entries/EntryTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,25 @@
44

55
use Facades\Statamic\Fields\BlueprintRepository;
66
use Illuminate\Foundation\Testing\RefreshDatabase;
7+
use Illuminate\Support\Facades\Facade;
78
use PHPUnit\Framework\Attributes\Test;
9+
use Statamic\Contracts\Taxonomies\TaxonomyRepository as TaxonomyRepositoryContract;
810
use Statamic\Eloquent\Collections\Collection;
911
use Statamic\Eloquent\Entries\Entry;
1012
use Statamic\Eloquent\Entries\EntryModel;
13+
use Statamic\Eloquent\Taxonomies\Taxonomy;
1114
use Statamic\Facades;
1215
use Statamic\Facades\Collection as CollectionFacade;
1316
use Statamic\Facades\Entry as EntryFacade;
17+
use Statamic\Facades\Stache;
18+
use Statamic\Facades\Term as TermFacade;
19+
use Statamic\Statamic;
20+
use Statamic\Testing\Concerns\PreventsSavingStacheItemsToDisk;
1421
use Tests\TestCase;
1522

1623
class EntryTest extends TestCase
1724
{
25+
use PreventsSavingStacheItemsToDisk;
1826
use RefreshDatabase;
1927

2028
#[Test]
@@ -346,4 +354,47 @@ public function null_values_are_removed_from_data()
346354

347355
$this->assertArrayNotHasKey('null_value', $entry->model()->data);
348356
}
357+
358+
#[Test]
359+
public function it_doesnt_build_stache_associations_when_taxonomy_driver_is_eloquent()
360+
{
361+
Taxonomy::make('test')->title('test')->save();
362+
363+
TermFacade::make('test-term')->taxonomy('test')->data([])->save();
364+
365+
$taxonomyStore = Stache::stores()->get('terms');
366+
$this->assertCount(0, $taxonomyStore->store('test')->index('associations')->items());
367+
368+
$collection = \Statamic\Facades\Collection::make('blog')->routes('blog/{slug}')->taxonomies(['test'])->save();
369+
370+
(new Entry)->id(1)->collection($collection)->data(['title' => 'Post 1', 'test' => ['test-term']])->slug('alfa')->save();
371+
(new Entry)->id(2)->collection($collection)->data(['title' => 'Post 2', 'test' => ['test-term']])->slug('bravo')->save();
372+
(new Entry)->id(3)->collection($collection)->data(['title' => 'Post 3'])->slug('charlie')->save();
373+
374+
$this->assertCount(0, $taxonomyStore->store('test')->index('associations')->items());
375+
}
376+
377+
#[Test]
378+
public function it_build_stache_associations_when_taxonomy_driver_is_not_eloquent()
379+
{
380+
config()->set('statamic.eloquent-driver.taxonomies.driver', 'file');
381+
382+
Facade::clearResolvedInstance(TaxonomyRepositoryContract::class);
383+
Statamic::repository(TaxonomyRepositoryContract::class, \Statamic\Stache\Repositories\TaxonomyRepository::class);
384+
385+
Taxonomy::make('test')->title('test')->save();
386+
387+
TermFacade::make('test-term')->taxonomy('test')->data([])->save();
388+
389+
$taxonomyStore = Stache::stores()->get('terms');
390+
$this->assertCount(0, $taxonomyStore->store('test')->index('associations')->items());
391+
392+
$collection = \Statamic\Facades\Collection::make('blog')->routes('blog/{slug}')->taxonomies(['test'])->save();
393+
394+
(new Entry)->id(1)->collection($collection)->data(['title' => 'Post 1', 'test' => ['test-term']])->slug('alfa')->save();
395+
(new Entry)->id(2)->collection($collection)->data(['title' => 'Post 2', 'test' => ['test-term']])->slug('bravo')->save();
396+
(new Entry)->id(3)->collection($collection)->data(['title' => 'Post 3'])->slug('charlie')->save();
397+
398+
$this->assertCount(2, $taxonomyStore->store('test')->index('associations')->items());
399+
}
349400
}

tests/Terms/TermTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public function it_gets_entry_count_for_term()
8585
#[Test]
8686
public function it_build_stache_associations_when_taxonomy_driver_is_not_eloquent()
8787
{
88+
config()->set('statamic.eloquent-driver.taxonomies.driver', 'file');
89+
8890
Facade::clearResolvedInstance(TaxonomyRepositoryContract::class);
8991
Statamic::repository(TaxonomyRepositoryContract::class, \Statamic\Stache\Repositories\TaxonomyRepository::class);
9092

0 commit comments

Comments
 (0)