Completed
Push — master ( a84ecf...ac90c5 )
by Nikola
01:16
created

resolveFromContainer()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

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