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

AbstractDiContainerLoggerFactory::__callStatic()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 2
nop 2
crap 3
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