Issues (590)

src/Mapper/MapperFactory.php (3 issues)

1
<?php
2
3
namespace Bdf\Prime\Mapper;
4
5
use Bdf\Prime\Cache\CacheInterface;
6
use Bdf\Prime\Entity\Hydrator\MapperHydrator;
7
use Bdf\Prime\Entity\Hydrator\MapperHydratorInterface;
8
use Bdf\Prime\Mapper\NameResolver\ResolverInterface;
9
use Bdf\Prime\Mapper\NameResolver\SuffixResolver;
10
use Bdf\Prime\ServiceLocator;
11
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
12
13
/**
14
 * @package Bdf\Prime\Mapper
15
 */
16
class MapperFactory
17
{
18
    /**
19
     * @var ResolverInterface
20
     */
21
    private $nameResolver;
22
23
    /**
24
     * @var Psr16CacheInterface
25
     */
26
    private $metadataCache;
27
28
    /**
29
     * @var CacheInterface
30
     */
31
    private $resultCache;
32
33
    /**
34
     * @param ResolverInterface $nameResolver
35
     * @param Psr16CacheInterface|null $metadataCache
36
     * @param CacheInterface|null $resultCache
37
     */
38 392
    public function __construct(ResolverInterface $nameResolver = null, Psr16CacheInterface $metadataCache = null, CacheInterface $resultCache = null)
39
    {
40 392
        $this->nameResolver = $nameResolver ?: new SuffixResolver();
41 392
        $this->metadataCache = $metadataCache;
42 392
        $this->resultCache = $resultCache;
43
    }
44
45
    /**
46
     * Get associated entity mapper
47
     *
48
     * @param ServiceLocator $serviceLocator
49
     * @param class-string<E> $entityClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<E> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<E>.
Loading history...
50
     *
51
     * @return Mapper<E>|null
52
     * @template E as object
53
     */
54 420
    public function build(ServiceLocator $serviceLocator, $entityClass): ?Mapper
55
    {
56 420
        return $this->createMapper($serviceLocator, $this->nameResolver->resolve($entityClass), $entityClass);
57
    }
58
59
    /**
60
     * Get mapper object
61
     *
62
     * @param ServiceLocator $serviceLocator
63
     * @param class-string<Mapper> $mapperClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Mapper> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Mapper>.
Loading history...
64
     * @param class-string<E>|null $entityClass
65
     *
66
     * @return Mapper<E>|null
67
     * @template E as object
68
     */
69 445
    public function createMapper(ServiceLocator $serviceLocator, $mapperClass, $entityClass = null): ?Mapper
70
    {
71 445
        if (!$this->isMapper($mapperClass)) {
72 8
            return null;
73
        }
74
75 437
        if ($entityClass === null) {
76 52
            $entityClass = $this->nameResolver->reverse($mapperClass);
77
        }
78
79 437
        $metadata = null;
80 437
        if ($this->metadataCache !== null) {
81 2
            $cacheKey = $this->getCacheKey($mapperClass);
82 2
            $metadata = $this->metadataCache->get($cacheKey);
83
        }
84
85 437
        $hydrator = $serviceLocator->hydrator($entityClass);
86
87 437
        if (!($hydrator instanceof MapperHydratorInterface)) {
88 436
            $hydrator = new MapperHydrator();
89
        }
90
91
        /** @var Mapper<E> $mapper */
92 437
        $mapper = new $mapperClass($serviceLocator, $entityClass, $metadata, $hydrator, $this->resultCache);
93
94 437
        if ($this->metadataCache !== null && $metadata === null) {
95 1
            $this->metadataCache->set($cacheKey, $mapper->metadata());
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cacheKey does not seem to be defined for all execution paths leading up to this point.
Loading history...
96
        }
97
98 437
        if ($mapper instanceof MapperFactoryAwareInterface) {
99 61
            $mapper->setMapperFactory($this);
100
        }
101
102 437
        return $mapper;
103
    }
104
105
    /**
106
     * Check if class is a mapper
107
     *
108
     * @param string $className
109
     *
110
     * @return bool
111
     * @psalm-assert-if-true class-string<Mapper> $className
112
     */
113 548
    public function isMapper($className)
114
    {
115 548
        return is_subclass_of($className, Mapper::class);
116
    }
117
118
    /**
119
     * Check if class has a mapper
120
     *
121
     * @param string $className
122
     *
123
     * @return bool
124
     */
125 243
    public function isEntity($className)
126
    {
127 243
        return $this->isMapper($this->nameResolver->resolve($className));
128
    }
129
130
    /**
131
     * Create the valid cache key from mapperClass
132
     *
133
     * @param string $mapperClass
134
     *
135
     * @return string
136
     */
137 2
    private function getCacheKey($mapperClass)
138
    {
139 2
        return str_replace('\\', '.', $mapperClass);
140
    }
141
142
    /**
143
     * Get the mapper name resolver
144
     *
145
     * @return ResolverInterface
146
     */
147 41
    public function getNameResolver()
148
    {
149 41
        return $this->nameResolver;
150
    }
151
152
    /**
153
     * Set meta cache
154
     *
155
     * @param null|Psr16CacheInterface $cache
156
     *
157
     * @return void
158
     */
159 3
    public function setMetadataCache(?Psr16CacheInterface $cache): void
160
    {
161 3
        $this->metadataCache = $cache;
162
    }
163
164
    /**
165
     * Get meta cache
166
     *
167
     * @return Psr16CacheInterface
168
     */
169 4
    public function getMetadataCache(): ?Psr16CacheInterface
170
    {
171 4
        return $this->metadataCache;
172
    }
173
174
    /**
175
     * Set the result cache
176
     *
177
     * @param null|CacheInterface $cache
178
     *
179
     * @return void
180
     */
181 2
    public function setResultCache(?CacheInterface $cache): void
182
    {
183 2
        $this->resultCache = $cache;
184
    }
185
186
    /**
187
     * Get the resul cache
188
     *
189
     * @return CacheInterface
190
     */
191 3
    public function getResultCache(): ?CacheInterface
192
    {
193 3
        return $this->resultCache;
194
    }
195
}
196