Issues (590)

src/ServiceLocator.php (4 issues)

1
<?php
2
3
namespace Bdf\Prime;
4
5
use Bdf\Prime\Connection\ConnectionInterface;
6
use Bdf\Prime\Entity\Hydrator\HydratorInterface;
7
use Bdf\Prime\Entity\Hydrator\HydratorRegistry;
8
use Bdf\Prime\Entity\Instantiator\InstantiatorInterface;
9
use Bdf\Prime\Entity\Instantiator\RegistryInstantiator;
10
use Bdf\Prime\Mapper\MapperFactory;
11
use Bdf\Prime\Repository\EntityRepository;
12
use Bdf\Prime\Repository\RepositoryInterface;
13
use Bdf\Serializer\SerializerInterface;
14
use Psr\Container\ContainerInterface;
15
16
/**
17
 * ServiceLocator
18
 */
19
class ServiceLocator
20
{
21
    /**
22
     * @var ConnectionManager
23
     */
24
    private $connectionManager;
25
26
    /**
27
     * @var class-string-map<T, RepositoryInterface<T>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string-map<T, RepositoryInterface<T>> at position 0 could not be parsed: Unknown type name 'class-string-map' at position 0 in class-string-map<T, RepositoryInterface<T>>.
Loading history...
28
     */
29
    private $repositories = [];
30
31
    /**
32
     * @var MapperFactory
33
     */
34
    private $mapperFactory;
35
36
    /**
37
     * @var SerializerInterface
38
     */
39
    private $serializer;
40
41
    /**
42
     * @var \Closure
43
     */
44
    private $serializerResolver;
45
46
    /**
47
     * @var HydratorRegistry
48
     */
49
    private $hydrators;
50
51
    /**
52
     * @var InstantiatorInterface
53
     */
54
    private $instantiator;
55
56
    /**
57
     * DI container
58
     *
59
     * @var ContainerInterface
60
     */
61
    private $di;
62
63
    /**
64
     * SericeLocator constructor.
65
     *
66
     * @param ConnectionManager|null $connectionManager
67
     * @param MapperFactory|null $mapperFactory
68
     * @param InstantiatorInterface|null $instantiator
69
     */
70 391
    public function __construct(ConnectionManager $connectionManager = null, MapperFactory $mapperFactory = null, InstantiatorInterface $instantiator = null)
71
    {
72 391
        $this->connectionManager = $connectionManager ?: new ConnectionManager();
73 391
        $this->mapperFactory = $mapperFactory ?: new MapperFactory();
74 391
        $this->instantiator = $instantiator ?: new RegistryInstantiator();
75 391
        $this->hydrators = new HydratorRegistry();
76
    }
77
78
    /**
79
     * Returns connection manager
80
     *
81
     * @return ConnectionManager
82
     */
83 1446
    public function connections()
84
    {
85 1446
        return $this->connectionManager;
86
    }
87
88
    /**
89
     * Returns connection manager
90
     *
91
     * @return MapperFactory
92
     */
93 263
    public function mappers()
94
    {
95 263
        return $this->mapperFactory;
96
    }
97
98
    /**
99
     * Get a db connection
100
     *
101
     * @param string $name
102
     *
103
     * @return ConnectionInterface
104
     */
105 1259
    public function connection($name = null)
106
    {
107 1259
        return $this->connectionManager->getConnection($name);
108
    }
109
110
    /**
111
     * Register a repository
112
     *
113
     * @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...
114
     * @param RepositoryInterface<E> $repository
115
     *
116
     * @template E as object
117
     *
118
     * @return void
119
     */
120 3
    public function registerRepository($entityClass, RepositoryInterface $repository): void
121
    {
122
        // https://github.com/vimeo/psalm/issues/4460
123
        /** @psalm-suppress InvalidPropertyAssignmentValue */
124 3
        $this->repositories[$entityClass] = $repository;
125
    }
126
127
    /**
128
     * Unregister a repository
129
     *
130
     * @param string $entityClass
131
     *
132
     * @return void
133
     */
134 1
    public function unregisterRepository($entityClass): void
135
    {
136 1
        if (isset($this->repositories[$entityClass]) && $this->repositories[$entityClass] instanceof EntityRepository) {
137
            $this->repositories[$entityClass]->destroy();
138
        }
139
140 1
        unset($this->repositories[$entityClass]);
141
    }
142
143
    /**
144
     * Get mapper for specified entity
145
     *
146
     * @param class-string<T>|T $entityClass Name of Entity object to load mapper for
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T>|T at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>|T.
Loading history...
147
     *
148
     * @return RepositoryInterface<T>|null
149
     * @template T as object
150
     *
151
     * @psalm-ignore-nullable-return
152
     */
153 1245
    public function repository($entityClass): ?RepositoryInterface
154
    {
155 1245
        if (is_object($entityClass)) {
156 585
            $entityClass = get_class($entityClass);
157
        }
158
159 1245
        if (!isset($this->repositories[$entityClass])) {
160 414
            $mapper = $this->mapperFactory->build($this, $entityClass);
161
162 414
            if ($mapper === null) {
163 7
                return null;
164
            }
165
166 407
            $this->repositories[$entityClass] = $mapper->repository();
167
        }
168
169 1242
        return $this->repositories[$entityClass];
170
    }
171
172
    /**
173
     * Get repository names
174
     *
175
     * @return array
176
     */
177 3
    public function repositoryNames()
178
    {
179 3
        return array_keys($this->repositories);
180
    }
181
182
    /**
183
     * Set the serializer
184
     *
185
     * @param \Closure|SerializerInterface $serializer
186
     *
187
     * @return $this
188
     */
189 392
    public function setSerializer($serializer)
190
    {
191 392
        if ($serializer instanceof \Closure) {
192 1
            $this->serializerResolver = $serializer;
193 391
        } elseif ($serializer instanceof SerializerInterface) {
0 ignored issues
show
$serializer is always a sub-type of Bdf\Serializer\SerializerInterface.
Loading history...
194 391
            $this->serializer = $serializer;
195
        }
196
197 392
        return $this;
198
    }
199
200
    /**
201
     * Get the serializer
202
     *
203
     * @return SerializerInterface
204
     */
205 24
    public function serializer()
206
    {
207 24
        if ($this->serializerResolver !== null) {
208 1
            $resolver = $this->serializerResolver;
209 1
            $this->serializer = $resolver();
210 1
            $this->serializerResolver = null;
211
        }
212
213 24
        return $this->serializer;
214
    }
215
216
    /**
217
     * Get the entity hydrators registry
218
     *
219
     * @return HydratorRegistry
220
     */
221 3
    public function hydrators()
222
    {
223 3
        return $this->hydrators;
224
    }
225
226
    /**
227
     * Get the entity hydrator
228
     *
229
     * @param string|object $entity The entity class or object
230
     *
231
     * @return HydratorInterface
232
     */
233 872
    public function hydrator($entity)
234
    {
235 872
        if (is_object($entity)) {
236 742
            $entity = get_class($entity);
237
        }
238
239 872
        return $this->hydrators->get($entity);
240
    }
241
242
    /**
243
     * Get the entity instantiator
244
     *
245
     * @return InstantiatorInterface
246
     */
247 793
    public function instantiator()
248
    {
249 793
        return $this->instantiator;
250
    }
251
252
    /**
253
     * DI accessor
254
     *
255
     * @return ContainerInterface
256
     */
257 1
    public function di()
258
    {
259 1
        return $this->di;
260
    }
261
262
    /**
263
     * DI accessor
264
     *
265
     * @param ContainerInterface $di
266
     *
267
     * @return $this
268
     */
269 1
    public function setDI(ContainerInterface $di)
270
    {
271 1
        $this->di = $di;
272
273 1
        return $this;
274
    }
275
276
    /**
277
     * Clear all cache repositories
278
     *
279
     * @return void
280
     */
281 1
    public function clearRepositories(): void
282
    {
283 1
        foreach ($this->repositories as $repository) {
284 1
            if ($repository instanceof EntityRepository) {
285 1
                $repository->destroy();
286
            }
287
        }
288
289 1
        $this->repositories = [];
290
    }
291
}
292