Passed
Pull Request — master (#2)
by Alex
02:45
created

EntityManagerProvider   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 19
eloc 41
dl 0
loc 146
c 0
b 0
f 0
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setEntityManagers() 0 4 2
A getEntityManager() 0 22 6
A setEntityManager() 0 3 1
A refresh() 0 14 3
A setEntityManagerConfig() 0 3 1
A hasEntityManager() 0 3 2
A __construct() 0 6 1
A create() 0 15 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\LaminasDoctrine\Service\EntityManager;
6
7
use Arp\LaminasDoctrine\Config\DoctrineConfig;
8
use Arp\LaminasDoctrine\Factory\Service\EntityManagerFactory;
9
use Arp\LaminasDoctrine\Service\EntityManager\Exception\EntityManagerProviderException;
10
use Doctrine\ORM\EntityManagerInterface;
11
12
/**
13
 * @author  Alex Patterson <[email protected]>
14
 * @package Arp\LaminasDoctrine\Service\EntityManager
15
 */
16
final class EntityManagerProvider implements EntityManagerProviderInterface
17
{
18
    /**
19
     * @var DoctrineConfig
20
     */
21
    private DoctrineConfig $config;
22
23
    /**
24
     * @var EntityManagerManager
25
     */
26
    private EntityManagerManager $manager;
27
28
    /**
29
     * @param DoctrineConfig       $config
30
     * @param EntityManagerManager $manager
31
     * @param array                $entityManagers
32
     */
33
    public function __construct(DoctrineConfig $config, EntityManagerManager $manager, array $entityManagers = [])
34
    {
35
        $this->config = $config;
36
        $this->manager = $manager;
37
38
        $this->setEntityManagers($entityManagers);
39
    }
40
41
    /**
42
     * Set the configuration options for a single entity manager with the provided $name
43
     *
44
     * @param string $name
45
     * @param array  $config
46
     */
47
    public function setEntityManagerConfig(string $name, array $config): void
48
    {
49
        $this->config->setEntityManagerConfig($name, $config);
50
    }
51
52
    /**
53
     * Check if the entity manager is registered with the provider
54
     *
55
     * @param string $name The name of the entity manager to check
56
     *
57
     * @return bool
58
     */
59
    public function hasEntityManager(string $name): bool
60
    {
61
        return $this->manager->has($name) || $this->config->hasEntityManagerConfig($name);
62
    }
63
64
    /**
65
     * @param string $name
66
     *
67
     * @return EntityManagerInterface
68
     *
69
     * @throws EntityManagerProviderException
70
     */
71
    public function getEntityManager(string $name): EntityManagerInterface
72
    {
73
        try {
74
            if (!$this->manager->has($name) && $this->config->hasEntityManagerConfig($name)) {
75
                $this->manager->setService($name, $this->create($name, $this->config->getEntityManagerConfig($name)));
76
            }
77
78
            if ($this->manager->has($name)) {
79
                return $this->manager->get($name);
80
            }
81
        } catch (EntityManagerProviderException $e) {
82
            throw $e;
83
        } catch (\Throwable $e) {
84
            throw new EntityManagerProviderException(
85
                sprintf('Failed return entity manager \'%s\': %s', $name, $e->getMessage()),
86
                $e->getCode(),
87
                $e
88
            );
89
        }
90
91
        throw new EntityManagerProviderException(
92
            sprintf('Unable to find entity manager \'%s\'', $name)
93
        );
94
    }
95
96
    /**
97
     * @param string $name
98
     *
99
     * @return EntityManagerInterface
100
     *
101
     * @throws EntityManagerProviderException
102
     */
103
    public function refresh(string $name): EntityManagerInterface
104
    {
105
        if ($this->manager->has($name)) {
106
            $entityManager = $this->getEntityManager($name);
107
108
            if ($entityManager->isOpen()) {
109
                $entityManager->close();
110
            }
111
112
            $entityManager = $this->create($name, $this->config->getEntityManagerConfig($name));
113
            $this->manager->setService($name, $entityManager);
114
        }
115
116
        return $this->getEntityManager($name);
117
    }
118
119
    /**
120
     * @param string                 $name
121
     * @param EntityManagerInterface $entityManager
122
     */
123
    public function setEntityManager(string $name, EntityManagerInterface $entityManager): void
124
    {
125
        $this->manager->setService($name, $entityManager);
126
    }
127
128
    /**
129
     * @param array $entityManagers
130
     */
131
    public function setEntityManagers(array $entityManagers): void
132
    {
133
        foreach ($entityManagers as $name => $entityManager) {
134
            $this->setEntityManager($name, $entityManager);
135
        }
136
    }
137
138
    /**
139
     * @param string      $name
140
     * @param array       $config
141
     * @param string|null $factoryClassName
142
     *
143
     * @return EntityManagerInterface
144
     *
145
     * @throws EntityManagerProviderException
146
     */
147
    private function create(string $name, array $config, string $factoryClassName = null): EntityManagerInterface
148
    {
149
        if (!$this->manager->has($name)) {
150
            // There is no manual entry for this entity manager. We can manually add it so we do not need
151
            // to explicitly define it each time with the 'entity_manager_manager'
152
            $this->manager->setFactory($name, $factoryClassName ?? EntityManagerFactory::class);
153
        }
154
155
        try {
156
            return $this->manager->build($name, $config);
157
        } catch (\Throwable $e) {
158
            throw new EntityManagerProviderException(
159
                sprintf('Failed to create entity manager \'%s\' from configuration: %s', $name, $e->getMessage()),
160
                $e->getCode(),
161
                $e
162
            );
163
        }
164
    }
165
}
166