getDefaultConnectionName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\DoctrineDbServiceProvider\Registry\Psr;
6
7
use Doctrine\Common\Persistence\ManagerRegistry;
8
use Doctrine\Common\Persistence\ObjectManager;
9
use Doctrine\Common\Persistence\ObjectRepository;
10
use Doctrine\Common\Persistence\Proxy;
11
use Doctrine\DBAL\Connection;
12
use Doctrine\ORM\EntityManagerInterface;
13
use Doctrine\ORM\EntityRepository;
14
use Doctrine\ORM\ORMException;
15
use Psr\Container\ContainerInterface;
16
17
final class DoctrineOrmManagerRegistry implements ManagerRegistry
18
{
19
    /**
20
     * @var ContainerInterface
21
     */
22
    private $container;
23
24
    /**
25
     * @var ContainerInterface
26
     */
27
    private $connections;
28
29
    /**
30
     * @var array<int, string>
31
     */
32
    private $connectionNames;
33
34
    /**
35
     * @var string
36
     */
37
    private $defaultConnectionName;
38
39
    /**
40
     * @var ContainerInterface
41
     */
42
    private $originalEntityManagers;
43
44
    /**
45
     * @var array<string, EntityManagerInterface>
46
     */
47
    private $resetedManagers = [];
48
49
    /**
50
     * @var array<int, string>
51
     */
52
    private $managerNames;
53
54
    /**
55
     * @var string
56
     */
57
    private $defaultManagerName;
58
59
    public function __construct(ContainerInterface $container)
60
    {
61
        $this->container = $container;
62
    }
63
64
    public function getDefaultConnectionName(): string
65
    {
66
        $this->loadConnections();
67
68
        return $this->defaultConnectionName;
69
    }
70
71
    /**
72
     * @param string|null $name
73
     *
74
     * @throws \InvalidArgumentException
75
     */
76
    public function getConnection($name = null): Connection
77
    {
78
        $this->loadConnections();
79
80
        $name = $name ?? $this->getDefaultConnectionName();
81
82
        if (!$this->connections->has($name)) {
83
            throw new \InvalidArgumentException(sprintf('Missing connection with name "%s".', $name));
84
        }
85
86
        return $this->connections->get($name);
87
    }
88
89
    /**
90
     * @return array<string, Connection>
91
     */
92
    public function getConnections(): array
93
    {
94
        $this->loadConnections();
95
96
        $connections = [];
97
        /** @var string $name */
98
        foreach ($this->connectionNames as $name) {
99
            /** @var Connection $connection */
100
            $connection = $this->connections->get($name);
101
            $connections[$name] = $connection;
102
        }
103
104
        return $connections;
105
    }
106
107
    /**
108
     * @return array<string>
109
     */
110
    public function getConnectionNames(): array
111
    {
112
        $this->loadConnections();
113
114
        return $this->connectionNames;
115
    }
116
117
    public function getDefaultManagerName(): string
118
    {
119
        $this->loadManagers();
120
121
        return $this->defaultManagerName;
122
    }
123
124
    /**
125
     * @param string|null $name
126
     *
127
     * @return EntityManagerInterface|ObjectManager
128
     */
129
    public function getManager($name = null): ObjectManager
130
    {
131
        $this->loadManagers();
132
133
        $name = $name ?? $this->getDefaultManagerName();
134
135
        if (!$this->originalEntityManagers->has($name)) {
136
            throw new \InvalidArgumentException(sprintf('Missing manager with name "%s".', $name));
137
        }
138
139
        if (isset($this->resetedManagers[$name])) {
140
            return $this->resetedManagers[$name];
141
        }
142
143
        return $this->originalEntityManagers->get($name);
144
    }
145
146
    /**
147
     * @return array<string, EntityManagerInterface>|array<string, ObjectManager>
148
     */
149
    public function getManagers(): array
150
    {
151
        $this->loadManagers();
152
153
        $entityManagers = [];
154
        /** @var string $name */
155
        foreach ($this->managerNames as $name) {
156
            /* @var EntityManagerInterface $entityManager */
157
            if (isset($this->resetedManagers[$name])) {
158
                $entityManager = $this->resetedManagers[$name];
159
            } else {
160
                $entityManager = $this->originalEntityManagers->get($name);
161
            }
162
163
            $entityManagers[$name] = $entityManager;
164
        }
165
166
        return $entityManagers;
167
    }
168
169
    /**
170
     * @return array<string>
171
     */
172
    public function getManagerNames(): array
173
    {
174
        $this->loadManagers();
175
176
        return $this->managerNames;
177
    }
178
179
    /**
180
     * @param string|null $name
181
     *
182
     * @return EntityManagerInterface|ObjectManager
183
     */
184
    public function resetManager($name = null)
185
    {
186
        $this->loadManagers();
187
188
        $name = $name ?? $this->getDefaultManagerName();
189
190
        if (!$this->originalEntityManagers->has($name)) {
191
            throw new \InvalidArgumentException(sprintf('Missing manager with name "%s".', $name));
192
        }
193
194
        /** @var EntityManagerInterface $originalEntityManager */
195
        $originalEntityManager = $this->originalEntityManagers->get($name);
196
197
        /** @var callable $entityManagerFactory */
198
        $entityManagerFactory = $this->container->get('doctrine.orm.em.factory');
199
200
        /** @var EntityManagerInterface $entityManager */
201
        $entityManager = $entityManagerFactory(
202
            $originalEntityManager->getConnection(),
203
            $originalEntityManager->getConfiguration(),
204
            $originalEntityManager->getEventManager()
205
        );
206
207
        $this->resetedManagers[$name] = $entityManager;
208
209
        return $entityManager;
210
    }
211
212
    /**
213
     * @param string $alias
214
     *
215
     * @throws ORMException
216
     */
217
    public function getAliasNamespace($alias): string
218
    {
219
        foreach ($this->getManagerNames() as $name) {
220
            try {
221
                /** @var EntityManagerInterface $entityManager */
222
                $entityManager = $this->getManager($name);
223
224
                return $entityManager->getConfiguration()->getEntityNamespace($alias);
225
            } catch (ORMException $exception) {
226
                // throw the exception only if no manager can solve it
227
            }
228
        }
229
        throw ORMException::unknownEntityNamespace($alias);
230
    }
231
232
    /**
233
     * @param string      $persistentObject
234
     * @param string|null $persistentManagerName
235
     *
236
     * @return EntityRepository|ObjectRepository
237
     */
238
    public function getRepository($persistentObject, $persistentManagerName = null): ObjectRepository
239
    {
240
        return $this->getManager($persistentManagerName)->getRepository($persistentObject);
241
    }
242
243
    /**
244
     * @param string $class
245
     *
246
     * @return EntityManagerInterface|ObjectManager|null
247
     */
248
    public function getManagerForClass($class)
249
    {
250
        $reflectionClass = new \ReflectionClass($class);
251
        if ($reflectionClass->implementsInterface(Proxy::class)) {
252
            /** @var \ReflectionClass $reflectionParentClass */
253
            $reflectionParentClass = $reflectionClass->getParentClass();
254
            $class = $reflectionParentClass->getName();
255
        }
256
257
        foreach ($this->getManagerNames() as $name) {
258
            $entityManager = $this->getManager($name);
259
            if (!$entityManager->getMetadataFactory()->isTransient($class)) {
260
                return $entityManager;
261
            }
262
        }
263
    }
264
265
    private function loadConnections(): void
266
    {
267
        if (null === $this->connections) {
268
            $this->connections = $this->container->get('doctrine.dbal.dbs');
269
            $this->connectionNames = $this->container->get('doctrine.dbal.dbs.name');
270
            $this->defaultConnectionName = $this->container->get('doctrine.dbal.dbs.default');
271
        }
272
    }
273
274
    private function loadManagers(): void
275
    {
276
        if (null === $this->originalEntityManagers) {
277
            $this->originalEntityManagers = $this->container->get('doctrine.orm.ems');
278
            $this->managerNames = $this->container->get('doctrine.orm.ems.name');
279
            $this->defaultManagerName = $this->container->get('doctrine.orm.ems.default');
280
        }
281
    }
282
}
283