Failed Conditions
Pull Request — master (#62)
by Adrien
06:30 queued 04:20
created

DefaultFieldResolver::__invoke()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
dl 0
loc 13
rs 10
c 1
b 0
f 0
ccs 8
cts 8
cp 1
cc 4
nc 6
nop 4
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Doctrine;
6
7
use Closure;
8
use GraphQL\Doctrine\Definition\EntityID;
1 ignored issue
show
Bug introduced by
The type GraphQL\Doctrine\Definition\EntityID was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use GraphQL\Type\Definition\ResolveInfo;
10
use ReflectionClass;
11
use ReflectionMethod;
12
13
/**
14
 * A field resolver that will allow access to public properties and getter.
15
 * Arguments, if any, will be forwarded as is to the method.
16
 */
17
final class DefaultFieldResolver
18
{
19
    /**
20
     * @param mixed $source
21
     * @param mixed[] $args
22
     * @param mixed $context
23
     *
24
     * @return null|mixed
25
     */
26 14
    public function __invoke($source, array $args, $context, ResolveInfo $info)
27
    {
28
        /** @var string $fieldName */
29 14
        $fieldName = $info->fieldName;
30 14
        $property = null;
31
32 14
        if (is_object($source)) {
33 13
            $property = $this->resolveObject($source, $args, $fieldName);
34 1
        } elseif (is_array($source)) {
35 1
            $property = $this->resolveArray($source, $fieldName);
36
        }
37
38 14
        return $property instanceof Closure ? $property($source, $args, $context) : $property;
39
    }
40
41
    /**
42
     * Resolve for an object.
43
     *
44
     * @return mixed
45
     */
46 13
    private function resolveObject(object $source, array $args, string $fieldName)
47
    {
48 13
        $getter = $this->getGetter($source, $fieldName);
49 13
        if ($getter) {
50 6
            $args = $this->orderArguments($getter, $args);
51
52 6
            return $getter->invoke($source, ...$args);
53
        }
54
55 7
        if (isset($source->{$fieldName})) {
56 1
            return $source->{$fieldName};
57
        }
58
59 6
        return null;
60
    }
61
62
    /**
63
     * Resolve for an array.
64
     *
65
     * @return mixed
66
     */
67 1
    private function resolveArray(array $source, string $fieldName)
68
    {
69 1
        return $source[$fieldName] ?? null;
70
    }
71
72
    /**
73
     * Return the getter/isser method if any valid one exists.
74
     */
75 13
    private function getGetter(object $source, string $name): ?ReflectionMethod
76
    {
77 13
        if (!preg_match('~^(is|has)[A-Z]~', $name)) {
78 11
            $name = 'get' . ucfirst($name);
79
        }
80
81 13
        $class = new ReflectionClass($source);
82 13
        if ($class->hasMethod($name)) {
83 8
            $method = $class->getMethod($name);
84 8
            if ($method->getModifiers() & ReflectionMethod::IS_PUBLIC) {
85 6
                return $method;
86
            }
87
        }
88
89 7
        return null;
90
    }
91
92
    /**
93
     * Re-order associative args to ordered args.
94
     */
95 6
    private function orderArguments(ReflectionMethod $method, array $args): array
96
    {
97 6
        $result = [];
98 6
        if (!$args) {
99 4
            return $result;
100
        }
101
102 2
        foreach ($method->getParameters() as $param) {
103 2
            if (array_key_exists($param->getName(), $args)) {
104 2
                $arg = $args[$param->getName()];
105
106
                // Fetch entity from DB
107 2
                if ($arg instanceof EntityID) {
108 1
                    $arg = $arg->getEntity();
109
                }
110
111 2
                $result[] = $arg;
112
            }
113
        }
114
115 2
        return $result;
116
    }
117
}
118