Skip to content

Commit e748140

Browse files
committed
Make code better extendable
1 parent 0f0a096 commit e748140

File tree

2 files changed

+104
-28
lines changed

2 files changed

+104
-28
lines changed

src/Config/Parser/GraphQLParser.php

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66

77
use Exception;
88
use GraphQL\Language\AST\DefinitionNode;
9+
use GraphQL\Language\AST\DocumentNode;
910
use GraphQL\Language\AST\EnumTypeDefinitionNode;
1011
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
1112
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
1213
use GraphQL\Language\AST\NodeKind;
14+
use GraphQL\Language\AST\NodeList;
1315
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
1416
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
1517
use GraphQL\Language\AST\UnionTypeDefinitionNode;
@@ -47,25 +49,24 @@ class GraphQLParser implements ParserInterface
4749
public static function parse(SplFileInfo $file, ContainerBuilder $container, array $configs = []): array
4850
{
4951
$container->addResource(new FileResource($file->getRealPath()));
50-
$content = trim((string) file_get_contents($file->getPathname()));
51-
$typesConfig = [];
5252

53-
// allow empty files
54-
if (empty($content)) {
55-
return [];
56-
}
57-
try {
58-
$ast = Parser::parse($content);
59-
} catch (Exception $e) {
60-
throw new InvalidArgumentException(sprintf('An error occurred while parsing the file "%s".', $file), $e->getCode(), $e);
61-
}
53+
return static::buildTypes(static::parseFile($file));
54+
}
55+
56+
/**
57+
* @return array<string,mixed>
58+
*/
59+
protected static function buildTypes(DocumentNode $ast): array
60+
{
61+
$nameGeneratorBag = [];
62+
$typesConfig = [];
6263

6364
foreach ($ast->definitions as $typeDef) {
6465
/**
6566
* @var ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeDefinitionNode|UnionTypeDefinitionNode|InputObjectTypeDefinitionNode|ScalarTypeDefinitionNode $typeDef
6667
*/
6768
$config = static::prepareConfig($typeDef);
68-
$typesConfig[$typeDef->name->value] = $config;
69+
$typesConfig[static::getTypeDefinitionName($typeDef, $nameGeneratorBag)] = $config;
6970
}
7071

7172
return $typesConfig;
@@ -95,6 +96,18 @@ protected static function getNodeClass(DefinitionNode $typeDef): string
9596
throw static::createUnsupportedDefinitionNodeException($typeDef);
9697
}
9798

99+
/**
100+
* @param array<string,mixed> $nameGeneratorBag
101+
*/
102+
protected static function getTypeDefinitionName(DefinitionNode $typeDef, array &$nameGeneratorBag): string
103+
{
104+
if (isset($typeDef->name)) {
105+
return $typeDef->name->value;
106+
}
107+
108+
throw static::createUnsupportedDefinitionNodeException($typeDef);
109+
}
110+
98111
/**
99112
* @return array<string,mixed>
100113
*/
@@ -104,4 +117,20 @@ protected static function prepareConfig(DefinitionNode $typeDef): array
104117

105118
return \call_user_func([$nodeClass, 'toConfig'], $typeDef);
106119
}
120+
121+
protected static function parseFile(SplFileInfo $file): DocumentNode
122+
{
123+
$content = trim((string) file_get_contents($file->getPathname()));
124+
125+
// allow empty files
126+
if (empty($content)) {
127+
return new DocumentNode(['definitions' => new NodeList([])]);
128+
}
129+
130+
try {
131+
return Parser::parse($content);
132+
} catch (Exception $e) {
133+
throw new InvalidArgumentException(sprintf('An error occurred while parsing the file "%s".', $file), $e->getCode(), $e);
134+
}
135+
}
107136
}

src/Definition/Builder/SchemaBuilder.php

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@ public function __construct(TypeResolver $typeResolver, bool $enableValidation =
2222
$this->enableValidation = $enableValidation;
2323
}
2424

25-
public function getBuilder(string $name, ?string $queryAlias, ?string $mutationAlias = null, ?string $subscriptionAlias = null, array $types = []): Closure
26-
{
25+
/**
26+
* @param string[] $types
27+
*/
28+
public function getBuilder(
29+
string $name,
30+
?string $queryAlias,
31+
?string $mutationAlias = null,
32+
?string $subscriptionAlias = null,
33+
array $types = []
34+
): Closure {
2735
return function () use ($name, $queryAlias, $mutationAlias, $subscriptionAlias, $types): ExtensibleSchema {
2836
static $schema = null;
2937
if (null === $schema) {
@@ -37,14 +45,22 @@ public function getBuilder(string $name, ?string $queryAlias, ?string $mutationA
3745
/**
3846
* @param string[] $types
3947
*/
40-
public function create(string $name, ?string $queryAlias, ?string $mutationAlias = null, ?string $subscriptionAlias = null, array $types = []): ExtensibleSchema
41-
{
48+
public function create(
49+
string $name,
50+
?string $queryAlias,
51+
?string $mutationAlias = null,
52+
?string $subscriptionAlias = null,
53+
array $types = []
54+
): ExtensibleSchema {
4255
$this->typeResolver->setCurrentSchemaName($name);
4356
$query = $this->typeResolver->resolve($queryAlias);
4457
$mutation = $this->typeResolver->resolve($mutationAlias);
4558
$subscription = $this->typeResolver->resolve($subscriptionAlias);
4659

47-
$schema = new ExtensibleSchema($this->buildSchemaArguments($name, $query, $mutation, $subscription, $types));
60+
/** @var class-string<ExtensibleSchema> $class */
61+
$class = $this->getSchemaClass();
62+
63+
$schema = new $class($this->buildSchemaArguments($name, $query, $mutation, $subscription, $types));
4864
$extensions = [];
4965

5066
if ($this->enableValidation) {
@@ -55,22 +71,53 @@ public function create(string $name, ?string $queryAlias, ?string $mutationAlias
5571
return $schema;
5672
}
5773

58-
private function buildSchemaArguments(string $schemaName, Type $query, ?Type $mutation, ?Type $subscription, array $types = []): array
59-
{
74+
/**
75+
* @param string[] $types
76+
*
77+
* @return array<string,mixed>
78+
*/
79+
protected function buildSchemaArguments(
80+
string $schemaName,
81+
?Type $query,
82+
?Type $mutation,
83+
?Type $subscription,
84+
array $types = []
85+
): array {
6086
return [
6187
'query' => $query,
6288
'mutation' => $mutation,
6389
'subscription' => $subscription,
64-
'typeLoader' => function ($name) use ($schemaName) {
65-
$this->typeResolver->setCurrentSchemaName($schemaName);
90+
'typeLoader' => $this->createTypeLoaderClosure($schemaName),
91+
'types' => $this->createTypesClosure($schemaName, $types),
92+
];
93+
}
6694

67-
return $this->typeResolver->resolve($name);
68-
},
69-
'types' => function () use ($types, $schemaName) {
70-
$this->typeResolver->setCurrentSchemaName($schemaName);
95+
protected function createTypeLoaderClosure(string $schemaName): Closure
96+
{
97+
return function ($name) use ($schemaName): ?Type {
98+
$this->typeResolver->setCurrentSchemaName($schemaName);
7199

72-
return array_map([$this->typeResolver, 'resolve'], $types);
73-
},
74-
];
100+
return $this->typeResolver->resolve($name);
101+
};
102+
}
103+
104+
/**
105+
* @param string[] $types
106+
*/
107+
protected function createTypesClosure(string $schemaName, array $types): Closure
108+
{
109+
return function () use ($types, $schemaName): array {
110+
$this->typeResolver->setCurrentSchemaName($schemaName);
111+
112+
return array_map(fn (string $x): ?Type => $this->typeResolver->resolve($x), $types);
113+
};
114+
}
115+
116+
/**
117+
* @return class-string<ExtensibleSchema>
118+
*/
119+
protected function getSchemaClass(): string
120+
{
121+
return ExtensibleSchema::class;
75122
}
76123
}

0 commit comments

Comments
 (0)