Completed
Pull Request — master (#50)
by Jonathan
05:13 queued 03:02
created

AbstractManagerRegistry::getDefaultManagerName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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