Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.00% covered (warning)
64.00%
16 / 25
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
DiscriminatorMapping
64.00% covered (warning)
64.00%
16 / 25
62.50% covered (warning)
62.50%
5 / 8
25.50
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
 getPropertyName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfigs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfigForClass
66.67% covered (warning)
66.67%
8 / 12
0.00% covered (danger)
0.00%
0 / 1
7.33
 getDiscriminatorForClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDiscriminatorForObject
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getClassNameFromDiscriminator
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 provideSchema
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace Apie\Core\Other;
3
4use Apie\Core\Attributes\SchemaMethod;
5use Apie\Core\Entities\PolymorphicEntityInterface;
6use Apie\Core\Exceptions\DiscriminatorValueException;
7use Apie\Core\Exceptions\InvalidTypeException;
8use ReflectionClass;
9
10#[SchemaMethod('provideSchema')]
11final class DiscriminatorMapping
12{
13    /** @var DiscriminatorConfig[] */
14    private array $configs;
15
16    public function __construct(private string $propertyName, DiscriminatorConfig... $configs)
17    {
18        $this->configs = $configs;
19    }
20
21    public function getPropertyName(): string
22    {
23        return $this->propertyName;
24    }
25
26    /**
27     * @return DiscriminatorConfig[]
28     */
29    public function getConfigs(): array
30    {
31        return $this->configs;
32    }
33
34    /**
35     * @param ReflectionClass<PolymorphicEntityInterface>|PolymorphicEntityInterface $class
36     */
37    public function getConfigForClass(ReflectionClass|PolymorphicEntityInterface $class): DiscriminatorConfig
38    {
39        if ($class instanceof PolymorphicEntityInterface) {
40            $class = new ReflectionClass($class);
41        }
42        $classes = [];
43        foreach ($this->configs as $config) {
44            $refl = new ReflectionClass($config->getClassName());
45            if ($refl->name === $class->name || $class->isSubclassOf($refl)) {
46                return $config;
47            }
48            $classes[] = $config->getClassName();
49        }
50        throw new InvalidTypeException(
51            $class->name,
52            $classes ? implode(', ', $classes) : 'none'
53        );
54    }
55
56    /**
57     * @param ReflectionClass<PolymorphicEntityInterface> $class
58     */
59    public function getDiscriminatorForClass(ReflectionClass $class): string
60    {
61        return $this->getConfigForClass($class)->getDiscriminator();
62    }
63
64    public function getDiscriminatorForObject(object $object): string
65    {
66        return $this->getConfigForClass($object)->getDiscriminator();
67    }
68
69    public function getClassNameFromDiscriminator(string $discriminatorValue): string
70    {
71        foreach ($this->configs as $config) {
72            if ($config->getDiscriminator() === $discriminatorValue) {
73                return $config->getClassName();
74            }
75        }
76        throw new DiscriminatorValueException($discriminatorValue);
77    }
78
79    /**
80     * @return array<string, mixed>
81     */
82    public static function provideSchema(): array
83    {
84        return [
85            'type' => 'object',
86            'additionalProperties' => true,
87        ];
88    }
89}