Completed
Push — master ( 9f7282...4881a6 )
by Nikola
01:20
created

AbstractDiContainerLoggerFactory   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 96.3%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 2
dl 0
loc 127
ccs 52
cts 54
cp 0.963
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A __invoke() 0 12 1
A __callStatic() 0 8 3
getLoggerConfig() 0 1 ?
A createLogger() 0 15 3
A getContainer() 0 4 1
A prepareHandlers() 0 12 5
A prepareProcessors() 0 10 2
A resolveHandler() 0 4 1
A resolveFormatter() 0 4 1
A resolveProcessor() 0 4 1
A resolveFromContainer() 0 17 4
A getLoggerFactory() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MonologFactory;
6
7
use Monolog\Formatter\FormatterInterface;
8
use Monolog\Handler\HandlerInterface;
9
use Monolog\Logger;
10
use MonologFactory\Exception\BadStaticDiContainerFactoryUsage;
11
use MonologFactory\Exception\CannotResolveLoggerComponent;
12
use Psr\Container\ContainerInterface;
13
use Throwable;
14
15
abstract class AbstractDiContainerLoggerFactory
16
{
17
    /** @var string */
18
    protected $loggerName;
19
20
    /** @var ContainerInterface */
21
    private $container;
22
23
    /** @var LoggerFactory */
24
    private $loggerFactory;
25
26 10
    public function __construct(string $loggerName = 'default')
27
    {
28 10
        $this->loggerName = $loggerName;
29 10
    }
30
31 10
    public function __invoke(ContainerInterface $container): Logger
32
    {
33 10
        $this->container = $container;
34
35 10
        $loggerConfig = array_merge([
36 10
            'name' => $this->loggerName,
37
            'handlers' => [],
38
            'processors' => [],
39 10
        ], $this->getLoggerConfig($this->loggerName));
40
41 10
        return $this->createLogger($loggerConfig);
42
    }
43
44 2
    public static function __callStatic(string $name, array $arguments): Logger
45
    {
46 2
        if (0 === count($arguments) || ! ($container = current($arguments)) instanceof ContainerInterface) {
47 1
            throw BadStaticDiContainerFactoryUsage::missingContainerArgument(static::class);
48
        }
49
50 1
        return (new static($name))->__invoke($container);
51
    }
52
53
    abstract protected function getLoggerConfig(string $loggerName): array;
54
55 10
    protected function createLogger(array $config): Logger
56
    {
57 10
        $name = $config['name'];
58 10
        unset($config['name']);
59
60 10
        if (is_array($config['handlers'])) {
61 10
            $config['handlers'] = $this->prepareHandlers($config['handlers']);
62
        }
63
64 8
        if (is_array($config['processors'])) {
65 8
            $config['processors'] = $this->prepareProcessors($config['processors']);
66
        }
67
68 7
        return $this->getLoggerFactory()->createLogger($name, $config);
69
    }
70
71 10
    protected function getContainer(): ContainerInterface
72
    {
73 10
        return $this->container;
74
    }
75
76 10
    private function prepareHandlers(array $handlers): array
77
    {
78
        return array_map(function ($handler) {
79 9
            if (is_string($handler)) {
80 4
                $handler = $this->resolveHandler($handler);
81 8
            } elseif (is_array($handler) && isset($handler['options']['formatter']) && is_string($handler['options']['formatter'])) {
82 4
                $handler['options']['formatter'] = $this->resolveFormatter($handler['options']['formatter']);
83
            }
84
85 7
            return $handler;
86 10
        }, $handlers);
87
    }
88
89 8
    private function prepareProcessors(array $processors): array
90
    {
91
        return array_map(function ($processor) {
92 6
            if (is_string($processor)) {
93 4
                $processor = $this->resolveProcessor($processor);
94
            }
95
96 5
            return $processor;
97 8
        }, $processors);
98
    }
99
100 4
    private function resolveHandler(string $handlerName): HandlerInterface
101
    {
102 4
        return $this->resolveFromContainer($handlerName);
103
    }
104
105 4
    private function resolveFormatter(string $formatterName): FormatterInterface
106
    {
107 4
        return $this->resolveFromContainer($formatterName);
108
    }
109
110 4
    private function resolveProcessor(string $processorName): callable
111
    {
112 4
        return $this->resolveFromContainer($processorName);
113
    }
114
115 6
    private function resolveFromContainer(string $serviceOrFactory)
116
    {
117
        try {
118 6
            if ($this->container->has($serviceOrFactory)) {
119 3
                return $this->container->get($serviceOrFactory);
120
            }
121
122 6
            if (class_exists($serviceOrFactory)) {
123 3
                $factory = new $serviceOrFactory();
124 6
                return $factory($this->container);
125
            }
126
        } catch (Throwable $ex) {
127
            throw CannotResolveLoggerComponent::resolutionFailed($serviceOrFactory, $ex);
128
        }
129
130 3
        throw CannotResolveLoggerComponent::unknownService($serviceOrFactory);
131
    }
132
133 7
    private function getLoggerFactory(): LoggerFactory
134
    {
135 7
        if (null === $this->loggerFactory) {
136 7
            $this->loggerFactory = new LoggerFactory();
137
        }
138
139 7
        return $this->loggerFactory;
140
    }
141
}
142