Completed
Push — master ( ea9893...01c438 )
by Nikola
03:09
created

ContainerInteropLoggerFactory::resolveFormatter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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