getFieldDescription()   B
last analyzed

Complexity

Conditions 10
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 10

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 11
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 20
ccs 12
cts 12
cp 1
crap 10
rs 7.6666

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
declare(strict_types=1);
4
5
namespace Andi\GraphQL\ObjectFieldResolver\Middleware;
6
7
use Andi\GraphQL\Attribute\ObjectField;
8
use Andi\GraphQL\Common\LazyParserType;
9
use Andi\GraphQL\Common\LazyTypeByReflectionType;
10
use Andi\GraphQL\Exception\CantResolveGraphQLTypeException;
11
use Andi\GraphQL\ObjectFieldResolver\ObjectFieldResolverInterface;
12
use Andi\GraphQL\TypeRegistryInterface;
13
use GraphQL\Type\Definition as Webonyx;
14
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
15
use phpDocumentor\Reflection\DocBlock\Tags\Param;
16
use phpDocumentor\Reflection\DocBlockFactory;
17
use ReflectionProperty;
18
use Spiral\Attributes\ReaderInterface;
19
20
final class ObjectFieldByReflectionPropertyMiddleware implements MiddlewareInterface
21
{
22
    public const PRIORITY = 3072;
23
24 7
    public function __construct(
25
        private readonly ReaderInterface $reader,
26
        private readonly TypeRegistryInterface $typeRegistry,
27
    ) {
28 7
    }
29
30 6
    public function process(mixed $field, ObjectFieldResolverInterface $fieldResolver): Webonyx\FieldDefinition
31
    {
32 6
        if (! $field instanceof ReflectionProperty) {
33 1
            return $fieldResolver->resolve($field);
34
        }
35
36 5
        $attribute = $this->reader->firstPropertyMetadata($field, ObjectField::class);
37
38 5
        $config = [
39 5
            'name' => $this->getName($field, $attribute),
40 5
            'description' => $this->getFieldDescription($field, $attribute),
41 5
            'type' => $this->getFieldType($field, $attribute),
42 5
            'resolve' => $this->getFieldResolver($field),
43 5
            'deprecationReason' => $this->getFieldDeprecationReason($field, $attribute),
44 5
        ];
45
46 4
        return new Webonyx\FieldDefinition($config);
47
    }
48
49 5
    private function getName(ReflectionProperty $property, ?ObjectField $attribute): string
50
    {
51 5
        return $attribute?->name
52 5
            ?? $property->getName();
53
    }
54
55 5
    private function getFieldDescription(ReflectionProperty $property, ?ObjectField $attribute): ?string
56
    {
57 5
        if ($attribute?->description) {
58 1
            return $attribute->description;
59
        }
60
61 4
        if ($property->isPromoted()) {
62 1
            if ($docComment = $property->getDeclaringClass()->getConstructor()->getDocComment()) {
63 1
                $docBlock = DocBlockFactory::createInstance(['psalm-param' => Param::class])->create($docComment);
64 1
                foreach ($docBlock->getTags() as $tag) {
65 1
                    if ($tag instanceof Param && $tag->getVariableName() === $property->getName()) {
66 1
                        return (string) $tag->getDescription() ?: null;
67
                    }
68
                }
69
            }
70 3
        } elseif ($docComment = $property->getDocComment()) {
71 1
            return DocBlockFactory::createInstance()->create($docComment)->getSummary() ?: null;
72
        }
73
74 2
        return null;
75
    }
76
77 5
    private function getFieldType(ReflectionProperty $property, ?ObjectField $attribute): callable
78
    {
79 5
        if ($attribute?->type) {
80 1
            return new LazyParserType($attribute->type, $attribute->mode ?? 0, $this->typeRegistry);
81
        }
82
83 4
        if (! $property->hasType()) {
84 1
            throw new CantResolveGraphQLTypeException(\sprintf(
85 1
                'Can\'t resolve GraphQL type for field "%s"',
86 1
                $property->getName()
87 1
            ));
88
        }
89
90 3
        return new LazyTypeByReflectionType(
91 3
            $property->getType(),
92 3
            $this->typeRegistry,
93 3
            $property->getDeclaringClass()->getName(),
94 3
        );
95
    }
96
97 4
    private function getFieldResolver(ReflectionProperty $property): callable
98
    {
99 4
        return static function ($object) use ($property): mixed {
100 4
            return $property->getValue($object);
101 4
        };
102
    }
103
104 4
    private function getFieldDeprecationReason(ReflectionProperty $property, ?ObjectField $attribute): ?string
105
    {
106 4
        if ($attribute?->deprecationReason) {
107 1
            return $attribute->deprecationReason;
108
        }
109
110 3
        if ($docComment = $property->getDocComment()) {
111 1
            $docBlock = DocBlockFactory::createInstance(['property-deprecated' => Deprecated::class])
112 1
                ->create($docComment);
113 1
            foreach ($docBlock->getTags() as $tag) {
114 1
                if ($tag instanceof Deprecated) {
115 1
                    return (string) $tag->getDescription() ?: null;
116
                }
117
            }
118
        }
119
120 2
        return null;
121
    }
122
}
123