Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x] Support scopes as query methods #5927

Merged
merged 40 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
12cb726
Fix error when the scope a filter
aerni Apr 27, 2022
b42cfe9
Automatically apply the scopes to the builders
aerni Apr 27, 2022
396112b
Apply same magic to the tag scopes
aerni Apr 27, 2022
46ca391
Add method to manually register a scope
aerni Apr 27, 2022
73b257e
Move methods to the base builder
aerni Apr 27, 2022
c4696ca
Move logic to a trait
aerni Apr 27, 2022
9ff2ba9
Also apply the scopes when using a DB
aerni Apr 27, 2022
4e2f6f0
Use `get_class` instead of `::class`
aerni Apr 27, 2022
57aab9b
Also use `get_class` here
aerni Apr 27, 2022
5f0256e
Revert "Add method to manually register a scope"
aerni Apr 27, 2022
e9be34c
Fix typo
aerni Apr 27, 2022
f144d4d
Fix tests by filtering empty values
aerni Apr 27, 2022
f35527e
Add tests
aerni Apr 28, 2022
ae2167a
No need to set to an empty array
aerni Apr 28, 2022
b2d9387
Add tests
aerni Apr 28, 2022
014d06e
Fix styling
aerni May 13, 2022
d5b5570
Merge branch '3.3' of https:/aerni/cms into feature/query…
aerni Jun 15, 2022
ce7bc84
Merge branch '4.x' into feature/query-scopes
jasonvarga Jul 6, 2023
002e765
Merge branch '4.x' into pr/5927
duncanmcclean Dec 5, 2023
c0a7ddf
Eloquent queries: check if scope can be applied
duncanmcclean Dec 5, 2023
04e330b
Merge branch '4.x' into pr/5927
duncanmcclean Dec 5, 2023
ae6a277
Eloquent: move response to under scope check
duncanmcclean Dec 5, 2023
a380ed9
Pass arguments to query scope
duncanmcclean Dec 5, 2023
06b94c6
add array typehint
duncanmcclean Dec 5, 2023
718271f
Add Parameters to applyScope typehint
duncanmcclean Dec 5, 2023
d2c1c17
update tests to ensure arguments are passed along
duncanmcclean Dec 5, 2023
5d3a1ef
Merge branch '4.x' into pr/5927
duncanmcclean Feb 13, 2024
5fba217
Pint
duncanmcclean Feb 13, 2024
9852d59
Merge branch '5.x' into pr/5927
duncanmcclean May 13, 2024
5bb88e5
🍺
duncanmcclean May 13, 2024
92baa6e
Replace `snake_case` helper
duncanmcclean May 14, 2024
3142d95
Replace another usage of `snake_case`
duncanmcclean May 14, 2024
4e35c27
Merge branch '5.x' into feature/query-scopes
jasonvarga Sep 30, 2024
9cefa55
rework things ...
jasonvarga Oct 2, 2024
8df7a29
revert unnecessary changes
jasonvarga Oct 2, 2024
c86430b
handled in other tests
jasonvarga Oct 2, 2024
c53e9f9
prevent scope being applied via statamic and also on underlying eloqu…
jasonvarga Oct 2, 2024
33748ab
statamic scopes require arrays as context
jasonvarga Oct 3, 2024
762a1ab
unused
jasonvarga Oct 3, 2024
6cc4c56
revert. this was fixed on main branch already.
jasonvarga Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
use InvalidArgumentException;
use Statamic\Contracts\Query\Builder as Contract;
use Statamic\Extensions\Pagination\LengthAwarePaginator;
use Statamic\Query\Scopes\AppliesScopes;

abstract class Builder implements Contract
{
use AppliesScopes;

protected $columns;
protected $limit;
protected $offset = 0;
Expand All @@ -33,6 +36,13 @@ abstract class Builder implements Contract
'<=' => 'LessThanOrEqualTo',
];

public function __call($method, $args)
{
$this->appplyScope($method);

return $this;
}

public function select($columns = ['*'])
{
$this->columns = $columns;
Expand Down
5 changes: 5 additions & 0 deletions src/Query/EloquentQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Statamic\Contracts\Query\Builder;
use Statamic\Extensions\Pagination\LengthAwarePaginator;
use Statamic\Query\Scopes\AppliesScopes;
use Statamic\Support\Arr;

abstract class EloquentQueryBuilder implements Builder
{
use AppliesScopes;

protected $builder;
protected $columns;

Expand All @@ -21,6 +24,8 @@ public function __call($method, $args)
{
$this->builder->$method(...$args);

$this->appplyScope($method);

return $this;
}

Expand Down
29 changes: 29 additions & 0 deletions src/Query/Scopes/AppliesScopes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Statamic\Query\Scopes;

use Statamic\Facades\Scope;

trait AppliesScopes
{
public function appplyScope($method, $context = [])
{
// Throw an exception if the scope doesn't exist.
if (! $scope = Scope::find(snake_case($method))) {
throw new \Exception("The [$method] scope does not exist.");
}

// Apply the scope to all builders if none were defined.
if ($scope->builders()->isEmpty()) {
return $scope->apply($this, $context);
}

// Only apply the scope to the defined builders.
if ($scope->builders()->contains(get_class($this))) {
return $scope->apply($this, $context);
}

// Throw an exception if a user is trying to access a scope that is not supported by this builder.
throw new \Exception("The [" . get_class($this) . "] query builder does not support the [$method] scope.");
}
}
14 changes: 14 additions & 0 deletions src/Query/Scopes/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Statamic\Query\Scopes;

use Statamic\Statamic;
use Statamic\Extend\HasHandle;
use Statamic\Extend\RegistersItself;

Expand All @@ -10,6 +11,7 @@ abstract class Scope
use RegistersItself, HasHandle;

protected static $binding = 'scopes';
protected static $builders = [];

/**
* Apply the scope to a given query builder.
Expand All @@ -19,4 +21,16 @@ abstract class Scope
* @return void
*/
abstract public function apply($query, $values);

/**
* Return the query builders that this scope supports.
*
* @return \Illuminate\Support\Collection
*/
public static function builders()
{
return collect(static::$builders)->map(function ($builder) {
return get_class(Statamic::query($builder));
});
}
}
10 changes: 8 additions & 2 deletions src/Query/Scopes/ScopeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ public function all()

public function find($key, $context = [])
{
if ($scope = app('statamic.scopes')->get($key)) {
return app($scope)->context($context);
if ($class = app('statamic.scopes')->get($key)) {
$scope = app($class);

if ($scope instanceof Filter) {
$scope->context($context);
}

return $scope;
}
}

Expand Down
12 changes: 3 additions & 9 deletions src/Tags/Concerns/QueriesScopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,9 @@ trait QueriesScopes
{
public function queryScopes($query)
{
$this->parseQueryScopes()
->map(function ($handle) {
return app('statamic.scopes')->get($handle);
})
->filter()
->each(function ($class) use ($query) {
$scope = app($class);
$scope->apply($query, $this->params);
});
$this->parseQueryScopes()->each(function ($handle) use ($query) {
$query->appplyScope($handle, $this->params);
aerni marked this conversation as resolved.
Show resolved Hide resolved
});
}

protected function parseQueryScopes()
Expand Down