Passed
Push — master ( 794acd...02fb57 )
by Shahrad
11:32
created

CrashPad::message()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 1
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace TelegramBot;
5
6
/**
7
 * CrashPad class
8
 *
9
 * @link    https://github.com/telegram-bot-php/core
10
 * @author  Shahrad Elahi (https://github.com/shahradelahi)
11
 * @license https://github.com/telegram-bot-php/core/blob/master/LICENSE (MIT License)
12
 */
13
class CrashPad
14
{
15
16
    /**
17
     * Report the error to the developers from the Telegram Bot API.
18
     *
19
     * @param \Exception $exception The exception to report.
20
     * @retrun void
21
     */
22
    public static function report(\Exception $exception): void
23
    {
24
        TelegramLog::error(($message = self::message($exception)));
25
        echo '<b>TelegramError:</b> ' . $message;
26
    }
27
28
    /**
29
     * Create crash message
30
     *
31
     * @param \Exception $exception The exception
32
     * @retrun string
33
     */
34
    private static function message(\Exception $exception): string
35
    {
36
        return sprintf(
37
            "%s(%d): %s\n%s",
38
            $exception->getFile(),
39
            $exception->getLine(),
40
            $exception->getMessage(),
41
            $exception->getTraceAsString()
42
        );
43
    }
44
45
    /**
46
     * Send crash message and log
47
     *
48
     * @param int $chat_id The chat id of the group to send the message to.
49
     * @param \Exception $exception The exception to report.
50
     * @param string|null $update (Optional) The update that caused the exception.
51
     *
52
     * @retrun bool
53
     */
54
    public static function sendCrash(int $chat_id, \Exception $exception, string|null $update = null): bool
55
    {
56
        if ($chat_id === -1) {
57
            throw new \RuntimeException(sprintf(
58
                'The given `chat_id` is not valid. given: %s',
59
                $chat_id
60
            ));
61
        }
62
63
        $text = Request::sendMessage([
64
            'chat_id' => $chat_id,
65
            'text' => ($message = self::message($exception)),
66
        ]);
67
68
        if ($update !== null) {
69
            $document = Request::sendDocument([
70
                'chat_id' => $chat_id,
71
                'document' => self::createCrashFile(
72
                    $message . "\n\n" . $update
73
                ),
74
            ]);
75
            return $text->isOk() && $document->isOk();
76
        }
77
78
        return $text->isOk();
79
    }
80
81
    /**
82
     * Create a log file for the error.
83
     *
84
     * @param string $content The content of the log file.
85
     * @retrun string The path of the log file.
86
     */
87
    private static function createCrashFile(string $content): string
88
    {
89
        $base_path = $_SERVER['DOCUMENT_ROOT'] . '.telegram-bot/';
90
        if (!file_exists($base_path)) {
91
            mkdir($base_path, 0777, true);
92
        }
93
94
        file_put_contents(($file = $base_path . uniqid('error_') . '.log'), $content);
95
        return $file;
96
    }
97
98
    /**
99
     * Clear crash files.
100
     *
101
     * @return void
102
     */
103
    public static function clearCrashFiles(): void
104
    {
105
        $files = glob(getcwd() . '.telegram-bot/*.log');
106
        foreach ($files as $file) {
107
            unlink($file);
108
        }
109
    }
110
111
    /**
112
     * Debug mode. Catch the crash reports.
113
     *
114
     * @param int $admin_id (optional) The admin chat id.
115
     * @return void
116
     */
117
    public static function setDebugMode(int $admin_id = -1): void
118
    {
119
        error_reporting(E_ALL);
120
        ini_set('display_errors', '1');
121
122
        defined('DEBUG_MODE') or define('DEBUG_MODE', true);
123
        if ($admin_id !== -1) {
124
            Telegram::setAdminId($admin_id);
125
        }
126
127
        set_exception_handler(function (\Throwable $throwable) {
128
            if (!defined('DEBUG_MODE') && !DEBUG_MODE) {
129
                throw new \RuntimeException(
130
                    $throwable->getMessage(),
131
                    $throwable->getCode(),
132
                    $throwable->getPrevious()
133
                );
134
            } else {
135
                if (Telegram::getAdminId() !== -1) {
136
                    $input = getenv('TG_CURRENT_UPDATE') ?? Telegram::getInput();
137
                    $update = Telegram::processUpdate($input, Telegram::getApiToken());
0 ignored issues
show
Bug introduced by
It seems like TelegramBot\Telegram::getApiToken() can also be of type false; however, parameter $apiKey of TelegramBot\Telegram::processUpdate() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

137
                    $update = Telegram::processUpdate($input, /** @scrutinizer ignore-type */ Telegram::getApiToken());
Loading history...
Bug introduced by
It seems like $input can also be of type null; however, parameter $input of TelegramBot\Telegram::processUpdate() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

137
                    $update = Telegram::processUpdate(/** @scrutinizer ignore-type */ $input, Telegram::getApiToken());
Loading history...
138
                    $exception = new \Exception($throwable->getMessage(), $throwable->getCode(), $throwable->getPrevious());
139
                    CrashPad::sendCrash(Telegram::getAdminId(), $exception, json_encode($update));
140
                    CrashPad::report($exception);
141
                }
142
            }
143
        });
144
    }
145
146
}