Passed
Push — master ( 7ab89a...b0680f )
by Adrien
01:53
created

InputFieldsConfigurationFactory   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
dl 0
loc 121
ccs 44
cts 44
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A convertTypeDeclarationsToInstances() 0 3 1
A getMethodPattern() 0 3 1
A methodToConfiguration() 0 18 3
A completeField() 0 14 3
A completeFieldType() 0 20 4
B completeFieldDefaultValue() 0 10 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Doctrine\Factory;
6
7
use GraphQL\Doctrine\Annotation\Input;
8
use GraphQL\Doctrine\DocBlockReader;
9
use GraphQL\Type\Definition\Type;
10
use ReflectionMethod;
11
use ReflectionParameter;
12
13
/**
14
 * A factory to create a configuration for all setters of an entity
15
 */
16
class InputFieldsConfigurationFactory extends AbstractFieldsConfigurationFactory
17
{
18 5
    protected function getMethodPattern(): string
19
    {
20 5
        return '~^set[A-Z]~';
21
    }
22
23
    /**
24
     * Get the entire configuration for a method
25
     *
26
     * @param ReflectionMethod $method
27
     *
28
     * @return null|array
29
     */
30 5
    protected function methodToConfiguration(ReflectionMethod $method): ?array
31
    {
32
        // Silently ignore setter with anything than exactly 1 parameter
33 5
        $params = $method->getParameters();
34 5
        if (count($params) !== 1) {
35 2
            return null;
36
        }
37 5
        $param = reset($params);
38
39
        // Get a field from annotation, or an empty one
40 5
        $field = $this->getAnnotationReader()->getMethodAnnotation($method, Input::class) ?? new Input();
41
42 5
        if (!$field->getTypeInstance()) {
43 5
            $this->convertTypeDeclarationsToInstances($method, $field);
44 5
            $this->completeField($field, $method, $param);
45
        }
46
47 4
        return $field->toArray();
48
    }
49
50
    /**
51
     * All its types will be converted from string to real instance of Type
52
     *
53
     * @param ReflectionMethod $method
54
     * @param Input $field
55
     */
56 5
    private function convertTypeDeclarationsToInstances(ReflectionMethod $method, Input $field): void
57
    {
58 5
        $field->setTypeInstance($this->getTypeFromPhpDeclaration($method, $field->getType()));
59 5
    }
60
61
    /**
62
     * Complete field with info from doc blocks and type hints
63
     *
64
     * @param Input $field
65
     * @param ReflectionMethod $method
66
     * @param ReflectionParameter $param
67
     *
68
     * @throws \GraphQL\Doctrine\Exception
69
     */
70 5
    private function completeField(Input $field, ReflectionMethod $method, ReflectionParameter $param): void
71
    {
72 5
        $fieldName = lcfirst(preg_replace('~^set~', '', $method->getName()));
73 5
        if (!$field->getName()) {
74 5
            $field->setName($fieldName);
75
        }
76
77 5
        $docBlock = new DocBlockReader($method);
78 5
        if (!$field->getDescription()) {
79 5
            $field->setDescription($docBlock->getMethodDescription());
80
        }
81
82 5
        $this->completeFieldDefaultValue($field, $param, $fieldName);
83 5
        $this->completeFieldType($field, $method, $param, $docBlock);
84 4
    }
85
86
    /**
87
     * Complete field default value from argument and property
88
     *
89
     * @param Input $field
90
     * @param ReflectionParameter $param
91
     * @param string $fieldName
92
     */
93 5
    private function completeFieldDefaultValue(Input $field, ReflectionParameter $param, string $fieldName): void
94
    {
95 5
        if (!$field->hasDefaultValue() && $param->isDefaultValueAvailable()) {
96 4
            $field->setDefaultValue($param->getDefaultValue());
97
        }
98
99 5
        if (!$field->hasDefaultValue()) {
100 5
            $defaultValue = $this->getPropertyDefaultValue($fieldName);
101 5
            if ($defaultValue !== null) {
102 4
                $field->setDefaultValue($defaultValue);
103
            }
104
        }
105 5
    }
106
107
    /**
108
     * Complete field type  from doc blocks and type hints
109
     *
110
     * @param Input $field
111
     * @param ReflectionMethod $method
112
     * @param ReflectionParameter $param
113
     * @param DocBlockReader $docBlock
114
     *
115
     * @throws \GraphQL\Doctrine\Exception
116
     */
117 5
    private function completeFieldType(Input $field, ReflectionMethod $method, ReflectionParameter $param, DocBlockReader $docBlock): void
118
    {
119
        // If still no type, look for docblock
120 5
        if (!$field->getTypeInstance()) {
121 5
            $typeDeclaration = $docBlock->getParameterType($param);
122 5
            $this->throwIfArray($param, $typeDeclaration);
123 5
            $field->setTypeInstance($this->getTypeFromPhpDeclaration($method, $typeDeclaration, true));
124
        }
125
126
        // If still no type, look for type hint
127 5
        $type = $param->getType();
128 5
        if (!$field->getTypeInstance() && $type) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $field->getTypeInstance() targeting GraphQL\Doctrine\Annotat...tion::getTypeInstance() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
129 4
            $this->throwIfArray($param, (string) $type);
130 4
            $field->setTypeInstance($this->reflectionTypeToType($type, true));
131
        }
132
133 5
        $this->nonNullIfHasDefault($field);
134
135
        // If still no type, cannot continue
136 5
        $this->throwIfNotInputType($param, $field);
137 4
    }
138
}
139