Passed
Pull Request — master (#2)
by Alex
08:14
created

EntityManagerProvider   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 25
eloc 66
c 0
b 0
f 0
dl 0
loc 198
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setEntityManagers() 0 7 3
A registerServiceFactory() 0 13 2
A getEntityManager() 0 22 6
A setEntityManager() 0 9 2
A refresh() 0 23 4
A setEntityManagerConfig() 0 3 1
A hasEntityManager() 0 3 2
A __construct() 0 6 1
A create() 0 14 4
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
use Laminas\ServiceManager\Exception\ContainerModificationsNotAllowedException;
12
use Psr\Container\ContainerExceptionInterface;
13
14
/**
15
 * @deprecated
16
 * @author  Alex Patterson <[email protected]>
17
 * @package Arp\LaminasDoctrine\Service\EntityManager
18
 */
19
final class EntityManagerProvider implements EntityManagerProviderInterface
0 ignored issues
show
Deprecated Code introduced by
The interface Arp\LaminasDoctrine\Serv...anagerProviderInterface has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

19
final class EntityManagerProvider implements /** @scrutinizer ignore-deprecated */ EntityManagerProviderInterface

This interface has been deprecated. The supplier of the interface has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.

Loading history...
20
{
21
    /**
22
     * @var DoctrineConfig
23
     */
24
    private DoctrineConfig $config;
25
26
    /**
27
     * @var ContainerInterface
28
     */
29
    private ContainerInterface $container;
30
31
    /**
32
     * @param DoctrineConfig                              $config
33
     * @param ContainerInterface                          $container
34
     * @param array<string, EntityManagerInterface|array> $entityManagers
35
     *
36
     * @throws EntityManagerProviderException
37
     */
38
    public function __construct(DoctrineConfig $config, ContainerInterface $container, array $entityManagers = [])
39
    {
40
        $this->config = $config;
41
        $this->container = $container;
42
43
        $this->setEntityManagers($entityManagers);
44
    }
45
46
    /**
47
     * @param string $name
48
     *
49
     * @return EntityManagerInterface
50
     *
51
     * @throws EntityManagerProviderException
52
     */
53
    public function getEntityManager(string $name): EntityManagerInterface
54
    {
55
        try {
56
            if (!$this->container->has($name) && $this->config->hasEntityManagerConfig($name)) {
57
                $this->container->setService($name, $this->create($name, $this->config->getEntityManagerConfig($name)));
58
            }
59
60
            if ($this->container->has($name)) {
61
                return $this->container->get($name);
62
            }
63
        } catch (EntityManagerProviderException $e) {
64
            throw $e;
65
        } catch (ContainerExceptionInterface $e) {
66
            throw new EntityManagerProviderException(
0 ignored issues
show
Deprecated Code introduced by
The class Arp\LaminasDoctrine\Serv...anagerProviderException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

66
            throw /** @scrutinizer ignore-deprecated */ new EntityManagerProviderException(
Loading history...
67
                sprintf('Failed retrieve entity manager \'%s\': %s', $name, $e->getMessage()),
0 ignored issues
show
Bug introduced by
The method getMessage() does not exist on Psr\Container\ContainerExceptionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Psr\Container\NotFoundExceptionInterface or Interop\Container\Exception\ContainerException or Interop\Container\Exception\NotFoundException or Interop\Container\Exception\NotFoundException or Laminas\ServiceManager\E...tion\ExceptionInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

67
                sprintf('Failed retrieve entity manager \'%s\': %s', $name, $e->/** @scrutinizer ignore-call */ getMessage()),
Loading history...
68
                $e->getCode(),
0 ignored issues
show
Bug introduced by
The method getCode() does not exist on Psr\Container\ContainerExceptionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Psr\Container\NotFoundExceptionInterface or Interop\Container\Exception\ContainerException or Interop\Container\Exception\NotFoundException or Interop\Container\Exception\NotFoundException or Laminas\ServiceManager\E...tion\ExceptionInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
                $e->/** @scrutinizer ignore-call */ 
69
                    getCode(),
Loading history...
69
                $e
70
            );
71
        }
72
73
        throw new EntityManagerProviderException(
0 ignored issues
show
Deprecated Code introduced by
The class Arp\LaminasDoctrine\Serv...anagerProviderException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

73
        throw /** @scrutinizer ignore-deprecated */ new EntityManagerProviderException(
Loading history...
74
            sprintf('Unable to find entity manager \'%s\'', $name)
75
        );
76
    }
77
78
    /**
79
     * @param string $name
80
     *
81
     * @return EntityManagerInterface
82
     *
83
     * @throws EntityManagerProviderException
84
     */
85
    public function refresh(string $name): EntityManagerInterface
86
    {
87
        $entityManager = $this->getEntityManager($name);
88
89
        if ($this->container->has($name)) {
90
            if ($entityManager->isOpen()) {
91
                $entityManager->close();
92
            }
93
94
            $entityManager = $this->create($name, $this->config->getEntityManagerConfig($name));
95
96
            try {
97
                $this->container->setService($name, $entityManager);
98
            } catch (ContainerExceptionInterface $e) {
99
                throw new EntityManagerProviderException(
0 ignored issues
show
Deprecated Code introduced by
The class Arp\LaminasDoctrine\Serv...anagerProviderException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

99
                throw /** @scrutinizer ignore-deprecated */ new EntityManagerProviderException(
Loading history...
100
                    sprintf('Failed to set create service \'%s\': %s', $name, $e->getMessage()),
101
                    $e->getCode(),
102
                    $e
103
                );
104
            }
105
        }
106
107
        return $entityManager;
108
    }
109
110
    /**
111
     * Set the configuration options for a single entity manager with the provided $name
112
     *
113
     * @param string               $name
114
     * @param array<string, mixed> $config
115
     */
116
    public function setEntityManagerConfig(string $name, array $config): void
117
    {
118
        $this->config->setEntityManagerConfig($name, $config);
119
    }
120
121
    /**
122
     * Check if the entity manager is registered with the provider
123
     *
124
     * @param string $name The name of the entity manager to check
125
     *
126
     * @return bool
127
     */
128
    public function hasEntityManager(string $name): bool
129
    {
130
        return $this->container->has($name) || $this->config->hasEntityManagerConfig($name);
131
    }
132
133
    /**
134
     * @param string                 $name
135
     * @param EntityManagerInterface $entityManager
136
     *
137
     * @throws EntityManagerProviderException
138
     */
139
    public function setEntityManager(string $name, EntityManagerInterface $entityManager): void
140
    {
141
        try {
142
            $this->container->setService($name, $entityManager);
143
        } catch (ContainerModificationsNotAllowedException $e) {
144
            throw new EntityManagerProviderException(
0 ignored issues
show
Deprecated Code introduced by
The class Arp\LaminasDoctrine\Serv...anagerProviderException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

144
            throw /** @scrutinizer ignore-deprecated */ new EntityManagerProviderException(
Loading history...
145
                sprintf('Unable to set entity manager service \'%s\': %s', $name, $e->getMessage()),
146
                $e->getCode(),
147
                $e
148
            );
149
        }
150
    }
151
152
    /**
153
     * @param array<string, EntityManagerInterface|array> $entityManagers
154
     *
155
     * @throws EntityManagerProviderException
156
     */
157
    public function setEntityManagers(array $entityManagers): void
158
    {
159
        foreach ($entityManagers as $name => $entityManager) {
160
            if (is_array($entityManager)) {
161
                $this->setEntityManagerConfig($name, $entityManager);
162
            } else {
163
                $this->setEntityManager($name, $entityManager);
164
            }
165
        }
166
    }
167
168
    /**
169
     * @param string               $name
170
     * @param array<string, mixed> $config
171
     * @param string|null          $factoryClassName
172
     *
173
     * @return EntityManagerInterface
174
     *
175
     * @throws EntityManagerProviderException
176
     */
177
    private function create(string $name, array $config, ?string $factoryClassName = null): EntityManagerInterface
178
    {
179
        // We must exclude calls from refresh() so we need to check
180
        if (!$this->container->has($name)) {
181
            $this->registerServiceFactory($name, $factoryClassName ?: EntityManagerFactory::class);
182
        }
183
184
        try {
185
            return $this->container->build($name, $config);
186
        } catch (ContainerExceptionInterface $e) {
187
            throw new EntityManagerProviderException(
0 ignored issues
show
Deprecated Code introduced by
The class Arp\LaminasDoctrine\Serv...anagerProviderException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

187
            throw /** @scrutinizer ignore-deprecated */ new EntityManagerProviderException(
Loading history...
188
                sprintf('Failed to create entity manager \'%s\' from configuration: %s', $name, $e->getMessage()),
189
                $e->getCode(),
190
                $e
191
            );
192
        }
193
    }
194
195
    /**
196
     * Add a manual factory service entry for entity manager $name, so we do not need to explicitly define it each
197
     * time with the 'entity_manager_container'
198
     *
199
     * @param string $name
200
     * @param string $factoryClassName
201
     *
202
     * @throws EntityManagerProviderException
203
     */
204
    private function registerServiceFactory(string $name, string $factoryClassName): void
205
    {
206
        try {
207
            $this->container->setFactory($name, $factoryClassName);
208
        } catch (ContainerModificationsNotAllowedException $e) {
209
            throw new EntityManagerProviderException(
0 ignored issues
show
Deprecated Code introduced by
The class Arp\LaminasDoctrine\Serv...anagerProviderException has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

209
            throw /** @scrutinizer ignore-deprecated */ new EntityManagerProviderException(
Loading history...
210
                sprintf(
211
                    'Unable to set entity manager factory service \'%s\': %s',
212
                    $factoryClassName,
213
                    $e->getMessage()
214
                ),
215
                $e->getCode(),
216
                $e
217
            );
218
        }
219
    }
220
}
221