Passed
Pull Request — master (#300)
by Christoffer
02:52
created

ResolverRegistry::getMiddlewareToApply()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Schema\Resolver;
4
5
use Digia\GraphQL\Execution\ResolveInfo;
6
7
class ResolverRegistry implements ResolverRegistryInterface
8
{
9
    /**
10
     * @var ResolverInterface[]
11
     */
12
    protected $resolverMap;
13
14
    /**
15
     * @var ResolverMiddlewareInterface[]|null
16
     */
17
    protected $middleware;
18
19
    /**
20
     * ResolverRegistry constructor.
21
     * @param ResolverInterface[]                $resolvers
22
     * @param ResolverMiddlewareInterface[]|null $middleware
23
     */
24
    public function __construct(array $resolvers = [], ?array $middleware = null)
25
    {
26
        $this->middleware = $middleware;
27
28
        $this->registerResolvers($resolvers);
29
    }
30
31
    /**
32
     * @inheritdoc
33
     */
34
    public function register(string $typeName, ResolverInterface $resolver): void
35
    {
36
        $this->resolverMap[$typeName] = $resolver;
37
    }
38
39
    /**
40
     * @inheritdoc
41
     */
42
    public function getFieldResolver(string $typeName, string $fieldName): ?callable
43
    {
44
        $resolver = $this->getResolver($typeName);
45
46
        $resolver = $resolver instanceof ResolverCollection
47
            ? $resolver->getResolver($fieldName)
48
            : $resolver;
49
50
        $resolveCallback = $resolver instanceof ResolverInterface
51
            ? $resolver->getResolveCallback()
52
            : $resolver;
53
54
        if (null === $resolveCallback) {
55
            return null;
56
        }
57
58
        if (null !== $this->middleware) {
59
            $middleware = $resolver instanceof ResolverInterface
60
                ? $this->getMiddlewareToApply($resolver, $this->middleware)
61
                : $this->middleware;
62
63
            return $this->applyMiddleware($resolveCallback, \array_reverse($middleware));
64
        }
65
66
        return $resolveCallback;
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function getTypeResolver(string $typeName): ?callable
73
    {
74
        $resolver = $this->getResolver($typeName);
75
76
        if ($resolver instanceof ResolverInterface) {
77
            return $resolver->getTypeResolver();
78
        }
79
80
        return null;
81
    }
82
83
    /**
84
     * @inheritdoc
85
     */
86
    public function getResolver(string $typeName): ?ResolverInterface
87
    {
88
        return $this->resolverMap[$typeName] ?? null;
89
    }
90
91
    /**
92
     * @param array $resolvers
93
     */
94
    protected function registerResolvers(array $resolvers): void
95
    {
96
        foreach ($resolvers as $typeName => $resolver) {
97
            if (\is_array($resolver)) {
98
                $resolver = new ResolverCollection($resolver);
99
            }
100
101
            $this->register($typeName, $resolver);
102
        }
103
    }
104
105
    /**
106
     * @param ResolverInterface             $resolver
107
     * @param ResolverMiddlewareInterface[] $middleware
108
     * @return array
109
     */
110
    protected function getMiddlewareToApply(ResolverInterface $resolver, array $middleware): array
111
    {
112
        $resolverMiddleware = $resolver->getMiddleware();
113
114
        if (null === $resolverMiddleware) {
115
            return $middleware;
116
        }
117
118
        return \array_filter($middleware, function ($name) use ($resolverMiddleware) {
119
            return \in_array(\get_class($name), $resolverMiddleware, true);
120
        });
121
    }
122
123
    /**
124
     * @param callable $resolveCallback
125
     * @param array    $middleware
126
     * @return callable
127
     */
128
    protected function applyMiddleware(callable $resolveCallback, array $middleware): callable
129
    {
130
        return \array_reduce(
131
            $middleware,
132
            function (callable $resolveCallback, ResolverMiddlewareInterface $middleware) {
133
                return function ($rootValue, array $arguments, $context = null, ?ResolveInfo $info = null) use (
134
                    $resolveCallback,
135
                    $middleware
136
                ) {
137
                    return $middleware->resolve($resolveCallback, $rootValue, $arguments, $context, $info);
138
                };
139
            },
140
            $resolveCallback
141
        );
142
    }
143
}
144