Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
43.48% covered (danger)
43.48%
10 / 23
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
DataLayerByBoundedContext
43.48% covered (danger)
43.48%
10 / 23
25.00% covered (danger)
25.00%
1 / 4
43.52
0.00% covered (danger)
0.00%
0 / 1
 offsetGet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDefaultDataLayer
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
 findDatalayerClass
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 pickDataLayerFor
55.56% covered (warning)
55.56%
5 / 9
0.00% covered (danger)
0.00%
0 / 1
7.19
1<?php
2namespace Apie\Core\Datalayers\Grouped;
3
4use Apie\Core\Attributes\Datalayer;
5use Apie\Core\BoundedContext\BoundedContextId;
6use Apie\Core\Datalayers\ApieDatalayer;
7use Apie\Core\Entities\EntityInterface;
8use Apie\Core\Exceptions\ObjectIsImmutable;
9use Apie\Core\Lists\ItemHashmap;
10use ReflectionClass;
11
12final class DataLayerByBoundedContext extends ItemHashmap
13{
14    private ApieDataLayer|DataLayerByClass $defaultDataLayer;
15
16    public function offsetGet(mixed $offset): DataLayerByClass
17    {
18        return parent::offsetGet($offset);
19    }
20
21    public function setDefaultDataLayer(ApieDatalayer|DataLayerByClass $defaultDataLayer): self
22    {
23        if (isset($this->defaultDataLayer)) {
24            throw new ObjectIsImmutable($this);
25        }
26        $this->mutable = false;
27        $this->defaultDataLayer = $defaultDataLayer;
28        return $this;
29    }
30
31    private function findDatalayerClass(string $datalayerClass): ApieDatalayer
32    {
33        if (is_a($this->defaultDataLayer, $datalayerClass, true)) {
34            return $this->defaultDataLayer;
35        }
36        foreach ($this as $dataLayerByClass) {
37            foreach ($dataLayerByClass as $dataLayer) {
38                if (is_a($dataLayer, $datalayerClass, true)) {
39                    return $dataLayer;
40                }
41            }
42        }
43        /** @var ApieDatalayer $datalayerInstance */
44        $datalayerInstance = new $datalayerClass();
45        return $datalayerInstance;
46    }
47
48    /**
49     * @param ReflectionClass<EntityInterface> $class
50     */
51    public function pickDataLayerFor(ReflectionClass $class, ?BoundedContextId $boundedContextId): ApieDatalayer
52    {
53        foreach ($class->getAttributes(Datalayer::class) as $attribute) {
54            /** @var Datalayer $datalayerAttribute */
55            $datalayerAttribute = $attribute->newInstance();
56            $datalayerClass = $datalayerAttribute->datalayerClass;
57
58            return $this->findDatalayerClass($datalayerClass);
59        }
60        if ($boundedContextId && isset($this[$boundedContextId->toNative()])) {
61            return $this[$boundedContextId->toNative()]->pickDataLayerFor($class);
62        }
63        if ($this->defaultDataLayer instanceof DataLayerByClass) {
64            return $this->defaultDataLayer->pickDataLayerFor($class);
65        }
66        return $this->defaultDataLayer;
67    }
68}