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

Passed
Push — master ( e143f5...f9ed24 )
by Jérémiah
11:37 queued 07:50
created

ArgumentsTransformer::populateObject()   B

Complexity

Conditions 11
Paths 21

Size

Total Lines 53
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 11.0324

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 33
c 1
b 1
f 0
dl 0
loc 53
ccs 29
cts 31
cp 0.9355
rs 7.3166
cc 11
nc 21
nop 4
crap 11.0324

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Overblog\GraphQLBundle\Transformer;
6
7
use GraphQL\Type\Definition\EnumType;
8
use GraphQL\Type\Definition\InputObjectType;
9
use GraphQL\Type\Definition\ListOfType;
10
use GraphQL\Type\Definition\NonNull;
11
use GraphQL\Type\Definition\ResolveInfo;
12
use GraphQL\Type\Definition\Type;
13
use Overblog\GraphQLBundle\Error\InvalidArgumentError;
14
use Overblog\GraphQLBundle\Error\InvalidArgumentsError;
15
use Symfony\Component\PropertyAccess\PropertyAccess;
16
use Symfony\Component\PropertyAccess\PropertyAccessor;
17
use Symfony\Component\Validator\ConstraintViolationList;
18
use Symfony\Component\Validator\Validator\ValidatorInterface;
19
use function array_map;
20
use function count;
21
use function is_array;
22
use function is_object;
23
use function sprintf;
24
use function strlen;
25
use function substr;
26
27
class ArgumentsTransformer
28
{
29
    protected PropertyAccessor $accessor;
30
    protected ?ValidatorInterface $validator;
31
    protected array $classesMap;
32
33 10
    public function __construct(ValidatorInterface $validator = null, array $classesMap = [])
34
    {
35 10
        $this->validator = $validator;
36 10
        $this->accessor = PropertyAccess::createPropertyAccessor();
37 10
        $this->classesMap = $classesMap;
38 10
    }
39
40
    /**
41
     * Get the PHP class for a given type.
42
     *
43
     * @return object|false
44
     */
45 10
    private function getTypeClassInstance(string $type)
46
    {
47 10
        $classname = isset($this->classesMap[$type]) ? $this->classesMap[$type]['class'] : false;
48
49 10
        return $classname ? new $classname() : false;
50
    }
51
52
    /**
53
     * Extract given type from Resolve Info.
54
     */
55 10
    private function getType(string $type, ResolveInfo $info): ?Type
56
    {
57 10
        return $info->schema->getType($type);
58
    }
59
60
    /**
61
     * Populate an object based on type with given data.
62
     *
63
     * @param mixed $data
64
     *
65
     * @return mixed
66
     */
67 10
    private function populateObject(Type $type, $data, bool $multiple, ResolveInfo $info)
68
    {
69 10
        if (null === $data) {
70 4
            return null;
71
        }
72
73 10
        if ($type instanceof NonNull) {
74
            $type = $type->getWrappedType();
75
        }
76
77 10
        if ($multiple) {
78 8
            return array_map(function ($data) use ($type, $info) {
79 8
                return $this->populateObject($type, $data, false, $info);
80 8
            }, $data);
81
        }
82
83 10
        if ($type instanceof EnumType) {
84 4
            $instance = $this->getTypeClassInstance($type->name);
85 4
            if ($instance) {
86 2
                $this->accessor->setValue($instance, 'value', $data);
87
88 2
                return $instance;
89
            } else {
90 3
                return $data;
91
            }
92 10
        } elseif ($type instanceof InputObjectType) {
93 10
            $instance = $this->getTypeClassInstance($type->name);
94 10
            if (!$instance) {
95
                return $data;
96
            }
97
98 10
            $fields = $type->getFields();
99
100 10
            foreach ($fields as $name => $field) {
101 10
                $fieldData = $this->accessor->getValue($data, sprintf('[%s]', $name));
102 10
                $fieldType = $field->getType();
103
104 10
                if ($fieldType instanceof NonNull) {
105 4
                    $fieldType = $fieldType->getWrappedType();
106
                }
107
108 10
                if ($fieldType instanceof ListOfType) {
109 4
                    $fieldValue = $this->populateObject($fieldType->getWrappedType(), $fieldData, true, $info);
110
                } else {
111 10
                    $fieldValue = $this->populateObject($fieldType, $fieldData, false, $info);
112
                }
113
114 10
                $this->accessor->setValue($instance, $name, $fieldValue);
115
            }
116
117 10
            return $instance;
118
        } else {
119 10
            return $data;
120
        }
121
    }
122
123
    /**
124
     * Given a GraphQL type and an array of data, populate corresponding object recursively
125
     * using annoted classes.
126
     *
127
     * @param mixed $data
128
     *
129
     * @return mixed
130
     */
131 10
    public function getInstanceAndValidate(string $argType, $data, ResolveInfo $info, string $argName)
132
    {
133 10
        $isRequired = '!' === $argType[strlen($argType) - 1];
134 10
        $isMultiple = '[' === $argType[0];
135 10
        $isStrictMultiple = false;
136 10
        if ($isMultiple) {
137 5
            $isStrictMultiple = '!' === $argType[strpos($argType, ']') - 1];
138
        }
139
140 10
        $endIndex = ($isRequired ? 1 : 0) + ($isMultiple ? 1 : 0) + ($isStrictMultiple ? 1 : 0);
141 10
        $type = substr($argType, $isMultiple ? 1 : 0, $endIndex > 0 ? -$endIndex : strlen($argType));
142
143 10
        $result = $this->populateObject($this->getType($type, $info), $data, $isMultiple, $info);
0 ignored issues
show
Bug introduced by
It seems like $this->getType($type, $info) can also be of type null; however, parameter $type of Overblog\GraphQLBundle\T...ormer::populateObject() does only seem to accept GraphQL\Type\Definition\Type, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

143
        $result = $this->populateObject(/** @scrutinizer ignore-type */ $this->getType($type, $info), $data, $isMultiple, $info);
Loading history...
144
145 10
        if (null !== $this->validator) {
146 10
            $errors = new ConstraintViolationList();
147 10
            if (is_object($result)) {
148 5
                $errors = $this->validator->validate($result);
149
            }
150 10
            if (is_array($result) && $isMultiple) {
151 5
                foreach ($result as $element) {
152 5
                    if (is_object($element)) {
153 5
                        $errors->addAll(
154 5
                            $this->validator->validate($element)
155
                        );
156
                    }
157
                }
158
            }
159
160 10
            if (count($errors) > 0) {
161 2
                throw new InvalidArgumentError($argName, $errors);
162
            }
163
        }
164
165 8
        return $result;
166
    }
167
168
    /**
169
     * Transform a list of arguments into their corresponding php class and validate them.
170
     *
171
     * @param mixed $data
172
     *
173
     * @return array
174
     */
175 4
    public function getArguments(array $mapping, $data, ResolveInfo $info)
176
    {
177 4
        $args = [];
178 4
        $exceptions = [];
179
180 4
        foreach ($mapping as $name => $type) {
181
            try {
182 4
                $value = $this->getInstanceAndValidate($type, $data[$name], $info, $name);
183 2
                $args[] = $value;
184 2
            } catch (InvalidArgumentError $exception) {
185 2
                $exceptions[] = $exception;
186
            }
187
        }
188
189 4
        if (!empty($exceptions)) {
190 2
            throw new InvalidArgumentsError($exceptions);
191
        }
192
193 2
        return $args;
194
    }
195
}
196