ConsoleLogger::interpolate()   B
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 3
nop 2
dl 0
loc 13
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/*
3
 * Copyright (c) 2015 Juan José Torroglosa Ramón
4
 *
5
 * This file is part of the Cliphar package.
6
 *
7
 * For the full copyright and license information, please view
8
 * the LICENSE file that was distributed with this source code.
9
 */
10
11
namespace Cliphar\Logger;
12
13
use Cliphar\Logger\Decorator\ConsoleMessageDecorator;
14
use Psr\Log\AbstractLogger;
15
use Psr\Log\LogLevel;
16
use Symfony\Component\Console\Output\ConsoleOutputInterface;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
class ConsoleLogger extends AbstractLogger
20
{
21
    private $levelToInt = array(
22
        LogLevel::DEBUG => 10,
23
        LogLevel::INFO => 20,
24
        LogLevel::NOTICE => 30,
25
        LogLevel::WARNING => 40,
26
        LogLevel::ERROR => 50,
27
        LogLevel::CRITICAL => 60,
28
        LogLevel::ALERT => 70,
29
        LogLevel::EMERGENCY => 80
30
    );
31
32
    /**
33
     * @var array
34
     */
35
    private $verbosityLevelMap = array(
36
        LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
37
        LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
38
        LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
39
        LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
40
        LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
41
        LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
42
        LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
43
        LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
44
    );
45
46
    /**
47
     * @var OutputInterface
48
     */
49
    private $output;
50
51
    /**
52
     * @var string
53
     */
54
    private $levelThresholdToStderr;
55
56
    /**
57
     * @var ConsoleMessageDecorator|null
58
     */
59
    private $decorator;
60
61
    /**
62
     * @param OutputInterface $output
63
     * @param string $levelThresholdToStderr
64
     * @param array $verbosityLevelMap
65
     * @param ConsoleMessageDecorator|null $decorator
66
     */
67
    public function __construct(
68
        OutputInterface $output,
69
        $levelThresholdToStderr = LogLevel::WARNING,
70
        $verbosityLevelMap = array(),
71
        $decorator = null
72
    ) {
73
        $this->output = $output;
74
        $this->levelThresholdToStderr = $levelThresholdToStderr;
75
        $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
76
        $this->decorator = $decorator ?: new ConsoleMessageDecorator();
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function log($level, $message, array $context = array())
83
    {
84
        // Write to the error output if necessary and available
85
        if ($this->isStderrThresholdReached($level) && $this->output instanceof ConsoleOutputInterface) {
86
            $output = $this->output->getErrorOutput();
87
        } else {
88
            $output = $this->output;
89
        }
90
91
        if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
92
            $output->writeln($this->getDecoratedMessage($level, $this->interpolate($message, $context)));
93
        }
94
    }
95
96
    /**
97
     * Interpolates context values into the message placeholders
98
     *
99
     * @author PHP Framework Interoperability Group
100
     *
101
     * @param string $message
102
     * @param array  $context
103
     *
104
     * @return string
105
     */
106
    private function interpolate($message, array $context)
107
    {
108
        // build a replacement array with braces around the context keys
109
        $replace = array();
110
        foreach ($context as $key => $val) {
111
            if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
112
                $replace[sprintf('{%s}', $key)] = $val;
113
            }
114
        }
115
116
        // interpolate replacement values into the message and return
117
        return strtr($message, $replace);
118
    }
119
120
    /**
121
     * @param $level
122
     * @return bool
123
     */
124
    private function isStderrThresholdReached($level)
125
    {
126
        return $this->levelToInt[$level] >= $this->levelToInt[$this->levelThresholdToStderr];
127
    }
128
129
    /**
130
     * @param $level
131
     * @param $message
132
     * @return string
133
     */
134
    private function getDecoratedMessage($level, $message)
135
    {
136
        return $this->decorator->decorate($level, $message);
137
    }
138
}