Skip to content

Commit a1f9a1b

Browse files
committed
Add support for mutations
1 parent 17d9a75 commit a1f9a1b

File tree

6 files changed

+123
-40
lines changed

6 files changed

+123
-40
lines changed

src/SchemaGenerator/CodeGenerator/QueryObjectClassBuilder.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ class QueryObjectClassBuilder extends ObjectClassBuilder
2323
*/
2424
public function __construct(string $writeDir, string $objectName, string $namespace = self::DEFAULT_NAMESPACE)
2525
{
26-
$className = $objectName . 'QueryObject';
26+
if ($objectName === QueryObject::ROOT_MUTATION_OBJECT_NAME) {
27+
$objectName = '';
28+
$className = 'RootMutationObject';
29+
} else {
30+
$className = $objectName . 'QueryObject';
31+
}
2732

2833
$this->classFile = new ClassFile($writeDir, $className);
2934
$this->classFile->setNamespace($namespace);

src/SchemaGenerator/SchemaClassGenerator.php

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use GraphQL\SchemaGenerator\CodeGenerator\InputObjectClassBuilder;
1010
use GraphQL\SchemaGenerator\CodeGenerator\InterfaceObjectBuilder;
1111
use GraphQL\SchemaGenerator\CodeGenerator\ObjectBuilderInterface;
12+
use GraphQL\SchemaGenerator\CodeGenerator\ObjectClassBuilder;
1213
use GraphQL\SchemaGenerator\CodeGenerator\QueryObjectClassBuilder;
1314
use GraphQL\SchemaGenerator\CodeGenerator\UnionObjectBuilder;
1415
use GraphQL\SchemaObject\QueryObject;
@@ -32,12 +33,12 @@ class SchemaClassGenerator
3233
/**
3334
* @var string
3435
*/
35-
private $writeDir;
36+
private $writeDir;
3637

3738
/**
3839
* @var string
3940
*/
40-
private $generationNamespace;
41+
private $generationNamespace;
4142

4243
/**
4344
* This array is used as a set to store the already generated objects
@@ -54,24 +55,53 @@ class SchemaClassGenerator
5455
* @param string $writeDir
5556
* @param string $namespace
5657
*/
57-
public function __construct(Client $client, string $writeDir = '', string $namespace = ObjectBuilderInterface::DEFAULT_NAMESPACE)
58+
public function __construct(Client $client, string $writeDir = '', string $namespace = ObjectBuilderInterface::DEFAULT_NAMESPACE)
5859
{
59-
$this->schemaInspector = new SchemaInspector($client);
60-
$this->generatedObjects = [];
61-
$this->writeDir = $writeDir;
60+
$this->schemaInspector = new SchemaInspector($client);
61+
$this->generatedObjects = [];
62+
$this->writeDir = $writeDir;
6263
$this->generationNamespace = $namespace;
6364
$this->setWriteDir();
6465
}
6566

67+
public function generateRootObjects(): bool
68+
{
69+
$this->generateRootQueryObject();
70+
$this->generateRootMutationObject();
71+
72+
return true;
73+
}
74+
6675
/**
6776
* @return bool
6877
*/
69-
public function generateRootQueryObject(): bool
70-
{
71-
$objectArray = $this->schemaInspector->getQueryTypeSchema();
78+
public function generateRootQueryObject(): bool
79+
{
80+
$objectArray = $this->schemaInspector->getRootSchema('query');
7281
$rootObjectName = QueryObject::ROOT_QUERY_OBJECT_NAME;
73-
$queryTypeName = $objectArray['name'];
74-
//$rootObjectDescr = $objectArray['description'];
82+
$queryTypeName = $objectArray['name'];
83+
84+
if (array_key_exists($queryTypeName, $this->generatedObjects)) {
85+
return true;
86+
}
87+
88+
$this->generatedObjects[$queryTypeName] = true;
89+
90+
$queryObjectBuilder = new QueryObjectClassBuilder($this->writeDir, $rootObjectName, $this->generationNamespace);
91+
$this->appendObjectFields($queryObjectBuilder, $rootObjectName, $objectArray['fields']);
92+
$queryObjectBuilder->build();
93+
94+
return true;
95+
}
96+
97+
/**
98+
* @return bool
99+
*/
100+
public function generateRootMutationObject(): bool
101+
{
102+
$objectArray = $this->schemaInspector->getRootSchema('mutation');
103+
$rootObjectName = QueryObject::ROOT_MUTATION_OBJECT_NAME;
104+
$queryTypeName = $objectArray['name'];
75105

76106
if (array_key_exists($queryTypeName, $this->generatedObjects)) {
77107
return true;
@@ -80,7 +110,7 @@ public function generateRootQueryObject(): bool
80110
$this->generatedObjects[$queryTypeName] = true;
81111

82112
$queryObjectBuilder = new QueryObjectClassBuilder($this->writeDir, $rootObjectName, $this->generationNamespace);
83-
$this->appendQueryObjectFields($queryObjectBuilder, $rootObjectName, $objectArray['fields']);
113+
$this->appendObjectFields($queryObjectBuilder, $rootObjectName, $objectArray['fields']);
84114
$queryObjectBuilder->build();
85115

86116
return true;
@@ -89,18 +119,17 @@ public function generateRootQueryObject(): bool
89119
/**
90120
* This method receives the array of object fields as an input and adds the fields to the query object building
91121
*
92-
* @param QueryObjectClassBuilder $queryObjectBuilder
93-
* @param string $currentTypeName
94-
* @param array $fieldsArray
122+
* @param ObjectClassBuilder $queryObjectBuilder
123+
* @param string $currentTypeName
124+
* @param array $fieldsArray
95125
*/
96-
private function appendQueryObjectFields(QueryObjectClassBuilder $queryObjectBuilder, string $currentTypeName, array $fieldsArray)
126+
private function appendObjectFields(ObjectClassBuilder $queryObjectBuilder, string $currentTypeName, array $fieldsArray)
97127
{
98128
foreach ($fieldsArray as $fieldArray) {
99129
$name = $fieldArray['name'];
100-
// Skip fields with name "query"
101-
if ($name === 'query') continue;
130+
// Skip fields with name "query" or "field"
131+
if ($name === 'query' || $name === 'field') continue;
102132

103-
//$description = $fieldArray['description'];
104133
[$typeName, $typeKind] = $this->getTypeInfo($fieldArray);
105134

106135
if ($typeKind === FieldTypeKindEnum::SCALAR) {
@@ -168,8 +197,8 @@ protected function generateQueryObject(string $objectName): bool
168197
}
169198

170199
$this->generatedObjects[$objectName] = true;
171-
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
172-
$objectName = $objectArray['name'];
200+
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
201+
$objectName = $objectArray['name'];
173202

174203
if ($objectArray['kind'] === FieldTypeKindEnum::INTERFACE_OBJECT) {
175204
$objectBuilder = new InterfaceObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);
@@ -180,7 +209,7 @@ protected function generateQueryObject(string $objectName): bool
180209
$objectBuilder = new QueryObjectClassBuilder($this->writeDir, $objectName, $this->generationNamespace);
181210
}
182211

183-
$this->appendQueryObjectFields($objectBuilder, $objectName, $objectArray['fields']);
212+
$this->appendObjectFields($objectBuilder, $objectName, $objectArray['fields']);
184213
$objectBuilder->build();
185214

186215
return true;
@@ -198,8 +227,8 @@ protected function generateInputObject(string $objectName): bool
198227
}
199228

200229
$this->generatedObjects[$objectName] = true;
201-
$objectArray = $this->schemaInspector->getInputObjectSchema($objectName);
202-
$objectName = $objectArray['name'];
230+
$objectArray = $this->schemaInspector->getInputObjectSchema($objectName);
231+
$objectName = $objectArray['name'];
203232
$objectBuilder = new InputObjectClassBuilder($this->writeDir, $objectName, $this->generationNamespace);
204233

205234
foreach ($objectArray['inputFields'] as $inputFieldArray) {
@@ -244,12 +273,12 @@ protected function generateEnumObject(string $objectName): bool
244273

245274
$this->generatedObjects[$objectName] = true;
246275

247-
$objectArray = $this->schemaInspector->getEnumObjectSchema($objectName);
248-
$objectName = $objectArray['name'];
276+
$objectArray = $this->schemaInspector->getEnumObjectSchema($objectName);
277+
$objectName = $objectArray['name'];
249278
$objectBuilder = new EnumObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);
250279

251280
foreach ($objectArray['enumValues'] as $enumValue) {
252-
$name = $enumValue['name'];
281+
$name = $enumValue['name'];
253282
//$description = $enumValue['description'];
254283
$objectBuilder->addEnumValue($name);
255284
}
@@ -271,8 +300,8 @@ protected function generateUnionObject(string $objectName): bool
271300

272301
$this->generatedObjects[$objectName] = true;
273302

274-
$objectArray = $this->schemaInspector->getUnionObjectSchema($objectName);
275-
$objectName = $objectArray['name'];
303+
$objectArray = $this->schemaInspector->getUnionObjectSchema($objectName);
304+
$objectName = $objectArray['name'];
276305
$objectBuilder = new UnionObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);
277306

278307
foreach ($objectArray['possibleTypes'] as $possibleType) {
@@ -297,8 +326,8 @@ protected function generateInterfaceObject(string $objectName): bool
297326

298327
$this->generatedObjects[$objectName] = true;
299328

300-
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
301-
$objectName = $objectArray['name'];
329+
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
330+
$objectName = $objectArray['name'];
302331
$objectBuilder = new UnionObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);
303332

304333
foreach ($objectArray['possibleTypes'] as $possibleType) {
@@ -312,7 +341,7 @@ protected function generateInterfaceObject(string $objectName): bool
312341

313342
/**
314343
* @param string $argsObjectName
315-
* @param array $arguments
344+
* @param array $arguments
316345
*
317346
* @return bool
318347
*/
@@ -382,7 +411,7 @@ protected function getTypeInfo(array $dataArray): array
382411
/**
383412
* Sets the write directory if it's not set for the class
384413
*/
385-
private function setWriteDir(): void
414+
private function setWriteDir(): void
386415
{
387416
if ($this->writeDir !== '') return;
388417

src/SchemaGenerator/SchemaInspector.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,14 @@ public function __construct(Client $client)
5454
}
5555

5656
/**
57+
* @param string $type query or mutation
5758
* @return array
5859
*/
59-
public function getQueryTypeSchema(): array
60+
public function getRootSchema(string $type): array
6061
{
6162
$schemaQuery = "{
6263
__schema{
63-
queryType{
64+
${type}Type{
6465
name
6566
kind
6667
description
@@ -82,7 +83,7 @@ public function getQueryTypeSchema(): array
8283
}";
8384
$response = $this->client->runRawQuery($schemaQuery, true);
8485

85-
return $response->getData()['__schema']['queryType'];
86+
return $response->getData()['__schema'][$type.'Type'];
8687
}
8788

8889
/**

src/SchemaObject/QueryObject.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ abstract class QueryObject extends AbstractQueryBuilder
2121
*/
2222
public const ROOT_QUERY_OBJECT_NAME = 'Root';
2323

24+
/**
25+
* This constant stores the name to be given to the root query object
26+
*
27+
* @var string
28+
*/
29+
public const ROOT_MUTATION_OBJECT_NAME = 'RootMutation';
30+
2431
/**
2532
* This constant stores the name of the object name in the API definition
2633
*

tests/SchemaClassGeneratorTest.php

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ public function testGenerateArgumentsObjectWithInputObjectArgs()
616616

617617
/**
618618
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateQueryObject
619-
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendQueryObjectFields
619+
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendObjectFields
620620
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateObject
621621
*/
622622
public function testGenerateQueryObjectWithScalarFields()
@@ -703,7 +703,7 @@ public function testGenerateQueryObjectWithScalarFields()
703703

704704
/**
705705
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateQueryObject
706-
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendQueryObjectFields
706+
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendObjectFields
707707
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateObject
708708
*/
709709
public function testGenerateQueryObjectWithObjectFields()
@@ -790,7 +790,7 @@ public function testGenerateQueryObjectWithObjectFields()
790790
/**
791791
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateRootQueryObject
792792
*/
793-
public function testGenerateRootObject()
793+
public function testGenerateRootQueryObject()
794794
{
795795
$this->mockHandler->append(new Response(200, [], json_encode([
796796
'data' => [
@@ -813,6 +813,32 @@ public function testGenerateRootObject()
813813
);
814814
}
815815

816+
/**
817+
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateRootQueryObject
818+
*/
819+
public function testGenerateRootMutationObject()
820+
{
821+
$this->mockHandler->append(new Response(200, [], json_encode([
822+
'data' => [
823+
'__schema' => [
824+
'mutationType' => [
825+
'name' => 'Mutation',
826+
'kind' => FieldTypeKindEnum::OBJECT,
827+
'description' => null,
828+
'fields' => []
829+
]
830+
]
831+
]
832+
])));
833+
$this->classGenerator->generateRootMutationObject();
834+
835+
$objectName = 'RootMutationObject';
836+
$this->assertFileEquals(
837+
static::getExpectedFilesDir() . "/mutation_objects/$objectName.php",
838+
static::getGeneratedFilesDir() . "/$objectName.php"
839+
);
840+
}
841+
816842
/**
817843
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateUnionObject
818844
*/
@@ -1010,6 +1036,11 @@ public function generateRootQueryObject(): bool
10101036
return parent::generateRootQueryObject();
10111037
}
10121038

1039+
public function generateRootMutationObject(): bool
1040+
{
1041+
return parent::generateRootMutationObject();
1042+
}
1043+
10131044
public function generateQueryObject(string $objectName): bool
10141045
{
10151046
return parent::generateQueryObject($objectName);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace GraphQL\Tests\SchemaObject;
4+
5+
use GraphQL\SchemaObject\QueryObject;
6+
7+
class RootMutationObject extends QueryObject
8+
{
9+
const OBJECT_NAME = "";
10+
}

0 commit comments

Comments
 (0)