Skip to content

Commit 32e4bde

Browse files
mynetxjasonvarga
andauthored
[6.x] Pass active query scope handles to relationship index scopes (#14883)
Co-authored-by: Jason Varga <jason@pixelfear.com>
1 parent 5c3c78b commit 32e4bde

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

src/Fieldtypes/Relationship.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,12 @@ public function toQueryableValue($value)
366366

367367
protected function applyIndexQueryScopes($query, $params)
368368
{
369-
collect(Arr::wrap($this->config('query_scopes')))
369+
$handles = Arr::wrap($this->config('query_scopes'));
370+
371+
// Pass the active handles along so an aliased scope knows which is in effect.
372+
$params = array_merge($params, ['queryScopes' => $handles]);
373+
374+
collect($handles)
370375
->map(fn ($handle) => Scope::find($handle))
371376
->filter()
372377
->each(fn ($scope) => $scope->apply($query, $params));

tests/Feature/Fieldtypes/RelationshipFieldtypeTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public function setUp(): void
3131
$this->collection = Collection::make('test')->save();
3232

3333
app('statamic.scopes')[StartsWithC::handle()] = StartsWithC::class;
34+
35+
// Register one scope class under an alias that differs from its handle, so the
36+
// test can prove the configured alias is what reaches the scope.
37+
app('statamic.scopes')['fruit_filter'] = AliasedScope::class;
3438
}
3539

3640
#[Test]
@@ -64,6 +68,34 @@ public function it_filters_entries_by_query_scopes()
6468
$this->assertNotContains('Banana', $titles);
6569
}
6670

71+
#[Test]
72+
public function it_passes_the_active_scope_handles_to_aliased_scopes()
73+
{
74+
Entry::make()->collection('test')->slug('apple')->data(['title' => 'Apple'])->save();
75+
Entry::make()->collection('test')->slug('carrot')->data(['title' => 'Carrot'])->save();
76+
Entry::make()->collection('test')->slug('cherry')->data(['title' => 'Cherry'])->save();
77+
Entry::make()->collection('test')->slug('banana')->data(['title' => 'Banana'])->save();
78+
79+
$this->setTestRoles(['test' => ['access cp', 'view test entries']]);
80+
$user = User::make()->assignRole('test')->save();
81+
82+
$config = base64_encode(json_encode([
83+
'type' => 'entries',
84+
'collections' => ['test'],
85+
'query_scopes' => ['fruit_filter'],
86+
]));
87+
88+
$response = $this
89+
->actingAs($user)
90+
->get("/cp/fieldtypes/relationship?config={$config}")
91+
->assertOk();
92+
93+
$titles = collect($response->json('data'))->pluck('title')->all();
94+
95+
// The scope only filters when its alias is present in the queryScopes param.
96+
$this->assertEqualsCanonicalizing(['Carrot', 'Cherry'], $titles);
97+
}
98+
6799
#[Test]
68100
public function it_limits_access_to_entries_from_collections_the_user_can_view()
69101
{
@@ -716,3 +748,13 @@ public function apply($query, $params)
716748
$query->where('title', 'like', 'C%');
717749
}
718750
}
751+
752+
class AliasedScope extends Scope
753+
{
754+
public function apply($query, $params)
755+
{
756+
if (in_array('fruit_filter', $params['queryScopes'] ?? [])) {
757+
$query->where('title', 'like', 'C%');
758+
}
759+
}
760+
}

0 commit comments

Comments
 (0)