Passed
Pull Request — 2.1 (#64)
by Vincent
11:26 queued 05:25
created

AbstractMapperFactory::getCacheKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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
use function is_subclass_of;
14
use function strtr;
15
16
/**
17
 * Base implementation of MapperFactoryInterface
18
 * Handle mapper resolution and configuration. Mapper instantiation is performed by the abstract method instantiateMapper()
19
 */
20
abstract class AbstractMapperFactory implements MapperFactoryInterface
21
{
22
    private ResolverInterface $nameResolver;
23
    private ?Psr16CacheInterface $metadataCache;
24
    private ?CacheInterface $resultCache;
25
26
    /**
27
     * @param ResolverInterface|null $nameResolver
28
     * @param Psr16CacheInterface|null $metadataCache
29
     * @param CacheInterface|null $resultCache
30
     */
31 404
    public function __construct(ResolverInterface $nameResolver = null, Psr16CacheInterface $metadataCache = null, CacheInterface $resultCache = null)
32
    {
33 404
        $this->nameResolver = $nameResolver ?? new SuffixResolver();
34 404
        $this->metadataCache = $metadataCache;
35 404
        $this->resultCache = $resultCache;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 426
    public function build(ServiceLocator $serviceLocator, string $entityClass): ?Mapper
42
    {
43 426
        return $this->createMapper($serviceLocator, $this->nameResolver->resolve($entityClass), $entityClass);
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     *
49
     * @param ServiceLocator $serviceLocator
50
     * @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...
51
     * @param class-string<E>|null $entityClass
52
     *
53
     * @return Mapper<E>|null
54
     * @template E as object
55
     */
56 457
    public function createMapper(ServiceLocator $serviceLocator, string $mapperClass, ?string $entityClass = null): ?Mapper
57
    {
58 457
        if (!$this->isMapper($mapperClass)) {
59 10
            return null;
60
        }
61
62 447
        if ($entityClass === null) {
63 56
            $entityClass = $this->nameResolver->reverse($mapperClass);
64
        }
65
66 447
        $metadata = null;
67 447
        if ($this->metadataCache !== null) {
68 4
            $cacheKey = $this->getCacheKey($mapperClass);
69 4
            $metadata = $this->metadataCache->get($cacheKey);
70
        }
71
72 447
        $hydrator = $serviceLocator->hydrator($entityClass);
73
74 447
        if (!($hydrator instanceof MapperHydratorInterface)) {
75 445
            $hydrator = new MapperHydrator();
76
        }
77
78
        /** @var Mapper<E> $mapper */
79 447
        $mapper = $this->instantiateMapper($serviceLocator, $mapperClass);
80
81 447
        $mapper->setEntityClass($entityClass);
82 447
        $mapper->setHydrator($hydrator);
83
84 447
        if ($metadata) {
85 2
            $mapper->setMetadata($metadata);
86
        }
87
88 447
        if ($this->resultCache) {
89
            $mapper->setResultCache($this->resultCache);
90
        }
91
92 447
        $mapper->build();
93
94 447
        if ($this->metadataCache !== null && $metadata === null) {
95 2
            $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 447
        if ($mapper instanceof MapperFactoryAwareInterface) {
99 61
            $mapper->setMapperFactory($this);
100
        }
101
102 447
        return $mapper;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 560
    public function isMapper(string $className): bool
109
    {
110 560
        return is_subclass_of($className, Mapper::class);
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 244
    public function isEntity(string $className): bool
117
    {
118 244
        return $this->isMapper($this->nameResolver->resolve($className));
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 6
    final public function setMetadataCache(?Psr16CacheInterface $cache): void
125
    {
126 6
        $this->metadataCache = $cache;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 5
    final public function getMetadataCache(): ?Psr16CacheInterface
133
    {
134 5
        return $this->metadataCache;
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 2
    final public function setResultCache(?CacheInterface $cache): void
141
    {
142 2
        $this->resultCache = $cache;
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 3
    final public function getResultCache(): ?CacheInterface
149
    {
150 3
        return $this->resultCache;
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156 42
    final public function getNameResolver(): ResolverInterface
157
    {
158 42
        return $this->nameResolver;
159
    }
160
161
    /**
162
     * Create the valid cache key from mapperClass
163
     *
164
     * @param string $mapperClass
165
     *
166
     * @return string
167
     */
168 4
    private function getCacheKey($mapperClass)
169
    {
170 4
        return strtr($mapperClass, '\\', '.');
171
    }
172
173
    /**
174
     * Instantiate the given mapper class
175
     *
176
     * @param ServiceLocator $locator
177
     * @param class-string<Mapper> $mapperClass Mapper class name
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...
178
     *
179
     * @return Mapper
180
     */
181
    abstract protected function instantiateMapper(ServiceLocator $locator, string $mapperClass): Mapper;
182
}
183