Completed
Push — master ( 186982...2975e7 )
by Rafael
05:12
created

ObjectFieldResolver::denyAccessUnlessGranted()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 9
cp 0
rs 9.9332
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 20
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 Symfony\Component\DependencyInjection\ContainerAwareInterface;
16
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
19
use Symfony\Component\PropertyAccess\PropertyAccessor;
20
use Ynlo\GraphQLBundle\Definition\QueryDefinition;
21
use Ynlo\GraphQLBundle\Events\GraphQLEvents;
22
use Ynlo\GraphQLBundle\Events\GraphQLFieldEvent;
23
use Ynlo\GraphQLBundle\Events\GraphQLFieldInfo;
24
use Ynlo\GraphQLBundle\Model\NodeInterface;
25
use Ynlo\GraphQLBundle\Type\Types;
26
use Ynlo\GraphQLBundle\Util\IDEncoder;
27
28
/**
29
 * Default resolver for all object fields
30
 */
31
class ObjectFieldResolver implements ContainerAwareInterface
32
{
33
    use ContainerAwareTrait;
34
35
    /**
36
     * ObjectFieldResolver constructor.
37
     *
38
     * @param ContainerInterface $container
39
     */
40
    public function __construct(ContainerInterface $container)
41
    {
42
        $this->container = $container;
43
    }
44
45
    /**
46
     * @param mixed                 $root
47
     * @param array                 $args
48
     * @param FieldExecutionContext $context
49
     * @param ResolveInfo           $info
50
     *
51
     * @return mixed|null|string
52
     *
53
     * @throws \Exception
54
     */
55
    public function __invoke($root, array $args, FieldExecutionContext $context, ResolveInfo $info)
56
    {
57
        $value = null;
58
        $fieldDefinition = $context->getDefinition()->getField($info->fieldName);
59
        $eventDispatcher = $this->container->get(EventDispatcherInterface::class);
60
61
        $fieldInfo = new GraphQLFieldInfo($context->getDefinition(), $fieldDefinition, $info);
62
        $event = new GraphQLFieldEvent(
63
            $fieldInfo,
64
            $root,
65
            $args,
66
            $context
67
        );
68
        $eventDispatcher->dispatch(GraphQLEvents::PRE_READ_FIELD, $event);
69
70
        if ($event->isPropagationStopped() || $event->getValue()) {
71
            $eventDispatcher->dispatch(GraphQLEvents::POST_READ_FIELD, $event);
72
73
            return $event->getValue();
74
        }
75
76
        //when use external resolver or use a object method with arguments
77
        if (($resolver = $fieldDefinition->getResolver()) || $fieldDefinition->getArguments()) {
78
            $queryDefinition = new QueryDefinition();
79
            $queryDefinition->setName($fieldDefinition->getName());
80
            $queryDefinition->setType($fieldDefinition->getType());
81
            $queryDefinition->setNode($fieldDefinition->getNode());
82
            $queryDefinition->setArguments($fieldDefinition->getArguments());
83
            $queryDefinition->setList($fieldDefinition->isList());
84
            $queryDefinition->setMetas($fieldDefinition->getMetas());
85
86
            if ($resolver) {
87
                $queryDefinition->setResolver($resolver);
88
            } elseif ($fieldDefinition->getOriginType() === \ReflectionMethod::class) {
89
                $queryDefinition->setResolver($fieldDefinition->getOriginName());
90
            }
91
92
            $resolver = new ResolverExecutor($this->container, $context->getQueryContext()->getEndpoint(), $queryDefinition);
93
            $value = $resolver($root, $args, $context, $info);
94
        } else {
95
            $accessor = new PropertyAccessor(true);
96
            $originName = $fieldDefinition->getOriginName() ?: $fieldDefinition->getName();
97
            $value = $accessor->getValue($root, $originName);
98
        }
99
100
        if (null !== $value && Types::ID === $fieldDefinition->getType() && $root instanceof NodeInterface) {
101
            //ID are formed with base64 representation of the Types and real database ID
102
            //in order to create a unique and global identifier for each resource
103
            //@see https://facebook.github.io/relay/docs/graphql-object-identification.html
104
            $value = IDEncoder::encode($root);
105
        }
106
107
        if ($value instanceof Collection) {
108
            $value = $value->toArray();
109
        }
110
111
        $event->setValue($value);
112
        $eventDispatcher->dispatch(GraphQLEvents::POST_READ_FIELD, $event);
113
114
        return $event->getValue();
115
    }
116
}
117