Issues (169)

src/Common/InputObjectFactory.php (2 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Andi\GraphQL\Common;
6
7
use Andi\GraphQL\Attribute\InputObjectField;
8
use ReflectionClass;
9
use ReflectionMethod;
10
use ReflectionProperty;
11
use Spiral\Core\ResolverInterface;
12
13
final class InputObjectFactory
14
{
15
    use InputObjectFieldNameTrait;
0 ignored issues
show
The trait Andi\GraphQL\Common\InputObjectFieldNameTrait requires the property $name which is not provided by Andi\GraphQL\Common\InputObjectFactory.
Loading history...
16
17
    /**
18
     * @var array<string, ReflectionMethod|ReflectionProperty>
19
     */
20
    private readonly array $map;
21
22 3
    public function __construct(
23
        private readonly ReflectionClass $class,
24
        private readonly ResolverInterface $resolver,
25
    ) {
26 3
        $map = [];
27 3
        foreach ($this->class->getProperties() as $property) {
28 2
            if ($attributes = $property->getAttributes(InputObjectField::class)) {
29 2
                $attribute = $attributes[0]->newInstance();
30
31 2
                $name = $this->getFieldNameByProperty($property, $attribute);
32
33 2
                $map[$name] = $property;
34
            }
35
        }
36
37 3
        foreach ($this->class->getMethods() as $method) {
38 2
            if ($attributes = $method->getAttributes(InputObjectField::class)) {
39 2
                $attribute = $attributes[0]->newInstance();
40
41 2
                $name = $this->getInputObjectFieldName($method, $attribute);
42
43 2
                $map[$name] = $method;
44
            }
45
        }
46
47 3
        $this->map = $map;
0 ignored issues
show
The property map is declared read-only in Andi\GraphQL\Common\InputObjectFactory.
Loading history...
48
    }
49
50
    /**
51
     * @param array<string,mixed> $values
52
     *
53
     * @return object
54
     */
55 2
    public function __invoke(array $values): object
56
    {
57 2
        $instance = $this->class->newInstanceWithoutConstructor();
58
59 2
        foreach ($values as $name => $value) {
60 2
            if (isset($this->map[$name])) {
61 2
                $reflection = $this->map[$name];
62
63 2
                if ($reflection instanceof ReflectionProperty) {
64 2
                    $reflection->setValue($instance, $value);
65
                } else {
66 2
                    $reflection->invokeArgs($instance, $this->resolver->resolveArguments($reflection, [$value]));
67
                }
68
            }
69
        }
70
71 2
        return $instance;
72
    }
73
74 2
    private function getFieldNameByProperty(ReflectionProperty $property, InputObjectField $attribute): string
75
    {
76 2
        return $attribute->name ?? $property->getName();
77
    }
78
}
79