TelegramLog   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 19
eloc 35
c 1
b 0
f 0
dl 0
loc 138
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A endDebugLogTempStream() 0 13 3
A interpolate() 0 13 5
A __callStatic() 0 22 5
A initialize() 0 4 3
A getDebugLogTempStream() 0 7 3
1
<?php
2
3
namespace TelegramBot;
4
5
use Psr\Log\LoggerInterface;
6
use Psr\Log\NullLogger;
7
8
/**
9
 * TelegramLog class
10
 *
11
 * @author Avtandil Kikabidze aka LONGMAN <[email protected]>
12
 * @license The MIT License (MIT)
13
 * @version 0.79.0
14
 *
15
 * @method static void emergency(string $message, array $context = [])
16
 * @method static void alert(string $message, array $context = [])
17
 * @method static void critical(string $message, array $context = [])
18
 * @method static void error(string $message, array $context = [])
19
 * @method static void warning(string $message, array $context = [])
20
 * @method static void notice(string $message, array $context = [])
21
 * @method static void info(string $message, array $context = [])
22
 * @method static void debug(string $message, array $context = [])
23
 * @method static void update(string $message, array $context = [])
24
 */
25
class TelegramLog
26
{
27
28
    /**
29
     * Logger instance
30
     *
31
     * @var LoggerInterface
32
     */
33
    protected static $logger;
34
35
    /**
36
     * Logger instance for update
37
     *
38
     * @var LoggerInterface
39
     */
40
    protected static $update_logger;
41
42
    /**
43
     * Always log the request and response data to the debug log, also for successful requests
44
     *
45
     * @var bool
46
     */
47
    public static $always_log_request_and_response = false;
48
49
    /**
50
     * Temporary stream handle for debug log
51
     *
52
     * @var resource|null
53
     */
54
    protected static $debug_log_temp_stream_handle;
55
56
    /**
57
     * Remove bot token from debug stream
58
     *
59
     * @var bool
60
     */
61
    public static $remove_bot_token = true;
62
63
    /**
64
     * Initialise logging.
65
     *
66
     * @param LoggerInterface|null $logger
67
     * @param LoggerInterface|null $update_logger
68
     */
69
    public static function initialize(LoggerInterface $logger = null, LoggerInterface $update_logger = null): void
70
    {
71
        self::$logger        = $logger ?: new NullLogger();
72
        self::$update_logger = $update_logger ?: new NullLogger();
73
    }
74
75
    /**
76
     * Get the stream handle of the temporary debug output
77
     *
78
     * @return mixed The stream if debug is active, else false
79
     */
80
    public static function getDebugLogTempStream()
81
    {
82
        if ((self::$debug_log_temp_stream_handle === null) && $temp_stream_handle = fopen('php://temp', 'wb+')) {
83
            self::$debug_log_temp_stream_handle = $temp_stream_handle;
84
        }
85
86
        return self::$debug_log_temp_stream_handle;
87
    }
88
89
    /**
90
     * Write the temporary debug stream to log and close the stream handle
91
     *
92
     * @param string $message Message (with placeholder) to write to the debug log
93
     */
94
    public static function endDebugLogTempStream($message = '%s'): void
95
    {
96
        if (is_resource(self::$debug_log_temp_stream_handle)) {
97
            rewind(self::$debug_log_temp_stream_handle);
98
            $stream_contents = stream_get_contents(self::$debug_log_temp_stream_handle);
99
100
            if (self::$remove_bot_token) {
101
                $stream_contents = preg_replace('/\/bot(\d+):[\w\-]+\//', '/botBOT_TOKEN_REMOVED/', $stream_contents);
102
            }
103
104
            self::debug(sprintf($message, $stream_contents));
105
            fclose(self::$debug_log_temp_stream_handle);
106
            self::$debug_log_temp_stream_handle = null;
107
        }
108
    }
109
110
    /**
111
     * Handle any logging method call.
112
     *
113
     * @param string $name
114
     * @param array  $arguments
115
     */
116
    public static function __callStatic(string $name, array $arguments)
117
    {
118
        // Get the correct logger instance.
119
        $logger = null;
120
        if (in_array($name, ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug',], true)) {
121
            $logger = self::$logger;
122
        } elseif ($name === 'update') {
123
            $logger = self::$update_logger;
124
            $name   = 'info';
125
        }
126
127
        // Clearly we have no logging enabled.
128
        if ($logger === null) {
129
            return;
130
        }
131
132
        // Replace any placeholders from the passed context.
133
        if (count($arguments) >= 2) {
134
            $arguments[0] = self::interpolate($arguments[0], $arguments[1]);
135
        }
136
137
        call_user_func_array([$logger, $name], $arguments);
138
    }
139
140
    /**
141
     * Interpolates context values into the message placeholders.
142
     *
143
     * @see https://www.php-fig.org/psr/psr-3/#12-message
144
     *
145
     * @param string $message
146
     * @param array  $context
147
     *
148
     * @return string
149
     */
150
    protected static function interpolate(string $message, array $context = []): string
151
    {
152
        // Build a replacement array with braces around the context keys.
153
        $replace = [];
154
        foreach ($context as $key => $val) {
155
            // check that the value can be casted to string
156
            if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
157
                $replace["{{$key}}"] = $val;
158
            }
159
        }
160
161
        // Interpolate replacement values into the message and return.
162
        return strtr($message, $replace);
163
    }
164
165
}
166