ManagerRegistryFactory::getEventManager()   A
last analyzed

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 140
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null): ManagerRegistry
30
    {
31 140
        $config = $container->has('config') ? $container->get('config') : [];
32
33 140
        $connections = $this->getConnections($container, $config);
34
35 140
        if (!isset($config['doctrine'])) {
36
            throw new MissingDoctrineConfigException(
37
                'Doctrine configuration is missing'
38
            );
39
        }
40
41 140
        $doctrineAutoloadConfig = $config['doctrine'];
42 140
        $emMapping = $doctrineAutoloadConfig['entity_manager_mapping'] ?? [];
43
44 140
        if (!isset($doctrineAutoloadConfig['entity_managers'])) {
45
            throw new MissingDoctrineConfigException(
46
                'Doctrine configuration is missing entity managers'
47
            );
48
        }
49
50 140
        $entityManagersConfig = $doctrineAutoloadConfig['entity_managers'];
51
52 140
        $managers = [];
53 140
        foreach ($entityManagersConfig as $key => $emConfig) {
54 140
            $paths = $emConfig['paths'] ?? [];
55 140
            $devMode = $emConfig['dev_mode'] ?? false;
56
57
            // get "base" config
58 140
            $doctrineConfiguration = Setup::createAnnotationMetadataConfiguration(
59 140
                $paths,
60 140
                $devMode,
61 140
                null,
62 140
                null,
63 140
                false
64
            );
65
66 140
            $this->populateConfig($emConfig, $doctrineConfiguration, $container);
67
68 140
            $connectionName = $emConfig['connection'] ?? 'default';
69
70 140
            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 140
            $managers[$key] = EntityManager::create(
78 140
                $connections[$connectionName],
79 140
                $doctrineConfiguration,
80 140
                $this->getEventManager($container, $doctrineAutoloadConfig)
81
            );
82
        }
83
84 140
        return new SimpleRegistry($connections, $managers, $emMapping);
85
    }
86
87 140
    private function populateConfig(
88
        array $configuration,
89
        Configuration $configurationObject,
90
        ContainerInterface $container
91
    ): void {
92 140
        if (isset($configuration['naming_strategy'])) {
93 140
            $configurationObject->setNamingStrategy($container->get($configuration['naming_strategy']));
94
        }
95 140
        if (isset($configuration['proxy_dir'])) {
96 140
            $configurationObject->setProxyDir($configuration['proxy_dir']);
97
        }
98 140
    }
99
100 140
    private function getEventManager(ContainerInterface $container, array $doctrineConfig): EventManager
101
    {
102 140
        if ($this->eventManager === null) {
103 140
            $this->eventManager = new EventManager();
104
105 140
            $subscribers = $doctrineConfig['subscribers'] ?? [];
106 140
            $listeners = $doctrineConfig['listeners'] ?? [];
107
108 140
            foreach ($subscribers as $subscriber) {
109 140
                $this->eventManager->addEventSubscriber($container->get($subscriber));
110
            }
111 140
            foreach ($listeners as $listener) {
112
                $this->eventManager->addEventListener(
113
                    $listener['events'] ?? [],
114
                    $container->get($listener['class'] ?? '')
115
                );
116
            }
117
        }
118
119 140
        return $this->eventManager;
120
    }
121
122 140
    private function getConnections(ContainerInterface $container, array $config): array
123
    {
124 140
        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 140
            return DriverManager::getConnection(
132 140
                $connection,
133 140
                null,
134 140
                $this->getEventManager($container, $config['doctrine'] ?? [])
135
            );
136 140
        }, $config['connections']);
137
    }
138
}
139