Completed
Push — master ( 088dd2...f9ebf5 )
by Oleg
107:14
created

ManagerRegistryFactory::getEventManager()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.25

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 9
cts 12
cp 0.75
rs 9.584
c 0
b 0
f 0
cc 4
nc 2
nop 2
crap 4.25
1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DataFlowServer\Doctrine\Factory;
5
6
use Doctrine\Common\EventManager;
7
use Doctrine\Common\Persistence\ManagerRegistry;
8
use Doctrine\DBAL\DriverManager;
9
use Doctrine\ORM\Configuration;
10
use Doctrine\ORM\EntityManager;
11
use Doctrine\ORM\Tools\Setup;
12
use Interop\Container\ContainerInterface;
13
use SlayerBirden\DataFlowServer\Doctrine\Exception\InvalidArgumentDoctrineConfigException;
14
use SlayerBirden\DataFlowServer\Doctrine\Exception\MissingDoctrineConfigException;
15
use SlayerBirden\DataFlowServer\Doctrine\SimpleRegistry;
16
use Zend\ServiceManager\Factory\FactoryInterface;
17
18
final class ManagerRegistryFactory implements FactoryInterface
19
{
20
    /**
21
     * @var EventManager
22
     */
23
    private $eventManager;
24
25
    /**
26
     * @inheritdoc
27
     * @throws \Doctrine\ORM\ORMException
28
     */
29 138
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null): ManagerRegistry
30
    {
31 138
        $config = $container->has('config') ? $container->get('config') : [];
32
33 138
        $connections = $this->getConnections($container, $config);
34
35 138
        if (!isset($config['doctrine'])) {
36
            throw new MissingDoctrineConfigException(
37
                'Doctrine configuration is missing'
38
            );
39
        }
40
41 138
        $doctrineAutoloadConfig = $config['doctrine'];
42 138
        $emMapping = $doctrineAutoloadConfig['entity_manager_mapping'] ?? [];
43
44 138
        if (!isset($doctrineAutoloadConfig['entity_managers'])) {
45
            throw new MissingDoctrineConfigException(
46
                'Doctrine configuration is missing entity managers'
47
            );
48
        }
49
50 138
        $entityManagersConfig = $doctrineAutoloadConfig['entity_managers'];
51
52 138
        $managers = [];
53 138
        foreach ($entityManagersConfig as $key => $emConfig) {
54 138
            $paths = $emConfig['paths'] ?? [];
55 138
            $devMode = $emConfig['dev_mode'] ?? false;
56
57
            // get "base" config
58 138
            $doctrineConfiguration = Setup::createAnnotationMetadataConfiguration(
59 138
                $paths,
60 138
                $devMode,
61 138
                null,
62 138
                null,
63 138
                false
64
            );
65
66 138
            $this->populateConfig($emConfig, $doctrineConfiguration, $container);
67
68 138
            $connectionName = $emConfig['connection'] ?? 'default';
69
70 138
            if (!isset($connections[$connectionName])) {
71
                throw new InvalidArgumentDoctrineConfigException(
72
                    sprintf('Can not find DB connection named %s', $connectionName)
73
                );
74
            }
75
76
            // obtaining the entity manager
77 138
            $managers[$key] = EntityManager::create(
78 138
                $connections[$connectionName],
79 138
                $doctrineConfiguration,
80 138
                $this->getEventManager($container, $doctrineAutoloadConfig)
81
            );
82
        }
83
84 138
        return new SimpleRegistry($connections, $managers, $emMapping);
85
    }
86
87 138
    private function populateConfig(
88
        array $configuration,
89
        Configuration $configurationObject,
90
        ContainerInterface $container
91
    ): void {
92 138
        if (isset($configuration['naming_strategy'])) {
93 138
            $configurationObject->setNamingStrategy($container->get($configuration['naming_strategy']));
94
        }
95 138
        if (isset($configuration['proxy_dir'])) {
96 138
            $configurationObject->setProxyDir($configuration['proxy_dir']);
97
        }
98 138
    }
99
100 138
    private function getEventManager(ContainerInterface $container, array $doctrineConfig): EventManager
101
    {
102 138
        if ($this->eventManager === null) {
103 138
            $this->eventManager = new EventManager();
104
105 138
            $subscribers = $doctrineConfig['subscribers'] ?? [];
106 138
            $listeners = $doctrineConfig['listeners'] ?? [];
107
108 138
            foreach ($subscribers as $subscriber) {
109 138
                $this->eventManager->addEventSubscriber($container->get($subscriber));
110
            }
111 138
            foreach ($listeners as $listener) {
112
                $this->eventManager->addEventListener(
113
                    $listener['events'] ?? [],
114
                    $container->get($listener['class'] ?? '')
115
                );
116
            }
117
        }
118
119 138
        return $this->eventManager;
120
    }
121
122 138
    private function getConnections(ContainerInterface $container, array $config): array
123
    {
124 138
        if (!isset($config['connections'])) {
125
            throw new MissingDoctrineConfigException(
126
                'DB Connections configuration is missing'
127
            );
128
        }
129
130
        return array_map(function (array $connection) use ($container, $config) {
131 138
            return DriverManager::getConnection(
132 138
                $connection,
133 138
                null,
134 138
                $this->getEventManager($container, $config['doctrine'] ?? [])
135
            );
136 138
        }, $config['connections']);
137
    }
138
}
139