Skip to content

Commit d3689d9

Browse files
committed
Adds EntryRespository#findByIds()
1 parent c98eb44 commit d3689d9

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/Entries/EntryRepository.php

+25
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Statamic\Contracts\Entries\QueryBuilder;
77
use Statamic\Eloquent\Jobs\UpdateCollectionEntryOrder;
88
use Statamic\Eloquent\Jobs\UpdateCollectionEntryParent;
9+
use Statamic\Entries\EntryCollection;
910
use Statamic\Facades\Blink;
1011
use Statamic\Stache\Repositories\EntryRepository as StacheRepository;
1112

@@ -51,6 +52,30 @@ public function findByUri(string $uri, ?string $site = null): ?EntryContract
5152
return $this->substitutionsById[$item->id()] ?? $item;
5253
}
5354

55+
public function findByIds($ids): EntryCollection
56+
{
57+
$cached = collect($ids)->flip()->map(fn ($_, $id) => Blink::get("eloquent-entry-{$id}"));
58+
$missingIds = $cached->reject()->keys();
59+
60+
$missingById = $this->query()
61+
->whereIn('id', $missingIds)
62+
->get()
63+
->keyBy->id();
64+
65+
$missingById->each(function ($entry, $id) {
66+
Blink::put("eloquent-entry-{$id}", $entry);
67+
});
68+
69+
$items = $cached
70+
->map(fn ($entry, $id) => $entry ?? $missingById->get($id))
71+
->filter()
72+
->values();
73+
74+
$this->applySubstitutions($items);
75+
76+
return EntryCollection::make($items);
77+
}
78+
5479
public function save($entry)
5580
{
5681
$model = $entry->toModel();

tests/Entries/EntryRepositoryTest.php

+72
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44

55
use Illuminate\Foundation\Testing\RefreshDatabase;
66
use Illuminate\Support\Facades\Event;
7+
use PHPUnit\Framework\Attributes\Group;
78
use PHPUnit\Framework\Attributes\Test;
89
use Statamic\Eloquent\Entries\Entry;
910
use Statamic\Eloquent\Entries\EntryModel;
1011
use Statamic\Eloquent\Entries\EntryRepository;
12+
use Statamic\Entries\EntryCollection;
1113
use Statamic\Events\CollectionTreeSaved;
14+
use Statamic\Facades\Blink;
1215
use Statamic\Facades\Collection;
1316
use Statamic\Stache\Stache;
1417
use Tests\TestCase;
@@ -234,4 +237,73 @@ public function it_updates_the_parents_of_specific_entries_in_a_collection()
234237
4 => null,
235238
], EntryModel::all()->mapWithKeys(fn ($e) => [$e->id => $e->data['parent'] ?? null])->all());
236239
}
240+
241+
#[Test, Group('EntryRepository#findByIds')]
242+
public function it_gets_entries_by_ids()
243+
{
244+
$collection = Collection::make('pages')->routes('{slug}')->save();
245+
$expected = collect([
246+
(new Entry)->collection($collection)->slug('foo'),
247+
(new Entry)->collection($collection)->slug('bar'),
248+
])->each->save();
249+
250+
$actual = (new EntryRepository(new Stache))->findByIds($expected->map->id());
251+
252+
$this->assertInstanceOf(EntryCollection::class, $actual);
253+
$this->assertEquals($expected->map->id()->all(), $actual->map->id()->all());
254+
}
255+
256+
#[Test, Group('EntryRepository#findByIds')]
257+
public function it_loads_entries_from_database_given_partial_cache_when_finding_by_ids()
258+
{
259+
$collection = Collection::make('pages')->routes('{slug}')->save();
260+
$expected = collect([
261+
(new Entry)->collection($collection)->slug('foo'),
262+
(new Entry)->collection($collection)->slug('bar'),
263+
]);
264+
265+
$expected->first()->save();
266+
Blink::flush();
267+
$expected->last()->save();
268+
269+
$actual = (new EntryRepository(new Stache))->findByIds($expected->map->id());
270+
271+
$this->assertNotNull($expected->first()->id());
272+
$this->assertNotSame($expected->first(), $actual->first());
273+
$this->assertEquals($expected->first()->id(), $actual->first()->id());
274+
$this->assertNotNull($actual->last());
275+
$this->assertSame($expected->last(), $actual->last());
276+
}
277+
278+
#[Test, Group('EntryRepository#findByIds')]
279+
public function it_returns_entries_in_exact_order_when_finding_by_ids()
280+
{
281+
$collection = Collection::make('pages')->routes('{slug}')->save();
282+
$entries = collect([
283+
(new Entry)->collection($collection)->slug('foo'),
284+
(new Entry)->collection($collection)->slug('bar'),
285+
(new Entry)->collection($collection)->slug('baz'),
286+
])->each->save();
287+
288+
Blink::flush();
289+
290+
$expected = collect([2, 0, 1])->map(fn ($index) => $entries[$index]->id())->all();
291+
$actual = (new EntryRepository(new Stache))->findByIds($expected);
292+
293+
$this->assertEquals($expected, $actual->map->id()->all());
294+
}
295+
296+
#[Test, Group('EntryRepository#findByIds')]
297+
public function it_skips_missing_entires_when_finding_by_ids()
298+
{
299+
$collection = Collection::make('pages')->routes('{slug}')->save();
300+
$expected = tap((new Entry)->collection($collection)->slug('foo'))->save();
301+
302+
$actual = (new EntryRepository(new Stache))->findByIds([
303+
$expected->id(),
304+
'missing',
305+
]);
306+
307+
$this->assertEquals([ $expected->id() ], $actual->map->id()->all());
308+
}
237309
}

0 commit comments

Comments
 (0)