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

PersistServiceFactory   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 44
c 0
b 0
f 0
dl 0
loc 118
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getEventDispatcher() 0 25 5
A getLogger() 0 22 5
A __invoke() 0 32 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\LaminasDoctrine\Factory\Repository\Persistence;
6
7
use Arp\DoctrineEntityRepository\Persistence\PersistService;
8
use Arp\DoctrineEntityRepository\Persistence\PersistServiceInterface;
9
use Arp\LaminasDoctrine\Factory\Service\EntityManagerFactoryProviderTrait;
10
use Arp\LaminasFactory\AbstractFactory;
11
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
12
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
13
use Laminas\ServiceManager\ServiceLocatorInterface;
14
use Psr\Container\ContainerInterface;
15
use Psr\EventDispatcher\EventDispatcherInterface;
16
use Psr\Log\LoggerInterface;
17
use Psr\Log\NullLogger;
18
19
/**
20
 * @author  Alex Patterson <[email protected]>
21
 * @package Arp\LaminasDoctrine\Factory\Repository\Persistence
22
 */
23
final class PersistServiceFactory extends AbstractFactory
24
{
25
    use EntityManagerFactoryProviderTrait;
26
27
    /**
28
     * @param ContainerInterface&ServiceLocatorInterface $container
29
     * @param string                                     $requestedName
30
     * @param array<mixed>|null                          $options
31
     *
32
     * @return PersistServiceInterface
33
     *
34
     * @throws ServiceNotCreatedException
35
     * @throws ServiceNotFoundException
36
     */
37
    public function __invoke(
38
        ContainerInterface $container,
39
        string $requestedName,
40
        array $options = null
41
    ): PersistServiceInterface {
42
        $options = array_replace_recursive($this->getServiceOptions($container, $requestedName), $options ?? []);
43
44
        $entityName = $options['entity_name'] ?? null;
45
        if (empty($entityName)) {
46
            throw new ServiceNotCreatedException(
47
                sprintf(
48
                    'The required \'entity_name\' configuration option is missing for service \'%s\'',
49
                    $requestedName
50
                )
51
            );
52
        }
53
54
        $entityManager = $options['entity_manager'] ?? null;
55
        if (empty($entityManager)) {
56
            throw new ServiceNotCreatedException(
57
                sprintf(
58
                    'The required \'entity_manager\' configuration option is missing for service \'%s\'',
59
                    $requestedName
60
                )
61
            );
62
        }
63
64
        return new PersistService(
65
            $entityName,
66
            $this->getEntityManager($container, $entityManager, $requestedName),
67
            $this->getEventDispatcher($container, $options['event_dispatcher'] ?? [], $requestedName),
68
            $this->getLogger($container, $options['logger'] ?? null, $requestedName)
69
        );
70
    }
71
72
    /**
73
     * @param ServiceLocatorInterface                      $container
74
     * @param EventDispatcherInterface|string|array<mixed> $eventDispatcher
75
     * @param string                                       $serviceName
76
     *
77
     * @return EventDispatcherInterface
78
     *
79
     * @throws ServiceNotCreatedException
80
     * @throws ServiceNotFoundException
81
     */
82
    private function getEventDispatcher(
83
        ServiceLocatorInterface $container,
84
        $eventDispatcher,
85
        string $serviceName
86
    ): EventDispatcherInterface {
87
        if (is_string($eventDispatcher)) {
88
            $eventDispatcher = $this->getService($container, $eventDispatcher, $serviceName);
89
        }
90
91
        if (is_array($eventDispatcher)) {
92
            $eventDispatcher = $this->buildService($container, 'EntityEventDispatcher', $eventDispatcher, $serviceName);
93
        }
94
95
        if (!$eventDispatcher instanceof EventDispatcherInterface) {
96
            throw new ServiceNotCreatedException(
97
                sprintf(
98
                    'The event dispatcher must be an object of type \'%s\'; \'%s\' provided for service \'%s\'',
99
                    EventDispatcherInterface::class,
100
                    is_object($eventDispatcher) ? get_class($eventDispatcher) : gettype($eventDispatcher),
101
                    $serviceName
102
                )
103
            );
104
        }
105
106
        return $eventDispatcher;
107
    }
108
109
    /**
110
     * @param ContainerInterface          $container
111
     * @param LoggerInterface|string|null $logger
112
     * @param string                      $serviceName
113
     *
114
     * @return LoggerInterface
115
     *
116
     * @throws ServiceNotCreatedException
117
     * @throws ServiceNotFoundException
118
     */
119
    private function getLogger(ContainerInterface $container, $logger, string $serviceName): LoggerInterface
120
    {
121
        if (null === $logger) {
122
            return new NullLogger();
123
        }
124
125
        if (is_string($logger)) {
126
            $logger = $this->getService($container, $logger, $serviceName);
127
        }
128
129
        if (!$logger instanceof LoggerInterface) {
130
            throw new ServiceNotCreatedException(
131
                sprintf(
132
                    'The logger must be of type \'%s\'; \'%s\' provided for service \'%s\'',
133
                    LoggerInterface::class,
134
                    is_object($logger) ? get_class($logger) : gettype($logger),
135
                    $serviceName
136
                )
137
            );
138
        }
139
140
        return $logger;
141
    }
142
}
143