Skip to content

Commit 46d5806

Browse files
committed
Added excludeCritiera to Config
1 parent 1ee1d1e commit 46d5806

File tree

3 files changed

+105
-11
lines changed

3 files changed

+105
-11
lines changed

src/Config.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ class Config
6767
*/
6868
protected bool|null $sortFields = null;
6969

70+
/**
71+
* @var string[] An array of filters to exclude from
72+
* available filters for all fields and
73+
* associations in every entity
74+
*/
75+
protected array $excludeCriteria = [];
76+
7077
/** @param mixed[] $config */
7178
public function __construct(array $config = [])
7279
{
@@ -189,4 +196,18 @@ public function getSortFields(): bool|null
189196
{
190197
return $this->sortFields;
191198
}
199+
200+
/** @param string[] $excludeCriteria */
201+
public function setExcludeCriteria(array $excludeCriteria): self
202+
{
203+
$this->excludeCriteria = $excludeCriteria;
204+
205+
return $this;
206+
}
207+
208+
/** @return string[] */
209+
public function getExcludeCriteria(): array
210+
{
211+
return $this->excludeCriteria;
212+
}
192213
}

src/Criteria/CriteriaFactory.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
use GraphQL\Type\Definition\Type;
1515
use League\Event\EventDispatcher;
1616

17+
use function array_diff;
1718
use function array_filter;
1819
use function array_keys;
20+
use function array_merge;
21+
use function array_unique;
1922
use function count;
2023
use function in_array;
2124

25+
use const SORT_REGULAR;
26+
2227
class CriteriaFactory
2328
{
2429
public function __construct(
@@ -44,17 +49,18 @@ public function get(
4449
return $this->typeManager->get($typeName);
4550
}
4651

47-
$fields = [];
48-
$entityMetadata = $targetEntity->getMetadata();
49-
$allowedFilters = Filters::toArray();
50-
51-
// Limit entity filters
52-
if ($entityMetadata['excludeCriteria']) {
53-
$excludeCriteria = $entityMetadata['excludeCriteria'];
54-
$allowedFilters = array_filter($allowedFilters, static function ($value) use ($excludeCriteria) {
55-
return ! in_array($value, $excludeCriteria);
56-
});
57-
}
52+
$fields = [];
53+
$entityMetadata = $targetEntity->getMetadata();
54+
$excludedFilters = array_unique(
55+
array_merge(
56+
$entityMetadata['excludeCriteria'],
57+
$this->config->getExcludeCriteria(),
58+
),
59+
SORT_REGULAR,
60+
);
61+
62+
// Limit filters
63+
$allowedFilters = array_diff(Filters::toArray(), $excludedFilters);
5864

5965
// Limit association filters
6066
if ($associationName) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ApiSkeletonsTest\Doctrine\GraphQL\Feature\Criteria;
6+
7+
use ApiSkeletons\Doctrine\GraphQL\Config;
8+
use ApiSkeletons\Doctrine\GraphQL\Driver;
9+
use ApiSkeletonsTest\Doctrine\GraphQL\AbstractTest;
10+
use ApiSkeletonsTest\Doctrine\GraphQL\Entity\Artist;
11+
use GraphQL\GraphQL;
12+
use GraphQL\Type\Definition\ObjectType;
13+
use GraphQL\Type\Schema;
14+
15+
class ConfigExcludeCriteriaTest extends AbstractTest
16+
{
17+
public function testConfigExcludeCriteria(): void
18+
{
19+
$config = new Config(['excludeCriteria' => ['eq', 'neq', 'contains']]);
20+
21+
$driver = new Driver($this->getEntityManager(), $config);
22+
23+
$schema = new Schema([
24+
'query' => new ObjectType([
25+
'name' => 'query',
26+
'fields' => [
27+
'artists' => [
28+
'type' => $driver->connection($driver->type(Artist::class)),
29+
'args' => [
30+
'filter' => $driver->filter(Artist::class),
31+
'pagination' => $driver->pagination(),
32+
],
33+
'resolve' => $driver->resolve(Artist::class),
34+
],
35+
],
36+
]),
37+
]);
38+
39+
$query = '{ artists (filter: { name: { eq: "Grateful Dead" } } ) { edges { node { name } } } }';
40+
$result = GraphQL::executeQuery($schema, $query);
41+
42+
foreach ($result->errors as $error) {
43+
$this->assertEquals('Field "eq" is not defined by type "artist_default_filter_name_filters".', $error->getMessage());
44+
}
45+
46+
$query = '{ artists (filter: { name: { neq: "Grateful Dead" } } ) { edges { node { name } } } }';
47+
$result = GraphQL::executeQuery($schema, $query);
48+
49+
foreach ($result->errors as $error) {
50+
$this->assertEquals('Field "neq" is not defined by type "artist_default_filter_name_filters".', $error->getMessage());
51+
}
52+
53+
$query = '{ artists { edges { node { performances ( filter: {venue: { neq: "test"} } ) { edges { node { venue } } } } } } }';
54+
$result = GraphQL::executeQuery($schema, $query);
55+
56+
foreach ($result->errors as $error) {
57+
$this->assertEquals('Field "neq" is not defined by type "artist_default_performances_filter_venue_filters".', $error->getMessage());
58+
}
59+
60+
$query = '{ artists { edges { node { performances ( filter: {venue: { contains: "test" } } ) { edges { node { venue } } } } } } }';
61+
$result = GraphQL::executeQuery($schema, $query);
62+
63+
foreach ($result->errors as $error) {
64+
$this->assertEquals('Field "contains" is not defined by type "artist_default_performances_filter_venue_filters". Did you mean "notin"?', $error->getMessage());
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)