Failed Conditions
Push — types ( 30d5cd...98b391 )
by Jonathan
02:28
created

AbstractManagerRegistry   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 248
Duplicated Lines 0 %

Test Coverage

Coverage 52.7%

Importance

Changes 0
Metric Value
wmc 29
eloc 65
dl 0
loc 248
ccs 39
cts 74
cp 0.527
rs 10
c 0
b 0
f 0

14 Methods

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