Completed
Push — master ( 7e6b75...39b5c8 )
by Julián
02:19
created

MongoDBBuilder::getAnnotationMappingDriver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/*
4
 * doctrine-manager-builder (https://github.com/juliangut/doctrine-manager-builder).
5
 * Doctrine2 managers builder.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/doctrine-manager-builder
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
namespace Jgut\Doctrine\ManagerBuilder;
13
14
use Doctrine\Common\Annotations\AnnotationReader;
15
use Doctrine\Common\Proxy\AbstractProxyFactory;
16
use Doctrine\MongoDB\Connection;
17
use Doctrine\ODM\MongoDB\Configuration;
18
use Doctrine\ODM\MongoDB\DocumentManager;
19
use Doctrine\ODM\MongoDB\DocumentRepository;
20
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
21
use Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver;
22
use Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver;
23
use Doctrine\ODM\MongoDB\Repository\RepositoryFactory;
24
use Doctrine\ODM\MongoDB\Tools\Console\Helper\DocumentManagerHelper;
25
use Symfony\Component\Console\Command\Command;
26
use Symfony\Component\Console\Helper\HelperSet;
27
28
/**
29
 * Doctrine MongoDB Document Manager builder.
30
 */
31
class MongoDBBuilder extends AbstractManagerBuilder
32
{
33
    /**
34
     * Document Manager.
35
     *
36
     * @var DocumentManager
37
     */
38
    protected $manager;
39
40
    /**
41
     * Logger callable.
42
     *
43
     * @var callable
44
     */
45
    protected $loggerCallable;
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    protected function getDefaultOptions()
51
    {
52
        return [
53
            'connection' => [], // Array or \Doctrine\MongoDB\Connection
54
            'proxies_namespace' => 'DoctrineMongoDBODMProxy',
55
            'metadata_cache_namespace' => 'DoctrineMongoDBODMMetadataCache',
56
            'default_repository_class' => DocumentRepository::class,
57
            'hydrators_namespace' => 'DoctrineMongoDBODMHydrator',
58
            'hydrators_auto_generation' => AbstractProxyFactory::AUTOGENERATE_NEVER,
59
            'persistent_collections_namespace' => 'DoctrineMongoDBODMPersistentCollection',
60
            'persistent_collections_auto_generation' => AbstractProxyFactory::AUTOGENERATE_NEVER,
61
        ];
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     *
67
     * @throws \Doctrine\ODM\MongoDB\MongoDBException
68
     * @throws \InvalidArgumentException
69
     * @throws \RuntimeException
70
     * @throws \UnexpectedValueException
71
     *
72
     * @return DocumentManager
73
     */
74
    public function getManager($force = false)
75
    {
76
        if ($force === true) {
77
            $this->wipe();
78
        }
79
80
        if (!$this->manager instanceof DocumentManager) {
81
            $this->manager = $this->buildManager();
82
        }
83
84
        return $this->manager;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    protected function wipe()
91
    {
92
        parent::wipe();
93
94
        $this->manager = null;
95
        $this->loggerCallable = null;
96
    }
97
98
    /**
99
     * Build Doctrine MongoDB Document Manager.
100
     *
101
     * @throws \Doctrine\ODM\MongoDB\MongoDBException
102
     * @throws \InvalidArgumentException
103
     * @throws \RuntimeException
104
     * @throws \UnexpectedValueException
105
     *
106
     * @return DocumentManager
107
     */
108
    protected function buildManager()
109
    {
110
        $config = new Configuration;
111
112
        $this->setUpGeneralConfigurations($config);
113
        $this->setUpSpecificConfigurations($config);
114
115
        $eventManager = $this->getEventManager();
116
        if ($this->getEventSubscribers() !== null) {
117
            /* @var array $eventSubscribers */
118
            $eventSubscribers = $this->getEventSubscribers();
119
120
            foreach ($eventSubscribers as $eventSubscriber) {
121
                $eventManager->addEventSubscriber($eventSubscriber);
122
            }
123
        }
124
125
        return DocumentManager::create($this->getConnection($config), $config, $eventManager);
126
    }
127
128
    /**
129
     * Set up general manager configurations.
130
     *
131
     * @param Configuration $config
132
     */
133
    protected function setUpGeneralConfigurations(Configuration $config)
134
    {
135
        $this->setupAnnotationMetadata();
136
        $config->setMetadataDriverImpl($this->getMetadataMappingDriver());
137
138
        $config->setProxyDir($this->getProxiesPath());
139
        $config->setProxyNamespace($this->getProxiesNamespace());
140
        $config->setAutoGenerateProxyClasses($this->getProxiesAutoGeneration());
141
142
        if ($this->getRepositoryFactory() !== null) {
143
            $config->setRepositoryFactory($this->getRepositoryFactory());
144
        }
145
146
        if ($this->getDefaultRepositoryClass() !== null) {
147
            $config->setDefaultRepositoryClassName($this->getDefaultRepositoryClass());
148
        }
149
150
        $config->setMetadataCacheImpl($this->getMetadataCacheDriver());
151
    }
152
153
    /**
154
     * Set up manager specific configurations.
155
     *
156
     * @param Configuration $config
157
     */
158
    protected function setUpSpecificConfigurations(Configuration $config)
159
    {
160
        $config->setHydratorDir($this->getHydratorsPath());
161
        $config->setHydratorNamespace($this->getHydratorsNamespace());
162
        $config->setAutoGenerateHydratorClasses($this->getHydratorsAutoGeneration());
163
164
        $config->setPersistentCollectionDir($this->getPersistentCollectionPath());
165
        $config->setPersistentCollectionNamespace($this->getPersistentCollectionNamespace());
166
        $config->setAutoGeneratePersistentCollectionClasses($this->getAutoGeneratePersistentCollection());
167
168
        if ($this->getDefaultDatabase() !== null) {
169
            $config->setDefaultDB($this->getDefaultDatabase());
170
        }
171
172
        if ($this->getLoggerCallable() !== null) {
173
            $config->setLoggerCallable($this->getLoggerCallable());
174
        }
175
176
        foreach ($this->getCustomFilters() as $name => $filterClass) {
177
            $config->addFilter($name, $filterClass);
178
        }
179
    }
180
181
    /**
182
     * Create MongoDB Connection.
183
     *
184
     * @param Configuration $config
185
     *
186
     * @throws \InvalidArgumentException
187
     * @throws \RuntimeException
188
     *
189
     * @return Connection
190
     */
191
    protected function getConnection(Configuration $config)
192
    {
193
        $connection = $this->getOption('connection');
194
195
        switch (true) {
196
            case is_array($connection):
197
                $connection = new Connection(
198
                    array_key_exists('server', $connection) ? $connection['server'] : null,
199
                    array_key_exists('options', $connection) ? $connection['options'] : [],
200
                    $config,
201
                    $this->getEventManager()
202
                );
203
                break;
204
205
            case $connection instanceof Connection:
206
                if ($connection->getEventManager() !== $this->getEventManager()) {
207
                    throw new \RuntimeException(
208
                        'Cannot use different EventManager instances for DocumentManager and Connection.'
209
                    );
210
                }
211
                break;
212
213
            default:
214
                throw new \InvalidArgumentException('Invalid argument: ' . $connection);
215
        }
216
217
        return $connection;
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223
    protected function getAnnotationMappingDriver(array $paths)
224
    {
225
        return new AnnotationDriver(new AnnotationReader, $paths);
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231
    protected function getXmlMappingDriver(array $paths, $extension = null)
232
    {
233
        $extension = $extension ?: XmlDriver::DEFAULT_FILE_EXTENSION;
234
235
        return new XmlDriver($paths, $extension);
236
    }
237
238
    /**
239
     * {@inheritdoc}
240
     */
241
    protected function getYamlMappingDriver(array $paths, $extension = null)
242
    {
243
        $extension = $extension ?: YamlDriver::DEFAULT_FILE_EXTENSION;
244
245
        return new YamlDriver($paths, $extension);
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     *
251
     * @throws \InvalidArgumentException
252
     *
253
     * @return RepositoryFactory|null
254
     */
255
    protected function getRepositoryFactory()
256
    {
257
        if (!array_key_exists('repository_factory', $this->options)) {
258
            return;
259
        }
260
261
        $repositoryFactory = $this->options['repository_factory'];
262
263
        if (!$repositoryFactory instanceof RepositoryFactory) {
264
            throw new \InvalidArgumentException(sprintf(
265
                'Invalid factory class "%s". It must be a Doctrine\ODM\MongoDB\Repository\RepositoryFactory.',
266
                get_class($repositoryFactory)
267
            ));
268
        }
269
270
        return $repositoryFactory;
271
    }
272
273
    /**
274
     * Retrieve hydrators path.
275
     *
276
     * @return string
277
     */
278
    protected function getHydratorsPath()
279
    {
280
        return (string) $this->getOption('hydrators_path', sys_get_temp_dir());
281
    }
282
283
    /**
284
     * Retrieve hydrators namespace.
285
     *
286
     * @return null|string
287
     */
288
    protected function getHydratorsNamespace()
289
    {
290
        $proxyNamespace = $this->getOption('hydrators_namespace');
291
292
        return is_string($proxyNamespace) ? $proxyNamespace : null;
293
    }
294
295
    /**
296
     * Retrieve hydrators generation strategy.
297
     *
298
     * @return int
299
     */
300
    protected function getHydratorsAutoGeneration()
301
    {
302
        return (int) $this->getOption('hydrators_auto_generation');
303
    }
304
305
    /**
306
     * Retrieve persistent collections path.
307
     *
308
     * @return string
309
     */
310
    protected function getPersistentCollectionPath()
311
    {
312
        return (string) $this->getOption('persistent_collections_path', sys_get_temp_dir());
313
    }
314
315
    /**
316
     * Retrieve persistent collections namespace.
317
     *
318
     * @return null|string
319
     */
320
    protected function getPersistentCollectionNamespace()
321
    {
322
        $collectionNamespace = $this->getOption('persistent_collections_namespace');
323
324
        return is_string($collectionNamespace) ? $collectionNamespace : null;
325
    }
326
327
    /**
328
     * Retrieve persistent collections generation strategy.
329
     *
330
     * @return int
331
     */
332
    protected function getAutoGeneratePersistentCollection()
333
    {
334
        return (int) $this->getOption('persistent_collections_auto_generation');
335
    }
336
337
    /**
338
     * Get default database.
339
     *
340
     * @return string|null
341
     */
342
    protected function getDefaultDatabase()
343
    {
344
        return $this->hasOption('default_database') ? (string) $this->getOption('default_database') : null;
345
    }
346
347
    /**
348
     * Retrieve logger callable.
349
     *
350
     * @return callable|null
351
     */
352
    protected function getLoggerCallable()
353
    {
354
        if (!is_callable($this->loggerCallable)) {
355
            $loggerCallable = $this->getOption('logger_callable');
356
357
            if (is_callable($loggerCallable)) {
358
                $this->loggerCallable = $loggerCallable;
359
            }
360
        }
361
362
        return $this->loggerCallable;
363
    }
364
365
    /**
366
     * Get custom registered filters.
367
     *
368
     * @return array
369
     */
370
    protected function getCustomFilters()
371
    {
372
        $filters = (array) $this->getOption('custom_filters');
373
374
        return array_filter(
375
            $filters,
376
            function ($name) {
377
                return is_string($name);
378
            },
379
            ARRAY_FILTER_USE_KEY
380
        );
381
    }
382
383
    /**
384
     * {@inheritdoc}
385
     *
386
     * @throws \Doctrine\ODM\MongoDB\MongoDBException
387
     * @throws \InvalidArgumentException
388
     * @throws \RuntimeException
389
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
390
     * @throws \Symfony\Component\Console\Exception\LogicException
391
     * @throws \UnexpectedValueException
392
     *
393
     * @return Command[]
394
     */
395
    public function getConsoleCommands()
396
    {
397
        $commands = [
398
            // ODM
399
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateDocumentsCommand,
400
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateHydratorsCommand,
401
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateProxiesCommand,
402
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateRepositoriesCommand,
403
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\QueryCommand,
404
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\ClearCache\MetadataCommand,
405
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\CreateCommand,
406
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\DropCommand,
407
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\UpdateCommand,
408
        ];
409
        $commandPrefix = (string) $this->getName();
410
411
        if ($commandPrefix !== '') {
412
            $commands = array_map(
413
                function (Command $command) use ($commandPrefix) {
414
                    $commandNames = array_map(
415
                        function ($commandName) use ($commandPrefix) {
416
                            return preg_replace('/^odm:/', $commandPrefix . ':odm:', $commandName);
417
                        },
418
                        array_merge([$command->getName()], $command->getAliases())
419
                    );
420
421
                    $command->setName(array_shift($commandNames));
422
                    $command->setAliases($commandNames);
423
424
                    return $command;
425
                },
426
                $commands
427
            );
428
        }
429
430
        return $commands;
431
    }
432
433
    /**
434
     * {@inheritdoc}
435
     *
436
     * @throws \Doctrine\ODM\MongoDB\MongoDBException
437
     * @throws \InvalidArgumentException
438
     * @throws \RuntimeException
439
     * @throws \UnexpectedValueException
440
     */
441
    public function getConsoleHelperSet()
442
    {
443
        return new HelperSet([
444
            'dm' => new DocumentManagerHelper($this->getManager()),
445
        ]);
446
    }
447
}
448