Skip to content

Commit

Permalink
Add support for mutations
Browse files Browse the repository at this point in the history
  • Loading branch information
jorrit committed Aug 23, 2024
1 parent 17d9a75 commit a1f9a1b
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ class QueryObjectClassBuilder extends ObjectClassBuilder
*/
public function __construct(string $writeDir, string $objectName, string $namespace = self::DEFAULT_NAMESPACE)
{
$className = $objectName . 'QueryObject';
if ($objectName === QueryObject::ROOT_MUTATION_OBJECT_NAME) {
$objectName = '';
$className = 'RootMutationObject';
} else {
$className = $objectName . 'QueryObject';
}

$this->classFile = new ClassFile($writeDir, $className);
$this->classFile->setNamespace($namespace);
Expand Down
95 changes: 62 additions & 33 deletions src/SchemaGenerator/SchemaClassGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use GraphQL\SchemaGenerator\CodeGenerator\InputObjectClassBuilder;
use GraphQL\SchemaGenerator\CodeGenerator\InterfaceObjectBuilder;
use GraphQL\SchemaGenerator\CodeGenerator\ObjectBuilderInterface;
use GraphQL\SchemaGenerator\CodeGenerator\ObjectClassBuilder;
use GraphQL\SchemaGenerator\CodeGenerator\QueryObjectClassBuilder;
use GraphQL\SchemaGenerator\CodeGenerator\UnionObjectBuilder;
use GraphQL\SchemaObject\QueryObject;
Expand All @@ -32,12 +33,12 @@ class SchemaClassGenerator
/**
* @var string
*/
private $writeDir;
private $writeDir;

/**
* @var string
*/
private $generationNamespace;
private $generationNamespace;

/**
* This array is used as a set to store the already generated objects
Expand All @@ -54,24 +55,53 @@ class SchemaClassGenerator
* @param string $writeDir
* @param string $namespace
*/
public function __construct(Client $client, string $writeDir = '', string $namespace = ObjectBuilderInterface::DEFAULT_NAMESPACE)
public function __construct(Client $client, string $writeDir = '', string $namespace = ObjectBuilderInterface::DEFAULT_NAMESPACE)
{
$this->schemaInspector = new SchemaInspector($client);
$this->generatedObjects = [];
$this->writeDir = $writeDir;
$this->schemaInspector = new SchemaInspector($client);
$this->generatedObjects = [];
$this->writeDir = $writeDir;
$this->generationNamespace = $namespace;
$this->setWriteDir();
}

public function generateRootObjects(): bool
{
$this->generateRootQueryObject();
$this->generateRootMutationObject();

return true;
}

/**
* @return bool
*/
public function generateRootQueryObject(): bool
{
$objectArray = $this->schemaInspector->getQueryTypeSchema();
public function generateRootQueryObject(): bool
{
$objectArray = $this->schemaInspector->getRootSchema('query');
$rootObjectName = QueryObject::ROOT_QUERY_OBJECT_NAME;
$queryTypeName = $objectArray['name'];
//$rootObjectDescr = $objectArray['description'];
$queryTypeName = $objectArray['name'];

if (array_key_exists($queryTypeName, $this->generatedObjects)) {
return true;
}

$this->generatedObjects[$queryTypeName] = true;

$queryObjectBuilder = new QueryObjectClassBuilder($this->writeDir, $rootObjectName, $this->generationNamespace);
$this->appendObjectFields($queryObjectBuilder, $rootObjectName, $objectArray['fields']);
$queryObjectBuilder->build();

return true;
}

/**
* @return bool
*/
public function generateRootMutationObject(): bool
{
$objectArray = $this->schemaInspector->getRootSchema('mutation');
$rootObjectName = QueryObject::ROOT_MUTATION_OBJECT_NAME;
$queryTypeName = $objectArray['name'];

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

$queryObjectBuilder = new QueryObjectClassBuilder($this->writeDir, $rootObjectName, $this->generationNamespace);
$this->appendQueryObjectFields($queryObjectBuilder, $rootObjectName, $objectArray['fields']);
$this->appendObjectFields($queryObjectBuilder, $rootObjectName, $objectArray['fields']);
$queryObjectBuilder->build();

return true;
Expand All @@ -89,18 +119,17 @@ public function generateRootQueryObject(): bool
/**
* This method receives the array of object fields as an input and adds the fields to the query object building
*
* @param QueryObjectClassBuilder $queryObjectBuilder
* @param string $currentTypeName
* @param array $fieldsArray
* @param ObjectClassBuilder $queryObjectBuilder
* @param string $currentTypeName
* @param array $fieldsArray
*/
private function appendQueryObjectFields(QueryObjectClassBuilder $queryObjectBuilder, string $currentTypeName, array $fieldsArray)
private function appendObjectFields(ObjectClassBuilder $queryObjectBuilder, string $currentTypeName, array $fieldsArray)
{
foreach ($fieldsArray as $fieldArray) {
$name = $fieldArray['name'];
// Skip fields with name "query"
if ($name === 'query') continue;
// Skip fields with name "query" or "field"
if ($name === 'query' || $name === 'field') continue;

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

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

$this->generatedObjects[$objectName] = true;
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
$objectName = $objectArray['name'];

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

$this->appendQueryObjectFields($objectBuilder, $objectName, $objectArray['fields']);
$this->appendObjectFields($objectBuilder, $objectName, $objectArray['fields']);
$objectBuilder->build();

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

$this->generatedObjects[$objectName] = true;
$objectArray = $this->schemaInspector->getInputObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectArray = $this->schemaInspector->getInputObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectBuilder = new InputObjectClassBuilder($this->writeDir, $objectName, $this->generationNamespace);

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

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

$objectArray = $this->schemaInspector->getEnumObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectArray = $this->schemaInspector->getEnumObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectBuilder = new EnumObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);

foreach ($objectArray['enumValues'] as $enumValue) {
$name = $enumValue['name'];
$name = $enumValue['name'];
//$description = $enumValue['description'];
$objectBuilder->addEnumValue($name);
}
Expand All @@ -271,8 +300,8 @@ protected function generateUnionObject(string $objectName): bool

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

$objectArray = $this->schemaInspector->getUnionObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectArray = $this->schemaInspector->getUnionObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectBuilder = new UnionObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);

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

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

$objectArray = $this->schemaInspector->getObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectArray = $this->schemaInspector->getObjectSchema($objectName);
$objectName = $objectArray['name'];
$objectBuilder = new UnionObjectBuilder($this->writeDir, $objectName, $this->generationNamespace);

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

/**
* @param string $argsObjectName
* @param array $arguments
* @param array $arguments
*
* @return bool
*/
Expand Down Expand Up @@ -382,7 +411,7 @@ protected function getTypeInfo(array $dataArray): array
/**
* Sets the write directory if it's not set for the class
*/
private function setWriteDir(): void
private function setWriteDir(): void
{
if ($this->writeDir !== '') return;

Expand Down
7 changes: 4 additions & 3 deletions src/SchemaGenerator/SchemaInspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,14 @@ public function __construct(Client $client)
}

/**
* @param string $type query or mutation
* @return array
*/
public function getQueryTypeSchema(): array
public function getRootSchema(string $type): array
{
$schemaQuery = "{
__schema{
queryType{
${type}Type{
name
kind
description
Expand All @@ -82,7 +83,7 @@ public function getQueryTypeSchema(): array
}";
$response = $this->client->runRawQuery($schemaQuery, true);

return $response->getData()['__schema']['queryType'];
return $response->getData()['__schema'][$type.'Type'];
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/SchemaObject/QueryObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ abstract class QueryObject extends AbstractQueryBuilder
*/
public const ROOT_QUERY_OBJECT_NAME = 'Root';

/**
* This constant stores the name to be given to the root query object
*
* @var string
*/
public const ROOT_MUTATION_OBJECT_NAME = 'RootMutation';

/**
* This constant stores the name of the object name in the API definition
*
Expand Down
37 changes: 34 additions & 3 deletions tests/SchemaClassGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ public function testGenerateArgumentsObjectWithInputObjectArgs()

/**
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateQueryObject
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendQueryObjectFields
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendObjectFields
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateObject
*/
public function testGenerateQueryObjectWithScalarFields()
Expand Down Expand Up @@ -703,7 +703,7 @@ public function testGenerateQueryObjectWithScalarFields()

/**
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateQueryObject
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendQueryObjectFields
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::appendObjectFields
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateObject
*/
public function testGenerateQueryObjectWithObjectFields()
Expand Down Expand Up @@ -790,7 +790,7 @@ public function testGenerateQueryObjectWithObjectFields()
/**
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateRootQueryObject
*/
public function testGenerateRootObject()
public function testGenerateRootQueryObject()
{
$this->mockHandler->append(new Response(200, [], json_encode([
'data' => [
Expand All @@ -813,6 +813,32 @@ public function testGenerateRootObject()
);
}

/**
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateRootQueryObject
*/
public function testGenerateRootMutationObject()
{
$this->mockHandler->append(new Response(200, [], json_encode([
'data' => [
'__schema' => [
'mutationType' => [
'name' => 'Mutation',
'kind' => FieldTypeKindEnum::OBJECT,
'description' => null,
'fields' => []
]
]
]
])));
$this->classGenerator->generateRootMutationObject();

$objectName = 'RootMutationObject';
$this->assertFileEquals(
static::getExpectedFilesDir() . "/mutation_objects/$objectName.php",
static::getGeneratedFilesDir() . "/$objectName.php"
);
}

/**
* @covers \GraphQL\SchemaGenerator\SchemaClassGenerator::generateUnionObject
*/
Expand Down Expand Up @@ -1010,6 +1036,11 @@ public function generateRootQueryObject(): bool
return parent::generateRootQueryObject();
}

public function generateRootMutationObject(): bool
{
return parent::generateRootMutationObject();
}

public function generateQueryObject(string $objectName): bool
{
return parent::generateQueryObject($objectName);
Expand Down
10 changes: 10 additions & 0 deletions tests/files_expected/mutation_objects/RootMutationObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace GraphQL\Tests\SchemaObject;

use GraphQL\SchemaObject\QueryObject;

class RootMutationObject extends QueryObject
{
const OBJECT_NAME = "";
}

0 comments on commit a1f9a1b

Please sign in to comment.