AbstractManagerRegistry::getManagerForClass()   A
last analyzed

Complexity

Conditions 6
Paths 14

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6.6829

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 30
ccs 11
cts 15
cp 0.7332
rs 9.2222
cc 6
nc 14
nop 1
crap 6.6829
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Persistence;
6
7
use InvalidArgumentException;
8
use ReflectionClass;
9
use function explode;
10
use function sprintf;
11
use function strpos;
12
13
/**
14
 * Abstract implementation of the ManagerRegistry contract.
15
 */
16
abstract class AbstractManagerRegistry implements ManagerRegistry
17
{
18
    /** @var string */
19
    private $name;
20
21
    /** @var array<string, string> */
22
    private $connections;
23
24
    /** @var array<string, string> */
25
    private $managers;
26
27
    /** @var string */
28
    private $defaultConnection;
29
30
    /** @var string */
31
    private $defaultManager;
32
33
    /** @var string */
34
    private $proxyInterfaceName;
35
36
    /**
37
     * @param array<string, string> $connections
38
     * @param array<string, string> $managers
39
     */
40 9
    public function __construct(
41
        string $name,
42
        array $connections,
43
        array $managers,
44
        string $defaultConnection,
45
        string $defaultManager,
46
        string $proxyInterfaceName
47
    ) {
48 9
        $this->name               = $name;
49 9
        $this->connections        = $connections;
50 9
        $this->managers           = $managers;
51 9
        $this->defaultConnection  = $defaultConnection;
52 9
        $this->defaultManager     = $defaultManager;
53 9
        $this->proxyInterfaceName = $proxyInterfaceName;
54 9
    }
55
56
    /**
57
     * Fetches/creates the given services.
58
     *
59
     * A service in this context is connection or a manager instance.
60
     *
61
     * @param string $name The name of the service.
62
     *
63
     * @return ObjectManager The instance of the given service.
64
     */
65
    abstract protected function getService(string $name);
66
67
    /**
68
     * Resets the given services.
69
     *
70
     * A service in this context is connection or a manager instance.
71
     *
72
     * @param string $name The name of the service.
73
     *
74
     * @return void
75
     */
76
    abstract protected function resetService(string $name);
77
78
    /**
79
     * Gets the name of the registry.
80
     *
81
     * @return string
82
     */
83
    public function getName()
84
    {
85
        return $this->name;
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function getConnection(?string $name = null)
92
    {
93
        if ($name === null) {
94
            $name = $this->defaultConnection;
95
        }
96
97
        if (! isset($this->connections[$name])) {
98
            throw new InvalidArgumentException(
99
                sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name)
100
            );
101
        }
102
103
        return $this->getService($this->connections[$name]);
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function getConnectionNames()
110
    {
111
        return $this->connections;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public function getConnections()
118
    {
119
        $connections = [];
120
        foreach ($this->connections as $name => $id) {
121
            $connections[$name] = $this->getService($id);
122
        }
123
124
        return $connections;
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function getDefaultConnectionName()
131
    {
132
        return $this->defaultConnection;
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function getDefaultManagerName()
139
    {
140
        return $this->defaultManager;
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     *
146
     * @throws InvalidArgumentException
147
     */
148 4
    public function getManager(?string $name = null)
149
    {
150 4
        if ($name === null) {
151 4
            $name = $this->defaultManager;
152
        }
153
154 4
        if (! isset($this->managers[$name])) {
155
            throw new InvalidArgumentException(
156
                sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)
157
            );
158
        }
159
160 4
        return $this->getService($this->managers[$name]);
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166 7
    public function getManagerForClass(string $class)
167
    {
168
        // Check for namespace alias
169 7
        if (strpos($class, ':') !== false) {
170 3
            [$namespaceAlias, $simpleClassName] = explode(':', $class, 2);
171
172 3
            $class = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName;
173
        }
174
175 7
        $proxyClass = new ReflectionClass($class);
176
177 5
        if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
178
            $parentClass = $proxyClass->getParentClass();
179
180
            if ($parentClass === false) {
181
                return null;
182
            }
183
184
            $class = $parentClass->getName();
185
        }
186
187 5
        foreach ($this->managers as $id) {
188 5
            $manager = $this->getService($id);
189
190 5
            if (! $manager->getMetadataFactory()->isTransient($class)) {
191 4
                return $manager;
192
            }
193
        }
194
195 1
        return null;
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function getManagerNames()
202
    {
203
        return $this->managers;
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function getManagers()
210
    {
211
        $managers = [];
212
213
        foreach ($this->managers as $name => $id) {
214
            /** @var ObjectManager $manager */
215
            $manager = $this->getService($id);
216
217
            $managers[$name] = $manager;
218
        }
219
220
        return $managers;
221
    }
222
223
    /**
224
     * {@inheritdoc}
225
     */
226 3
    public function getRepository(
227
        string $persistentObjectName,
228
        ?string $persistentManagerName = null
229
    ) {
230
        return $this
231 3
            ->selectManager($persistentObjectName, $persistentManagerName)
232 3
            ->getRepository($persistentObjectName);
233
    }
234
235
    /**
236
     * {@inheritdoc}
237
     */
238 1
    public function resetManager(?string $name = null)
239
    {
240 1
        if ($name === null) {
241 1
            $name = $this->defaultManager;
242
        }
243
244 1
        if (! isset($this->managers[$name])) {
245
            throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
246
        }
247
248
        // force the creation of a new document manager
249
        // if the current one is closed
250 1
        $this->resetService($this->managers[$name]);
251
252 1
        return $this->getManager($name);
253
    }
254
255 3
    private function selectManager(
256
        string $persistentObjectName,
257
        ?string $persistentManagerName = null
258
    ) : ObjectManager {
259 3
        if ($persistentManagerName !== null) {
260 1
            return $this->getManager($persistentManagerName);
261
        }
262
263 2
        return $this->getManagerForClass($persistentObjectName) ?? $this->getManager();
264
    }
265
}
266