Passed
Push — master ( 7f7158...8d1ed5 )
by Armando
02:55
created

Command::isAdminCommand()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\TelegramBot\Commands;
12
13
use Longman\TelegramBot\DB;
14
use Longman\TelegramBot\Entities\CallbackQuery;
15
use Longman\TelegramBot\Entities\ChosenInlineResult;
16
use Longman\TelegramBot\Entities\InlineQuery;
17
use Longman\TelegramBot\Entities\Message;
18
use Longman\TelegramBot\Entities\Payments\PreCheckoutQuery;
19
use Longman\TelegramBot\Entities\Payments\ShippingQuery;
20
use Longman\TelegramBot\Entities\Poll;
21
use Longman\TelegramBot\Entities\ServerResponse;
22
use Longman\TelegramBot\Entities\Update;
23
use Longman\TelegramBot\Exception\TelegramException;
24
use Longman\TelegramBot\Request;
25
use Longman\TelegramBot\Telegram;
26
27
/**
28
 * Class Command
29
 *
30
 * Base class for commands. It includes some helper methods that can fetch data directly from the Update object.
31
 *
32
 * @method Message             getMessage()            Optional. New incoming message of any kind — text, photo, sticker, etc.
33
 * @method Message             getEditedMessage()      Optional. New version of a message that is known to the bot and was edited
34
 * @method Message             getChannelPost()        Optional. New post in the channel, can be any kind — text, photo, sticker, etc.
35
 * @method Message             getEditedChannelPost()  Optional. New version of a post in the channel that is known to the bot and was edited
36
 * @method InlineQuery         getInlineQuery()        Optional. New incoming inline query
37
 * @method ChosenInlineResult  getChosenInlineResult() Optional. The result of an inline query that was chosen by a user and sent to their chat partner.
38
 * @method CallbackQuery       getCallbackQuery()      Optional. New incoming callback query
39
 * @method ShippingQuery       getShippingQuery()      Optional. New incoming shipping query. Only for invoices with flexible price
40
 * @method PreCheckoutQuery    getPreCheckoutQuery()   Optional. New incoming pre-checkout query. Contains full information about checkout
41
 * @method Poll                getPoll()               Optional. New poll state. Bots receive only updates about polls, which are sent or stopped by the bot
42
 */
43
abstract class Command
44
{
45
    /**
46
     * Telegram object
47
     *
48
     * @var Telegram
49
     */
50
    protected $telegram;
51
52
    /**
53
     * Update object
54
     *
55
     * @var Update
56
     */
57
    protected $update;
58
59
    /**
60
     * Name
61
     *
62
     * @var string
63
     */
64
    protected $name = '';
65
66
    /**
67
     * Description
68
     *
69
     * @var string
70
     */
71
    protected $description = 'Command description';
72
73
    /**
74
     * Usage
75
     *
76
     * @var string
77
     */
78
    protected $usage = 'Command usage';
79
80
    /**
81
     * Show in Help
82
     *
83
     * @var bool
84
     */
85
    protected $show_in_help = true;
86
87
    /**
88
     * Version
89
     *
90
     * @var string
91
     */
92
    protected $version = '1.0.0';
93
94
    /**
95
     * If this command is enabled
96
     *
97
     * @var boolean
98
     */
99
    protected $enabled = true;
100
101
    /**
102
     * If this command needs mysql
103
     *
104
     * @var boolean
105
     */
106
    protected $need_mysql = false;
107
108
    /*
109
    * Make sure this command only executes on a private chat.
110
    *
111
    * @var bool
112
    */
113
    protected $private_only = false;
114
115
    /**
116
     * Command config
117
     *
118
     * @var array
119
     */
120
    protected $config = [];
121
122
    /**
123
     * Constructor
124
     *
125
     * @param Telegram $telegram
126
     * @param Update   $update
127
     */
128 15
    public function __construct(Telegram $telegram, Update $update = null)
129
    {
130 15
        $this->telegram = $telegram;
131 15
        $this->setUpdate($update);
132 15
        $this->config = $telegram->getCommandConfig($this->name);
133 15
    }
134
135
    /**
136
     * Set update object
137
     *
138
     * @param Update $update
139
     *
140
     * @return Command
141
     */
142 15
    public function setUpdate(Update $update = null)
143
    {
144 15
        if ($update !== null) {
145 1
            $this->update = $update;
146
        }
147
148 15
        return $this;
149
    }
150
151
    /**
152
     * Pre-execute command
153
     *
154
     * @return ServerResponse
155
     * @throws TelegramException
156
     */
157
    public function preExecute()
158
    {
159
        if ($this->need_mysql && !($this->telegram->isDbEnabled() && DB::isDbConnected())) {
160
            return $this->executeNoDb();
161
        }
162
163
        if ($this->isPrivateOnly() && $this->removeNonPrivateMessage()) {
164
            $message = $this->getMessage();
165
166
            if ($user = $message->getFrom()) {
167
                return Request::sendMessage([
168
                    'chat_id'    => $user->getId(),
169
                    'parse_mode' => 'Markdown',
170
                    'text'       => sprintf(
171
                        "/%s command is only available in a private chat.\n(`%s`)",
172
                        $this->getName(),
173
                        $message->getText()
174
                    ),
175
                ]);
176
            }
177
178
            return Request::emptyResponse();
179
        }
180
181
        return $this->execute();
182
    }
183
184
    /**
185
     * Execute command
186
     *
187
     * @return ServerResponse
188
     * @throws TelegramException
189
     */
190
    abstract public function execute();
191
192
    /**
193
     * Execution if MySQL is required but not available
194
     *
195
     * @return ServerResponse
196
     * @throws TelegramException
197
     */
198
    public function executeNoDb()
199
    {
200
        //Preparing message
201
        $message = $this->getMessage();
202
        $chat_id = $message->getChat()->getId();
203
204
        $data = [
205
            'chat_id' => $chat_id,
206
            'text'    => 'Sorry no database connection, unable to execute "' . $this->name . '" command.',
207
        ];
208
209
        return Request::sendMessage($data);
210
    }
211
212
    /**
213
     * Get update object
214
     *
215
     * @return Update
216
     */
217 1
    public function getUpdate()
218
    {
219 1
        return $this->update;
220
    }
221
222
    /**
223
     * Relay any non-existing function calls to Update object.
224
     *
225
     * This is purely a helper method to make requests from within execute() method easier.
226
     *
227
     * @param string $name
228
     * @param array  $arguments
229
     *
230
     * @return Command
231
     */
232 1
    public function __call($name, array $arguments)
233
    {
234 1
        if ($this->update === null) {
235 1
            return null;
236
        }
237 1
        return call_user_func_array([$this->update, $name], $arguments);
238
    }
239
240
    /**
241
     * Get command config
242
     *
243
     * Look for config $name if found return it, if not return null.
244
     * If $name is not set return all set config.
245
     *
246
     * @param string|null $name
247
     *
248
     * @return array|mixed|null
249
     */
250 1
    public function getConfig($name = null)
251
    {
252 1
        if ($name === null) {
253 1
            return $this->config;
254
        }
255 1
        if (isset($this->config[$name])) {
256 1
            return $this->config[$name];
257
        }
258
259 1
        return null;
260
    }
261
262
    /**
263
     * Get telegram object
264
     *
265
     * @return Telegram
266
     */
267 1
    public function getTelegram()
268
    {
269 1
        return $this->telegram;
270
    }
271
272
    /**
273
     * Get usage
274
     *
275
     * @return string
276
     */
277 1
    public function getUsage()
278
    {
279 1
        return $this->usage;
280
    }
281
282
    /**
283
     * Get version
284
     *
285
     * @return string
286
     */
287 1
    public function getVersion()
288
    {
289 1
        return $this->version;
290
    }
291
292
    /**
293
     * Get description
294
     *
295
     * @return string
296
     */
297 1
    public function getDescription()
298
    {
299 1
        return $this->description;
300
    }
301
302
    /**
303
     * Get name
304
     *
305
     * @return string
306
     */
307 1
    public function getName()
308
    {
309 1
        return $this->name;
310
    }
311
312
    /**
313
     * Get Show in Help
314
     *
315
     * @return bool
316
     */
317 1
    public function showInHelp()
318
    {
319 1
        return $this->show_in_help;
320
    }
321
322
    /**
323
     * Check if command is enabled
324
     *
325
     * @return bool
326
     */
327 1
    public function isEnabled()
328
    {
329 1
        return $this->enabled;
330
    }
331
332
    /**
333
     * If this command is intended for private chats only.
334
     *
335
     * @return bool
336
     */
337
    public function isPrivateOnly()
338
    {
339
        return $this->private_only;
340
    }
341
342
    /**
343
     * If this is a SystemCommand
344
     *
345
     * @return bool
346
     */
347
    public function isSystemCommand()
348
    {
349
        return ($this instanceof SystemCommand);
350
    }
351
352
    /**
353
     * If this is an AdminCommand
354
     *
355
     * @return bool
356
     */
357
    public function isAdminCommand()
358
    {
359
        return ($this instanceof AdminCommand);
360
    }
361
362
    /**
363
     * If this is a UserCommand
364
     *
365
     * @return bool
366
     */
367
    public function isUserCommand()
368
    {
369
        return ($this instanceof UserCommand);
370
    }
371
372
    /**
373
     * Delete the current message if it has been called in a non-private chat.
374
     *
375
     * @return bool
376
     */
377
    protected function removeNonPrivateMessage()
378
    {
379
        $message = $this->getMessage() ?: $this->getEditedMessage();
380
381
        if ($message) {
0 ignored issues
show
introduced by
$message is of type Longman\TelegramBot\Entities\Message, thus it always evaluated to true.
Loading history...
382
            $chat = $message->getChat();
383
384
            if (!$chat->isPrivateChat()) {
385
                // Delete the falsely called command message.
386
                Request::deleteMessage([
387
                    'chat_id'    => $chat->getId(),
388
                    'message_id' => $message->getMessageId(),
389
                ]);
390
391
                return true;
392
            }
393
        }
394
395
        return false;
396
    }
397
398
    /**
399
     * Helper to reply to a chat directly.
400
     *
401
     * @param string $text
402
     * @param array  $data
403
     *
404
     * @return ServerResponse
405
     * @throws TelegramException
406
     */
407
    public function replyToChat($text, array $data = [])
408
    {
409
        if ($message = $this->getMessage() ?: $this->getEditedMessage() ?: $this->getChannelPost() ?: $this->getEditedChannelPost()) {
410
            return Request::sendMessage(array_merge([
411
                'chat_id' => $message->getChat()->getId(),
412
                'text'    => $text,
413
            ], $data));
414
        }
415
416
        return Request::emptyResponse();
417
    }
418
419
    /**
420
     * Helper to reply to a user directly.
421
     *
422
     * @param string $text
423
     * @param array  $data
424
     *
425
     * @return ServerResponse
426
     * @throws TelegramException
427
     */
428
    public function replyToUser($text, array $data = [])
429
    {
430
        if ($message = $this->getMessage() ?: $this->getEditedMessage()) {
431
            return Request::sendMessage(array_merge([
432
                'chat_id' => $message->getFrom()->getId(),
433
                'text'    => $text,
434
            ], $data));
435
        }
436
437
        return Request::emptyResponse();
438
    }
439
}
440