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

EntityManagerProvider::getEntityManager()   A

Complexity

Conditions 6
Paths 16

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 22
c 0
b 0
f 0
rs 9.2222
cc 6
nc 16
nop 1
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 Psr\Container\ContainerExceptionInterface;
12
13
/**
14
 * @author  Alex Patterson <[email protected]>
15
 * @package Arp\LaminasDoctrine\Service\EntityManager
16
 */
17
final class EntityManagerProvider implements EntityManagerProviderInterface
18
{
19
    /**
20
     * @var DoctrineConfig
21
     */
22
    private DoctrineConfig $config;
23
24
    /**
25
     * @var ContainerInterface
26
     */
27
    private ContainerInterface $container;
28
29
    /**
30
     * @param DoctrineConfig     $config
31
     * @param ContainerInterface $container
32
     * @param array              $entityManagers
33
     */
34
    public function __construct(DoctrineConfig $config, ContainerInterface $container, array $entityManagers = [])
35
    {
36
        $this->config = $config;
37
        $this->container = $container;
38
39
        $this->setEntityManagers($entityManagers);
40
    }
41
42
    /**
43
     * @param string $name
44
     *
45
     * @return EntityManagerInterface
46
     *
47
     * @throws EntityManagerProviderException
48
     */
49
    public function getEntityManager(string $name): EntityManagerInterface
50
    {
51
        try {
52
            if (!$this->container->has($name) && $this->config->hasEntityManagerConfig($name)) {
53
                $this->container->setService($name, $this->create($name, $this->config->getEntityManagerConfig($name)));
54
            }
55
56
            if ($this->container->has($name)) {
57
                return $this->container->get($name);
58
            }
59
        } catch (EntityManagerProviderException $e) {
60
            throw $e;
61
        } catch (ContainerExceptionInterface $e) {
62
            throw new EntityManagerProviderException(
63
                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

63
                sprintf('Failed retrieve entity manager \'%s\': %s', $name, $e->/** @scrutinizer ignore-call */ getMessage()),
Loading history...
64
                $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

64
                $e->/** @scrutinizer ignore-call */ 
65
                    getCode(),
Loading history...
65
                $e
66
            );
67
        }
68
69
        throw new EntityManagerProviderException(
70
            sprintf('Unable to find entity manager \'%s\'', $name)
71
        );
72
    }
73
74
    /**
75
     * @param string $name
76
     *
77
     * @return EntityManagerInterface
78
     *
79
     * @throws EntityManagerProviderException
80
     */
81
    public function refresh(string $name): EntityManagerInterface
82
    {
83
        $entityManager = $this->getEntityManager($name);
84
85
        if ($this->container->has($name)) {
86
            if ($entityManager->isOpen()) {
87
                $entityManager->close();
88
            }
89
90
            $entityManager = $this->create($name, $this->config->getEntityManagerConfig($name));
91
            $this->container->setService($name, $entityManager);
92
        }
93
94
        return $entityManager;
95
    }
96
97
    /**
98
     * Set the configuration options for a single entity manager with the provided $name
99
     *
100
     * @param string $name
101
     * @param array  $config
102
     */
103
    public function setEntityManagerConfig(string $name, array $config): void
104
    {
105
        $this->config->setEntityManagerConfig($name, $config);
106
    }
107
108
    /**
109
     * Check if the entity manager is registered with the provider
110
     *
111
     * @param string $name The name of the entity manager to check
112
     *
113
     * @return bool
114
     */
115
    public function hasEntityManager(string $name): bool
116
    {
117
        return $this->container->has($name) || $this->config->hasEntityManagerConfig($name);
118
    }
119
120
    /**
121
     * @param string                 $name
122
     * @param EntityManagerInterface $entityManager
123
     */
124
    public function setEntityManager(string $name, EntityManagerInterface $entityManager): void
125
    {
126
        $this->container->setService($name, $entityManager);
127
    }
128
129
    /**
130
     * @param array $entityManagers
131
     */
132
    public function setEntityManagers(array $entityManagers): void
133
    {
134
        foreach ($entityManagers as $name => $entityManager) {
135
            if (is_array($entityManager)) {
136
                $this->setEntityManagerConfig($name, $entityManager);
137
            } else {
138
                $this->setEntityManager($name, $entityManager);
139
            }
140
        }
141
    }
142
143
    /**
144
     * @param string      $name
145
     * @param array       $config
146
     * @param string|null $factoryClassName
147
     *
148
     * @return EntityManagerInterface
149
     *
150
     * @throws EntityManagerProviderException
151
     */
152
    private function create(string $name, array $config, string $factoryClassName = null): EntityManagerInterface
153
    {
154
        // We must exclude calls from refresh() so we need to check
155
        if (!$this->container->has($name)) {
156
            /**
157
             * There is no manual entry for this entity manager. We can manually add it so we do not need
158
             * to explicitly define it each time with the 'entity_manager_container'
159
             */
160
            $this->container->setFactory($name, $factoryClassName ?? EntityManagerFactory::class);
161
        }
162
163
        try {
164
            return $this->container->build($name, $config);
165
        } catch (ContainerExceptionInterface $e) {
166
            throw new EntityManagerProviderException(
167
                sprintf('Failed to create entity manager \'%s\' from configuration: %s', $name, $e->getMessage()),
168
                $e->getCode(),
169
                $e
170
            );
171
        }
172
    }
173
}
174