Skip to content

Commit

Permalink
use trait
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonvarga committed May 3, 2024
1 parent 727271f commit 41e1ee8
Showing 1 changed file with 22 additions and 50 deletions.
72 changes: 22 additions & 50 deletions src/Entries/EntryQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
use Statamic\Facades\Collection;
use Statamic\Facades\Entry;
use Statamic\Query\EloquentQueryBuilder;
use Statamic\Stache\Query\QueriesEntryStatus;
use Statamic\Stache\Query\QueriesTaxonomizedEntries;

class EntryQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
{
use QueriesTaxonomizedEntries;
use QueriesEntryStatus,
QueriesTaxonomizedEntries;

private $selectedQueryColumns;

Expand Down Expand Up @@ -182,65 +184,35 @@ public function whereIn($column, $values, $boolean = 'and')
return parent::whereIn($column, $values, $boolean);
}

public function whereStatus(string $status)
private function ensureCollectionsAreQueriedForStatusQuery()
{
if (! in_array($status, self::STATUSES)) {
throw new \Exception("Invalid status [$status]");
}
$wheres = collect($this->builder->getQuery()->wheres);

if ($status === 'draft') {
return $this->where('published', false);
// If there are where clauses on the collection column, it means the user has explicitly
// queried for them. In that case, we'll use them and skip the auto-detection.
if ($wheres->where('column', 'collection')->isNotEmpty()) {
return;
}

$this->where('published', true);
// Otherwise, we'll detect them by looking at where clauses targeting the "id" column.
$ids = $wheres->where('column', 'id')->flatMap(fn ($where) => $where['values'] ?? [$where['value']]);

return $this->where(fn ($query) => $this
->getCollectionsForStatus()
->each(fn ($collection) => $query->orWhere(fn ($q) => $this->addCollectionStatusLogicToQuery($q, $status, $collection))));
}

private function getCollectionsForStatus()
{
// Since we have to add nested queries for each collection, if collections have been provided,
// we'll use those to avoid the need for adding unnecessary query clauses.

$wheres = collect($this->builder->getQuery()->wheres);

if ($wheres->where('column', 'collection')->isEmpty()) {
return Collection::all();
// If no IDs were queried, fall back to all collections.
if ($ids->isEmpty()) {
return $this->whereIn('collection', Collection::handles());
}

return $wheres->where('column', 'collection')->pluck('value')->map(fn ($handle) => Collection::find($handle));
$this->whereIn('collection', app(static::class)->whereIn('id', $ids)->pluck('collection')->unique()->values());
}

private function addCollectionStatusLogicToQuery($query, $status, $collection)
private function getCollectionsForStatusQuery()
{
$query->where('collection', $collection->handle());

if ($collection->futureDateBehavior() === 'public' && $collection->pastDateBehavior() === 'public') {
if ($status === 'scheduled' || $status === 'expired') {
$query->where('date', 'invalid'); // intentionally trigger no results.
}
}

if ($collection->futureDateBehavior() === 'private') {
$status === 'scheduled'
? $query->where('date', '>', now())
: $query->where('date', '<', now());
// Since we have to add nested queries for each collection, we only want to add clauses for the
// applicable collections. By this point, there should be where clauses on the collection column.

if ($status === 'expired') {
$query->where('date', 'invalid'); // intentionally trigger no results.
}
}

if ($collection->pastDateBehavior() === 'private') {
$status === 'expired'
? $query->where('date', '<', now())
: $query->where('date', '>', now());

if ($status === 'scheduled') {
$query->where('date', 'invalid'); // intentionally trigger no results.
}
}
return collect($this->builder->getQuery()->wheres)
->where('column', 'collection')
->flatMap(fn ($where) => $where['values'] ?? [$where['value']])
->map(fn ($handle) => Collection::find($handle));
}
}

0 comments on commit 41e1ee8

Please sign in to comment.