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
Push — master ( 4a5a36...2a8ecf )
by Jérémiah
39s
created

resolveAccessAndWrapResolveCallback()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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