Message   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 110
ccs 21
cts 21
cp 1
rs 10
wmc 7

5 Methods

Rating   Name   Duplication   Size   Complexity  
A message() 0 3 1
A parse() 0 14 2
A context() 0 7 2
A level() 0 3 1
A __construct() 0 6 1
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 Stringable;
11
12
use function preg_replace_callback;
13
14
/**
15
 * Message is a data object that stores log message data.
16
 *
17
 * @psalm-type Backtrace = list<array{
18
 *     file:string,
19
 *     line:int,
20
 *     function?:string,
21
 *     class?:string,
22
 *     type?:string,
23
 * }>
24
 * @psalm-type LogMessageContext = array{
25
 *     category?:string,
26
 *     memory?:int,
27
 *     time?:float,
28
 *     trace?:Backtrace,
29
 * }&array
30
 */
31
final class Message
32
{
33
    /**
34
     * @var string Log message level.
35
     *
36
     * @see LogLevel See constants for valid level names.
37
     */
38
    private string $level;
39
40
    /**
41
     * @var string Log message.
42
     */
43
    private string $message;
44
45
    /**
46
     * @var array<string, mixed> Log message context.
47
     * @psalm-var LogMessageContext
48
     *
49
     * Message context has a following keys:
50
     *
51
     * - category: string, message category.
52
     * - memory: int, memory usage in bytes, obtained by `memory_get_usage()`.
53
     * - time: float, message timestamp obtained by microtime(true).
54
     * - trace: array, debug backtrace, contains the application code call stacks.
55
     */
56
    private array $context;
57
58
    /**
59
     * @param string $level Log message level.
60
     * @param string|Stringable $message Log message.
61
     * @param array<string, mixed> $context Log message context.
62
     * @psalm-param LogMessageContext $context
63
     *
64
     * @throws InvalidArgumentException for invalid log message level.
65
     *
66
     * @see LoggerTrait::log()
67
     * @see LogLevel
68
     */
69 134
    public function __construct(string $level, string|Stringable $message, array $context = [])
70
    {
71 134
        Logger::assertLevelIsSupported($level);
72 133
        $this->level = $level;
73 133
        $this->message = $this->parse($message, $context);
74 133
        $this->context = $context;
75
    }
76
77
    /**
78
     * Gets a log message level.
79
     *
80
     * @return string Log message level.
81
     */
82 88
    public function level(): string
83
    {
84 88
        return $this->level;
85
    }
86
87
    /**
88
     * Gets a log message.
89
     *
90
     * @return string Log message.
91
     */
92 97
    public function message(): string
93
    {
94 97
        return $this->message;
95
    }
96
97
    /**
98
     * Returns a value of the context parameter for the specified name.
99
     *
100
     * If no name is specified, the entire context is returned.
101
     *
102
     * @param string|null $name The context parameter name.
103
     * @param mixed $default If the context parameter does not exist, the `$default` will be returned.
104
     *
105
     * @return mixed The context parameter value.
106
     * @psalm-return LogMessageContext|mixed
107
     */
108 116
    public function context(string $name = null, mixed $default = null): mixed
109
    {
110 116
        if ($name === null) {
111 50
            return $this->context;
112
        }
113
114 115
        return $this->context[$name] ?? $default;
115
    }
116
117
    /**
118
     * Parses log message resolving placeholders in the form: "{foo}",
119
     * where foo will be replaced by the context data in key "foo".
120
     *
121
     * @param string|Stringable $message Raw log message.
122
     * @param array<string, mixed> $context Message context.
123
     * @psalm-param LogMessageContext $context
124
     *
125
     * @return string Parsed message.
126
     */
127 133
    private function parse(string|Stringable $message, array $context): string
128
    {
129 133
        $message = (string)$message;
130
131 133
        return preg_replace_callback('/{([\w.]+)}/', static function (array $matches) use ($context) {
132 4
            $placeholderName = $matches[1];
133
134 4
            if (isset($context[$placeholderName])) {
135
                /** @psalm-suppress PossiblyInvalidCast */
136 2
                return (string) $context[$placeholderName];
137
            }
138
139 2
            return $matches[0];
140 133
        }, $message);
141
    }
142
}
143