Skip to content

Commit 533612b

Browse files
committed
Support native enums in Filters #10257
If the custom types container is correctly configured to be able to create a `\GraphQL\Type\Definition\EnumType` matching the FQCN of a PHP native enum, then `graphql-doctrine` will be able to use PHP native enum in output, input and filters.
1 parent 8cd6fef commit 533612b

File tree

10 files changed

+341
-2
lines changed

10 files changed

+341
-2
lines changed

src/Factory/Type/FilterGroupConditionTypeFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ private function getLeafType(ReflectionProperty $property, FieldMapping $mapping
128128
}
129129

130130
/** @var LeafType $leafType */
131-
$leafType = $this->types->get($mapping->type);
131+
$leafType = $this->types->get($mapping->enumType ?? $mapping->type);
132132

133133
return $leafType;
134134
}

tests/Blog/Enum/Status.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GraphQLTests\Doctrine\Blog\Enum;
6+
7+
enum Status: string
8+
{
9+
case New = 'new';
10+
case Active = 'active';
11+
case Archived = 'archived';
12+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GraphQLTests\Doctrine\Blog\Model\Special;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use GraphQLTests\Doctrine\Blog\Enum\Status;
9+
use GraphQLTests\Doctrine\Blog\Model\AbstractModel;
10+
11+
#[ORM\Entity]
12+
final class EnumSupport extends AbstractModel
13+
{
14+
#[ORM\Column(type: 'enum')]
15+
private Status $status;
16+
17+
public function getStatus(): Status
18+
{
19+
return $this->status;
20+
}
21+
22+
public function setStatus(Status $status): void
23+
{
24+
$this->status = $status;
25+
}
26+
}

tests/FilterTypesTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Exception;
88
use GraphQL\Type\Definition\Type;
99
use GraphQLTests\Doctrine\Blog\Model\Post;
10+
use GraphQLTests\Doctrine\Blog\Model\Special\EnumSupport;
1011
use GraphQLTests\Doctrine\Blog\Model\Special\InvalidFilter;
1112
use GraphQLTests\Doctrine\Blog\Model\Special\InvalidFilterGroupCondition;
1213
use GraphQLTests\Doctrine\Blog\Model\Special\ModelWithTraits;
@@ -20,7 +21,6 @@ final class FilterTypesTest extends TestCase
2021
public function testCanGetPostFilter(): void
2122
{
2223
$actual = $this->types->getFilter(Post::class);
23-
2424
$this->assertAllTypes('tests/data/PostFilter.graphqls', $actual);
2525
}
2626

@@ -30,6 +30,12 @@ public function testCanInheritFilterFromTraits(): void
3030
$this->assertAllTypes('tests/data/ModelWithTraitsFilter.graphqls', $actual);
3131
}
3232

33+
public function testCanUseNativeEnum(): void
34+
{
35+
$actual = $this->types->getFilter(EnumSupport::class);
36+
$this->assertAllTypes('tests/data/EnumSupportFilter.graphqls', $actual);
37+
}
38+
3339
public static function providerFilteredQueryBuilder(): array
3440
{
3541
$values = [];

tests/InputTypesTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ public function testSelfSupportInput(): void
4141
$this->assertType('tests/data/SelfSupportInput.graphqls', $actual);
4242
}
4343

44+
public function testEnumSupportInput(): void
45+
{
46+
$actual = $this->types->getInput(Blog\Model\Special\EnumSupport::class);
47+
$this->assertType('tests/data/EnumSupportInput.graphqls', $actual);
48+
}
49+
4450
public function testNamespaceSupportInput(): void
4551
{
4652
$actual = $this->types->getInput(Blog\Model\Special\NamespaceSupport::class);

tests/OutputTypesTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ public function testSelfSupportOutput(): void
5555
$this->assertType('tests/data/SelfSupport.graphqls', $actual);
5656
}
5757

58+
public function testEnumSupportOutput(): void
59+
{
60+
$actual = $this->types->getOutput(Blog\Model\Special\EnumSupport::class);
61+
$this->assertType('tests/data/EnumSupport.graphqls', $actual);
62+
}
63+
5864
public function testNamespaceSupportOutput(): void
5965
{
6066
$actual = $this->types->getOutput(Blog\Model\Special\NamespaceSupport::class);

tests/TypesTrait.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@
1111
use GraphQL\Type\Definition\InputType;
1212
use GraphQL\Type\Definition\ObjectType;
1313
use GraphQL\Type\Definition\OutputType;
14+
use GraphQL\Type\Definition\PhpEnumType;
1415
use GraphQL\Type\Definition\Type;
1516
use GraphQL\Type\Definition\WrappingType;
1617
use GraphQL\Type\Schema;
1718
use GraphQL\Utils\SchemaPrinter;
19+
use GraphQLTests\Doctrine\Blog\Enum\Status;
1820
use GraphQLTests\Doctrine\Blog\Types\CustomType;
1921
use GraphQLTests\Doctrine\Blog\Types\DateTimeType;
2022
use GraphQLTests\Doctrine\Blog\Types\PostStatusType;
23+
use Laminas\ServiceManager\Factory\AbstractFactoryInterface;
2124
use Laminas\ServiceManager\ServiceManager;
25+
use Psr\Container\ContainerInterface;
2226
use stdClass;
2327

2428
/**
@@ -44,6 +48,19 @@ public function setUp(): void
4448
'aliases' => [
4549
'datetime_immutable' => DateTimeImmutable::class, // Declare alias for Doctrine type to be used for filters
4650
],
51+
'abstract_factories' => [
52+
new class() implements AbstractFactoryInterface {
53+
public function canCreate(ContainerInterface $container, string $requestedName): bool
54+
{
55+
return $requestedName === Status::class;
56+
}
57+
58+
public function __invoke(ContainerInterface $container, string $requestedName, ?array $options = null): PhpEnumType
59+
{
60+
return new PhpEnumType(Status::class);
61+
}
62+
},
63+
],
4764
]);
4865

4966
$this->types = new Types($this->entityManager, $customTypes);

tests/data/EnumSupport.graphqls

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type EnumSupport {
2+
status: Status!
3+
id: ID!
4+
creationDate: DateTime!
5+
}

0 commit comments

Comments
 (0)