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

Test Setup Failed
Pull Request — 0.9 (#389)
by Jérémiah
23:29
created

AccessResolver::processFilter()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 19
cts 19
cp 1
rs 8.5546
c 0
b 0
f 0
cc 7
nc 4
nop 3
crap 7
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;
13
14
use GraphQL\Executor\Promise\Adapter\SyncPromise;
15
use GraphQL\Executor\Promise\Promise;
16
use GraphQL\Executor\Promise\PromiseAdapter;
17
use GraphQL\Type\Definition\ListOfType;
18
use GraphQL\Type\Definition\ResolveInfo;
19
use Overblog\GraphQLBundle\Error\UserError;
20
use Overblog\GraphQLBundle\Error\UserWarning;
21
use Overblog\GraphQLBundle\Relay\Connection\Output\Connection;
22
use Overblog\GraphQLBundle\Relay\Connection\Output\Edge;
23
24
class AccessResolver
25
{
26
    /** @var PromiseAdapter */
27 9
    private $promiseAdapter;
28
29 9
    public function __construct(PromiseAdapter $promiseAdapter)
30 9
    {
31
        $this->promiseAdapter = $promiseAdapter;
32 9
    }
33
34
    public function resolve(callable $accessChecker, callable $resolveCallback, array $resolveArgs = [], $isMutation = false)
35 9
    {
36 3
        // operation is mutation and is mutation field
37 1
        if ($isMutation) {
38
            if (!$this->hasAccess($accessChecker, null, $resolveArgs)) {
39
                throw new UserError('Access denied to this field.');
40 2
            }
41
42 8
            $result = call_user_func_array($resolveCallback, $resolveArgs);
43
        } else {
44
            $result = $this->filterResultUsingAccess($accessChecker, $resolveCallback, $resolveArgs);
45 7
        }
46
47
        return $result;
48 8
    }
49
50 8
    private function filterResultUsingAccess(callable $accessChecker, callable $resolveCallback, array $resolveArgs = [])
51 8
    {
52 1
        $result = call_user_func_array($resolveCallback, $resolveArgs);
53
        if ($result instanceof Promise) {
54
            $result = $result->adoptedPromise;
55 8
        }
56 1
57 1
        if ($this->promiseAdapter->isThenable($result) || $result instanceof SyncPromise) {
58 1
            return $this->promiseAdapter->then(
59 1
                new Promise($result, $this->promiseAdapter),
60 1
                function ($result) use ($accessChecker, $resolveArgs) {
61
                    return $this->processFilter($result, $accessChecker, $resolveArgs);
62
                }
63
            );
64 8
        }
65
66
        return $this->processFilter($result, $accessChecker, $resolveArgs);
67 8
    }
68
69 8
    private function processFilter($result, $accessChecker, $resolveArgs)
70 3
    {
71 3
        /** @var ResolveInfo $resolveInfo */
72 3
        $resolveInfo = $resolveArgs[3];
73 3
74 3
        if (self::isIterable($result) && $resolveInfo->returnType instanceof ListOfType) {
75
            $result = array_map(
76 5
                function ($object) use ($accessChecker, $resolveArgs) {
77 1
                    return $this->hasAccess($accessChecker, $object, $resolveArgs) ? $object : null;
78 1
                },
79 1
                $result
80
            );
81 1
        } elseif ($result instanceof Connection) {
82 1
            $result->edges = array_map(
83 1
                function (Edge $edge) use ($accessChecker, $resolveArgs) {
84
                    $edge->node = $this->hasAccess($accessChecker, $edge->node, $resolveArgs) ? $edge->node : null;
85 5
86 2
                    return $edge;
87
                },
88
                $result->edges
89 6
            );
90
        } elseif (!$this->hasAccess($accessChecker, $result, $resolveArgs)) {
91
            throw new UserWarning('Access denied to this field.');
92 9
        }
93
94 9
        return $result;
95 9
    }
96
97 9
    private function hasAccess(callable $accessChecker, $object, array $resolveArgs = [])
98
    {
99
        $resolveArgs[] = $object;
100
        $access = (bool) call_user_func_array($accessChecker, $resolveArgs);
101
102
        return $access;
103
    }
104
105
    /**
106
     * @param mixed $data
107
     *
108
     * @return bool
109
     */
110
    private static function isIterable($data)
111
    {
112
        if (function_exists('is_iterable')) {
113
            return \is_iterable($data);
114
        } else {
115
            return \is_array($data) || (\is_object($data) && ($data instanceof \Traversable));
116
        }
117
    }
118
}
119