Completed
Push — 427-fix_forward_date ( f4b67e )
by Armando
02:06
created

Command::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
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\Update;
22
use Longman\TelegramBot\Request;
23
use Longman\TelegramBot\Telegram;
24
25
/**
26
 * Class Command
27
 *
28
 * Base class for commands. It includes some helper methods that can fetch data directly from the Update object.
29
 *
30
 * @method Message             getMessage()            Optional. New incoming message of any kind — text, photo, sticker, etc.
31
 * @method Message             getEditedMessage()      Optional. New version of a message that is known to the bot and was edited
32
 * @method Message             getChannelPost()        Optional. New post in the channel, can be any kind — text, photo, sticker, etc.
33
 * @method Message             getEditedChannelPost()  Optional. New version of a post in the channel that is known to the bot and was edited
34
 * @method InlineQuery         getInlineQuery()        Optional. New incoming inline query
35
 * @method ChosenInlineResult  getChosenInlineResult() Optional. The result of an inline query that was chosen by a user and sent to their chat partner.
36
 * @method CallbackQuery       getCallbackQuery()      Optional. New incoming callback query
37
 * @method ShippingQuery       getShippingQuery()      Optional. New incoming shipping query. Only for invoices with flexible price
38
 * @method PreCheckoutQuery    getPreCheckoutQuery()   Optional. New incoming pre-checkout query. Contains full information about checkout
39
 * @method Poll                getPoll()               Optional. New poll state. Bots receive only updates about polls, which are sent or stopped by the bot
40
 */
41
abstract class Command
42
{
43
    /**
44
     * Telegram object
45
     *
46
     * @var \Longman\TelegramBot\Telegram
47
     */
48
    protected $telegram;
49
50
    /**
51
     * Update object
52
     *
53
     * @var \Longman\TelegramBot\Entities\Update
54
     */
55
    protected $update;
56
57
    /**
58
     * Name
59
     *
60
     * @var string
61
     */
62
    protected $name = '';
63
64
    /**
65
     * Description
66
     *
67
     * @var string
68
     */
69
    protected $description = 'Command description';
70
71
    /**
72
     * Usage
73
     *
74
     * @var string
75
     */
76
    protected $usage = 'Command usage';
77
78
    /**
79
     * Show in Help
80
     *
81
     * @var bool
82
     */
83
    protected $show_in_help = true;
84
85
    /**
86
     * Version
87
     *
88
     * @var string
89
     */
90
    protected $version = '1.0.0';
91
92
    /**
93
     * If this command is enabled
94
     *
95
     * @var boolean
96
     */
97
    protected $enabled = true;
98
99
    /**
100
     * If this command needs mysql
101
     *
102
     * @var boolean
103
     */
104
    protected $need_mysql = false;
105
106
    /*
107
    * Make sure this command only executes on a private chat.
108
    *
109
    * @var bool
110
    */
111
    protected $private_only = false;
112
113
    /**
114
     * Command config
115
     *
116
     * @var array
117
     */
118
    protected $config = [];
119
120
    /**
121
     * Constructor
122
     *
123
     * @param \Longman\TelegramBot\Telegram        $telegram
124
     * @param \Longman\TelegramBot\Entities\Update $update
125
     */
126 15
    public function __construct(Telegram $telegram, Update $update = null)
127
    {
128 15
        $this->telegram = $telegram;
129 15
        $this->setUpdate($update);
130 15
        $this->config = $telegram->getCommandConfig($this->name);
131 15
    }
132
133
    /**
134
     * Set update object
135
     *
136
     * @param \Longman\TelegramBot\Entities\Update $update
137
     *
138
     * @return \Longman\TelegramBot\Commands\Command
139
     */
140 15
    public function setUpdate(Update $update = null)
141
    {
142 15
        if ($update !== null) {
143 1
            $this->update = $update;
144
        }
145
146 15
        return $this;
147
    }
148
149
    /**
150
     * Pre-execute command
151
     *
152
     * @return \Longman\TelegramBot\Entities\ServerResponse
153
     * @throws \Longman\TelegramBot\Exception\TelegramException
154
     */
155
    public function preExecute()
156
    {
157
        if ($this->need_mysql && !($this->telegram->isDbEnabled() && DB::isDbConnected())) {
158
            return $this->executeNoDb();
159
        }
160
161
        if ($this->isPrivateOnly() && $this->removeNonPrivateMessage()) {
162
            $message = $this->getMessage();
163
164
            if ($user = $message->getFrom()) {
165
                return Request::sendMessage([
166
                    'chat_id'    => $user->getId(),
167
                    'parse_mode' => 'Markdown',
168
                    'text'       => sprintf(
169
                        "/%s command is only available in a private chat.\n(`%s`)",
170
                        $this->getName(),
171
                        $message->getText()
172
                    ),
173
                ]);
174
            }
175
176
            return Request::emptyResponse();
177
        }
178
179
        return $this->execute();
180
    }
181
182
    /**
183
     * Execute command
184
     *
185
     * @return \Longman\TelegramBot\Entities\ServerResponse
186
     * @throws \Longman\TelegramBot\Exception\TelegramException
187
     */
188
    abstract public function execute();
189
190
    /**
191
     * Execution if MySQL is required but not available
192
     *
193
     * @return \Longman\TelegramBot\Entities\ServerResponse
194
     * @throws \Longman\TelegramBot\Exception\TelegramException
195
     */
196 View Code Duplication
    public function executeNoDb()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
197
    {
198
        //Preparing message
199
        $message = $this->getMessage();
200
        $chat_id = $message->getChat()->getId();
201
202
        $data = [
203
            'chat_id' => $chat_id,
204
            'text'    => 'Sorry no database connection, unable to execute "' . $this->name . '" command.',
205
        ];
206
207
        return Request::sendMessage($data);
208
    }
209
210
    /**
211
     * Get update object
212
     *
213
     * @return \Longman\TelegramBot\Entities\Update
214
     */
215 1
    public function getUpdate()
216
    {
217 1
        return $this->update;
218
    }
219
220
    /**
221
     * Relay any non-existing function calls to Update object.
222
     *
223
     * This is purely a helper method to make requests from within execute() method easier.
224
     *
225
     * @param string $name
226
     * @param array  $arguments
227
     *
228
     * @return Command
229
     */
230 1
    public function __call($name, array $arguments)
231
    {
232 1
        if ($this->update === null) {
233 1
            return null;
234
        }
235 1
        return call_user_func_array([$this->update, $name], $arguments);
236
    }
237
238
    /**
239
     * Get command config
240
     *
241
     * Look for config $name if found return it, if not return null.
242
     * If $name is not set return all set config.
243
     *
244
     * @param string|null $name
245
     *
246
     * @return array|mixed|null
247
     */
248 1
    public function getConfig($name = null)
249
    {
250 1
        if ($name === null) {
251 1
            return $this->config;
252
        }
253 1
        if (isset($this->config[$name])) {
254 1
            return $this->config[$name];
255
        }
256
257 1
        return null;
258
    }
259
260
    /**
261
     * Get telegram object
262
     *
263
     * @return \Longman\TelegramBot\Telegram
264
     */
265 1
    public function getTelegram()
266
    {
267 1
        return $this->telegram;
268
    }
269
270
    /**
271
     * Get usage
272
     *
273
     * @return string
274
     */
275 1
    public function getUsage()
276
    {
277 1
        return $this->usage;
278
    }
279
280
    /**
281
     * Get version
282
     *
283
     * @return string
284
     */
285 1
    public function getVersion()
286
    {
287 1
        return $this->version;
288
    }
289
290
    /**
291
     * Get description
292
     *
293
     * @return string
294
     */
295 1
    public function getDescription()
296
    {
297 1
        return $this->description;
298
    }
299
300
    /**
301
     * Get name
302
     *
303
     * @return string
304
     */
305 1
    public function getName()
306
    {
307 1
        return $this->name;
308
    }
309
310
    /**
311
     * Get Show in Help
312
     *
313
     * @return bool
314
     */
315 1
    public function showInHelp()
316
    {
317 1
        return $this->show_in_help;
318
    }
319
320
    /**
321
     * Check if command is enabled
322
     *
323
     * @return bool
324
     */
325 1
    public function isEnabled()
326
    {
327 1
        return $this->enabled;
328
    }
329
330
    /**
331
     * If this command is intended for private chats only.
332
     *
333
     * @return bool
334
     */
335
    public function isPrivateOnly()
336
    {
337
        return $this->private_only;
338
    }
339
340
    /**
341
     * If this is a SystemCommand
342
     *
343
     * @return bool
344
     */
345
    public function isSystemCommand()
346
    {
347
        return ($this instanceof SystemCommand);
348
    }
349
350
    /**
351
     * If this is an AdminCommand
352
     *
353
     * @return bool
354
     */
355
    public function isAdminCommand()
356
    {
357
        return ($this instanceof AdminCommand);
358
    }
359
360
    /**
361
     * If this is a UserCommand
362
     *
363
     * @return bool
364
     */
365
    public function isUserCommand()
366
    {
367
        return ($this instanceof UserCommand);
368
    }
369
370
    /**
371
     * Delete the current message if it has been called in a non-private chat.
372
     *
373
     * @return bool
374
     */
375
    protected function removeNonPrivateMessage()
376
    {
377
        $message = $this->getMessage() ?: $this->getEditedMessage();
378
379
        if ($message) {
380
            $chat = $message->getChat();
381
382
            if (!$chat->isPrivateChat()) {
383
                // Delete the falsely called command message.
384
                Request::deleteMessage([
385
                    'chat_id'    => $chat->getId(),
386
                    'message_id' => $message->getMessageId(),
387
                ]);
388
389
                return true;
390
            }
391
        }
392
393
        return false;
394
    }
395
396
    /**
397
     * Helper to reply to a chat directly.
398
     *
399
     * @param string $text
400
     * @param array  $data
401
     *
402
     * @return \Longman\TelegramBot\Entities\ServerResponse
403
     */
404
    public function replyToChat($text, array $data = [])
405
    {
406
        if ($message = $this->getMessage() ?: $this->getEditedMessage() ?: $this->getChannelPost() ?: $this->getEditedChannelPost()) {
407
            return Request::sendMessage(array_merge([
408
                'chat_id' => $message->getChat()->getId(),
409
                'text'    => $text,
410
            ], $data));
411
        }
412
413
        return Request::emptyResponse();
414
    }
415
416
    /**
417
     * Helper to reply to a user directly.
418
     *
419
     * @param string $text
420
     * @param array  $data
421
     *
422
     * @return \Longman\TelegramBot\Entities\ServerResponse
423
     */
424
    public function replyToUser($text, array $data = [])
425
    {
426
        if ($message = $this->getMessage() ?: $this->getEditedMessage()) {
427
            return Request::sendMessage(array_merge([
428
                'chat_id' => $message->getFrom()->getId(),
429
                'text'    => $text,
430
            ], $data));
431
        }
432
433
        return Request::emptyResponse();
434
    }
435
}
436