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
18:05
created

AccessResolver::resolve()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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