mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-14 11:33:13 +03:00
Refactoring abstract type resolution
This commit is contained in:
parent
afbd5dbc90
commit
6023c0ff60
@ -722,11 +722,11 @@ class Executor
|
|||||||
*/
|
*/
|
||||||
private static function completeAbstractValue(ExecutionContext $exeContext, AbstractType $returnType, $fieldASTs, ResolveInfo $info, $path, &$result)
|
private static function completeAbstractValue(ExecutionContext $exeContext, AbstractType $returnType, $fieldASTs, ResolveInfo $info, $path, &$result)
|
||||||
{
|
{
|
||||||
$resolveType = $returnType->getResolveTypeFn();
|
$runtimeType = $returnType->resolveType($result, $exeContext->contextValue, $info);
|
||||||
|
|
||||||
$runtimeType = $resolveType ?
|
if (null === $runtimeType) {
|
||||||
call_user_func($resolveType, $result, $exeContext->contextValue, $info) :
|
$runtimeType = self::inferTypeOf($result, $exeContext->contextValue, $info, $returnType);
|
||||||
Type::getTypeOf($result, $exeContext->contextValue, $info, $returnType);
|
}
|
||||||
|
|
||||||
// If resolveType returns a string, we assume it's a ObjectType name.
|
// If resolveType returns a string, we assume it's a ObjectType name.
|
||||||
if (is_string($runtimeType)) {
|
if (is_string($runtimeType)) {
|
||||||
@ -849,4 +849,25 @@ class Executor
|
|||||||
|
|
||||||
return self::executeFields($exeContext, $returnType, $result, $path, $subFieldASTs);
|
return self::executeFields($exeContext, $returnType, $result, $path, $subFieldASTs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infer type of the value using isTypeOf of corresponding AbstractType
|
||||||
|
*
|
||||||
|
* @param $value
|
||||||
|
* @param $context
|
||||||
|
* @param ResolveInfo $info
|
||||||
|
* @param AbstractType $abstractType
|
||||||
|
* @return ObjectType|null
|
||||||
|
*/
|
||||||
|
private static function inferTypeOf($value, $context, ResolveInfo $info, AbstractType $abstractType)
|
||||||
|
{
|
||||||
|
$possibleTypes = $info->schema->getPossibleTypes($abstractType);
|
||||||
|
|
||||||
|
foreach ($possibleTypes as $type) {
|
||||||
|
if ($type->isTypeOf($value, $context, $info)) {
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,12 @@ GraphQLUnionType;
|
|||||||
interface AbstractType
|
interface AbstractType
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return callable|null
|
* Resolves concrete ObjectType for given object value
|
||||||
|
*
|
||||||
|
* @param $objectValue
|
||||||
|
* @param $context
|
||||||
|
* @param ResolveInfo $info
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getResolveTypeFn();
|
public function resolveType($objectValue, $context, ResolveInfo $info);
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,6 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
*/
|
*/
|
||||||
public $description;
|
public $description;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var callback
|
|
||||||
*/
|
|
||||||
private $resolveTypeFn;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@ -51,7 +46,6 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
|
|
||||||
$this->name = $config['name'];
|
$this->name = $config['name'];
|
||||||
$this->description = isset($config['description']) ? $config['description'] : null;
|
$this->description = isset($config['description']) ? $config['description'] : null;
|
||||||
$this->resolveTypeFn = isset($config['resolveType']) ? $config['resolveType'] : null;
|
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,10 +78,19 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Resolves concrete ObjectType for given object value
|
||||||
|
*
|
||||||
|
* @param $objectValue
|
||||||
|
* @param $context
|
||||||
|
* @param ResolveInfo $info
|
||||||
* @return callable|null
|
* @return callable|null
|
||||||
*/
|
*/
|
||||||
public function getResolveTypeFn()
|
public function resolveType($objectValue, $context, ResolveInfo $info)
|
||||||
{
|
{
|
||||||
return $this->resolveTypeFn;
|
if (isset($this->config['resolveType'])) {
|
||||||
|
$fn = $this->config['resolveType'];
|
||||||
|
return $fn($objectValue, $context, $info);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,26 +211,6 @@ abstract class Type
|
|||||||
return $type;
|
return $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $value
|
|
||||||
* @param mixed $context
|
|
||||||
* @param AbstractType $abstractType
|
|
||||||
* @return Type
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public static function getTypeOf($value, $context, ResolveInfo $info, AbstractType $abstractType)
|
|
||||||
{
|
|
||||||
$possibleTypes = $info->schema->getPossibleTypes($abstractType);
|
|
||||||
|
|
||||||
foreach ($possibleTypes as $type) {
|
|
||||||
/** @var ObjectType $type */
|
|
||||||
if ($type->isTypeOf($value, $context, $info)) {
|
|
||||||
return $type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
|
@ -20,11 +20,6 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType
|
|||||||
*/
|
*/
|
||||||
private $possibleTypeNames;
|
private $possibleTypeNames;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var callback
|
|
||||||
*/
|
|
||||||
private $resolveTypeFn;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@ -54,7 +49,6 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType
|
|||||||
*/
|
*/
|
||||||
$this->name = $config['name'];
|
$this->name = $config['name'];
|
||||||
$this->description = isset($config['description']) ? $config['description'] : null;
|
$this->description = isset($config['description']) ? $config['description'] : null;
|
||||||
$this->resolveTypeFn = isset($config['resolveType']) ? $config['resolveType'] : null;
|
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +79,10 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType
|
|||||||
$this->name
|
$this->name
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: Return some sort of generator to avoid multiple loops
|
$this->types = [];
|
||||||
$this->types = Utils::map($types, function($type) {
|
foreach ($types as $type) {
|
||||||
return $type instanceof DefinitionContainer ? $type->getDefinition() : $type;
|
$this->types[] = Type::resolve($type);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
return $this->types;
|
return $this->types;
|
||||||
}
|
}
|
||||||
@ -113,10 +107,19 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Resolves concrete ObjectType for given object value
|
||||||
|
*
|
||||||
|
* @param $objectValue
|
||||||
|
* @param $context
|
||||||
|
* @param ResolveInfo $info
|
||||||
* @return callable|null
|
* @return callable|null
|
||||||
*/
|
*/
|
||||||
public function getResolveTypeFn()
|
public function resolveType($objectValue, $context, ResolveInfo $info)
|
||||||
{
|
{
|
||||||
return $this->resolveTypeFn;
|
if (isset($this->config['resolveType'])) {
|
||||||
|
$fn = $this->config['resolveType'];
|
||||||
|
return $fn($objectValue, $context, $info);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user