Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
53.85% covered (warning)
53.85%
21 / 39
38.46% covered (danger)
38.46%
5 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
OptionalField
53.85% covered (warning)
53.85%
21 / 39
38.46% covered (danger)
38.46%
5 / 13
132.68
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
 hasDefaultValue
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
4.59
 getDefaultValue
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 allowsNull
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 isRequired
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 isField
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 appliesToContext
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFieldPriority
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setValue
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 markValueAsMissing
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 getValue
40.00% covered (danger)
40.00%
2 / 5
0.00% covered (danger)
0.00%
0 / 1
4.94
 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%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2namespace Apie\Core\Metadata\Fields;
3
4use Apie\Core\Context\ApieContext;
5use Apie\Core\Metadata\GetterInterface;
6use Apie\Core\Metadata\SetterInterface;
7use ReflectionType;
8
9class OptionalField implements FieldWithPossibleDefaultValue, GetterInterface, SetterInterface
10{
11    public function __construct(private FieldInterface $field1, private ?FieldInterface $field2 = null)
12    {
13    }
14
15    public function hasDefaultValue(): bool
16    {
17        if ($this->field1 instanceof FieldWithPossibleDefaultValue && $this->field1->hasDefaultValue()) {
18            return true;
19        }
20
21        return $this->field2 instanceof FieldWithPossibleDefaultValue && $this->field2->hasDefaultValue();
22    }
23
24    public function getDefaultValue(): mixed
25    {
26        if ($this->field1 instanceof FieldWithPossibleDefaultValue && $this->field1->hasDefaultValue()) {
27            return $this->field1->getDefaultValue();
28        }
29        assert($this->field2 instanceof FieldWithPossibleDefaultValue);
30        return $this->field2->getDefaultValue();
31    }
32
33    public function allowsNull(): bool
34    {
35        if ($this->field2 && $this->field2->allowsNull()) {
36            return true;
37        }
38        return $this->field1->allowsNull();
39    }
40
41    public function isRequired(): bool
42    {
43        if ($this->field2 !== null && !$this->field2->isRequired()) {
44            return false;
45        }
46
47        return $this->field1->isRequired();
48    }
49
50    public function isField(): bool
51    {
52        if ($this->field2 !== null && !$this->field2->isField()) {
53            return false;
54        }
55        return $this->field1->isField();
56    }
57
58    public function appliesToContext(ApieContext $apieContext): bool
59    {
60        return $this->field1->appliesToContext($apieContext);
61    }
62
63    public function getFieldPriority(): ?int
64    {
65        if ($this->field2 === null) {
66            return $this->field1->getFieldPriority();
67        }
68        return min($this->field1->getFieldPriority(), $this->field2->getFieldPriority());
69    }
70
71    public function setValue(object $object, mixed $value, ApieContext $apieContext): void
72    {
73        if ($this->field1 instanceof SetterInterface) {
74            $this->field1->setValue($this->field1, $value, $apieContext);
75        }
76        if ($this->field2 instanceof SetterInterface) {
77            $this->field2->setValue($this->field1, $value, $apieContext);
78        }
79    }
80
81    public function markValueAsMissing(): void
82    {
83        if ($this->field1 instanceof SetterInterface) {
84            $this->field1->markValueAsMissing();
85        }
86        if ($this->field2 instanceof SetterInterface) {
87            $this->field2->markValueAsMissing();
88        }
89    }
90
91    public function getValue(object $object, ApieContext $apieContext): mixed
92    {
93        if ($this->field1 instanceof GetterInterface) {
94            return $this->field1->getValue($object, $apieContext);
95        }
96        if ($this->field2 instanceof GetterInterface) {
97            return $this->field2->getValue($object, $apieContext);
98        }
99
100        return null;
101    }
102
103    public function getTypehint(): ?ReflectionType
104    {
105        // TODO: merge with $this->field2
106        return $this->field1->getTypehint();
107    }
108
109    public function getAttributes(string $attributeClass, bool $classDocBlock = true, bool $propertyDocblock = true, bool $argumentDocBlock = true): array
110    {
111        $attributes = $this->field1->getAttributes($attributeClass, $classDocBlock, $propertyDocblock, $argumentDocBlock);
112        if (!empty($attributes)) {
113            return $attributes;
114        }
115        return $this->field2?->getAttributes($attributeClass, $classDocBlock, $propertyDocblock, $argumentDocBlock) ?? [];
116    }
117}