Skip to content

Commit ba3637c

Browse files
Fix use of MagicField with phpType on a proxy class without magic __get method (#405)
Authored-by: Michael Vostrikov <mikhail.vostrikov@vseinstrumenti.ru>
1 parent b5230f7 commit ba3637c

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

src/FieldsBuilder.php

+30-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use TheCodingMachine\GraphQLite\Mappers\Root\RootTypeMapperInterface;
3333
use TheCodingMachine\GraphQLite\Middlewares\FieldHandlerInterface;
3434
use TheCodingMachine\GraphQLite\Middlewares\FieldMiddlewareInterface;
35+
use TheCodingMachine\GraphQLite\Middlewares\MissingMagicGetException;
3536
use TheCodingMachine\GraphQLite\Parameters\InputTypeProperty;
3637
use TheCodingMachine\GraphQLite\Parameters\ParameterInterface;
3738
use TheCodingMachine\GraphQLite\Reflection\CachedDocBlockFactory;
@@ -618,8 +619,9 @@ private function getQueryFieldsFromSourceFields(array $sourceFields, ReflectionC
618619
} else {
619620
$phpTypeStr = $sourceField->getPhpType();
620621
Assert::notNull($phpTypeStr);
621-
$refMethod = $refClass->getMethod('__get');
622-
$type = $this->resolvePhpType($phpTypeStr, $refClass, $refMethod);
622+
$magicGefRefMethod = $this->getMagicGetMethodFromSourceClassOrProxy($refClass);
623+
624+
$type = $this->resolvePhpType($phpTypeStr, $refClass, $magicGefRefMethod);
623625
}
624626
}
625627

@@ -644,6 +646,32 @@ public function handle(QueryFieldDescriptor $fieldDescriptor): ?FieldDefinition
644646
return $queryList;
645647
}
646648

649+
/**
650+
* @throws ReflectionException
651+
* @throws MissingAnnotationException
652+
* @throws MissingMagicGetException
653+
*/
654+
private function getMagicGetMethodFromSourceClassOrProxy(ReflectionClass $proxyRefClass): ReflectionMethod
655+
{
656+
$magicGet = '__get';
657+
if ($proxyRefClass->hasMethod($magicGet)) {
658+
return $proxyRefClass->getMethod($magicGet);
659+
}
660+
661+
$typeField = $this->annotationReader->getTypeAnnotation($proxyRefClass);
662+
if ($typeField === null) {
663+
throw MissingAnnotationException::missingTypeException($proxyRefClass->getName());
664+
}
665+
666+
$sourceClassName = $typeField->getClass();
667+
$sourceRefClass = new ReflectionClass($sourceClassName);
668+
if (! $sourceRefClass->hasMethod($magicGet)) {
669+
throw MissingMagicGetException::cannotFindMagicGet($sourceClassName);
670+
}
671+
672+
return $sourceRefClass->getMethod($magicGet);
673+
}
674+
647675
/**
648676
* @param ReflectionClass<object> $refClass
649677
*

tests/FieldsBuilderTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithFailWith;
5151
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithInvalidPrefetchParameter;
5252
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithMagicProperty;
53+
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithMagicPropertyType;
5354
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithPrefetchMethod;
5455
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithSourceFieldInterface;
5556
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithSourceFieldInvalidParameterAnnotation;
@@ -786,4 +787,21 @@ public function testMagicField(): void
786787
$this->expectExceptionMessage('You cannot use a @MagicField annotation on an object that does not implement the __get() magic method. The class stdClass must implement a __get() method.');
787788
$result = $resolve(new stdClass(), [], null, $this->createMock(ResolveInfo::class));
788789
}
790+
791+
public function testProxyClassWithMagicPropertyOfPhpType(): void
792+
{
793+
$controller = new TestTypeWithMagicPropertyType();
794+
795+
$queryProvider = $this->buildFieldsBuilder();
796+
797+
$fields = $queryProvider->getFields($controller);
798+
799+
$query = $fields['foo'];
800+
$this->assertSame('foo', $query->name);
801+
802+
$resolve = $query->resolveFn;
803+
$result = $resolve(new TestTypeWithMagicProperty(), [], null, $this->createMock(ResolveInfo::class));
804+
805+
$this->assertSame('foo', $result);
806+
}
789807
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace TheCodingMachine\GraphQLite\Fixtures;
4+
5+
use TheCodingMachine\GraphQLite\Annotations\Type;
6+
use TheCodingMachine\GraphQLite\Annotations\MagicField;
7+
8+
/**
9+
* @Type(class=TestTypeWithMagicProperty::class)
10+
* @MagicField(name="foo", phpType="string")
11+
*/
12+
class TestTypeWithMagicPropertyType
13+
{
14+
}

0 commit comments

Comments
 (0)