Completed
Push — develop ( 69ed1e...8a9b0d )
by Armando
01:49 queued 01:44
created

Command   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 352
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 6

Test Coverage

Coverage 47.95%

Importance

Changes 0
Metric Value
wmc 30
lcom 3
cbo 6
dl 0
loc 352
ccs 35
cts 73
cp 0.4795
rs 10
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setUpdate() 0 8 2
C preExecute() 0 26 7
execute() 0 1 ?
A executeNoDb() 0 13 1
A getUpdate() 0 4 1
A __call() 0 7 2
A getConfig() 0 11 3
A getTelegram() 0 4 1
A getUsage() 0 4 1
A getVersion() 0 4 1
A getDescription() 0 4 1
A getName() 0 4 1
A showInHelp() 0 4 1
A isEnabled() 0 4 1
A isPrivateOnly() 0 4 1
A isSystemCommand() 0 4 1
A isAdminCommand() 0 4 1
A isUserCommand() 0 4 1
A removeNonPrivateMessage() 0 17 2
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
    public function executeNoDb()
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();
372
        $chat    = $message->getChat();
373
374
        if (!$chat->isPrivateChat()) {
375
            // Delete the falsely called command message.
376
            Request::deleteMessage([
377
                'chat_id'    => $chat->getId(),
378
                'message_id' => $message->getMessageId(),
379
            ]);
380
381
            return true;
382
        }
383
384
        return false;
385
    }
386
}
387