Passed
Push — main ( aee526...df35b1 )
by Tan
13:15
created

CallbackService::handleSettingsBack()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace CSlant\LaravelTelegramGitNotifier\Services;
6
7
use CSlant\LaravelTelegramGitNotifier\Traits\Markup;
8
use CSlant\TelegramGitNotifier\Bot;
9
use CSlant\TelegramGitNotifier\Constants\SettingConstant;
10
use CSlant\TelegramGitNotifier\Exceptions\BotException;
11
use CSlant\TelegramGitNotifier\Exceptions\CallbackException;
12
use CSlant\TelegramGitNotifier\Exceptions\InvalidViewTemplateException;
13
use CSlant\TelegramGitNotifier\Exceptions\MessageIsEmptyException;
14
use Illuminate\Support\Facades\Config;
15
16
class CallbackService
17
{
18
    use Markup;
19
20
    private const CONFIG_VIEW_NAMESPACE = 'telegram-git-notifier.view.namespace';
21
22
    public function __construct(
23
        private Bot $bot,
24
        private string $viewNamespace
25
    ) {
26
    }
27
28
    public static function create(Bot $bot): self
29
    {
30
        return new self(
31
            $bot,
32
            (string) Config::get(self::CONFIG_VIEW_NAMESPACE, '')
33
        );
34
    }
35
36
    /**
37
     * Answer the back button.
38
     *
39
     * @throws MessageIsEmptyException
40
     * @throws BotException
41
     * @throws CallbackException
42
     */
43
    public function answerBackButton(string $callback): void
44
    {
45
        $callback = str_replace(SettingConstant::SETTING_BACK, '', $callback);
46
47
        $result = match ($callback) {
48
            'settings' => $this->handleSettingsBack(),
49
            'settings.custom_events.github' => $this->handleGithubEventsBack(),
50
            'settings.custom_events.gitlab' => $this->handleGitlabEventsBack(),
51
            'menu' => $this->handleMenuBack(),
52
            default => null,
53
        };
54
55
        if ($result === null) {
56
            $this->bot->answerCallbackQuery(__('tg-notifier::app.unknown_callback'));
57
58
            return;
59
        }
60
61
        ['view' => $view, 'markup' => $markup] = $result;
62
        $this->bot->editMessageText($view, ['reply_markup' => $markup]);
63
    }
64
65
    /**
66
     * Handle settings back button.
67
     *
68
     * @return array{view: string, markup: mixed}
69
     */
70
    private function handleSettingsBack(): array
71
    {
72
        return [
73
            'view' => view("$this->viewNamespace::tools.settings"),
74
            'markup' => $this->bot->settingMarkup(),
75
        ];
76
    }
77
78
    /**
79
     * Handle GitHub events back button.
80
     *
81
     * @return array{view: string, markup: mixed}
82
     */
83
    private function handleGithubEventsBack(): array
84
    {
85
        return [
86
            'view' => view("$this->viewNamespace::tools.custom_event", ['platform' => 'github']),
87
            'markup' => $this->bot->eventMarkup(),
88
        ];
89
    }
90
91
    /**
92
     * Handle GitLab events back button.
93
     *
94
     * @return array{view: string, markup: mixed}
95
     */
96
    private function handleGitlabEventsBack(): array
97
    {
98
        return [
99
            'view' => view("$this->viewNamespace::tools.custom_event", ['platform' => 'gitlab']),
100
            'markup' => $this->bot->eventMarkup(null, 'gitlab'),
101
        ];
102
    }
103
104
    /**
105
     * Handle menu back button.
106
     *
107
     * @return array{view: string, markup: mixed}
108
     */
109
    private function handleMenuBack(): array
110
    {
111
        return [
112
            'view' => view("$this->viewNamespace::tools.menu"),
113
            'markup' => $this->menuMarkup($this->bot->telegram),
114
        ];
115
    }
116
117
    /**
118
     * Handle the callback action.
119
     *
120
     * @throws MessageIsEmptyException
121
     * @throws InvalidViewTemplateException
122
     * @throws BotException
123
     * @throws CallbackException
124
     */
125
    public function handle(): void
126
    {
127
        $callback = (string) $this->bot->telegram->Callback_Data();
128
129
        if ($this->handleCustomEvents($callback) || $this->handleBackButton($callback)) {
130
            return;
131
        }
132
133
        $this->handleSettingUpdate($callback);
134
    }
135
136
    /**
137
     * Handle custom events callback.
138
     */
139
    private function handleCustomEvents(string $callback): bool
140
    {
141
        if (!str_contains($callback, SettingConstant::SETTING_CUSTOM_EVENTS)) {
142
            return false;
143
        }
144
145
        $this->bot->eventHandle($callback);
146
147
        return true;
148
    }
149
150
    /**
151
     * Handle back button callback.
152
     */
153
    private function handleBackButton(string $callback): bool
154
    {
155
        if (!str_contains($callback, SettingConstant::SETTING_BACK)) {
156
            return false;
157
        }
158
159
        $this->answerBackButton($callback);
160
161
        return true;
162
    }
163
164
    /**
165
     * Handle setting update callback.
166
     */
167
    private function handleSettingUpdate(string $callback): void
168
    {
169
        $settingKey = str_replace(SettingConstant::SETTING_PREFIX, '', $callback);
170
        $settings = $this->bot->setting->getSettings();
171
172
        if (!array_key_exists($settingKey, $settings)) {
173
            return;
174
        }
175
176
        $newValue = !$settings[$settingKey];
177
        $success = $this->bot->setting->updateSetting($settingKey, $newValue);
178
179
        if ($success) {
180
            $this->updateMessageMarkup();
181
        } else {
182
            $this->sendUnknownCallbackError();
183
        }
184
    }
185
186
    /**
187
     * Update the message markup with the latest settings.
188
     */
189
    private function updateMessageMarkup(): void
190
    {
191
        $this->bot->editMessageReplyMarkup([
192
            'reply_markup' => $this->bot->settingMarkup(),
193
        ]);
194
    }
195
196
    /**
197
     * Send an unknown callback error to the user.
198
     */
199
    private function sendUnknownCallbackError(): void
200
    {
201
        $this->bot->answerCallbackQuery(__('tg-notifier::app.unknown_callback'));
202
    }
203
}
204