Passed
Push — master ( e52344...df819b )
by Rafael
09:21
created

ObjectFieldResolver::__invoke()   C

Complexity

Conditions 9
Paths 24

Size

Total Lines 47
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 9.0329

Importance

Changes 0
Metric Value
dl 0
loc 47
c 0
b 0
f 0
ccs 25
cts 27
cp 0.9259
rs 5.2941
cc 9
eloc 29
nc 24
nop 4
crap 9.0329
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Resolver;
12
13
use Doctrine\Common\Collections\Collection;
14
use GraphQL\Type\Definition\ResolveInfo;
15
use Ynlo\GraphQLBundle\Type\Types;
16
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
17
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
18
use Symfony\Component\DependencyInjection\ContainerInterface;
19
use Symfony\Component\PropertyAccess\PropertyAccessor;
20
use Ynlo\GraphQLBundle\Definition\FieldsAwareDefinitionInterface;
21
use Ynlo\GraphQLBundle\Definition\QueryDefinition;
22
use Ynlo\GraphQLBundle\Definition\Registry\Endpoint;
23
use Ynlo\GraphQLBundle\Model\ID;
24
use Ynlo\GraphQLBundle\Type\Definition\EndpointAwareInterface;
25
use Ynlo\GraphQLBundle\Type\Definition\EndpointAwareTrait;
26
27
/**
28
 * Default resolver for all object fields
29
 */
30
class ObjectFieldResolver implements ContainerAwareInterface, EndpointAwareInterface
31
{
32
    use ContainerAwareTrait;
33
    use EndpointAwareTrait;
34
35
    /**
36
     * @var FieldsAwareDefinitionInterface
37
     */
38
    protected $definition;
39
40
    /**
41
     * ObjectFieldResolver constructor.
42
     *
43
     * @param ContainerInterface             $container
44
     * @param Endpoint                       $endpoint
45
     * @param FieldsAwareDefinitionInterface $definition
46
     */
47 21
    public function __construct(ContainerInterface $container, Endpoint $endpoint, FieldsAwareDefinitionInterface $definition)
48
    {
49 21
        $this->definition = $definition;
50 21
        $this->container = $container;
51 21
        $this->endpoint = $endpoint;
52 21
    }
53
54
    /**
55
     * @param mixed       $root
56
     * @param array       $args
57
     * @param mixed       $context
58
     * @param ResolveInfo $info
59
     *
60
     * @return mixed|null|string
61
     */
62 21
    public function __invoke($root, array $args, $context, ResolveInfo $info)
63
    {
64 21
        $value = null;
65 21
        $fieldDefinition = $this->definition->getField($info->fieldName);
66
67
        //when use external resolver or use a object method with arguments
68 21
        if ($fieldDefinition->getResolver() || $fieldDefinition->getArguments()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fieldDefinition->getResolver() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
69 19
            $queryDefinition = new QueryDefinition();
70 19
            $queryDefinition->setName($fieldDefinition->getName());
71 19
            $queryDefinition->setType($fieldDefinition->getType());
72 19
            $queryDefinition->setNode($fieldDefinition->getNode());
73 19
            $queryDefinition->setArguments($fieldDefinition->getArguments());
74 19
            $queryDefinition->setList($fieldDefinition->isList());
75 19
            $queryDefinition->setMetas($fieldDefinition->getMetas());
76
77 19
            if (!$fieldDefinition->getResolver()) {
78
                if ($fieldDefinition->getOriginType() === \ReflectionMethod::class) {
79
                    $queryDefinition->setResolver($fieldDefinition->getOriginName());
80
                }
81
            } else {
82 19
                $queryDefinition->setResolver($fieldDefinition->getResolver());
83
            }
84
85 19
            $resolver = new ResolverExecutor($this->container, $this->endpoint, $queryDefinition);
86 19
            $value = $resolver($root, $args, $context, $info);
87
        } else {
88 21
            $accessor = new PropertyAccessor(true);
89 21
            $originName = $fieldDefinition->getOriginName() ?? $fieldDefinition->getName();
90 21
            $value = $accessor->getValue($root, $originName);
91
        }
92
93 21
        if (null !== $value && Types::ID === $fieldDefinition->getType()) {
94
            //ID are formed with base64 representation of the Types and real database ID
95
            //in order to create a unique and global identifier for each resource
96
            //@see https://facebook.github.io/relay/docs/graphql-object-identification.html
97 16
            if ($value instanceof ID) {
98 2
                $value = (string) $value;
99
            } else {
100 15
                $value = (string) new ID($this->definition->getName(), $value);
101
            }
102
        }
103
104 21
        if ($value instanceof Collection) {
105 3
            $value = $value->toArray();
106
        }
107
108 21
        return $value;
109
    }
110
}
111