Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.17% covered (warning)
79.17%
38 / 48
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
UnionTypeMetadata
79.17% covered (warning)
79.17%
38 / 48
62.50% covered (warning)
62.50%
5 / 8
33.59
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
 toClass
83.33% covered (warning)
83.33%
10 / 12
0.00% covered (danger)
0.00%
0 / 1
5.12
 getTypes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHashmap
57.14% covered (warning)
57.14%
4 / 7
0.00% covered (danger)
0.00%
0 / 1
5.26
 getRequiredFields
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 toScalarType
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 getArrayItemType
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 getValueOptions
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2namespace Apie\Core\Metadata;
3
4use Apie\Core\Context\ApieContext;
5use Apie\Core\Context\MetadataFieldHashmap;
6use Apie\Core\Enums\ScalarType;
7use Apie\Core\Lists\StringList;
8use Apie\Core\Lists\ValueOptionList;
9use Apie\Core\Metadata\Fields\OptionalField;
10use ReflectionClass;
11
12class UnionTypeMetadata implements NullableMetadataInterface
13{
14    /**
15     * @var MetadataInterface[] $metadata
16     */
17    private array $metadata;
18
19    public function __construct(MetadataInterface... $metadata)
20    {
21        $this->metadata = $metadata;
22    }
23
24    public function toClass(): ?ReflectionClass
25    {
26        $first = true;
27        $class = null;
28        foreach ($this->metadata as $metadata) {
29            $current = $metadata->toClass();
30            if (null === $current) {
31                return null;
32            }
33            if ($first) {
34                $class = $metadata->toClass();
35                $first = false;
36            }
37            if ($current->name !== $class->name) {
38                return null;
39            }
40        }
41        return null;
42    }
43
44    /**
45     * @return MetadataInterface[]
46     */
47    public function getTypes(): array
48    {
49        return $this->metadata;
50    }
51
52    public function getHashmap(): MetadataFieldHashmap
53    {
54        $map = [];
55        foreach ($this->metadata as $objectData) {
56            foreach ($objectData->getHashmap() as $key => $value) {
57                if (isset($map[$key])) {
58                    $value = new OptionalField($value, $map[$key]);
59                }
60                $map[$key] = $value;
61            }
62        }
63        return new MetadataFieldHashmap($map);
64    }
65    
66    public function getRequiredFields(): StringList
67    {
68        $requiredFields = [];
69        foreach ($this->metadata as $objectData) {
70            $required = $objectData->getRequiredFields()->toArray();
71            $requiredFields[] = array_combine($required, $required);
72        }
73        return new StringList($requiredFields ? array_intersect_key(...$requiredFields) : []);
74    }
75
76    public function toScalarType(bool $ignoreNull = false): ScalarType
77    {
78        $current = null;
79        foreach ($this->metadata as $objectData) {
80            $type = $objectData->toScalarType($ignoreNull);
81            if ($ignoreNull && $type === ScalarType::NULLVALUE) {
82                continue;
83            }
84            if ($current === null) {
85                $current = $type;
86            } elseif ($type !== $current) {
87                return ScalarType::MIXED;
88            }
89        }
90        return $current ?? ScalarType::MIXED;
91    }
92
93    public function getArrayItemType(): ?MetadataInterface
94    {
95        foreach ($this->metadata as $objectData) {
96            $arrayPrototype = $objectData->getArrayItemType();
97            if (!isset($arrayType) || $arrayType === $arrayPrototype) {
98                $arrayType = $arrayPrototype;
99            }
100        }
101        return $arrayType ?? null;
102    }
103
104    public function getValueOptions(ApieContext $context, bool $runtimeFilter = false): ?ValueOptionList
105    {
106        $result = [];
107        foreach ($this->metadata as $objectData) {
108            $valueOptions = $objectData->getValueOptions($context, $runtimeFilter);
109            if ($valueOptions === null) {
110                return null;
111            }
112            $result = [...$result, ...$valueOptions];
113        }
114        return new ValueOptionList($result);
115    }
116}