Completed
Push — master ( d34e64...7e6b75 )
by Julián
06:06
created

getAutoGeneratePersistentCollection()   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 0
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
        if (count($this->getCustomFilters())) {
177
            foreach ($this->getCustomFilters() as $name => $filterClass) {
178
                $config->addFilter($name, $filterClass);
179
            }
180
        }
181
    }
182
183
    /**
184
     * Create MongoDB Connection.
185
     *
186
     * @param Configuration $config
187
     *
188
     * @throws \InvalidArgumentException
189
     * @throws \RuntimeException
190
     *
191
     * @return Connection
192
     */
193
    protected function getConnection(Configuration $config)
194
    {
195
        $connection = $this->getOption('connection');
196
197
        switch (true) {
198
            case is_array($connection):
199
                $connection = new Connection(
200
                    array_key_exists('server', $connection) ? $connection['server'] : null,
201
                    array_key_exists('options', $connection) ? $connection['options'] : [],
202
                    $config,
203
                    $this->getEventManager()
204
                );
205
                break;
206
207
            case $connection instanceof Connection:
208
                if ($connection->getEventManager() !== $this->getEventManager()) {
209
                    throw new \RuntimeException(
210
                        'Cannot use different EventManager instances for DocumentManager and Connection.'
211
                    );
212
                }
213
                break;
214
215
            default:
216
                throw new \InvalidArgumentException('Invalid argument: ' . $connection);
217
        }
218
219
        return $connection;
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    protected function getAnnotationMetadataDriver(array $paths)
226
    {
227
        return new AnnotationDriver(new AnnotationReader, $paths);
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233
    protected function getXmlMetadataDriver(array $paths, $extension = null)
234
    {
235
        $extension = $extension ?: XmlDriver::DEFAULT_FILE_EXTENSION;
236
237
        return new XmlDriver($paths, $extension);
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    protected function getYamlMetadataDriver(array $paths, $extension = null)
244
    {
245
        $extension = $extension ?: YamlDriver::DEFAULT_FILE_EXTENSION;
246
247
        return new YamlDriver($paths, $extension);
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     *
253
     * @throws \InvalidArgumentException
254
     *
255
     * @return RepositoryFactory|null
256
     */
257
    protected function getRepositoryFactory()
258
    {
259
        if (!array_key_exists('repository_factory', $this->options)) {
260
            return;
261
        }
262
263
        $repositoryFactory = $this->options['repository_factory'];
264
265
        if (!$repositoryFactory instanceof RepositoryFactory) {
266
            throw new \InvalidArgumentException(sprintf(
267
                'Invalid factory class "%s". It must be a Doctrine\ODM\MongoDB\Repository\RepositoryFactory.',
268
                get_class($repositoryFactory)
269
            ));
270
        }
271
272
        return $repositoryFactory;
273
    }
274
275
    /**
276
     * Retrieve hydrators path.
277
     *
278
     * @return string
279
     */
280
    protected function getHydratorsPath()
281
    {
282
        return (string) $this->getOption('hydrators_path', sys_get_temp_dir());
283
    }
284
285
    /**
286
     * Retrieve hydrators namespace.
287
     *
288
     * @return null|string
289
     */
290
    protected function getHydratorsNamespace()
291
    {
292
        $proxyNamespace = $this->getOption('hydrators_namespace');
293
294
        return is_string($proxyNamespace) ? $proxyNamespace : null;
295
    }
296
297
    /**
298
     * Retrieve hydrators generation strategy.
299
     *
300
     * @return int
301
     */
302
    protected function getHydratorsAutoGeneration()
303
    {
304
        return (int) $this->getOption('hydrators_auto_generation');
305
    }
306
307
    /**
308
     * Retrieve persistent collections path.
309
     *
310
     * @return string
311
     */
312
    protected function getPersistentCollectionPath()
313
    {
314
        return (string) $this->getOption('persistent_collections_path', sys_get_temp_dir());
315
    }
316
317
    /**
318
     * Retrieve persistent collections namespace.
319
     *
320
     * @return null|string
321
     */
322
    protected function getPersistentCollectionNamespace()
323
    {
324
        $collectionNamespace = $this->getOption('persistent_collections_namespace');
325
326
        return is_string($collectionNamespace) ? $collectionNamespace : null;
327
    }
328
329
    /**
330
     * Retrieve persistent collections generation strategy.
331
     *
332
     * @return int
333
     */
334
    protected function getAutoGeneratePersistentCollection()
335
    {
336
        return (int) $this->getOption('persistent_collections_auto_generation');
337
    }
338
339
    /**
340
     * Get default database.
341
     *
342
     * @return string|null
343
     */
344
    protected function getDefaultDatabase()
345
    {
346
        return $this->hasOption('default_database') ? (string) $this->getOption('default_database') : null;
347
    }
348
349
    /**
350
     * Retrieve logger callable.
351
     *
352
     * @return callable|null
353
     */
354
    protected function getLoggerCallable()
355
    {
356
        if (!is_callable($this->loggerCallable)) {
357
            $loggerCallable = $this->getOption('logger_callable');
358
359
            if (is_callable($loggerCallable)) {
360
                $this->loggerCallable = $loggerCallable;
361
            }
362
        }
363
364
        return $this->loggerCallable;
365
    }
366
367
    /**
368
     * Get custom registered filters.
369
     *
370
     * @return array
371
     */
372
    protected function getCustomFilters()
373
    {
374
        $filters = (array) $this->getOption('custom_filters');
375
376
        return array_filter(
377
            $filters,
378
            function ($name) {
379
                return is_string($name);
380
            },
381
            ARRAY_FILTER_USE_KEY
382
        );
383
    }
384
385
    /**
386
     * {@inheritdoc}
387
     *
388
     * @throws \Doctrine\ODM\MongoDB\MongoDBException
389
     * @throws \InvalidArgumentException
390
     * @throws \RuntimeException
391
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
392
     * @throws \Symfony\Component\Console\Exception\LogicException
393
     * @throws \UnexpectedValueException
394
     *
395
     * @return Command[]
396
     */
397
    public function getConsoleCommands()
398
    {
399
        $commands = [
400
            // ODM
401
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateDocumentsCommand,
402
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateHydratorsCommand,
403
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateProxiesCommand,
404
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateRepositoriesCommand,
405
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\QueryCommand,
406
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\ClearCache\MetadataCommand,
407
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\CreateCommand,
408
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\DropCommand,
409
            new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\UpdateCommand,
410
        ];
411
        $commandPrefix = (string) $this->getName();
412
413
        if ($commandPrefix !== '') {
414
            $commands = array_map(
415
                function (Command $command) use ($commandPrefix) {
416
                    $commandNames = array_map(
417
                        function ($commandName) use ($commandPrefix) {
418
                            return preg_replace('/^odm:/', $commandPrefix . ':odm:', $commandName);
419
                        },
420
                        array_merge([$command->getName()], $command->getAliases())
421
                    );
422
423
                    $command->setName(array_shift($commandNames));
424
                    $command->setAliases($commandNames);
425
426
                    return $command;
427
                },
428
                $commands
429
            );
430
        }
431
432
        return $commands;
433
    }
434
435
    /**
436
     * {@inheritdoc}
437
     *
438
     * @throws \Doctrine\ODM\MongoDB\MongoDBException
439
     * @throws \InvalidArgumentException
440
     * @throws \RuntimeException
441
     * @throws \UnexpectedValueException
442
     */
443
    public function getConsoleHelperSet()
444
    {
445
        return new HelperSet([
446
            'dm' => new DocumentManagerHelper($this->getManager()),
447
        ]);
448
    }
449
}
450