Skip to content

Commit d3a117b

Browse files
author
Sylvester Damgaard
authored
Merge pull request #23 from tv2regionerne/feature/use-hooks
Use hooks, update test suite
2 parents f488d4b + a7cfa85 commit d3a117b

File tree

9 files changed

+303
-10
lines changed

9 files changed

+303
-10
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ vendor
33
mix-manifest.json
44
public/hot
55
composer.lock
6-
.idea
6+
.idea
7+
.phpunit.cache

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@ By using `pluck('id')`, you ensure that the returned data is a flat array of IDs
4141
Here’s how to apply this advanced filter within your template:
4242

4343
```antlers
44-
{{ collection:articles query_scope="filter_builder" :filter_builder="my_filter_builder_field_handle" }}
44+
{{ collection:articles :filter_builder="my_filter_builder_field_handle" }}
4545
<!-- Articles that match the locations of the current page will be displayed -->
4646
{{ /collection:articles }}
47+
4748
```
49+
Note: the filter builder requires a query scope behind the scenes, so will not work alongside a query_scope parameter.
50+
4851
You may combine the dynamic Filter Builder query with filter parameters.
4952

5053
The Statamic Filter Builder addon is your pathway to creating a responsive and context-aware website, where content curation is as intelligent as it is effortless.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
}
2626
},
2727
"require": {
28-
"statamic/cms": "^4.50 || ^5.0"
28+
"statamic/cms": "^5.0"
2929
},
3030
"require-dev": {
3131
"nunomaduro/collision": "^7.4",

src/Scopes/FilterBuilder.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ public function apply($query, $values)
2424
$variables = $filter['values']['variables'];
2525

2626
$field = $fields[$handle];
27-
$json = in_array($field->type(), ['entries', 'terms', 'users']) && $field->get('max_items', 0) !== 1;
27+
28+
$json = $field->isRelationship() && $field->get('max_items', 0) !== 1;
2829

2930
$cascade = Cascade::toArray();
3031
foreach ($variables as $variable) {
3132
if (! $parsed = VariableParser::parse($variable, $cascade)) {
3233
continue;
3334
}
35+
3436
$values = array_merge($values, $parsed);
3537
}
3638

src/ServiceProvider.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tv2regionerne\StatamicFilterBuilder;
44

55
use Statamic\Providers\AddonServiceProvider;
6+
use Statamic\Tags\Collection\Collection as CollectionTag;
67

78
class ServiceProvider extends AddonServiceProvider
89
{
@@ -20,4 +21,30 @@ class ServiceProvider extends AddonServiceProvider
2021
'resources/js/addon.js',
2122
],
2223
];
24+
25+
public function boot()
26+
{
27+
$this->addCollectionHook();
28+
}
29+
30+
private function addCollectionHook(): self
31+
{
32+
CollectionTag::hook('init', function ($value, $next) {
33+
if (! $this->params->get('filter_builder')) {
34+
return $next($value);
35+
}
36+
37+
if ($this->params->get('query_scope')) {
38+
return $next($value);
39+
}
40+
41+
$this->params = $this->params->merge([
42+
'query_scope' => 'filter_builder',
43+
]);
44+
45+
return $next($value);
46+
});
47+
48+
return $this;
49+
}
2350
}

tests/TestCase.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,26 @@
22

33
namespace Tests;
44

5+
use Statamic\Testing\AddonTestCase;
6+
use Statamic\Testing\Concerns\PreventsSavingStacheItemsToDisk;
57
use Tv2regionerne\StatamicFilterBuilder\ServiceProvider;
68

7-
class TestCase extends \Orchestra\Testbench\TestCase
9+
class TestCase extends AddonTestCase
810
{
9-
protected function getPackageProviders($app)
11+
use PreventsSavingStacheItemsToDisk;
12+
13+
protected $fakeStacheDirectory = __DIR__.'/__fixtures__/dev-null';
14+
15+
protected string $addonServiceProvider = ServiceProvider::class;
16+
17+
protected function setUp(): void
1018
{
11-
return [
12-
ServiceProvider::class,
13-
\Statamic\Providers\StatamicServiceProvider::class,
14-
];
19+
parent::setUp();
20+
21+
$this->withoutVite();
22+
23+
if (! file_exists($this->fakeStacheDirectory)) {
24+
mkdir($this->fakeStacheDirectory, 0777, true);
25+
}
1526
}
1627
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
use Statamic\Facades;
4+
use Statamic\Tags\Collection\Collection as CollectionTag;
5+
6+
uses(Tests\TestCase::class);
7+
8+
beforeEach(function () {
9+
Facades\Collection::make()
10+
->handle('pages')
11+
->save();
12+
});
13+
14+
it('adds query scope when none is applied', function () {
15+
$params = [];
16+
CollectionTag::hook('fetched-entries', function () use (&$params) {
17+
$params = $this->params->all();
18+
});
19+
20+
Facades\Antlers::parse('{{ collection:pages filter_builder="something" }}{{ title }}{{ /collection:pages }}');
21+
22+
$this->assertArrayHasKey('query_scope', $params);
23+
});
24+
25+
it('doesnt add a query scope if one already exists', function () {
26+
$params = [];
27+
CollectionTag::hook('fetched-entries', function () use (&$params) {
28+
$params = $this->params->all();
29+
});
30+
31+
Facades\Antlers::parse('{{ collection:pages filter_builder="something" query_scope="some_scope" }}{{ title }}{{ /collection:pages }}');
32+
33+
$this->assertArrayHasKey('query_scope', $params);
34+
$this->assertNotSame('filter_builder', $params['query_scope']);
35+
});
36+
37+
it('doesn\'t add query scope when no filter builder param is added', function () {
38+
$params = [];
39+
CollectionTag::hook('fetched-entries', function () use (&$params) {
40+
$params = $this->params->all();
41+
});
42+
43+
Facades\Antlers::parse('{{ collection:pages }}{{ title }}{{ /collection:pages }}');
44+
45+
$this->assertArrayNotHasKey('query_scope', $params);
46+
});
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
<?php
2+
3+
use Statamic\Facades;
4+
5+
uses(Tests\TestCase::class);
6+
7+
beforeEach(function () {
8+
app('statamic.scopes')->put('filter_builder', 'Tv2regionerne\\StatamicFilterBuilder\\Scopes\\FilterBuilder');
9+
10+
$collection = tap(Facades\Collection::make()
11+
->handle('pages'))
12+
->save();
13+
14+
$collection->entryBlueprints()->first()->setContents([
15+
'fields' => [
16+
[
17+
'handle' => 'title',
18+
'field' => [
19+
'type' => 'text',
20+
],
21+
],
22+
[
23+
'handle' => 'entries',
24+
'field' => [
25+
'type' => 'entries',
26+
'max_items' => 5,
27+
],
28+
],
29+
],
30+
])->save();
31+
32+
Facades\Entry::make()
33+
->id('one')
34+
->collection('pages')
35+
->merge([
36+
'title' => 'One',
37+
'entries' => ['One'],
38+
])
39+
->save();
40+
41+
Facades\Entry::make()
42+
->id('two')
43+
->collection('pages')
44+
->merge([
45+
'title' => 'Two',
46+
'entries' => ['One', 'Two'],
47+
])
48+
->save();
49+
50+
Facades\Entry::make()
51+
->id('three')
52+
->collection('pages')
53+
->merge([
54+
'title' => 'Three',
55+
'entries' => ['One', 'Two', 'Three'],
56+
])
57+
->save();
58+
});
59+
60+
it('filters text fields', function () {
61+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
62+
'params' => [
63+
[
64+
'handle' => 'title',
65+
'values' => [
66+
'operator' => '=',
67+
'values' => ['one'],
68+
'variables' => [],
69+
],
70+
],
71+
],
72+
]);
73+
74+
$this->assertSame('One', $result);
75+
76+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
77+
'params' => [
78+
[
79+
'handle' => 'title',
80+
'values' => [
81+
'operator' => '<>',
82+
'values' => ['one'],
83+
'variables' => [],
84+
],
85+
],
86+
],
87+
]);
88+
89+
$this->assertSame('ThreeTwo', $result);
90+
91+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
92+
'params' => [
93+
[
94+
'handle' => 'title',
95+
'values' => [
96+
'operator' => '=',
97+
'values' => ['one', 'two'],
98+
'variables' => [],
99+
],
100+
],
101+
],
102+
]);
103+
104+
$this->assertSame('OneTwo', $result);
105+
106+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
107+
'params' => [
108+
[
109+
'handle' => 'title',
110+
'values' => [
111+
'operator' => '=',
112+
'values' => ['four'],
113+
'variables' => [],
114+
],
115+
],
116+
],
117+
]);
118+
119+
$this->assertSame('', $result);
120+
});
121+
122+
it('filters fields with values from the cascade', function () {
123+
Facades\Cascade::set('cascade_variable', 'one');
124+
125+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
126+
'params' => [
127+
[
128+
'handle' => 'title',
129+
'values' => [
130+
'operator' => '=',
131+
'values' => [],
132+
'variables' => ['{{ cascade_variable }}'],
133+
],
134+
],
135+
],
136+
]);
137+
138+
$this->assertSame('One', $result);
139+
});
140+
141+
it('filters relationship fields', function () {
142+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
143+
'params' => [
144+
[
145+
'handle' => 'entries',
146+
'values' => [
147+
'operator' => '=',
148+
'values' => ['Three'],
149+
'variables' => [],
150+
],
151+
],
152+
],
153+
]);
154+
155+
//dd(Facades\Entry::query()->whereJsonContains('entries', ['One'])->get());
156+
157+
$this->assertSame('Three', $result);
158+
159+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
160+
'params' => [
161+
[
162+
'handle' => 'entries',
163+
'values' => [
164+
'operator' => '<>',
165+
'values' => ['Three'],
166+
'variables' => [],
167+
],
168+
],
169+
],
170+
]);
171+
172+
$this->assertSame('OneTwo', $result);
173+
174+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
175+
'params' => [
176+
[
177+
'handle' => 'entries',
178+
'values' => [
179+
'operator' => '=',
180+
'values' => ['Three', 'Two'],
181+
'variables' => [],
182+
],
183+
],
184+
],
185+
]);
186+
187+
$this->assertSame('ThreeTwo', $result);
188+
189+
$result = (string) Facades\Antlers::parse('{{ collection:pages :filter_builder="params" }}{{ title }}{{ /collection:pages }}', [
190+
'params' => [
191+
[
192+
'handle' => 'title',
193+
'values' => [
194+
'operator' => '=',
195+
'values' => ['Four'],
196+
'variables' => [],
197+
],
198+
],
199+
],
200+
]);
201+
202+
$this->assertSame('', $result);
203+
});

0 commit comments

Comments
 (0)