Passed
Push — master ( b455fc...fe3421 )
by Dominik
02:24
created

DoctrineOrmManagerRegistry::validateName()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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