Skip to content

Commit

Permalink
Moved type handling to the driver. You can still access the type mana…
Browse files Browse the repository at this point in the history
…ger but it is not longer necessary.
  • Loading branch information
TomHAnderson committed Mar 20, 2024
1 parent 1753bff commit 75b40bf
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 28 deletions.
55 changes: 35 additions & 20 deletions src/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@

namespace ApiSkeletons\Doctrine\ORM\GraphQL;

use ApiSkeletons\Doctrine\ORM\GraphQL\Type\TypeManager;
use ApiSkeletons\Doctrine\ORM\GraphQL\Type\Entity;
use Closure;
use GraphQL\Error\Error;
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\ObjectType;

use GraphQL\Type\Definition\ScalarType;
use function method_exists;

class Driver extends AbstractContainer
{
use Services;
Expand All @@ -30,25 +27,28 @@ public function connection(ObjectType $objectType): ObjectType
}

/**
* A shortcut into the TypeManager
*
* This handles the special case for types that are both a GraphQL type
* and a PHP type by resolving the __invoke method.
* A shortcut into the TypeManager that also handles Entity objects
*
* @throws Error
*/
public function type(string $typeName): ObjectType|ScalarType
public function type(string $typeName): mixed
{
$typeManager = $this->get(Type\TypeManager::class);

if (! $typeManager->has($typeName)) {
return $typeManager->build(Type\Entity::class, $typeName)();
}
try {
// If a type is not registered, try to resolve it as an Entity
if (! $typeManager->has($typeName)) {
return $this->entityType($typeName)();
}

$type = $typeManager->get($typeName);
$type = $typeManager->get($typeName);

if (method_exists($type, '__invoke')) {
return $type();
// Resolve an Entity type to its GraphQL representation
if ($type instanceof Entity) {
return $type();
}
} catch (Error) {
throw new Error('Type "' . $typeName . '" is not registered');
}

return $type;
Expand All @@ -63,8 +63,7 @@ public function type(string $typeName): ObjectType|ScalarType
public function filter(string $entityClass): object
{
return $this->get(Filter\FilterFactory::class)->get(
$this->get(Type\TypeManager::class)
->build(Type\Entity::class, $entityClass),
$this->entityType($entityClass),
);
}

Expand All @@ -75,7 +74,7 @@ public function filter(string $entityClass): object
*/
public function pagination(): object
{
return $this->get(TypeManager::class)->get('pagination');
return $this->type('pagination');
}

/**
Expand All @@ -86,8 +85,7 @@ public function pagination(): object
public function resolve(string $entityClass, string|null $eventName = null): Closure
{
return $this->get(Resolve\ResolveEntityFactory::class)->get(
$this->get(Type\TypeManager::class)
->build(Type\Entity::class, $entityClass),
$this->entityType($entityClass),
$eventName,
);
}
Expand All @@ -102,4 +100,21 @@ public function input(string $entityClass, array $requiredFields = [], array $op
{
return $this->get(Input\InputFactory::class)->get($entityClass, $requiredFields, $optionalFields);
}

/**
* Internally an Entity object is used for Doctrine entities.
* The Entity object has an __invoke method which returns the
* GraphQL ObjectType. This method exists to fetch that Entity
* object. It is resolved by $this->type()
*
* Access to this method is not recommended. It is used internally
* but requires public scope.
*
* @throws Error
*/
public function entityType(string $entityClass): Entity
{
return $this->get(Type\TypeManager::class)
->build(Type\Entity::class, $entityClass);
}
}
4 changes: 2 additions & 2 deletions src/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ static function () use ($config) {
)
->set(
EventDispatcher::class,
static fn () => new EventDispatcher()
static fn () => new EventDispatcher(),
)
->set(
Type\TypeManager::class,
static fn (AbstractContainer $container) => new Type\TypeManager($container)
static fn (AbstractContainer $container) => new Type\TypeManager($container),
)
->set(
'metadata',
Expand Down
10 changes: 10 additions & 0 deletions test/Feature/DriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,14 @@ public function testTypeMethodForCustomScalarValues(): void

$this->assertInstanceOf(BooleanType::class, $driver->type('custom'));
}

public function testTypeMethodInvalidType(): void
{
$this->expectException(Error::class);
$this->expectExceptionMessage('Type "custom" is not registered');

$driver = new Driver($this->getEntityManager());

$this->assertInstanceOf(BooleanType::class, $driver->type('custom'));
}
}
3 changes: 1 addition & 2 deletions test/Feature/Metadata/TypeNameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use ApiSkeletons\Doctrine\ORM\GraphQL\Config;
use ApiSkeletons\Doctrine\ORM\GraphQL\Driver;
use ApiSkeletons\Doctrine\ORM\GraphQL\Type\TypeManager;
use ApiSkeletonsTest\Doctrine\ORM\GraphQL\AbstractTest;
use ApiSkeletonsTest\Doctrine\ORM\GraphQL\Entity\Artist;
use GraphQL\GraphQL;
Expand Down Expand Up @@ -38,7 +37,7 @@ public function testGroupSuffix(): void
]),
]);

$artistClass = $driver->get(TypeManager::class)->get(Artist::class);
$artistClass = $driver->entityType(Artist::class);

$this->assertEquals('Artist_unittest', $artistClass->getTypeName());
}
Expand Down
3 changes: 1 addition & 2 deletions test/Feature/Type/BlobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use ApiSkeletons\Doctrine\ORM\GraphQL\Config;
use ApiSkeletons\Doctrine\ORM\GraphQL\Driver;
use ApiSkeletons\Doctrine\ORM\GraphQL\Type\Blob;
use ApiSkeletons\Doctrine\ORM\GraphQL\Type\TypeManager;
use ApiSkeletonsTest\Doctrine\ORM\GraphQL\AbstractTest;
use ApiSkeletonsTest\Doctrine\ORM\GraphQL\Entity\TypeTest;
use Doctrine\ORM\EntityManager;
Expand Down Expand Up @@ -127,7 +126,7 @@ public function testMutation(): void
'typetest' => [
'type' => $driver->type(TypeTest::class),
'args' => [
'blob' => $driver->get(TypeManager::class)->get('blob'),
'blob' => $driver->type('blob'),
],
'resolve' => function ($root, array $args, $context, ResolveInfo $info) use ($driver) {
$control = file_get_contents(__DIR__ . '/../../../banner.png');
Expand Down
3 changes: 1 addition & 2 deletions test/Feature/Type/UuidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use ApiSkeletons\Doctrine\ORM\GraphQL\Config;
use ApiSkeletons\Doctrine\ORM\GraphQL\Driver;
use ApiSkeletons\Doctrine\ORM\GraphQL\Type\TypeManager;
use ApiSkeletons\Doctrine\ORM\GraphQL\Type\Uuid;
use ApiSkeletonsTest\Doctrine\ORM\GraphQL\AbstractTest;
use ApiSkeletonsTest\Doctrine\ORM\GraphQL\Entity\TypeTest;
Expand Down Expand Up @@ -109,7 +108,7 @@ public function testMutation(): void
'typetest' => [
'type' => $driver->type(TypeTest::class),
'args' => [
'uuid' => $driver->get(TypeManager::class)->get('uuid'),
'uuid' => $driver->type('uuid'),
],
'resolve' => function ($root, array $args, $context, ResolveInfo $info) use ($driver) {
// This tests the Uuid type for changing a string into a UuidInterface
Expand Down

0 comments on commit 75b40bf

Please sign in to comment.