Passed
Push — master ( 627c19...f3fe5e )
by Armando
03:09
created

TelegramLog::__callStatic()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

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