Skip to content

Commit

Permalink
Fix bug: cant correct resolve attribute data for several attributes o…
Browse files Browse the repository at this point in the history
…n method
  • Loading branch information
andrey-mokhov committed Feb 14, 2024
1 parent ab80eba commit 29f471f
Show file tree
Hide file tree
Showing 17 changed files with 159 additions and 57 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use Andi\GraphQL\Attribute\QueryField;
final class SimpleController
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
return 'echo: ' . $message;
Expand Down
1 change: 1 addition & 0 deletions docs/en/spiral/argument.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use App\GraphQL\Type\UserInterface;
final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
return 'echo: ' . $message;
Expand Down
1 change: 1 addition & 0 deletions docs/en/spiral/mutation-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use Andi\GraphQL\Attribute\QueryField;

final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
Expand Down
1 change: 1 addition & 0 deletions docs/en/spiral/query-filed.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use Andi\GraphQL\Attribute\QueryField;
final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
return 'echo: ' . $message;
Expand Down
1 change: 1 addition & 0 deletions docs/ru/spiral/argument.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use App\GraphQL\Type\UserInterface;
final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
return 'echo: ' . $message;
Expand Down
1 change: 1 addition & 0 deletions docs/ru/spiral/mutation-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use Andi\GraphQL\Attribute\QueryField;

final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
Expand Down
1 change: 1 addition & 0 deletions docs/ru/spiral/query-filed.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use Andi\GraphQL\Attribute\QueryField;
final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
return 'echo: ' . $message;
Expand Down
1 change: 1 addition & 0 deletions examples/spiral/app/src/GraphQL/Field/SimpleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
final class SimpleService
{
#[QueryField(name: 'echo')]
#[MutationField(name: 'echo')]
public function echoMessage(#[Argument] string $message): string
{
return 'echo: ' . $message;
Expand Down
16 changes: 16 additions & 0 deletions src/Common/ReflectionMethodWithAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Andi\GraphQL\Common;

use Andi\GraphQL\Attribute\AbstractField;

final class ReflectionMethodWithAttribute
{
public function __construct(
public readonly \ReflectionMethod $method,
public readonly AbstractField $attribute,
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Andi\GraphQL\Common\InputObjectFieldNameTrait;
use Andi\GraphQL\Common\LazyParserType;
use Andi\GraphQL\Common\LazyTypeByReflectionParameter;
use Andi\GraphQL\Common\ReflectionMethodWithAttribute;
use Andi\GraphQL\Exception\CantResolveGraphQLTypeException;
use Andi\GraphQL\InputObjectFieldResolver\InputObjectFieldResolverInterface;
use Andi\GraphQL\TypeRegistryInterface;
Expand All @@ -32,23 +33,25 @@ public function __construct(

public function process(mixed $field, InputObjectFieldResolverInterface $fieldResolver): Webonyx\InputObjectField
{
if (! $field instanceof ReflectionMethod) {
if (! $field instanceof ReflectionMethodWithAttribute) {
return $fieldResolver->resolve($field);
}

$attribute = $this->reader->firstFunctionMetadata($field, InputObjectField::class);
if (! $field->attribute instanceof InputObjectField) {
return $fieldResolver->resolve($field);
}

$config = [
'name' => $this->getInputObjectFieldName($field, $attribute),
'description' => $this->getFieldDescription($field, $attribute),
'type' => $this->getFieldType($field, $attribute),
'deprecationReason' => $this->getFieldDeprecationReason($field, $attribute),
'name' => $this->getInputObjectFieldName($field->method, $field->attribute),
'description' => $this->getFieldDescription($field->method, $field->attribute),
'type' => $this->getFieldType($field->method, $field->attribute),
'deprecationReason' => $this->getFieldDeprecationReason($field->method, $field->attribute),
];

$parameter = $field->getParameters()[0];
$parameter = $field->method->getParameters()[0];

if ($this->hasDefaultValue($parameter, $attribute)) {
$config['defaultValue'] = $this->getDefaultValue($parameter, $attribute);
if ($this->hasDefaultValue($parameter, $field->attribute)) {
$config['defaultValue'] = $this->getDefaultValue($parameter, $field->attribute);
}

return new Webonyx\InputObjectField($config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
use Andi\GraphQL\Attribute\Argument;
use Andi\GraphQL\Common\LazyParserType;
use Andi\GraphQL\Common\LazyTypeByReflectionType;
use Andi\GraphQL\Common\ReflectionMethodWithAttribute;
use Andi\GraphQL\Exception\CantResolveGraphQLTypeException;
use Andi\GraphQL\ObjectFieldResolver\ObjectFieldResolverInterface;
use Andi\GraphQL\TypeRegistryInterface;
use GraphQL\Type\Definition as Webonyx;
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlockFactory;
use ReflectionMethod;
use Spiral\Attributes\ReaderInterface;

/**
Expand All @@ -39,27 +39,25 @@ public function __construct(

public function process(mixed $field, ObjectFieldResolverInterface $fieldResolver): Webonyx\FieldDefinition
{
if (! $field instanceof ReflectionMethod) {
if (! $field instanceof ReflectionMethodWithAttribute) {
return $fieldResolver->resolve($field);
}

$attribute = $this->reader->firstFunctionMetadata($field, $this->targetAttribute);

if (null === $attribute) {
if (! $field->attribute instanceof $this->targetAttribute) {
return $fieldResolver->resolve($field);
}

$config = [
'name' => $this->getFieldName($field, $attribute),
'description' => $this->getFieldDescription($field, $attribute),
'type' => $this->getFieldType($field, $attribute),
'deprecationReason' => $this->getFieldDeprecationReason($field, $attribute),
'name' => $this->getFieldName($field->method, $field->attribute),
'description' => $this->getFieldDescription($field->method, $field->attribute),
'type' => $this->getFieldType($field->method, $field->attribute),
'deprecationReason' => $this->getFieldDeprecationReason($field->method, $field->attribute),
];

return $this->buildField($config, $field);
return $this->buildField($config, $field->method);
}

private function getFieldName(ReflectionMethod $method, AbstractField $attribute): ?string
private function getFieldName(\ReflectionMethod $method, AbstractField $attribute): ?string
{
if ($attribute->name) {
return $attribute->name;
Expand All @@ -74,7 +72,7 @@ private function getFieldName(ReflectionMethod $method, AbstractField $attribute
return \lcfirst($name);
}

private function getFieldDescription(ReflectionMethod $method, AbstractField $attribute): ?string
private function getFieldDescription(\ReflectionMethod $method, AbstractField $attribute): ?string
{
if ($attribute->description) {
return $attribute->description;
Expand All @@ -88,7 +86,7 @@ private function getFieldDescription(ReflectionMethod $method, AbstractField $at

}

private function getFieldType(ReflectionMethod $method, AbstractField $attribute): callable
private function getFieldType(\ReflectionMethod $method, AbstractField $attribute): callable
{
if ($attribute->type) {
return new LazyParserType($attribute->type, $attribute->mode ?? 0, $this->typeRegistry);
Expand All @@ -108,7 +106,7 @@ private function getFieldType(ReflectionMethod $method, AbstractField $attribute
);
}

protected function getFieldArguments(ReflectionMethod $method): \Generator
protected function getFieldArguments(\ReflectionMethod $method): \Generator
{
$map = [];
foreach ($method->getParameters() as $parameter) {
Expand All @@ -125,13 +123,13 @@ protected function getFieldArguments(ReflectionMethod $method): \Generator

/**
* @param FieldDefinitionConfig $config
* @param ReflectionMethod $method
* @param \ReflectionMethod $method
*
* @return Webonyx\FieldDefinition
*/
abstract protected function buildField(array $config, ReflectionMethod $method): Webonyx\FieldDefinition;
abstract protected function buildField(array $config, \ReflectionMethod $method): Webonyx\FieldDefinition;

private function getFieldDeprecationReason(ReflectionMethod $method, AbstractField $attribute): ?string
private function getFieldDeprecationReason(\ReflectionMethod $method, AbstractField $attribute): ?string
{
if ($attribute->deprecationReason) {
return $attribute->deprecationReason;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Andi\GraphQL\Common\LazyObjectFields;
use Andi\GraphQL\Common\LazyTypeIterator;
use Andi\GraphQL\Common\LazyTypeResolver;
use Andi\GraphQL\Common\ReflectionMethodWithAttribute;
use Andi\GraphQL\Common\ResolveType;
use Andi\GraphQL\Definition\Type\FieldsAwareInterface;
use Andi\GraphQL\Definition\Type\InterfacesAwareInterface;
Expand Down Expand Up @@ -194,8 +195,8 @@ private function registerAdditionalFieldByMethods(
string $targetAttribute,
): void {
foreach ($class->getMethods() as $method) {
if (null !== $this->reader->firstFunctionMetadata($method, $targetAttribute)) {
$type->addAdditionalField($method);
if ($attribute = $this->reader->firstFunctionMetadata($method, $targetAttribute)) {
$type->addAdditionalField(new ReflectionMethodWithAttribute($method, $attribute));
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions tests/Common/ReflectionMethodWithAttributeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Andi\Tests\GraphQL\Common;

use Andi\GraphQL\Attribute\AbstractDefinition;
use Andi\GraphQL\Attribute\AbstractField;
use Andi\GraphQL\Attribute\QueryField;
use Andi\GraphQL\Common\ReflectionMethodWithAttribute;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(ReflectionMethodWithAttribute::class)]
#[UsesClass(AbstractDefinition::class)]
#[UsesClass(AbstractField::class)]
final class ReflectionMethodWithAttributeTest extends TestCase
{
public function testClass(): void
{
$object = new class {
#[QueryField]
public function foo(): void
{
}
};

$reflectionClass = new \ReflectionClass($object);
$method = null;
foreach ($reflectionClass->getMethods() as $method) {
break;
}

$attribute = null;
foreach ($method->getAttributes() as $reflectionAttribute) {
$attribute = $reflectionAttribute->newInstance();
break;
}

$instance = new ReflectionMethodWithAttribute($method, $attribute);

self::assertSame($method, $instance->method);
self::assertSame($attribute, $instance->attribute);
}
}

0 comments on commit 29f471f

Please sign in to comment.