Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Completed
Pull Request — master (#7)
by Jérémiah
09:02
created

FieldsConfigSolution::filterResultUsingAccess()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 34
ccs 24
cts 24
cp 1
rs 8.439
cc 6
eloc 21
nc 3
nop 3
crap 6
1
<?php
2
3
/*
4
 * This file is part of the OverblogGraphQLBundle package.
5
 *
6
 * (c) Overblog <http://github.com/overblog/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Overblog\GraphQLBundle\Resolver\Config;
13
14
use Overblog\GraphQLBundle\Definition\Builder\MappingInterface;
15
use Overblog\GraphQLBundle\Error\UserError;
16
use Overblog\GraphQLBundle\Relay\Connection\Output\Connection;
17
use Overblog\GraphQLBundle\Relay\Connection\Output\Edge;
18
use Overblog\GraphQLBundle\Resolver\ResolverInterface;
19
20
class FieldsConfigSolution extends AbstractConfigSolution implements UniqueConfigSolutionInterface
21
{
22
    /**
23
     * @var TypeConfigSolution
24
     */
25
    private $typeConfigSolution;
26
27
    /**
28
     * @var ResolveCallbackConfigSolution
29
     */
30
    private $resolveCallbackConfigSolution;
31
32 31
    public function __construct(
33
        TypeConfigSolution $typeConfigSolution,
34
        ResolveCallbackConfigSolution $resolveCallbackConfigSolution
35
    ) {
36 31
        $this->typeConfigSolution = $typeConfigSolution;
37 31
        $this->resolveCallbackConfigSolution = $resolveCallbackConfigSolution;
38 31
    }
39
40 26
    public function solve($values, $config = null)
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
41
    {
42
        // builder must be last
43 26
        $fieldsTreated = ['type', 'args', 'argsBuilder', 'deprecationReason', 'builder'];
44
45 26
        foreach ($values as $field => &$options) {
46 26
            foreach ($fieldsTreated as $fieldTreated) {
47 26
                if (isset($options[$fieldTreated])) {
48 26
                    $method = 'solve'.ucfirst($fieldTreated);
49 26
                    $options = $this->$method($options, $field);
50 26
                }
51 26
            }
52
53 26
            $options = $this->resolveResolveAndAccessIfNeeded($options);
54 26
        }
55
56 26
        return $values;
57
    }
58
59 19
    private function solveBuilder($options, $field)
60
    {
61 19
        $builderConfig = isset($options['builderConfig']) ? $options['builderConfig'] : [];
62
63 19
        $access = isset($options['access']) ? $options['access'] : null;
64 19
        $options = $this->builderToMappingDefinition($options['builder'], $builderConfig, $this->fieldResolver, $field);
65 19
        $options['access'] = $access;
66 19
        $options = $this->resolveResolveAndAccessIfNeeded($options);
67
68 19
        unset($options['builderConfig'], $options['builder']);
69
70 19
        return $options;
71
    }
72
73 26
    private function solveType($options)
74
    {
75 26
        $options['type'] = $this->typeConfigSolution->solveTypeCallback($options['type']);
76
77 26
        return $options;
78
    }
79
80
    private function solveArgs($options)
81
    {
82
        foreach ($options['args'] as &$argsOptions) {
83
            $argsOptions['type'] = $this->typeConfigSolution->solveTypeCallback($argsOptions['type']);
84
            if (isset($argsOptions['defaultValue'])) {
85
                $argsOptions['defaultValue'] = $this->solveUsingExpressionLanguageIfNeeded($argsOptions['defaultValue']);
86
            }
87
        }
88
89
        return $options;
90
    }
91
92 7
    private function solveArgsBuilder($options)
93
    {
94 7
        $argsBuilderConfig = isset($options['argsBuilder']['config']) ? $options['argsBuilder']['config'] : [];
95
96 7
        $options['args'] = array_merge(
97 7
            $this->builderToMappingDefinition($options['argsBuilder']['builder'], $argsBuilderConfig, $this->argResolver),
98 7
            isset($options['args']) ? $options['args'] : []
99 7
        );
100
101 7
        unset($options['argsBuilder']);
102
103 7
        return $options;
104
    }
105
106
    private function solveDeprecationReason($options)
107
    {
108
        $options['deprecationReason'] = $this->solveUsingExpressionLanguageIfNeeded($options['deprecationReason']);
109
110
        return $options;
111
    }
112
113 26
    private function builderToMappingDefinition($rawBuilder, array $rawBuilderConfig, ResolverInterface $builderResolver, $name = null)
114
    {
115
        /** @var MappingInterface $builder */
116 26
        $builder = $builderResolver->resolve($rawBuilder);
117 26
        $builderConfig = [];
118 26
        if (!empty($rawBuilderConfig)) {
119 19
            $builderConfig = $rawBuilderConfig;
120 19
            $builderConfig = $this->configResolver->resolve($builderConfig);
121 19
        }
122
123 26
        if (null !== $name) {
124 19
            $builderConfig['name'] = $name;
125 19
        }
126
127 26
        return $builder->toMappingDefinition($builderConfig);
128
    }
129
130 26
    private function resolveResolveAndAccessIfNeeded(array $options)
131
    {
132 26
        $treatedOptions = $options;
133
134 26
        if (isset($treatedOptions['resolve'])) {
135 26
            $treatedOptions['resolve'] = $this->resolveCallbackConfigSolution->solve($treatedOptions['resolve']);
136 26
        }
137
138 26
        if (isset($treatedOptions['access'])) {
139
            $resolveCallback = $this->configResolver->getDefaultResolveFn();
140
141
            if (isset($treatedOptions['resolve'])) {
142
                $resolveCallback = $treatedOptions['resolve'];
143
            }
144
145
            $treatedOptions['resolve'] = $this->resolveAccessAndWrapResolveCallback($treatedOptions['access'], $resolveCallback);
146
        }
147 26
        unset($treatedOptions['access']);
148
149 26
        return $treatedOptions;
150
    }
151
152 5
    private function resolveAccessAndWrapResolveCallback($expression, callable $resolveCallback = null)
153
    {
154
        return function () use ($expression, $resolveCallback) {
155 5
            $args = func_get_args();
156
157 5
            $result = null !== $resolveCallback  ? call_user_func_array($resolveCallback, $args) : null;
158
159 5
            $values = call_user_func_array([$this, 'solveResolveCallbackArgs'], $args);
160
161 5
            return $this->filterResultUsingAccess($result, $expression, $values);
162 5
        };
163
    }
164
165 5
    private function filterResultUsingAccess($result, $expression, $values)
166
    {
167 5
        $checkAccess = $this->checkAccessCallback($expression, $values);
168
169 5
        switch (true) {
170 5
            case is_array($result) || $result instanceof \ArrayAccess:
171 1
                $result = array_filter(
172 1
                    array_map(
173
                        function ($object) use ($checkAccess) {
174 1
                            return $checkAccess($object) ? $object : null;
175 1
                        },
176
                        $result
177 1
                    )
178 1
                );
179 1
                break;
180
181 4
            case $result instanceof Connection:
182 1
                $result->edges = array_map(
183
                    function (Edge $edge) use ($checkAccess) {
184 1
                        $edge->node = $checkAccess($edge->node) ? $edge->node : null;
185
186 1
                        return $edge;
187 1
                    },
188 1
                    $result->edges
189 1
                );
190 1
                break;
191
192 3
            default:
193 3
                $checkAccess($result, true);
194 1
                break;
195 3
        }
196
197 3
        return $result;
198
    }
199
200
    private function checkAccessCallback($expression, $values)
201
    {
202 5
        return function ($object, $throwException = false) use ($expression, $values) {
203
            try {
204 5
                $access = $this->solveUsingExpressionLanguageIfNeeded(
205 5
                    $expression,
206 5
                    array_merge($values, ['object' => $object])
207 5
                );
208 5
            } catch (\Exception $e) {
209 1
                $access = false;
210
            }
211
212 5
            if ($throwException && !$access) {
213 2
                throw new UserError('Access denied to this field.');
214
            }
215
216 3
            return $access;
217 5
        };
218
    }
219
}
220