Skip to content

Commit 1f3f1a9

Browse files
Make entries count more performant when we use eloquent for terms and entries (#553)
Co-authored-by: Duncan McClean <duncan@duncanmcclean.com>
1 parent ddb9084 commit 1f3f1a9

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/Taxonomies/TermRepository.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
use Statamic\Contracts\Taxonomies\Term as TermContract;
66
use Statamic\Facades\Blink;
77
use Statamic\Facades\Collection;
8+
use Statamic\Facades\Entry;
89
use Statamic\Facades\Taxonomy;
910
use Statamic\Stache\Repositories\TermRepository as StacheRepository;
1011
use Statamic\Support\Str;
12+
use Statamic\Taxonomies\LocalizedTerm;
1113

1214
class TermRepository extends StacheRepository
1315
{
@@ -131,4 +133,28 @@ protected function ensureAssociations()
131133

132134
parent::ensureAssociations();
133135
}
136+
137+
public function entriesCount(TermContract $term, ?string $status = null): int
138+
{
139+
if (config('statamic.eloquent-driver.entries.driver', 'file') !== 'eloquent') {
140+
return parent::entriesCount($term, $status);
141+
}
142+
143+
$query = Entry::query()
144+
->whereTaxonomy($term->taxonomyHandle().'::'.$term->inDefaultLocale()->slug());
145+
146+
if ($term instanceof LocalizedTerm) {
147+
$query->where('site', $term->locale());
148+
}
149+
150+
if ($collection = $term->collection()) {
151+
$query->where('collection', $collection->handle());
152+
}
153+
154+
if ($status) {
155+
$query->whereStatus($status);
156+
}
157+
158+
return $query->count();
159+
}
134160
}

tests/Terms/TermTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,63 @@ public function it_gets_entry_count_for_term()
8484
$this->assertEquals(2, TermFacade::entriesCount($term));
8585
}
8686

87+
#[Test]
88+
public function it_gets_entry_count_for_term_filtered_by_status()
89+
{
90+
Taxonomy::make('test')->title('test')->save();
91+
92+
$term = tap(TermFacade::make('test-term')->taxonomy('test')->data([]))->save();
93+
94+
$collection = Collection::make('blog')->routes('blog/{slug}')->taxonomies(['test'])->save();
95+
96+
(new Entry)->id(1)->collection($collection)->data(['title' => 'Post 1', 'test' => ['test-term']])->slug('alfa')->published(true)->save();
97+
(new Entry)->id(2)->collection($collection)->data(['title' => 'Post 2', 'test' => ['test-term']])->slug('bravo')->published(false)->save();
98+
(new Entry)->id(3)->collection($collection)->data(['title' => 'Post 3', 'test' => ['test-term']])->slug('charlie')->published(false)->save();
99+
100+
$this->assertEquals(1, TermFacade::entriesCount($term, 'published'));
101+
$this->assertEquals(2, TermFacade::entriesCount($term, 'draft'));
102+
}
103+
104+
#[Test]
105+
public function it_gets_entry_count_for_term_scoped_to_collection()
106+
{
107+
Taxonomy::make('test')->title('test')->save();
108+
109+
$term = tap(TermFacade::make('test-term')->taxonomy('test')->data([]))->save();
110+
111+
$blog = Collection::make('blog')->routes('blog/{slug}')->taxonomies(['test'])->save();
112+
$news = Collection::make('news')->routes('news/{slug}')->taxonomies(['test'])->save();
113+
114+
(new Entry)->id(1)->collection($blog)->data(['title' => 'Blog 1', 'test' => ['test-term']])->slug('alfa')->save();
115+
(new Entry)->id(2)->collection($blog)->data(['title' => 'Blog 2', 'test' => ['test-term']])->slug('bravo')->save();
116+
(new Entry)->id(3)->collection($news)->data(['title' => 'News 1', 'test' => ['test-term']])->slug('charlie')->save();
117+
118+
$this->assertEquals(2, TermFacade::entriesCount(TermFacade::find('test::test-term')->collection($blog)));
119+
$this->assertEquals(1, TermFacade::entriesCount(TermFacade::find('test::test-term')->collection($news)));
120+
}
121+
122+
#[Test]
123+
public function it_gets_entry_count_for_term_filtered_by_site()
124+
{
125+
$this->setSites([
126+
'en' => ['url' => '/', 'locale' => 'en_US', 'name' => 'English'],
127+
'fr' => ['url' => '/fr/', 'locale' => 'fr_FR', 'name' => 'French'],
128+
]);
129+
130+
Taxonomy::make('test')->title('test')->sites(['en', 'fr'])->save();
131+
132+
$term = tap(TermFacade::make('test-term')->taxonomy('test')->data([]))->save();
133+
134+
$collection = Collection::make('blog')->routes('blog/{slug}')->taxonomies(['test'])->sites(['en', 'fr'])->save();
135+
136+
(new Entry)->id(1)->collection($collection)->locale('en')->data(['title' => 'Post 1', 'test' => ['test-term']])->slug('alfa')->save();
137+
(new Entry)->id(2)->collection($collection)->locale('en')->data(['title' => 'Post 2', 'test' => ['test-term']])->slug('bravo')->save();
138+
(new Entry)->id(3)->collection($collection)->locale('fr')->data(['title' => 'Post 3', 'test' => ['test-term']])->slug('charlie')->save();
139+
140+
$this->assertEquals(2, TermFacade::entriesCount($term->in('en')));
141+
$this->assertEquals(1, TermFacade::entriesCount($term->in('fr')));
142+
}
143+
87144
#[Test]
88145
public function it_build_stache_associations_when_taxonomy_driver_is_not_eloquent()
89146
{

0 commit comments

Comments
 (0)