Completed
Push — master ( 8fbc07...04de59 )
by Armando
03:05 queued 01:27
created

Command::replyToUser()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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