Completed
Push — master ( 2d4091...8b66fd )
by Nikola
11s
created

AbstractDiContainerLoggerFactory   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

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