diff --git a/src/Stache/Query/EntryQueryBuilder.php b/src/Stache/Query/EntryQueryBuilder.php index 89d421252cb..923cecc9e44 100644 --- a/src/Stache/Query/EntryQueryBuilder.php +++ b/src/Stache/Query/EntryQueryBuilder.php @@ -5,6 +5,7 @@ use Statamic\Contracts\Entries\QueryBuilder; use Statamic\Entries\EntryCollection; use Statamic\Facades; +use Statamic\Facades\Blink; use Statamic\Facades\Collection; use Statamic\Support\Arr; @@ -69,6 +70,39 @@ protected function getFilteredKeys() : $this->getKeysFromCollectionsWithWheres($collections, $this->wheres); } + private function addCollectionWheres(): void + { + $this->collections = $this->getCollectionWheres(); + } + + private function getCollectionWheres(): array + { + // If the collections property isn't empty, it means the user has explicitly + // queried for them. In that case, we'll use them and skip the auto-detection. + if (! empty($this->collections)) { + return $this->collections; + } + + // Otherwise, we'll detect them by looking at where clauses targeting the "id" column. + $ids = collect($this->wheres)->where('column', 'id')->flatMap(fn ($where) => $where['values'] ?? [$where['value']]); + + // If no IDs were queried, fall back to all collections. + if ($ids->isEmpty()) { + return Collection::handles()->all(); + } + + return Blink::once('entry-to-collection-map', function () { + return Collection::handles() + ->flatMap(fn ($collection) => $this->getWhereColumnKeysFromStore($collection, ['column' => 'collectionHandle'])) + ->keys() + ->mapWithKeys(function ($value) { + [$collection, $id] = explode('::', $value); + + return [$id => $collection]; + }); + })->only($ids->all())->unique()->values()->all(); + } + protected function getKeysFromCollections($collections) { return collect($collections)->flatMap(function ($collection) { @@ -146,6 +180,8 @@ protected function getWhereColumnKeyValuesByIndex($column) public function whereStatus(string $status) { + $this->addCollectionWheres(); + if (! in_array($status, self::STATUSES)) { throw new \Exception("Invalid status [$status]"); }