Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
26 / 28
80.00% covered (warning)
80.00%
8 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
RequestAwareInMemoryDatalayer
92.86% covered (success)
92.86%
26 / 28
80.00% covered (warning)
80.00%
8 / 10
16.09
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
 isSupported
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
4.13
 all
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 find
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getMetadata
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 persistNew
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 persistExisting
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getRepository
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
4.03
 removeExisting
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 upsert
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\Common\Wrappers;
3
4use Apie\Common\Interfaces\BoundedContextSelection;
5use Apie\Core\BoundedContext\BoundedContextId;
6use Apie\Core\Datalayers\ApieDatalayerWithFilters;
7use Apie\Core\Datalayers\ApieDatalayerWithSupport;
8use Apie\Core\Datalayers\Concerns\FiltersOnAllFields;
9use Apie\Core\Datalayers\DataLayerMetadata;
10use Apie\Core\Datalayers\InMemory\InMemoryDatalayer;
11use Apie\Core\Datalayers\Lists\EntityListInterface;
12use Apie\Core\Datalayers\Search\LazyLoadedListFilterer;
13use Apie\Core\Entities\EntityInterface;
14use Apie\Core\Identifiers\IdentifierInterface;
15use ReflectionClass;
16
17final class RequestAwareInMemoryDatalayer implements ApieDatalayerWithFilters, ApieDatalayerWithSupport
18{
19    use FiltersOnAllFields;
20
21    /**
22     * @var array<string, InMemoryDatalayer>
23     */
24    private array $createdRepositories = [];
25
26    public function __construct(
27        private readonly BoundedContextSelection $boundedContextSelected,
28        private readonly LazyLoadedListFilterer $filterer
29    ) {
30    }
31
32    public function isSupported(
33        EntityInterface|ReflectionClass|IdentifierInterface $instance,
34        BoundedContextId $boundedContextId
35    ): bool {
36        $className = ($instance instanceof ReflectionClass) ? $instance->name : get_class($instance);
37        if ($instance instanceof IdentifierInterface) {
38            $className = $instance->getReferenceFor()->name;
39        }
40        $boundedContext = $this->boundedContextSelected->getBoundedContextFromClassName($className);
41        return $boundedContext ? $boundedContext->getId()->toNative() === $boundedContextId->toNative() : false;
42    }
43
44    public function all(ReflectionClass $class, ?BoundedContextId $boundedContextId = null): EntityListInterface
45    {
46        return $this->getRepository($class, $boundedContextId)
47            ->all($class, $boundedContextId);
48    }
49
50    public function find(IdentifierInterface $identifier, ?BoundedContextId $boundedContextId = null): EntityInterface
51    {
52        return $this->getRepository($identifier::getReferenceFor(), $boundedContextId)
53            ->find($identifier, $boundedContextId);
54    }
55
56    /**
57     * @template T of EntityInterface
58     * @param IdentifierInterface<T> $identifier
59     */
60    public function getMetadata(
61        IdentifierInterface $identifier,
62        ?BoundedContextId $boundedContextId = null
63    ): DataLayerMetadata {
64        return $this->getRepository($identifier::getReferenceFor(), $boundedContextId)
65            ->getMetadata($identifier, $boundedContextId);
66    }
67
68    /**
69     * @template T of EntityInterface
70     * @param T $entity
71     * @return T
72     */
73    public function persistNew(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): EntityInterface
74    {
75        return $this->getRepository($entity->getId()::getReferenceFor(), $boundedContextId)
76            ->persistNew($entity, $boundedContextId);
77    }
78
79    /**
80     * @template T of EntityInterface
81     * @param T $entity
82     * @return T
83     */
84    public function persistExisting(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): EntityInterface
85    {
86        return $this->getRepository($entity->getId()::getReferenceFor(), $boundedContextId)
87            ->persistExisting($entity, $boundedContextId);
88    }
89
90    /**
91     * @param ReflectionClass<covariant object> $class
92     */
93    private function getRepository(ReflectionClass $class, ?BoundedContextId $boundedContextId = null): InMemoryDatalayer
94    {
95        if ($boundedContextId === null) {
96            $boundedContextId = $this->boundedContextSelected->getBoundedContextFromRequest()?->getId();
97            if (!$boundedContextId) {
98                $boundedContextId = $this->boundedContextSelected->getBoundedContextFromClassName($class->name)?->getId();
99            }
100        }
101        $boundedContextId ??= new BoundedContextId('unknown');
102        if (!isset($this->createdRepositories[$boundedContextId->toNative()])) {
103            $this->createdRepositories[$boundedContextId->toNative()] = new InMemoryDatalayer($boundedContextId, $this->filterer);
104        }
105
106        return $this->createdRepositories[$boundedContextId->toNative()];
107    }
108
109    public function removeExisting(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): void
110    {
111        $this->getRepository($entity->getId()::getReferenceFor(), $boundedContextId)
112            ->removeExisting($entity, $boundedContextId);
113    }
114
115    public function upsert(EntityInterface $entity, ?BoundedContextId $boundedContextId): EntityInterface
116    {
117        return $this->getRepository($entity->getId()::getReferenceFor(), $boundedContextId)
118            ->upsert($entity, $boundedContextId);
119    }
120}