Passed
Push — master ( dc96af...1f8a30 )
by Alexander
02:08
created

Message::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Log;
6
7
use Psr\Log\InvalidArgumentException;
8
use Psr\Log\LoggerTrait;
9
use Psr\Log\LogLevel;
10
use Yiisoft\VarDumper\VarDumper;
11
12
use function is_scalar;
13
use function is_object;
14
use function method_exists;
15
use function preg_replace_callback;
16
17
/**
18
 * Message is a data object that stores log message data.
19
 */
20
final class Message
21
{
22
    /**
23
     * @var string Log message level.
24
     *
25
     * @see LogLevel See constants for valid level names.
26
     */
27
    private string $level;
28
29
    /**
30
     * @var string Log message.
31
     */
32
    private string $message;
33
34
    /**
35
     * @var array Log message context.
36
     *
37
     * Message context has a following keys:
38
     *
39
     * - category: string, message category.
40
     * - memory: int, memory usage in bytes, obtained by `memory_get_usage()`.
41
     * - time: float, message timestamp obtained by microtime(true).
42
     * - trace: array, debug backtrace, contains the application code call stacks.
43
     */
44
    private array $context;
45
46
    /**
47
     * @param mixed $level Log message level.
48
     * @param mixed $message Log message.
49
     * @param array $context Log message context.
50
     *
51
     * @throws InvalidArgumentException for invalid log message level.
52
     *
53
     * @see LoggerTrait::log()
54
     * @see LogLevel
55
     */
56 139
    public function __construct($level, $message, array $context = [])
57
    {
58 139
        $this->level = Logger::validateLevel($level);
59 138
        $this->message = $this->parse($message, $context);
60 138
        $this->context = $context;
61 138
    }
62
63
    /**
64
     * Gets a log message level.
65
     *
66
     * @return string Log message level.
67
     */
68 92
    public function level(): string
69
    {
70 92
        return $this->level;
71
    }
72
73
    /**
74
     * Gets a log message.
75
     *
76
     * @return string Log message.
77
     */
78 101
    public function message(): string
79
    {
80 101
        return $this->message;
81
    }
82
83
    /**
84
     * Returns a value of the context parameter for the specified name.
85
     *
86
     * If no name is specified, the entire context is returned.
87
     *
88
     * @param string|null $name The context parameter name.
89
     * @param mixed $default If the context parameter does not exist, the `$default` will be returned.
90
     *
91
     * @return mixed The context parameter value.
92
     */
93 116
    public function context(string $name = null, $default = null)
94
    {
95 116
        if ($name === null) {
96 49
            return $this->context;
97
        }
98
99 115
        return $this->context[$name] ?? $default;
100
    }
101
102
    /**
103
     * Parses log message resolving placeholders in the form: "{foo}",
104
     * where foo will be replaced by the context data in key "foo".
105
     *
106
     * @param mixed $message Raw log message.
107
     * @param array $context Message context.
108
     *
109
     * @return string Parsed message.
110
     */
111 138
    private function parse($message, array $context): string
112
    {
113 138
        $message = (is_scalar($message) || (is_object($message) && method_exists($message, '__toString')))
114 136
            ? (string) $message
115 138
            : VarDumper::create($message)->export()
116
        ;
117
118 138
        return preg_replace_callback('/{([\w.]+)}/', static function (array $matches) use ($context) {
119 5
            $placeholderName = $matches[1];
120
121 5
            if (isset($context[$placeholderName])) {
122 2
                return (string) $context[$placeholderName];
123
            }
124
125 3
            return $matches[0];
126 138
        }, $message);
127
    }
128
}
129