Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.32% covered (warning)
76.32%
29 / 38
70.00% covered (warning)
70.00%
7 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
GetterMethod
76.32% covered (warning)
76.32%
29 / 38
70.00% covered (warning)
70.00%
7 / 10
34.98
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReflectionMethod
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 allowsNull
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 isRequired
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isField
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 appliesToContext
62.50% covered (warning)
62.50%
5 / 8
0.00% covered (danger)
0.00%
0 / 1
7.90
 getValue
42.86% covered (danger)
42.86%
3 / 7
0.00% covered (danger)
0.00%
0 / 1
6.99
 getFieldPriority
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
2.26
 getTypehint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAttributes
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
7
1<?php
2namespace Apie\Core\Metadata\Fields;
3
4use Apie\Core\Attributes\ColumnPriority;
5use Apie\Core\Context\ApieContext;
6use Apie\Core\Metadata\Concerns\UseContextKey;
7use Apie\Core\Metadata\GetterInterface;
8use Apie\Core\Utils\ConverterUtils;
9use Apie\TypeConverter\Exceptions\CanNotConvertObjectException;
10use ReflectionMethod;
11use ReflectionType;
12
13final class GetterMethod implements FieldInterface, GetterInterface
14{
15    use UseContextKey;
16
17    public function __construct(private readonly ReflectionMethod $method)
18    {
19    }
20
21    public function getReflectionMethod(): ReflectionMethod
22    {
23        return $this->method;
24    }
25
26    public function allowsNull(): bool
27    {
28        $type = $this->method->getReturnType();
29        return $type === null || $type->allowsNull();
30    }
31
32    public function isRequired(): bool
33    {
34        return true;
35    }
36
37    public function isField(): bool
38    {
39        return true;
40    }
41
42    public function appliesToContext(ApieContext $apieContext): bool
43    {
44        if (!$apieContext->appliesToContext($this->method)) {
45            return false;
46        }
47        $parameters = $this->method->getParameters();
48        foreach ($parameters as $parameter) {
49            $contextKey = $this->getContextKey($apieContext, $parameter);
50            if ($contextKey === null || ($parameter->isDefaultValueAvailable() && !$apieContext->hasContext($contextKey))) {
51                return false;
52            }
53        }
54        return true;
55    }
56
57    public function getValue(object $object, ApieContext $apieContext): mixed
58    {
59        $arguments = [];
60        foreach ($this->method->getParameters() as $parameter) {
61            $contextKey = $this->getContextKey($apieContext, $parameter);
62            if ($contextKey === null || !$apieContext->hasContext($contextKey)) {
63                $arguments[] = $parameter->getDefaultValue();
64            } else {
65                $arguments[] = $apieContext->getContext($contextKey);
66            }
67        }
68
69        return $this->method->invokeArgs($object, $arguments);
70    }
71
72    public function getFieldPriority(): ?int
73    {
74        $attributes = $this->method->getAttributes(ColumnPriority::class);
75        if (empty($attributes)) {
76            return null;
77        }
78
79        $attribute = reset($attributes);
80        return $attribute->newInstance()->priority;
81    }
82
83    public function getTypehint(): ?ReflectionType
84    {
85        return $this->method->getReturnType();
86    }
87
88    public function getAttributes(string $attributeClass, bool $classDocBlock = true, bool $propertyDocblock = true, bool $argumentDocBlock = true): array
89    {
90        $list = [];
91        if ($propertyDocblock) {
92            foreach ($this->method->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
93                $list[] = $attribute->newInstance();
94            }
95        }
96        try {
97            $class = ConverterUtils::toReflectionClass($this->method);
98        } catch (CanNotConvertObjectException) {
99            return $list;
100        }
101        if ($class && $classDocBlock) {
102            foreach ($class->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
103                $list[] = $attribute->newInstance();
104            }
105        }
106
107        return $list;
108    }
109}