Completed
Push — master ( 1826e3...724c6f )
by Rafael
07:29
created

TypeUtil::resolveConcreteType()   C

Complexity

Conditions 11
Paths 30

Size

Total Lines 38
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 13.2953

Importance

Changes 0
Metric Value
dl 0
loc 38
ccs 22
cts 30
cp 0.7332
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 20
nc 30
nop 3
crap 13.2953

How to fix   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
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Util;
12
13
use Doctrine\Common\Util\ClassUtils as DoctrineClassUtils;
14
use Doctrine\Common\Util\Inflector;
15
use Symfony\Component\PropertyAccess\PropertyAccessor;
16
use Ynlo\GraphQLBundle\Definition\ClassAwareDefinitionInterface;
17
use Ynlo\GraphQLBundle\Definition\InterfaceDefinition;
18
use Ynlo\GraphQLBundle\Definition\PolymorphicDefinitionInterface;
19
use Ynlo\GraphQLBundle\Definition\Registry\Endpoint;
20
use Ynlo\GraphQLBundle\Type\Types;
21
22
/**
23
 * Util to work with GraphQL types
24
 */
25
final class TypeUtil
26 2
{
27
    /**
28 2
     * Resolve the object type for given object instance
29
     *
30
     * @param Endpoint $endpoint
31
     * @param mixed    $object
32
     *
33
     * @return null|string
34
     */
35
    public static function resolveObjectType(Endpoint $endpoint, $object): ?string
36 1
    {
37
        $types = $endpoint->getTypesForClass(DoctrineClassUtils::getClass($object));
38 1
39
        //if only one type for given object class return the type
40
        if (count($types) === 1) {
41
            return $types[0];
42
        }
43
44
        //in case of multiple types using polymorphic definitions
45
        foreach ($types as $type) {
46 1
            $definition = $endpoint->getType($type);
47
            if ($definition instanceof PolymorphicDefinitionInterface) {
48 1
                return self::resolveConcreteType($endpoint, $definition, $object);
49
            }
50
        }
51
52
        //as fallback use the first type in the list
53
        return $types[0];
54
    }
55
56 4
    /**
57
     * Resolve the object type for given object instance when object use polymorphic definitions
58 4
     *
59 4
     * @param Endpoint                       $endpoint
60
     * @param PolymorphicDefinitionInterface $definition
61
     * @param mixed                          $object
62
     *
63 4
     * @return null|string
64 4
     */
65 1
    public static function resolveConcreteType(Endpoint $endpoint, PolymorphicDefinitionInterface $definition, $object)
66 1
    {
67 4
        //if discriminator map is set is used to get the value type
68 4
        if ($map = $definition->getDiscriminatorMap()) {
69
            //get concrete type based on property
70
            if ($definition->getDiscriminatorProperty()) {
71 4
                $property = $definition->getDiscriminatorProperty();
72 4
                $accessor = new PropertyAccessor();
73 1
                $propValue = $accessor->getValue($object, $property);
74 1
                $resolvedType = $map[$propValue] ?? null;
75 4
            }
76 1
77 1
            //get concrete type based on class
78 4
            if (!$resolvedType) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $resolvedType does not seem to be defined for all execution paths leading up to this point.
Loading history...
79
                $class = DoctrineClassUtils::getClass($object);
80
                $resolvedType = $map[$class] ?? null;
81 4
            }
82 4
        }
83 4
84 1
        //final solution in case of not mapping is guess type based on class
85 1
        if (!$resolvedType && $definition instanceof InterfaceDefinition) {
86 4
            foreach ($definition->getImplementors() as $implementor) {
87
                $implementorDef = $endpoint->getType($implementor);
88
                if ($implementorDef instanceof ClassAwareDefinitionInterface
89 4
                    && $implementorDef->getClass() === DoctrineClassUtils::getClass($object)) {
90 4
                    $resolvedType = $implementorDef->getName();
91 4
                }
92
            }
93
        }
94
95
        if ($endpoint->hasType($resolvedType)) {
96 4
            $resolvedTypeDefinition = $endpoint->getType($resolvedType);
97
            if ($resolvedTypeDefinition instanceof PolymorphicDefinitionInterface) {
98
                $resolvedType = self::resolveConcreteType($endpoint, $resolvedTypeDefinition, $object);
99
            }
100
        }
101
102
        return $resolvedType;
103
    }
104
105
    /**
106
     * @param string $type
107
     *
108
     * @return bool
109
     */
110
    public static function isTypeList($type): bool
111
    {
112
        return (bool) preg_match('/^\[([\\\\\w]*)!?\]!?$/', $type);
113
    }
114
115
    /**
116
     * @param string $type
117
     *
118
     * @return bool
119
     */
120
    public static function isTypeNonNullList($type): bool
121
    {
122
        return (bool) preg_match('/^\[([\\\\\w]*)!\]!?$/', $type);
123
    }
124
125
    /**
126
     * @param string $type
127
     *
128
     * @return bool
129
     */
130
    public static function isTypeNonNull($type): bool
131
    {
132
        return (bool) preg_match('/!$/', $type);
133
    }
134
135
    /**
136
     * @param string $type
137
     *
138
     * @return string
139
     */
140
    public static function normalize($type)
141
    {
142
        if (preg_match('/^\[?([\\\\\w]*)!?\]?!?$/', $type, $matches)) {
143
            $type = $matches[1];
144
        }
145
146
        switch ($type) {
147
            case 'bool':
148
            case 'boolean':
149
                $type = Types::BOOLEAN;
150
                break;
151
            case 'decimal':
152
            case 'float':
153
                $type = Types::FLOAT;
154
                break;
155
            case 'int':
156
            case 'integer':
157
                $type = Types::INT;
158
                break;
159
            case 'string':
160
                $type = Types::STRING;
161
                break;
162
            case 'id':
163
                $type = Types::ID;
164
                break;
165
            case 'datetime':
166
            case 'date_time':
167
            case 'date':
168
                $type = Types::DATETIME;
169
                break;
170
            case 'any':
171
                $type = Types::ANY;
172
                break;
173
            case 'dynamic':
174
            case 'dynamicObject':
175
            case 'dynamic_object':
176
                $type = Types::DYNAMIC_OBJECT;
177
                break;
178
        }
179
180
        return Inflector::classify($type);
181
    }
182
}
183