Passed
Push — logger ( fa6ca8...aacfbb )
by Arnaud
05:39 queued 02:50
created

PrintLogger::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Logger;
12
13
use Cecil\Builder;
14
use Psr\Log\AbstractLogger;
15
use Psr\Log\InvalidArgumentException;
16
use Psr\Log\LogLevel;
17
18
class PrintLogger extends AbstractLogger
19
{
20
    /** @var int */
21
    protected $printLevel = null;
22
    /** @var array */
23
    private $verbosityLevelMap = [
24
        LogLevel::EMERGENCY => Builder::VERBOSITY_NORMAL,
25
        LogLevel::ALERT     => Builder::VERBOSITY_NORMAL,
26
        LogLevel::CRITICAL  => Builder::VERBOSITY_NORMAL,
27
        LogLevel::ERROR     => Builder::VERBOSITY_NORMAL,
28
        LogLevel::WARNING   => Builder::VERBOSITY_NORMAL,
29
        LogLevel::NOTICE    => Builder::VERBOSITY_NORMAL,
30
        LogLevel::INFO      => Builder::VERBOSITY_VERBOSE,
31
        LogLevel::DEBUG     => Builder::VERBOSITY_DEBUG,
32
    ];
33
34
    /**
35
     * @var int Print only this maximum level.
36
     */
37
    public function __construct(int $printLevel = null)
38
    {
39
        $this->printLevel = $printLevel;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     *
45
     * @return void
46
     */
47
    public function log($level, $message, array $context = [])
48
    {
49
        if (!isset($this->verbosityLevelMap[$level])) {
50
            throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
51
        }
52
53
        if ($this->printLevel !== null && $this->verbosityLevelMap[$level] > $this->printLevel) {
54
            return;
55
        }
56
57
        if (array_key_exists('progress', $context)) {
58
            printf(
59
                " (%s/%s) %s\n",
60
                $context['progress'][0],
61
                $context['progress'][1],
62
                $this->interpolate($message, $context)
63
            );
64
65
            return;
66
        }
67
68
        printf("[%s] %s\n", $level, $this->interpolate($message, $context));
69
    }
70
71
    /**
72
     * Interpolates context values into the message placeholders.
73
     *
74
     * @author PHP Framework Interoperability Group
75
     */
76
    private function interpolate(string $message, array $context): string
77
    {
78
        if (false === strpos($message, '{')) {
79
            return $message;
80
        }
81
82
        $replacements = [];
83
        foreach ($context as $key => $val) {
84
            if (null === $val || is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) {
85
                $replacements["{{$key}}"] = $val;
86
            } elseif ($val instanceof \DateTimeInterface) {
87
                $replacements["{{$key}}"] = $val->format(\DateTime::RFC3339);
88
            } elseif (\is_object($val)) {
89
                $replacements["{{$key}}"] = '[object '.\get_class($val).']';
90
            } else {
91
                $replacements["{{$key}}"] = '['.\gettype($val).']';
92
            }
93
        }
94
95
        return strtr($message, $replacements);
96
    }
97
}
98