Test Setup Failed
Push — master ( 7f80a6...f6af0d )
by Carlos
02:39
created

Config::getFormatter()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 4
cp 0
crap 6
1
<?php
2
3
/*
4
 * This file is part of the overtrue/cuttle.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Overtrue\Cuttle;
13
14
use Closure;
15
use InvalidArgumentException;
16
use Monolog\Formatter\FormatterInterface;
17
use Monolog\Formatter\LineFormatter;
18
use Monolog\Handler\HandlerInterface;
19
use Monolog\Handler\StreamHandler;
20
21
/**
22
 * Class Config.
23
 *
24
 * @author overtrue <[email protected]>
25
 */
26
class Config
27
{
28
    /**
29
     * @var array
30
     */
31
    protected $formatters = [];
32
33
    /**
34
     * @var array
35
     */
36
    protected $handlers = [];
37
38
    /**
39
     * @var array
40
     */
41
    protected $processors = [];
42
43
    /**
44
     * @var array
45
     */
46
    protected $channels = [];
47
48
    /**
49
     * Config constructor.
50
     *
51
     * @param array $config
52
     */
53
    public function __construct(array $config)
54
    {
55
        $this->parse($config);
56
    }
57
58
    /**
59
     * @param string $name
60
     *
61
     * @return array
62
     */
63
    public function getChannel(string $name)
64
    {
65
        if (empty($this->channels[$name])) {
66
            throw new InvalidArgumentException("No channel named '{$name}' found.");
67
        }
68
69
        $this->channels[$name]['handlers'] = $this->getHandlers($this->channels[$name]['handlers']);
70
        $this->channels[$name]['processors'] = $this->getProcessors($this->channels[$name]['processors']);
71
72
        return $this->channels[$name];
73
    }
74
75
    /**
76
     * @param array $names
77
     *
78
     * @return array
79
     */
80
    protected function getFormatters(array $names)
81
    {
82
        return array_map(function ($name) {
83
            return $this->getFormatter($name);
84
        }, $names);
85
    }
86
87
    /**
88
     * @param array $names
89
     *
90
     * @return array
91
     */
92
    protected function getHandlers(array $names)
93
    {
94
        return array_map(function ($name) {
95
            return $this->getHandler($name);
96
        }, $names);
97
    }
98
99
    /**
100
     * @param array $names
101
     *
102
     * @return array
103
     */
104
    protected function getProcessors(array $names)
105
    {
106
        return array_map(function ($name) {
107
            return $this->getProcessor($name);
108
        }, $names);
109
    }
110
111
    /**
112
     * @param string $formatterId
113
     *
114
     * @return \Monolog\Formatter\FormatterInterface
115
     */
116
    protected function getFormatter(string $formatterId)
117
    {
118
        if (!$this->formatters[$formatterId] instanceof FormatterInterface) {
119
            $this->formatters[$formatterId] = $this->makeInstance(
0 ignored issues
show
Bug introduced by
The method makeInstance() does not seem to exist on object<Overtrue\Cuttle\Config>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
120
                $this->formatters[$formatterId], 'formatter'
121
            );
122
        }
123
124
        return $this->formatters[$formatterId];
125
    }
126
127
    /**
128
     * @param string $handlerId
129
     *
130
     * @return \Monolog\Handler\HandlerInterface
131
     */
132
    protected function getHandler(string $handlerId)
133
    {
134
        if ($this->handlers[$handlerId] instanceof HandlerInterface) {
135
            return $this->handlers[$handlerId];
136
        }
137
138
        return $this->handlers[$handlerId] = $this->handlers[$handlerId]();
139
    }
140
141
    /**
142
     * @param string $processorId
143
     *
144
     * @return \Monolog\Handler\HandlerInterface
145
     */
146
    protected function getProcessor(string $processorId)
147
    {
148
        if ($this->processors[$processorId] instanceof Closure) {
149
            $this->processors[$processorId] = $this->processors[$processorId]();
150
        }
151
152
        return $this->processors[$processorId];
153
    }
154
155
    /**
156
     * @param array $config
157
     */
158
    protected function parse(array $config): void
159
    {
160
        $this->formatters = $this->formatFormatters($config['formatters'] ?? []);
161
        $this->handlers = $this->formatHandlers($config['handlers'] ?? []);
162
        $this->processors = $this->formatProcessors($config['processors'] ?? []);
163
        $this->channels = $this->formatChannels($config['channels'] ?? []);
164
    }
165
166
    /**
167
     * @param array $formatters
168
     *
169
     * @return array
170
     */
171 View Code Duplication
    protected function formatFormatters(array $formatters = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
172
    {
173
        foreach ($formatters as $id => $option) {
174
            $class = $option['formatter'] ?? LineFormatter::class;
175
            unset($option['formatter']);
176
177
            $formatters[$id] = function () use ($class, $option) {
178
                return (new ClassResolver($class))->resolve($option);
179
            };
180
        }
181
182
        return $formatters;
183
    }
184
185
    /**
186
     * @param array $handlers
187
     *
188
     * @return array
189
     */
190
    protected function formatHandlers(array $handlers = [])
191
    {
192
        foreach ($handlers as $id => $option) {
193
            if (isset($option['formatter']) && !isset($this->formatters[$option['formatter']])) {
194
                throw new InvalidArgumentException(sprintf('Formatter %s not configured.', $option['formatter']));
195
            }
196
197 View Code Duplication
            foreach ($option['processors'] ?? [] as $processorId) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
198
                if (!isset($this->processors[$processorId])) {
199
                    throw new InvalidArgumentException(sprintf('Processor %s not configured.', $processorId));
200
                }
201
            }
202
203
            $class = $option['handler'] ?? StreamHandler::class;
204
            unset($option['handler']);
205
206
            $handlers[$id] = function () use ($class, $option) {
207
                $handler = (new ClassResolver($class))->resolve($option);
208
209
                if (!empty($option['formatter'])) {
210
                    $handler->setFormatter($this->getFormatter($option['formatter']));
211
                }
212
213
                if (!empty($option['processors'])) {
214
                    $handler->pushProcessor($this->getProcessors($option['processors']));
215
                }
216
217
                return $handler;
218
            };
219
        }
220
221
        return $handlers;
222
    }
223
224
    /**
225
     * @param array $processors
226
     *
227
     * @return array
228
     */
229 View Code Duplication
    protected function formatProcessors(array $processors = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
230
    {
231
        foreach ($processors as $id => $option) {
232
            if (empty($option['processor'])) {
233
                continue;
234
            }
235
236
            $class = $option['processor'];
237
            unset($option['processor']);
238
239
            $processors[$id] = function () use ($class, $option) {
240
                return (new ClassResolver($class))->resolve($option);
241
            };
242
        }
243
244
        return $processors;
245
    }
246
247
    /**
248
     * @param array $channels
249
     *
250
     * @return array
251
     */
252
    protected function formatChannels(array $channels = [])
253
    {
254
        foreach ($channels as $id => $option) {
255 View Code Duplication
            foreach ($option['processors'] ?? [] as $processorId) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
                if (!isset($this->processors[$processorId])) {
257
                    throw new InvalidArgumentException(sprintf('Processor %s not configured.', $processorId));
258
                }
259
            }
260
261 View Code Duplication
            foreach ($option['handlers'] ?? [] as $handlerId) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
262
                if (!isset($this->handlers[$handlerId])) {
263
                    throw new InvalidArgumentException(sprintf('Handler %s not configured.', $handlerId));
264
                }
265
            }
266
            $channels[$id] = array_merge(['handlers' => [], 'processors' => []], $option);
267
        }
268
269
        return $channels;
270
    }
271
}
272