mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 04:46:04 +03:00
Merge pull request #505 from spawnia/root-value-consistent-naming
Consistently name the first resolver argument and the root value
This commit is contained in:
commit
22a0da9b98
@ -152,7 +152,7 @@ class SchemaGenerator
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resolveField($value, $args, $context, $resolveInfo)
|
public function resolveField($objectValue, $args, $context, $resolveInfo)
|
||||||
{
|
{
|
||||||
return $resolveInfo->fieldName . '-value';
|
return $resolveInfo->fieldName . '-value';
|
||||||
}
|
}
|
||||||
|
@ -103,23 +103,23 @@ for a field you simply override this default resolver.
|
|||||||
**graphql-php** provides following default field resolver:
|
**graphql-php** provides following default field resolver:
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
function defaultFieldResolver($source, $args, $context, \GraphQL\Type\Definition\ResolveInfo $info)
|
function defaultFieldResolver($objectValue, $args, $context, \GraphQL\Type\Definition\ResolveInfo $info)
|
||||||
{
|
{
|
||||||
$fieldName = $info->fieldName;
|
$fieldName = $info->fieldName;
|
||||||
$property = null;
|
$property = null;
|
||||||
|
|
||||||
if (is_array($source) || $source instanceof \ArrayAccess) {
|
if (is_array($objectValue) || $objectValue instanceof \ArrayAccess) {
|
||||||
if (isset($source[$fieldName])) {
|
if (isset($objectValue[$fieldName])) {
|
||||||
$property = $source[$fieldName];
|
$property = $objectValue[$fieldName];
|
||||||
}
|
}
|
||||||
} else if (is_object($source)) {
|
} elseif (is_object($objectValue)) {
|
||||||
if (isset($source->{$fieldName})) {
|
if (isset($objectValue->{$fieldName})) {
|
||||||
$property = $source->{$fieldName};
|
$property = $objectValue->{$fieldName};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $property instanceof Closure
|
return $property instanceof Closure
|
||||||
? $property($source, $args, $context, $info)
|
? $property($objectValue, $args, $context, $info)
|
||||||
: $property;
|
: $property;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -163,7 +163,6 @@ $userType = new ObjectType([
|
|||||||
Keep in mind that **field resolver** has precedence over **default field resolver per type** which in turn
|
Keep in mind that **field resolver** has precedence over **default field resolver per type** which in turn
|
||||||
has precedence over **default field resolver**.
|
has precedence over **default field resolver**.
|
||||||
|
|
||||||
|
|
||||||
# Solving N+1 Problem
|
# Solving N+1 Problem
|
||||||
Since: 0.9.0
|
Since: 0.9.0
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ $queryType = new ObjectType([
|
|||||||
'args' => [
|
'args' => [
|
||||||
'message' => Type::nonNull(Type::string()),
|
'message' => Type::nonNull(Type::string()),
|
||||||
],
|
],
|
||||||
'resolve' => function ($root, $args) {
|
'resolve' => function ($rootValue, $args) {
|
||||||
return $root['prefix'] . $args['message'];
|
return $rootValue['prefix'] . $args['message'];
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -33,7 +33,7 @@ See [related documentation](executing-queries.md).
|
|||||||
* fieldResolver:
|
* fieldResolver:
|
||||||
* A resolver function to use when one is not provided by the schema.
|
* A resolver function to use when one is not provided by the schema.
|
||||||
* If not provided, the default field resolver is used (which looks for a
|
* If not provided, the default field resolver is used (which looks for a
|
||||||
* value on the source value with the field's name).
|
* value on the object value with the field's name).
|
||||||
* validationRules:
|
* validationRules:
|
||||||
* A set of rules for query validation step. Default value is all available rules.
|
* A set of rules for query validation step. Default value is all available rules.
|
||||||
* Empty array would allow to skip query validation (may be convenient for persisted
|
* Empty array would allow to skip query validation (may be convenient for persisted
|
||||||
|
@ -158,7 +158,7 @@ $heroType = new ObjectType([
|
|||||||
'args' => [
|
'args' => [
|
||||||
'episode' => Type::nonNull($enumType)
|
'episode' => Type::nonNull($enumType)
|
||||||
],
|
],
|
||||||
'resolve' => function($_value, $args) {
|
'resolve' => function($hero, $args) {
|
||||||
return $args['episode'] === 5 ? true : false;
|
return $args['episode'] === 5 ? true : false;
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -80,7 +80,7 @@ Option | Type | Notes
|
|||||||
name | `string` | **Required.** Name of the field. When not set - inferred from **fields** array key (read about [shorthand field definition](#shorthand-field-definitions) below)
|
name | `string` | **Required.** Name of the field. When not set - inferred from **fields** array key (read about [shorthand field definition](#shorthand-field-definitions) below)
|
||||||
type | `Type` | **Required.** An instance of internal or custom type. Note: type must be represented by a single instance within one schema (see also [Type Registry](index.md#type-registry))
|
type | `Type` | **Required.** An instance of internal or custom type. Note: type must be represented by a single instance within one schema (see also [Type Registry](index.md#type-registry))
|
||||||
args | `array` | An array of possible type arguments. Each entry is expected to be an array with keys: **name**, **type**, **description**, **defaultValue**. See [Field Arguments](#field-arguments) section below.
|
args | `array` | An array of possible type arguments. Each entry is expected to be an array with keys: **name**, **type**, **description**, **defaultValue**. See [Field Arguments](#field-arguments) section below.
|
||||||
resolve | `callable` | **function($value, $args, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Given the **$value** of this type, it is expected to return actual value of the current field. See section on [Data Fetching](../data-fetching.md) for details
|
resolve | `callable` | **function($objectValue, $args, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Given the **$objectValue** of this type, it is expected to return actual value of the current field. See section on [Data Fetching](../data-fetching.md) for details
|
||||||
complexity | `callable` | **function($childrenComplexity, $args)**<br> Used to restrict query complexity. The feature is disabled by default, read about [Security](../security.md#query-complexity-analysis) to use it.
|
complexity | `callable` | **function($childrenComplexity, $args)**<br> Used to restrict query complexity. The feature is disabled by default, read about [Security](../security.md#query-complexity-analysis) to use it.
|
||||||
description | `string` | Plain-text description of this field for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
description | `string` | Plain-text description of this field for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||||
deprecationReason | `string` | Text describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced)
|
deprecationReason | `string` | Text describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced)
|
||||||
|
@ -62,7 +62,7 @@ $mutationType = new ObjectType([
|
|||||||
'episode' => $episodeEnum,
|
'episode' => $episodeEnum,
|
||||||
'review' => $reviewInputObject
|
'review' => $reviewInputObject
|
||||||
],
|
],
|
||||||
'resolve' => function($val, $args) {
|
'resolve' => function($rootValue, $args) {
|
||||||
// TODOC
|
// TODOC
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -19,8 +19,8 @@ try {
|
|||||||
'args' => [
|
'args' => [
|
||||||
'message' => ['type' => Type::string()],
|
'message' => ['type' => Type::string()],
|
||||||
],
|
],
|
||||||
'resolve' => function ($root, $args) {
|
'resolve' => function ($rootValue, $args) {
|
||||||
return $root['prefix'] . $args['message'];
|
return $rootValue['prefix'] . $args['message'];
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -35,7 +35,7 @@ try {
|
|||||||
'x' => ['type' => Type::int()],
|
'x' => ['type' => Type::int()],
|
||||||
'y' => ['type' => Type::int()],
|
'y' => ['type' => Type::int()],
|
||||||
],
|
],
|
||||||
'resolve' => function ($root, $args) {
|
'resolve' => function ($calc, $args) {
|
||||||
return $args['x'] + $args['y'];
|
return $args['x'] + $args['y'];
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -35,12 +35,12 @@ class CommentType extends ObjectType
|
|||||||
Types::htmlField('body')
|
Types::htmlField('body')
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
'resolveField' => function($value, $args, $context, ResolveInfo $info) {
|
'resolveField' => function($comment, $args, $context, ResolveInfo $info) {
|
||||||
$method = 'resolve' . ucfirst($info->fieldName);
|
$method = 'resolve' . ucfirst($info->fieldName);
|
||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
return $this->{$method}($value, $args, $context, $info);
|
return $this->{$method}($comment, $args, $context, $info);
|
||||||
} else {
|
} else {
|
||||||
return $value->{$info->fieldName};
|
return $comment->{$info->fieldName};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -57,8 +57,8 @@ class QueryType extends ObjectType
|
|||||||
],
|
],
|
||||||
'hello' => Type::string()
|
'hello' => Type::string()
|
||||||
],
|
],
|
||||||
'resolveField' => function($val, $args, $context, ResolveInfo $info) {
|
'resolveField' => function($rootValue, $args, $context, ResolveInfo $info) {
|
||||||
return $this->{$info->fieldName}($val, $args, $context, $info);
|
return $this->{$info->fieldName}($rootValue, $args, $context, $info);
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
parent::__construct($config);
|
parent::__construct($config);
|
||||||
|
@ -75,12 +75,12 @@ class StoryType extends ObjectType
|
|||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
Types::node()
|
Types::node()
|
||||||
],
|
],
|
||||||
'resolveField' => function($value, $args, $context, ResolveInfo $info) {
|
'resolveField' => function($story, $args, $context, ResolveInfo $info) {
|
||||||
$method = 'resolve' . ucfirst($info->fieldName);
|
$method = 'resolve' . ucfirst($info->fieldName);
|
||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
return $this->{$method}($value, $args, $context, $info);
|
return $this->{$method}($story, $args, $context, $info);
|
||||||
} else {
|
} else {
|
||||||
return $value->{$info->fieldName};
|
return $story->{$info->fieldName};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -44,12 +44,12 @@ class UserType extends ObjectType
|
|||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
Types::node()
|
Types::node()
|
||||||
],
|
],
|
||||||
'resolveField' => function($value, $args, $context, ResolveInfo $info) {
|
'resolveField' => function($user, $args, $context, ResolveInfo $info) {
|
||||||
$method = 'resolve' . ucfirst($info->fieldName);
|
$method = 'resolve' . ucfirst($info->fieldName);
|
||||||
if (method_exists($this, $method)) {
|
if (method_exists($this, $method)) {
|
||||||
return $this->{$method}($value, $args, $context, $info);
|
return $this->{$method}($user, $args, $context, $info);
|
||||||
} else {
|
} else {
|
||||||
return $value->{$info->fieldName};
|
return $user->{$info->fieldName};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
interface Resolver {
|
interface Resolver {
|
||||||
public function resolve($root, $args, $context);
|
public function resolve($rootValue, $args, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Addition implements Resolver
|
class Addition implements Resolver
|
||||||
{
|
{
|
||||||
public function resolve($root, $args, $context)
|
public function resolve($rootValue, $args, $context)
|
||||||
{
|
{
|
||||||
return $args['x'] + $args['y'];
|
return $args['x'] + $args['y'];
|
||||||
}
|
}
|
||||||
@ -14,22 +14,22 @@ class Addition implements Resolver
|
|||||||
|
|
||||||
class Echoer implements Resolver
|
class Echoer implements Resolver
|
||||||
{
|
{
|
||||||
public function resolve($root, $args, $context)
|
public function resolve($rootValue, $args, $context)
|
||||||
{
|
{
|
||||||
return $root['prefix'].$args['message'];
|
return $rootValue['prefix'].$args['message'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'sum' => function($root, $args, $context) {
|
'sum' => function($rootValue, $args, $context) {
|
||||||
$sum = new Addition();
|
$sum = new Addition();
|
||||||
|
|
||||||
return $sum->resolve($root, $args, $context);
|
return $sum->resolve($rootValue, $args, $context);
|
||||||
},
|
},
|
||||||
'echo' => function($root, $args, $context) {
|
'echo' => function($rootValue, $args, $context) {
|
||||||
$echo = new Echoer();
|
$echo = new Echoer();
|
||||||
|
|
||||||
return $echo->resolve($root, $args, $context);
|
return $echo->resolve($rootValue, $args, $context);
|
||||||
},
|
},
|
||||||
'prefix' => 'You said: ',
|
'prefix' => 'You said: ',
|
||||||
];
|
];
|
||||||
|
@ -19,8 +19,8 @@ try {
|
|||||||
'args' => [
|
'args' => [
|
||||||
'message' => ['type' => Type::string()],
|
'message' => ['type' => Type::string()],
|
||||||
],
|
],
|
||||||
'resolve' => function ($root, $args) {
|
'resolve' => function ($rootValue, $args) {
|
||||||
return $root['prefix'] . $args['message'];
|
return $rootValue['prefix'] . $args['message'];
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -35,7 +35,7 @@ try {
|
|||||||
'x' => ['type' => Type::int()],
|
'x' => ['type' => Type::int()],
|
||||||
'y' => ['type' => Type::int()],
|
'y' => ['type' => Type::int()],
|
||||||
],
|
],
|
||||||
'resolve' => function ($root, $args) {
|
'resolve' => function ($calc, $args) {
|
||||||
return $args['x'] + $args['y'];
|
return $args['x'] + $args['y'];
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -50,7 +50,7 @@ class ExecutionContext
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
$schema,
|
$schema,
|
||||||
$fragments,
|
$fragments,
|
||||||
$root,
|
$rootValue,
|
||||||
$contextValue,
|
$contextValue,
|
||||||
$operation,
|
$operation,
|
||||||
$variableValues,
|
$variableValues,
|
||||||
@ -60,7 +60,7 @@ class ExecutionContext
|
|||||||
) {
|
) {
|
||||||
$this->schema = $schema;
|
$this->schema = $schema;
|
||||||
$this->fragments = $fragments;
|
$this->fragments = $fragments;
|
||||||
$this->rootValue = $root;
|
$this->rootValue = $rootValue;
|
||||||
$this->contextValue = $contextValue;
|
$this->contextValue = $contextValue;
|
||||||
$this->operation = $operation;
|
$this->operation = $operation;
|
||||||
$this->variableValues = $variableValues;
|
$this->variableValues = $variableValues;
|
||||||
|
@ -157,33 +157,33 @@ class Executor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* If a resolve function is not given, then a default resolve behavior is used
|
* If a resolve function is not given, then a default resolve behavior is used
|
||||||
* which takes the property of the source object of the same name as the field
|
* which takes the property of the root value of the same name as the field
|
||||||
* and returns it as the result, or if it's a function, returns the result
|
* and returns it as the result, or if it's a function, returns the result
|
||||||
* of calling that function while passing along args and context.
|
* of calling that function while passing along args and context.
|
||||||
*
|
*
|
||||||
* @param mixed $source
|
* @param mixed $objectValue
|
||||||
* @param mixed[] $args
|
* @param mixed[] $args
|
||||||
* @param mixed|null $context
|
* @param mixed|null $context
|
||||||
*
|
*
|
||||||
* @return mixed|null
|
* @return mixed|null
|
||||||
*/
|
*/
|
||||||
public static function defaultFieldResolver($source, $args, $context, ResolveInfo $info)
|
public static function defaultFieldResolver($objectValue, $args, $context, ResolveInfo $info)
|
||||||
{
|
{
|
||||||
$fieldName = $info->fieldName;
|
$fieldName = $info->fieldName;
|
||||||
$property = null;
|
$property = null;
|
||||||
|
|
||||||
if (is_array($source) || $source instanceof ArrayAccess) {
|
if (is_array($objectValue) || $objectValue instanceof ArrayAccess) {
|
||||||
if (isset($source[$fieldName])) {
|
if (isset($objectValue[$fieldName])) {
|
||||||
$property = $source[$fieldName];
|
$property = $objectValue[$fieldName];
|
||||||
}
|
}
|
||||||
} elseif (is_object($source)) {
|
} elseif (is_object($objectValue)) {
|
||||||
if (isset($source->{$fieldName})) {
|
if (isset($objectValue->{$fieldName})) {
|
||||||
$property = $source->{$fieldName};
|
$property = $objectValue->{$fieldName};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $property instanceof Closure
|
return $property instanceof Closure
|
||||||
? $property($source, $args, $context, $info)
|
? $property($objectValue, $args, $context, $info)
|
||||||
: $property;
|
: $property;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
/**
|
/**
|
||||||
* Implements the "Evaluating operations" section of the spec.
|
* Implements the "Evaluating operations" section of the spec.
|
||||||
*
|
*
|
||||||
* @param mixed[] $rootValue
|
* @param mixed $rootValue
|
||||||
*
|
*
|
||||||
* @return Promise|stdClass|mixed[]
|
* @return Promise|stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
@ -463,21 +463,21 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
* Implements the "Evaluating selection sets" section of the spec
|
* Implements the "Evaluating selection sets" section of the spec
|
||||||
* for "write" mode.
|
* for "write" mode.
|
||||||
*
|
*
|
||||||
* @param mixed[] $sourceValue
|
* @param mixed $rootValue
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param ArrayObject $fields
|
* @param ArrayObject $fields
|
||||||
*
|
*
|
||||||
* @return Promise|stdClass|mixed[]
|
* @return Promise|stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
private function executeFieldsSerially(ObjectType $parentType, $sourceValue, $path, $fields)
|
private function executeFieldsSerially(ObjectType $parentType, $rootValue, $path, $fields)
|
||||||
{
|
{
|
||||||
$result = $this->promiseReduce(
|
$result = $this->promiseReduce(
|
||||||
array_keys($fields->getArrayCopy()),
|
array_keys($fields->getArrayCopy()),
|
||||||
function ($results, $responseName) use ($path, $parentType, $sourceValue, $fields) {
|
function ($results, $responseName) use ($path, $parentType, $rootValue, $fields) {
|
||||||
$fieldNodes = $fields[$responseName];
|
$fieldNodes = $fields[$responseName];
|
||||||
$fieldPath = $path;
|
$fieldPath = $path;
|
||||||
$fieldPath[] = $responseName;
|
$fieldPath[] = $responseName;
|
||||||
$result = $this->resolveField($parentType, $sourceValue, $fieldNodes, $fieldPath);
|
$result = $this->resolveField($parentType, $rootValue, $fieldNodes, $fieldPath);
|
||||||
if ($result === self::$UNDEFINED) {
|
if ($result === self::$UNDEFINED) {
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
@ -505,18 +505,19 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the field on the given source object. In particular, this
|
* Resolves the field on the given root value.
|
||||||
* figures out the value that the field returns by calling its resolve function,
|
|
||||||
* then calls completeValue to complete promises, serialize scalars, or execute
|
|
||||||
* the sub-selection-set for objects.
|
|
||||||
*
|
*
|
||||||
* @param object|null $source
|
* In particular, this figures out the value that the field returns
|
||||||
|
* by calling its resolve function, then calls completeValue to complete promises,
|
||||||
|
* serialize scalars, or execute the sub-selection-set for objects.
|
||||||
|
*
|
||||||
|
* @param mixed $rootValue
|
||||||
* @param FieldNode[] $fieldNodes
|
* @param FieldNode[] $fieldNodes
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
*
|
*
|
||||||
* @return mixed[]|Exception|mixed|null
|
* @return mixed[]|Exception|mixed|null
|
||||||
*/
|
*/
|
||||||
private function resolveField(ObjectType $parentType, $source, $fieldNodes, $path)
|
private function resolveField(ObjectType $parentType, $rootValue, $fieldNodes, $path)
|
||||||
{
|
{
|
||||||
$exeContext = $this->exeContext;
|
$exeContext = $this->exeContext;
|
||||||
$fieldNode = $fieldNodes[0];
|
$fieldNode = $fieldNodes[0];
|
||||||
@ -557,7 +558,7 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
$fieldDef,
|
$fieldDef,
|
||||||
$fieldNode,
|
$fieldNode,
|
||||||
$resolveFn,
|
$resolveFn,
|
||||||
$source,
|
$rootValue,
|
||||||
$context,
|
$context,
|
||||||
$info
|
$info
|
||||||
);
|
);
|
||||||
@ -615,13 +616,13 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
* @param FieldDefinition $fieldDef
|
* @param FieldDefinition $fieldDef
|
||||||
* @param FieldNode $fieldNode
|
* @param FieldNode $fieldNode
|
||||||
* @param callable $resolveFn
|
* @param callable $resolveFn
|
||||||
* @param mixed $source
|
* @param mixed $rootValue
|
||||||
* @param mixed $context
|
* @param mixed $context
|
||||||
* @param ResolveInfo $info
|
* @param ResolveInfo $info
|
||||||
*
|
*
|
||||||
* @return Throwable|Promise|mixed
|
* @return Throwable|Promise|mixed
|
||||||
*/
|
*/
|
||||||
private function resolveOrError($fieldDef, $fieldNode, $resolveFn, $source, $context, $info)
|
private function resolveOrError($fieldDef, $fieldNode, $resolveFn, $rootValue, $context, $info)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Build a map of arguments from the field.arguments AST, using the
|
// Build a map of arguments from the field.arguments AST, using the
|
||||||
@ -632,7 +633,7 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
$this->exeContext->variableValues
|
$this->exeContext->variableValues
|
||||||
);
|
);
|
||||||
|
|
||||||
return $resolveFn($source, $args, $context, $info);
|
return $resolveFn($rootValue, $args, $context, $info);
|
||||||
} catch (Exception $error) {
|
} catch (Exception $error) {
|
||||||
return $error;
|
return $error;
|
||||||
} catch (Throwable $error) {
|
} catch (Throwable $error) {
|
||||||
@ -1236,20 +1237,20 @@ class ReferenceExecutor implements ExecutorImplementation
|
|||||||
* Implements the "Evaluating selection sets" section of the spec
|
* Implements the "Evaluating selection sets" section of the spec
|
||||||
* for "read" mode.
|
* for "read" mode.
|
||||||
*
|
*
|
||||||
* @param mixed|null $source
|
* @param mixed $rootValue
|
||||||
* @param mixed[] $path
|
* @param mixed[] $path
|
||||||
* @param ArrayObject $fields
|
* @param ArrayObject $fields
|
||||||
*
|
*
|
||||||
* @return Promise|stdClass|mixed[]
|
* @return Promise|stdClass|mixed[]
|
||||||
*/
|
*/
|
||||||
private function executeFields(ObjectType $parentType, $source, $path, $fields)
|
private function executeFields(ObjectType $parentType, $rootValue, $path, $fields)
|
||||||
{
|
{
|
||||||
$containsPromise = false;
|
$containsPromise = false;
|
||||||
$finalResults = [];
|
$finalResults = [];
|
||||||
foreach ($fields as $responseName => $fieldNodes) {
|
foreach ($fields as $responseName => $fieldNodes) {
|
||||||
$fieldPath = $path;
|
$fieldPath = $path;
|
||||||
$fieldPath[] = $responseName;
|
$fieldPath[] = $responseName;
|
||||||
$result = $this->resolveField($parentType, $source, $fieldNodes, $fieldPath);
|
$result = $this->resolveField($parentType, $rootValue, $fieldNodes, $fieldPath);
|
||||||
if ($result === self::$UNDEFINED) {
|
if ($result === self::$UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -391,13 +391,13 @@ class Helper
|
|||||||
*/
|
*/
|
||||||
private function resolveRootValue(ServerConfig $config, OperationParams $params, DocumentNode $doc, $operationType)
|
private function resolveRootValue(ServerConfig $config, OperationParams $params, DocumentNode $doc, $operationType)
|
||||||
{
|
{
|
||||||
$root = $config->getRootValue();
|
$rootValue = $config->getRootValue();
|
||||||
|
|
||||||
if (is_callable($root)) {
|
if (is_callable($rootValue)) {
|
||||||
$root = $root($params, $doc, $operationType);
|
$rootValue = $rootValue($params, $doc, $operationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $root;
|
return $rootValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,7 +202,7 @@ class ObjectType extends Type implements OutputType, CompositeType, NullableType
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[] $value
|
* @param mixed $value
|
||||||
* @param mixed[]|null $context
|
* @param mixed[]|null $context
|
||||||
*
|
*
|
||||||
* @return bool|null
|
* @return bool|null
|
||||||
|
@ -109,10 +109,10 @@ class DeferredFieldsTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'title' => [
|
'title' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => function ($entry, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($story, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return $entry['title'];
|
return $story['title'];
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'author' => [
|
'author' => [
|
||||||
@ -185,7 +185,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'topStories' => [
|
'topStories' => [
|
||||||
'type' => Type::listOf($this->storyType),
|
'type' => Type::listOf($this->storyType),
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($rootValue, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return Utils::filter(
|
return Utils::filter(
|
||||||
@ -198,7 +198,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
],
|
],
|
||||||
'featuredCategory' => [
|
'featuredCategory' => [
|
||||||
'type' => $this->categoryType,
|
'type' => $this->categoryType,
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($rootValue, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return $this->categoryDataSource[0];
|
return $this->categoryDataSource[0];
|
||||||
@ -206,7 +206,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
],
|
],
|
||||||
'categories' => [
|
'categories' => [
|
||||||
'type' => Type::listOf($this->categoryType),
|
'type' => Type::listOf($this->categoryType),
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($rootValue, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return $this->categoryDataSource;
|
return $this->categoryDataSource;
|
||||||
@ -401,7 +401,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
return [
|
return [
|
||||||
'sync' => [
|
'sync' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($complexType, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return 'sync';
|
return 'sync';
|
||||||
@ -409,7 +409,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
],
|
],
|
||||||
'deferred' => [
|
'deferred' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($complexType, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return new Deferred(function () use ($info) {
|
return new Deferred(function () use ($info) {
|
||||||
@ -421,7 +421,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
],
|
],
|
||||||
'nest' => [
|
'nest' => [
|
||||||
'type' => $complexType,
|
'type' => $complexType,
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($complexType, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
@ -429,7 +429,7 @@ class DeferredFieldsTest extends TestCase
|
|||||||
],
|
],
|
||||||
'deferredNest' => [
|
'deferredNest' => [
|
||||||
'type' => $complexType,
|
'type' => $complexType,
|
||||||
'resolve' => function ($val, $args, $context, ResolveInfo $info) {
|
'resolve' => function ($complexType, $args, $context, ResolveInfo $info) {
|
||||||
$this->paths[] = $info->path;
|
$this->paths[] = $info->path;
|
||||||
|
|
||||||
return new Deferred(function () use ($info) {
|
return new Deferred(function () use ($info) {
|
||||||
|
@ -75,7 +75,7 @@ class ExecutorSchemaTest extends TestCase
|
|||||||
'article' => [
|
'article' => [
|
||||||
'type' => $BlogArticle,
|
'type' => $BlogArticle,
|
||||||
'args' => ['id' => ['type' => Type::id()]],
|
'args' => ['id' => ['type' => Type::id()]],
|
||||||
'resolve' => function ($_, $args) {
|
'resolve' => function ($rootValue, $args) {
|
||||||
return $this->article($args['id']);
|
return $this->article($args['id']);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -273,7 +273,7 @@ class ExecutorTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'test' => [
|
'test' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => static function ($val, $args, $ctx, $_info) use (&$info) {
|
'resolve' => static function ($test, $args, $ctx, $_info) use (&$info) {
|
||||||
$info = $_info;
|
$info = $_info;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -16,7 +16,7 @@ class Adder
|
|||||||
{
|
{
|
||||||
$this->num = $num;
|
$this->num = $num;
|
||||||
|
|
||||||
$this->test = function ($source, $args, $context) {
|
$this->test = function ($objectValue, $args, $context) {
|
||||||
return $this->num + $args['addend1'] + $context['addend2'];
|
return $this->num + $args['addend1'] + $context['addend2'];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ class GraphQLTest extends TestCase
|
|||||||
'type' => Type::nonNull(Type::string()),
|
'type' => Type::nonNull(Type::string()),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($value, $args) use ($promiseAdapter) {
|
'resolve' => static function ($rootValue, $args) use ($promiseAdapter) {
|
||||||
return $promiseAdapter->createFulfilled(sprintf('Hi %s!', $args['name']));
|
return $promiseAdapter->createFulfilled(sprintf('Hi %s!', $args['name']));
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -30,7 +30,7 @@ class Issue396Test extends TestCase
|
|||||||
$unionResult = new UnionType([
|
$unionResult = new UnionType([
|
||||||
'name' => 'UnionResult',
|
'name' => 'UnionResult',
|
||||||
'types' => [$a, $b, $c],
|
'types' => [$a, $b, $c],
|
||||||
'resolveType' => static function ($result, $root, ResolveInfo $info) use ($a, $b, $c, &$log) : Type {
|
'resolveType' => static function ($result, $value, ResolveInfo $info) use ($a, $b, $c, &$log) : Type {
|
||||||
$log[] = [$result, $info->path];
|
$log[] = [$result, $info->path];
|
||||||
if (stristr($result['name'], 'A')) {
|
if (stristr($result['name'], 'A')) {
|
||||||
return $a;
|
return $a;
|
||||||
@ -97,7 +97,7 @@ class Issue396Test extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'name' => Type::string(),
|
'name' => Type::string(),
|
||||||
],
|
],
|
||||||
'resolveType' => static function ($result, $root, ResolveInfo $info) use (&$a, &$b, &$c, &$log) : Type {
|
'resolveType' => static function ($result, $value, ResolveInfo $info) use (&$a, &$b, &$c, &$log) : Type {
|
||||||
$log[] = [$result, $info->path];
|
$log[] = [$result, $info->path];
|
||||||
if (stristr($result['name'], 'A')) {
|
if (stristr($result['name'], 'A')) {
|
||||||
return $a;
|
return $a;
|
||||||
|
@ -25,13 +25,13 @@ abstract class ServerTestCase extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'f1' => [
|
'f1' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => static function ($root, $args, $context, $info) {
|
'resolve' => static function ($rootValue, $args, $context, $info) {
|
||||||
return $info->fieldName;
|
return $info->fieldName;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'fieldWithPhpError' => [
|
'fieldWithPhpError' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => static function ($root, $args, $context, $info) {
|
'resolve' => static function ($rootValue, $args, $context, $info) {
|
||||||
trigger_error('deprecated', E_USER_DEPRECATED);
|
trigger_error('deprecated', E_USER_DEPRECATED);
|
||||||
trigger_error('notice', E_USER_NOTICE);
|
trigger_error('notice', E_USER_NOTICE);
|
||||||
trigger_error('warning', E_USER_WARNING);
|
trigger_error('warning', E_USER_WARNING);
|
||||||
@ -55,8 +55,8 @@ abstract class ServerTestCase extends TestCase
|
|||||||
],
|
],
|
||||||
'testContextAndRootValue' => [
|
'testContextAndRootValue' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'resolve' => static function ($root, $args, $context, $info) {
|
'resolve' => static function ($rootValue, $args, $context, $info) {
|
||||||
$context->testedRootValue = $root;
|
$context->testedRootValue = $rootValue;
|
||||||
|
|
||||||
return $info->fieldName;
|
return $info->fieldName;
|
||||||
},
|
},
|
||||||
@ -68,7 +68,7 @@ abstract class ServerTestCase extends TestCase
|
|||||||
'type' => Type::nonNull(Type::string()),
|
'type' => Type::nonNull(Type::string()),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($root, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
return $args['arg'];
|
return $args['arg'];
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -79,7 +79,7 @@ abstract class ServerTestCase extends TestCase
|
|||||||
'type' => Type::nonNull(Type::int()),
|
'type' => Type::nonNull(Type::int()),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($root, $args, $context) {
|
'resolve' => static function ($rootValue, $args, $context) {
|
||||||
$context['buffer']($args['num']);
|
$context['buffer']($args['num']);
|
||||||
|
|
||||||
return new Deferred(static function () use ($args, $context) {
|
return new Deferred(static function () use ($args, $context) {
|
||||||
|
@ -273,7 +273,7 @@ class StarWarsSchema
|
|||||||
'type' => $episodeEnum,
|
'type' => $episodeEnum,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($root, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
return StarWarsData::getHero($args['episode'] ?? null);
|
return StarWarsData::getHero($args['episode'] ?? null);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -286,7 +286,7 @@ class StarWarsSchema
|
|||||||
'type' => Type::nonNull(Type::string()),
|
'type' => Type::nonNull(Type::string()),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($root, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
$humans = StarWarsData::humans();
|
$humans = StarWarsData::humans();
|
||||||
|
|
||||||
return $humans[$args['id']] ?? null;
|
return $humans[$args['id']] ?? null;
|
||||||
@ -301,7 +301,7 @@ class StarWarsSchema
|
|||||||
'type' => Type::nonNull(Type::string()),
|
'type' => Type::nonNull(Type::string()),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($root, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
$droids = StarWarsData::droids();
|
$droids = StarWarsData::droids();
|
||||||
|
|
||||||
return $droids[$args['id']] ?? null;
|
return $droids[$args['id']] ?? null;
|
||||||
|
@ -74,7 +74,7 @@ class EnumTypeTest extends TestCase
|
|||||||
'fromInt' => ['type' => Type::int()],
|
'fromInt' => ['type' => Type::int()],
|
||||||
'fromString' => ['type' => Type::string()],
|
'fromString' => ['type' => Type::string()],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($value, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
if (isset($args['fromInt'])) {
|
if (isset($args['fromInt'])) {
|
||||||
return $args['fromInt'];
|
return $args['fromInt'];
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ class EnumTypeTest extends TestCase
|
|||||||
'fromName' => ['type' => Type::string()],
|
'fromName' => ['type' => Type::string()],
|
||||||
'fromValue' => ['type' => Type::string()],
|
'fromValue' => ['type' => Type::string()],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($value, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
if (isset($args['fromName'])) {
|
if (isset($args['fromName'])) {
|
||||||
return $args['fromName'];
|
return $args['fromName'];
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ class EnumTypeTest extends TestCase
|
|||||||
'fromEnum' => ['type' => $ColorType],
|
'fromEnum' => ['type' => $ColorType],
|
||||||
'fromInt' => ['type' => Type::int()],
|
'fromInt' => ['type' => Type::int()],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($value, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
if (isset($args['fromInt'])) {
|
if (isset($args['fromInt'])) {
|
||||||
return $args['fromInt'];
|
return $args['fromInt'];
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ class EnumTypeTest extends TestCase
|
|||||||
'type' => Type::boolean(),
|
'type' => Type::boolean(),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'resolve' => static function ($value, $args) use ($Complex2) {
|
'resolve' => static function ($rootValue, $args) use ($Complex2) {
|
||||||
if (! empty($args['provideGoodValue'])) {
|
if (! empty($args['provideGoodValue'])) {
|
||||||
// Note: this is one of the references of the internal values which
|
// Note: this is one of the references of the internal values which
|
||||||
// ComplexEnum allows.
|
// ComplexEnum allows.
|
||||||
@ -156,7 +156,7 @@ class EnumTypeTest extends TestCase
|
|||||||
'favoriteEnum' => [
|
'favoriteEnum' => [
|
||||||
'type' => $ColorType,
|
'type' => $ColorType,
|
||||||
'args' => ['color' => ['type' => $ColorType]],
|
'args' => ['color' => ['type' => $ColorType]],
|
||||||
'resolve' => static function ($value, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
return $args['color'] ?? null;
|
return $args['color'] ?? null;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -169,7 +169,7 @@ class EnumTypeTest extends TestCase
|
|||||||
'subscribeToEnum' => [
|
'subscribeToEnum' => [
|
||||||
'type' => $ColorType,
|
'type' => $ColorType,
|
||||||
'args' => ['color' => ['type' => $ColorType]],
|
'args' => ['color' => ['type' => $ColorType]],
|
||||||
'resolve' => static function ($value, $args) {
|
'resolve' => static function ($rootValue, $args) {
|
||||||
return $args['color'] ?? null;
|
return $args['color'] ?? null;
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -1049,7 +1049,7 @@ class IntrospectionTest extends TestCase
|
|||||||
'field' => [
|
'field' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'args' => ['complex' => ['type' => $TestInputObject]],
|
'args' => ['complex' => ['type' => $TestInputObject]],
|
||||||
'resolve' => static function ($_, $args) {
|
'resolve' => static function ($testType, $args) {
|
||||||
return json_encode($args['complex']);
|
return json_encode($args['complex']);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -393,7 +393,7 @@ final class QueryPlanTest extends TestCase
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
$result = GraphQL::executeQuery($schema, $query)->toArray();
|
GraphQL::executeQuery($schema, $query)->toArray();
|
||||||
|
|
||||||
self::assertTrue($hasCalled);
|
self::assertTrue($hasCalled);
|
||||||
self::assertEquals($expectedQueryPlan, $queryPlan->queryPlan());
|
self::assertEquals($expectedQueryPlan, $queryPlan->queryPlan());
|
||||||
|
@ -51,7 +51,7 @@ class BuildSchemaTest extends TestCase
|
|||||||
');
|
');
|
||||||
|
|
||||||
$root = [
|
$root = [
|
||||||
'add' => static function ($root, $args) {
|
'add' => static function ($rootValue, $args) {
|
||||||
return $args['x'] + $args['y'];
|
return $args['x'] + $args['y'];
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -464,7 +464,7 @@ type WorldTwo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
';
|
';
|
||||||
$root = [
|
$rootValue = [
|
||||||
'fruits' => [
|
'fruits' => [
|
||||||
[
|
[
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
@ -485,7 +485,7 @@ type WorldTwo {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
$result = GraphQL::executeQuery($schema, $query, $root);
|
$result = GraphQL::executeQuery($schema, $query, $rootValue);
|
||||||
self::assertEquals($expected, $result->toArray(true));
|
self::assertEquals($expected, $result->toArray(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +526,7 @@ type WorldTwo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
';
|
';
|
||||||
$root = [
|
$rootValue = [
|
||||||
'characters' => [
|
'characters' => [
|
||||||
[
|
[
|
||||||
'name' => 'Han Solo',
|
'name' => 'Han Solo',
|
||||||
@ -549,7 +549,7 @@ type WorldTwo {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
$result = GraphQL::executeQuery($schema, $query, $root);
|
$result = GraphQL::executeQuery($schema, $query, $rootValue);
|
||||||
self::assertEquals($expected, $result->toArray(true));
|
self::assertEquals($expected, $result->toArray(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user