Completed
Push — master ( f8702a...461e07 )
by Alexandr
04:08
created

Processor::resolveValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 8
Bugs 1 Features 2
Metric Value
c 8
b 1
f 2
dl 0
loc 11
rs 9.4285
ccs 6
cts 6
cp 1
cc 2
eloc 6
nc 2
nop 3
crap 2
1
<?php
2
/*
3
* This file is a part of graphql-youshido project.
4
*
5
* @author Portey Vasil <[email protected]>
6
* @author Alexandr Viniychuk <[email protected]>
7
* created: 11/28/15 1:05 AM
8
*/
9
10
namespace Youshido\GraphQL;
11
12
use Youshido\GraphQL\Introspection\QueryType;
13
use Youshido\GraphQL\Introspection\SchemaType;
14
use Youshido\GraphQL\Introspection\TypeDefinitionType;
15
use Youshido\GraphQL\Parser\Ast\FragmentReference;
16
use Youshido\GraphQL\Parser\Ast\Mutation;
17
use Youshido\GraphQL\Parser\Ast\Query;
18
use Youshido\GraphQL\Parser\Ast\TypedFragmentReference;
19
use Youshido\GraphQL\Parser\Parser;
20
use Youshido\GraphQL\Type\AbstractType;
21
use Youshido\GraphQL\Type\Field\Field;
22
use Youshido\GraphQL\Type\Object\AbstractEnumType;
23
use Youshido\GraphQL\Type\Object\AbstractInterfaceType;
24
use Youshido\GraphQL\Type\Object\ObjectType;
25
use Youshido\GraphQL\Type\Scalar\AbstractScalarType;
26
use Youshido\GraphQL\Type\TypeInterface;
27
use Youshido\GraphQL\Type\TypeMap;
28
use Youshido\GraphQL\Parser\Ast\Field as AstField;
29
use Youshido\GraphQL\Validator\ErrorContainer\ErrorContainerTrait;
30
use Youshido\GraphQL\Validator\Exception\ConfigurationException;
31
use Youshido\GraphQL\Validator\Exception\ResolveException;
32
use Youshido\GraphQL\Validator\ResolveValidator\ResolveValidator;
33
use Youshido\GraphQL\Validator\ResolveValidator\ResolveValidatorInterface;
34
use Youshido\GraphQL\Validator\SchemaValidator\SchemaValidator;
35
36
class Processor
37
{
38
    use ErrorContainerTrait;
39
40
    const TYPE_NAME_QUERY = '__typename';
41
42
    /** @var  array */
43
    protected $data;
44
45
    /** @var ResolveValidatorInterface */
46
    protected $resolveValidator;
47
48
    /** @var SchemaValidator */
49
    protected $schemaValidator;
50
51
    /** @var AbstractSchema */
52
    protected $schema;
53
54
    /** @var Request */
55
    protected $request;
56
57 19
    public function __construct()
58
    {
59 19
        $this->resolveValidator = new ResolveValidator();
60 19
        $this->schemaValidator  = new SchemaValidator();
61 19
    }
62
63 19
    public function setSchema(AbstractSchema $schema)
64
    {
65 19
        if (!$this->schemaValidator->validate($schema)) {
66
            $this->mergeErrors($this->schemaValidator);
67
68
            return;
69
        }
70
71 19
        $this->schema = $schema;
72
73 19
        $__schema = new SchemaType();
74 19
        $__schema->setSchema($schema);
75
76 19
        $__type = new TypeDefinitionType();
77
78 19
        $this->schema->addQuery('__schema', $__schema);
79 19
        $this->schema->addQuery('__type', $__type);
80 19
    }
81
82 19
    public function processRequest($payload, $variables = [])
83
    {
84 19
        if ($this->hasErrors()) return $this;
85
86 19
        $this->data = [];
87
88
        try {
89 19
            $this->parseAndCreateRequest($payload, $variables);
90
91 19
            foreach ($this->request->getQueries() as $query) {
92 19
                if ($queryResult = $this->executeQuery($query, $this->getSchema()->getQueryType())) {
93 19
                    $this->data = array_merge($this->data, $queryResult);
94
                };
95
            }
96
97 19
            foreach ($this->request->getMutations() as $mutation) {
98
                if ($mutationResult = $this->executeMutation($mutation, $this->getSchema()->getMutationType())) {
99 19
                    $this->data = array_merge($this->data, $mutationResult);
100
                }
101
            }
102
103
        } catch (\Exception $e) {
104
            $this->resolveValidator->clearErrors();
105
106
            $this->resolveValidator->addError($e);
107
        }
108
109 19
        return $this;
110
    }
111
112 19
    protected function parseAndCreateRequest($query, $variables = [])
113
    {
114 19
        $parser = new Parser();
115
116 19
        $data = $parser->parse($query);
117
118 19
        $this->request = new Request($data);
119 19
        $this->request->setVariables($variables);
120 19
    }
121
122
    /**
123
     * @param Query|Field          $query
124
     * @param ObjectType|QueryType $currentLevelSchema
125
     * @param null                 $contextValue
126
     * @return array|bool|mixed
127
     */
128 19
    protected function executeQuery($query, $currentLevelSchema, $contextValue = null)
129
    {
130 19
        if (!$this->resolveValidator->checkFieldExist($currentLevelSchema, $query)) {
131
            return null;
132
        }
133
134
        /** @var Field $field */
135 19
        $field = $currentLevelSchema->getField($query->getName());
0 ignored issues
show
Bug introduced by
The method getName does only exist in Youshido\GraphQL\Parser\Ast\Query, but not in Youshido\GraphQL\Type\Field\Field.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
136 19
        $alias = $query->getAlias() ?: $query->getName();
0 ignored issues
show
Bug introduced by
The method getAlias does only exist in Youshido\GraphQL\Parser\Ast\Query, but not in Youshido\GraphQL\Type\Field\Field.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
137
138 19
        if ($query instanceof AstField) {
139 17
            $value = $this->processAstFieldQuery($query, $contextValue, $field);
140
        } else {
141 19
            if (!$this->resolveValidator->validateArguments($field, $query, $this->request)) {
142 2
                return null;
143
            }
144
145 17
            $value = $this->processFieldTypeQuery($query, $contextValue, $field);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $value is correct as $this->processFieldTypeQ... $contextValue, $field) (which targets Youshido\GraphQL\Process...processFieldTypeQuery()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
146
147
        }
148
149 17
        return [$alias => $value];
150
    }
151
152
    /**
153
     * @param Mutation $mutation
154
     * @param ObjectType $currentLevelSchema
155
     * @return array|null
156
     * @throws ConfigurationException
157
     */
158
    protected function executeMutation(Mutation $mutation, $currentLevelSchema)
159
    {
160
        if (!$currentLevelSchema) throw new ConfigurationException('There is no mutation '. $mutation->getName());
161
162
        if (!$this->resolveValidator->checkFieldExist($currentLevelSchema, $mutation)) {
163
            return null;
164
        }
165
166
        /** @var Field $field */
167
        $field = $currentLevelSchema->getConfig()->getField($mutation->getName());
168
        $alias = $mutation->getAlias() ?: $mutation->getName();
169
170
        if (!$this->resolveValidator->validateArguments($field, $mutation, $this->request)) {
171
            return null;
172
        }
173
174
        $resolvedValue = $this->resolveValue($field, null, $mutation);
175
176 View Code Duplication
        if (!$this->resolveValidator->validateResolvedValue($resolvedValue, $field->getType())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
            $this->resolveValidator->addError(new ResolveException(sprintf('Not valid resolved value for mutation "%s"', $field->getType()->getName())));
178
179
            return [$alias => null];
180
        }
181
182
        $value = $resolvedValue;
183
        if ($mutation->hasFields()) {
184
            if ($field->getType()->isAbstractType()) {
185
                $outputType = $field->getType()->getConfig()->resolveType($resolvedValue);
0 ignored issues
show
Documentation Bug introduced by
The method resolveType does not exist on object<Youshido\GraphQL\...bject\ObjectTypeConfig>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
186
            } else {
187
                /** @var AbstractType $outputType */
188
                $outputType = $field->getType();
189
            }
190
191
            $value = $this->collectListOrSingleValue($outputType, $resolvedValue, $mutation);
192
        }
193
194
        return [$alias => $value];
195
    }
196
197
    /**
198
     * @param AstField $astField
199
     * @param mixed    $contextValue
200
     * @param Field    $field
201
     * @return array|mixed|null
202
     * @throws \Exception
203
     */
204 17
    protected function processAstFieldQuery(AstField $astField, $contextValue, Field $field)
205
    {
206 17
        $value            = null;
207 17
        $preResolvedValue = $this->getPreResolvedValue($contextValue, $astField, $field);
208
209 17
        if ($field->getConfig()->getType()->getKind() == TypeMap::KIND_LIST) {
210 1
            if (!is_array($preResolvedValue)) {
211
                $this->resolveValidator->addError(new ResolveException('Not valid resolve value for list type'));
212
                return null;
213
            }
214
215 1
            $listValue = [];
216 1
            foreach ($preResolvedValue as $resolvedValueItem) {
217
                /** @var TypeInterface $type */
218 1
                $type = $field->getType()->getConfig()->getItem();
0 ignored issues
show
Documentation Bug introduced by
The method getItem does not exist on object<Youshido\GraphQL\...bject\ObjectTypeConfig>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
219
220 1
                if ($type->getKind() == TypeMap::KIND_ENUM) {
221
                    /** @var $type AbstractEnumType */
222 1
                    if (!$type->isValidValue($resolvedValueItem)) {
223
                        $this->resolveValidator->addError(new ResolveException('Not valid value for enum type'));
224
225
                        $listValue = null;
226
                        break;
227
                    }
228
229 1
                    $listValue[] = $type->resolve($resolvedValueItem);
230
                } else {
231
                    /** @var AbstractScalarType $type */
232 1
                    $listValue[] = $type->serialize($preResolvedValue);
233
                }
234
            }
235
236 1
            $value = $listValue;
237
        } else {
238 17
            if ($field->getType()->getKind() == TypeMap::KIND_ENUM) {
239
                if (!$field->getType()->isValidValue($preResolvedValue)) {
240
                    $this->resolveValidator->addError(new ResolveException(sprintf('Not valid value for %s type', ($field->getType()->getKind()))));
241
                    $value = null;
242
                } else {
243
                    $value = $preResolvedValue;
244
                    /** $field->getType()->resolve($preResolvedValue); */
245
                }
246 17
            } elseif ($field->getType()->getKind() == TypeMap::KIND_NON_NULL) {
247
                if (!$field->getType()->isValidValue($preResolvedValue)) {
248
                    $this->resolveValidator->addError(new ResolveException(sprintf('Cannot return null for non-nullable field %s', $astField->getName() . '.' . $field->getName())));
0 ignored issues
show
Bug introduced by
The method getName() does not exist on Youshido\GraphQL\Type\Field\Field. Did you maybe mean getNamedType()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
249
                } elseif (!$field->getType()->getNullableType()->isValidValue($preResolvedValue)) {
250
                    $this->resolveValidator->addError(new ResolveException(sprintf('Not valid value for %s field %s', $field->getType()->getNullableType()->getKind(), $field->getName())));
0 ignored issues
show
Bug introduced by
The method getName() does not exist on Youshido\GraphQL\Type\Field\Field. Did you maybe mean getNamedType()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
251
                    $value = null;
252
                } else {
253
                    $value = $preResolvedValue;
254
                }
255
            } else {
256 17
                $value = $field->getType()->serialize($preResolvedValue);
257
            }
258
        }
259
260 17
        return $value;
261
    }
262
263
    /**
264
     * @param       $query
265
     * @param mixed $contextValue
266
     * @param Field $field
267
     * @return null
268
     * @throws \Exception
269
     */
270 17
    protected function processFieldTypeQuery($query, $contextValue, $field)
271
    {
272 17
        if (!($resolvedValue = $this->resolveValue($field, $contextValue, $query))) {
273 3
            return $resolvedValue;
274
        }
275
276 17 View Code Duplication
        if (!$this->resolveValidator->validateResolvedValue($resolvedValue, $field->getType())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
277
            $this->resolveValidator->addError(new ResolveException(sprintf('Not valid resolved value for query "%s"', $field->getType()->getName())));
278
279
            return null;
280
        }
281
282 17
        return $this->collectListOrSingleValue($field->getType(), $resolvedValue, $query);
283
    }
284
285
    /**
286
     * @param AbstractType   $fieldType
287
     * @param mixed          $resolvedValue
288
     * @param Query|Mutation $query
289
     * @return array|mixed
290
     * @throws \Exception
291
     */
292 17
    protected function collectListOrSingleValue(AbstractType $fieldType, $resolvedValue, $query)
293
    {
294 17
        $value = [];
295 17
        if ($fieldType->getKind() == TypeMap::KIND_LIST) {
296 7
            foreach ($resolvedValue as $resolvedValueItem) {
297 7
                $value[]   = [];
298 7
                $index     = count($value) - 1;
299 7
                $namedType = $fieldType->getNamedType();
300
301 7
                if ($namedType->isAbstractType()) {
302 4
                    $resolvedType = $namedType->getConfig()->resolveType($resolvedValueItem);
0 ignored issues
show
Documentation Bug introduced by
The method resolveType does not exist on object<Youshido\GraphQL\...bject\ObjectTypeConfig>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
303 4
                    if ($namedType instanceof AbstractInterfaceType) {
304 2
                        $this->resolveValidator->assertTypeImplementsInterface($resolvedType, $namedType);
305
                    }
306 4
                    $namedType = $resolvedType;
307
                }
308
309 7
                $value[$index] = $this->processQueryFields($query, $namedType, $resolvedValueItem, $value[$index]);
310
            }
311
        } else {
312 15
            $value = $this->processQueryFields($query, $fieldType, $resolvedValue, $value);
313
        }
314
315 17
        return $value;
316
    }
317
318
    /**
319
     * @param          $value
320
     * @param AstField $astField
321
     * @param Field    $field
322
     *
323
     * @throws \Exception
324
     *
325
     * @return mixed
326
     */
327 17
    protected function getPreResolvedValue($value, AstField $astField, Field $field)
328
    {
329 17
        $resolved      = false;
330 17
        $resolverValue = null;
331
332 17
        if (is_array($value) && array_key_exists($astField->getName(), $value)) {
333 12
            $resolverValue = $value[$astField->getName()];
334 12
            $resolved      = true;
335 5
        } elseif (is_object($value)) {
336
            try {
337 5
                $resolverValue = $this->getPropertyValue($value, $astField->getName());
338 5
                $resolved      = true;
339 5
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
340
            }
341
        } elseif ($field->getNamedType()->getKind() == TypeMap::KIND_SCALAR) {
342
            $resolved = true;
343
        }
344
345 17
        if ($resolved) {
346 17
            if ($field->getConfig() && ($field->getConfig()->issetResolve())) {
347 1
                $resolverValue = $field->resolve($resolverValue, $astField->getKeyValueArguments(), $field->getType());
348
            }
349
350 17
            return $resolverValue;
351
        }
352
353
        throw new \Exception(sprintf('Property "%s" not found in resolve result', $astField->getName()));
354
    }
355
356 5
    protected function getPropertyValue($data, $path)
357
    {
358 5
        if (is_object($data)) {
359 5
            $getter = 'get' . $this->classify($path);
360
361 5
            return is_callable([$data, $getter]) ? $data->$getter() : null;
362
        } elseif (is_array($data)) {
363
            return array_key_exists($path, $data) ? $data[$path] : null;
364
        }
365
366
        return null;
367
    }
368
369 5
    protected function classify($text)
370
    {
371 5
        $text       = explode(' ', str_replace(['_', '/', '-', '.'], ' ', $text));
372 5
        $textLength = count($text);
373 5
        for ($i = 0; $i < $textLength; $i++) {
374 5
            $text[$i] = ucfirst($text[$i]);
375
        }
376 5
        $text = ucfirst(implode('', $text));
377
378 5
        return $text;
379
    }
380
381
    /**
382
     * @param Field $field
383
     * @param mixed $contextValue
384
     * @param Query $query
385
     *
386
     * @return mixed
387
     */
388 17
    protected function resolveValue($field, $contextValue, $query)
389
    {
390 17
        $resolvedValue = $field->resolve($contextValue, $this->parseArgumentsValues($field, $query), $field->getType());
391
392 17
        if ($field->getType()->isAbstractType()) {
393 6
            $resolvedType = $field->getType()->resolveType($resolvedValue);
0 ignored issues
show
Documentation Bug introduced by
The method resolveType does not exist on object<Youshido\GraphQL\...ect\AbstractObjectType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
394 6
            $field->setType($resolvedType);
395
        }
396
397 17
        return $resolvedValue;
398
    }
399
400
    /**
401
     * @param $field     Field
402
     * @param $query     Query
403
     *
404
     * @return array
405
     */
406 17
    public function parseArgumentsValues($field, $query)
407
    {
408 17
        if ($query instanceof \Youshido\GraphQL\Parser\Ast\Field) {
409
            return [];
410
        }
411
412 17
        $args = [];
413 17
        foreach ($query->getArguments() as $argument) {
414 5
            $args[$argument->getName()] = $field->getConfig()->getArgument($argument->getName())->getType()->parseValue($argument->getValue()->getValue());
415
        }
416
417 17
        return $args;
418
    }
419
420
    /**
421
     * @param $query         Query
422
     * @param $queryType     ObjectType|TypeInterface|Field
423
     * @param $resolvedValue mixed
424
     * @param $value         array
425
     *
426
     * @throws \Exception
427
     *
428
     * @return array
429
     */
430 17
    protected function processQueryFields($query, $queryType, $resolvedValue, $value)
431
    {
432 17
        foreach ($query->getFields() as $field) {
433 17
            if ($field instanceof FragmentReference) {
434 1
                if (!$fragment = $this->request->getFragment($field->getName())) {
435
                    throw new \Exception(sprintf('Fragment reference "%s" not found', $field->getName()));
436
                }
437
438 1
                if ($fragment->getModel() !== $queryType->getName()) {
439
                    throw new \Exception(sprintf('Fragment reference "%s" not found on model "%s"', $field->getName(), $queryType->getName()));
440
                }
441
442 1
                foreach ($fragment->getFields() as $fragmentField) {
443 1
                    $value = $this->collectValue($value, $this->executeQuery($fragmentField, $queryType, $resolvedValue));
444
                }
445
            } elseif ($field instanceof TypedFragmentReference) {
446 2
                if ($field->getTypeName() !== $queryType->getName()) {
447 1
                    continue;
448
                }
449
450 2
                foreach ($field->getFields() as $fragmentField) {
451 2
                    $value = $this->collectValue($value, $this->executeQuery($fragmentField, $queryType, $resolvedValue));
0 ignored issues
show
Documentation introduced by
$fragmentField is of type object<Youshido\GraphQL\Parser\Ast\Field>, but the function expects a object<Youshido\GraphQL\...aphQL\Type\Field\Field>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
452
                }
453 17
            } elseif ($field->getName() == self::TYPE_NAME_QUERY) {
454 1
                $value = $this->collectValue($value, [$field->getAlias() ?: $field->getName() => $queryType->getName()]);
455
            } else {
456 17
                $value = $this->collectValue($value, $this->executeQuery($field, $queryType, $resolvedValue));
457
            }
458
        }
459
460 17
        return $value;
461
    }
462
463 17
    protected function collectValue($value, $queryValue)
464
    {
465 17
        if ($queryValue && is_array($queryValue)) {
466 17
            $value = array_merge(is_array($value) ? $value : [], $queryValue);
467
        } else {
468
            $value = $queryValue;
469
        }
470
471 17
        return $value;
472
    }
473
474 19
    public function getSchema()
475
    {
476 19
        return $this->schema;
477
    }
478
479 19
    public function getResponseData()
480
    {
481 19
        $result = [];
482
483 19
        if (!empty($this->data)) {
484 17
            $result['data'] = $this->data;
485
        }
486
487 19
        $this->mergeErrors($this->resolveValidator);
0 ignored issues
show
Documentation introduced by
$this->resolveValidator is of type object<Youshido\GraphQL\...olveValidatorInterface>, but the function expects a object<Youshido\GraphQL\...rrorContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
488 19
        if ($this->hasErrors()) {
489 2
            $result['errors'] = $this->getErrorsArray();
490
        }
491 19
        $this->clearErrors();
492 19
        $this->resolveValidator->clearErrors();
493 19
        $this->schemaValidator->clearErrors();
494
495 19
        return $result;
496
    }
497
}
498