Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
61.82% covered (warning)
61.82%
34 / 55
36.36% covered (danger)
36.36%
4 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
SetterMethod
61.82% covered (warning)
61.82%
34 / 55
36.36% covered (danger)
36.36%
4 / 11
84.49
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
 getMethod
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 allowsNull
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 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
55.56% covered (warning)
55.56%
5 / 9
0.00% covered (danger)
0.00%
0 / 1
9.16
 markValueAsMissing
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setValue
58.33% covered (warning)
58.33%
7 / 12
0.00% covered (danger)
0.00%
0 / 1
6.81
 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%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getAttributes
76.47% covered (warning)
76.47%
13 / 17
0.00% covered (danger)
0.00%
0 / 1
11.30
1<?php
2namespace Apie\Core\Metadata\Fields;
3
4use Apie\Core\Attributes\ColumnPriority;
5use Apie\Core\Context\ApieContext;
6use Apie\Core\Enums\DoNotChangeUploadedFile;
7use Apie\Core\Metadata\Concerns\UseContextKey;
8use Apie\Core\Metadata\SetterInterface;
9use Apie\Core\Utils\ConverterUtils;
10use Apie\TypeConverter\Exceptions\CanNotConvertObjectException;
11use ReflectionMethod;
12use ReflectionType;
13
14final class SetterMethod implements FieldInterface, SetterInterface
15{
16    use UseContextKey;
17
18    public function __construct(private readonly ReflectionMethod $method)
19    {
20    }
21
22    public function getMethod(): ReflectionMethod
23    {
24        return $this->method;
25    }
26
27    public function allowsNull(): bool
28    {
29        $parameters = $this->method->getParameters();
30        $parameter = array_pop($parameters);
31        $type = $parameter->getType();
32        return $type === null || $type->allowsNull();
33    }
34
35    public function isRequired(): bool
36    {
37        return false;
38    }
39
40    public function isField(): bool
41    {
42        return true;
43    }
44
45    public function appliesToContext(ApieContext $apieContext): bool
46    {
47        if (!$apieContext->appliesToContext($this->method)) {
48            return false;
49        }
50        $parameters = $this->method->getParameters();
51        // last argument is value set, so we skip that one.
52        array_pop($parameters);
53        foreach ($parameters as $parameter) {
54            $contextKey = $this->getContextKey($apieContext, $parameter);
55            if ($contextKey === null || ($parameter->isDefaultValueAvailable() && !$apieContext->hasContext($contextKey))) {
56                return false;
57            }
58        }
59        return true;
60    }
61
62    public function markValueAsMissing(): void
63    {
64    }
65
66    public function setValue(object $object, mixed $value, ApieContext $apieContext): void
67    {
68        if ($value === DoNotChangeUploadedFile::DoNotChange) {
69            return;
70        }
71        $parameters = $this->method->getParameters();
72        // last argument is value set, so we skip that one.
73        array_pop($parameters);
74        $arguments = [];
75        foreach ($parameters as $parameter) {
76            $contextKey = $this->getContextKey($apieContext, $parameter);
77            if ($contextKey === null || !$apieContext->hasContext($contextKey)) {
78                $arguments[] = $parameter->getDefaultValue();
79            } else {
80                $arguments[] = $apieContext->getContext($contextKey);
81            }
82        }
83        $arguments[] = $value;
84
85        $this->method->invokeArgs($object, $arguments);
86    }
87
88    public function getFieldPriority(): ?int
89    {
90        $attributes = $this->method->getAttributes(ColumnPriority::class);
91        if (empty($attributes)) {
92            return null;
93        }
94
95        $attribute = reset($attributes);
96        return $attribute->newInstance()->priority;
97    }
98
99    public function getTypehint(): ?ReflectionType
100    {
101        $parameters = $this->method->getParameters();
102        // last argument is value set, so also the typehint
103        $parameter = array_pop($parameters);
104        return $parameter->getType();
105    }
106
107    public function getAttributes(string $attributeClass, bool $classDocBlock = true, bool $propertyDocblock = true, bool $argumentDocBlock = true): array
108    {
109        $list = [];
110        if ($argumentDocBlock) {
111            $arguments = $this->method->getParameters();
112            $argument = end($arguments);
113            if ($argument) {
114                foreach ($argument->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
115                    $list[] = $attribute->newInstance();
116                }
117            }
118        }
119        if ($propertyDocblock) {
120            foreach ($this->method->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
121                $list[] = $attribute->newInstance();
122            }
123        }
124        try {
125            $class = ConverterUtils::toReflectionClass($this->method);
126        } catch (CanNotConvertObjectException) {
127            $class = null;
128        }
129        if ($class && $classDocBlock) {
130            foreach ($class->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
131                $list[] = $attribute->newInstance();
132            }
133        }
134
135        return $list;
136    }
137}