Client::editedChannelPost()   A
last analyzed

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
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 1
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace TelegramBot\Api;
4
5
use Closure;
6
use ReflectionFunction;
7
use TelegramBot\Api\Events\EventCollection;
8
use TelegramBot\Api\Http\HttpClientInterface;
9
use TelegramBot\Api\Types\Update;
10
use TelegramBot\Api\Types\Message;
11
use TelegramBot\Api\Types\Inline\InlineKeyboardMarkup;
12
use TelegramBot\Api\Types\ReplyKeyboardRemove;
13
use TelegramBot\Api\Types\ForceReply;
14
use TelegramBot\Api\Types\ReplyKeyboardMarkup;
15
16
/**
17
 * Class Client
18
 *
19
 * @package TelegramBot\Api
20
 * @method Message editMessageText(string $chatId, int $messageId, string $text, string $parseMode = null, bool $disablePreview = false, ReplyKeyboardMarkup|ForceReply|ReplyKeyboardRemove|InlineKeyboardMarkup|null $replyMarkup = null, string $inlineMessageId = null)
21
 */
22
class Client
23
{
24
    /**
25
     * RegExp for bot commands
26
     */
27
    const REGEXP = '/^(?:@\w+\s)?\/([^\s@]+)(@\S+)?\s?(.*)$/';
28
29
    /**
30
     * @var \TelegramBot\Api\BotApi
31
     */
32
    protected $api;
33
34
    /**
35
     * @var \TelegramBot\Api\Events\EventCollection
36
     */
37
    protected $events;
38
39
    /**
40
     * Client constructor
41
     *
42
     * @param string $token Telegram Bot API token
43
     * @param string|null $trackerToken Yandex AppMetrica application api_key
44
     * @param HttpClientInterface|null $httpClient
45 7
     * @param string|null $endpoint
46
     */
47 7
    public function __construct($token, $trackerToken = null, HttpClientInterface $httpClient = null, $endpoint = null)
48 7
    {
49 7
        if ($trackerToken) {
50
            @trigger_error(sprintf('Passing $trackerToken to %s is deprecated', self::class), \E_USER_DEPRECATED);
51
        }
52
        $this->api = new BotApi($token, $trackerToken, $httpClient, $endpoint);
53
        $this->events = new EventCollection($trackerToken);
54
    }
55
56
    /**
57
     * Use this method to add command. Parameters will be automatically parsed and passed to closure.
58
     *
59
     * @param string $name
60
     * @param \Closure $action
61
     *
62
     * @return \TelegramBot\Api\Client
63
     */
64
    public function command($name, Closure $action)
65
    {
66
        return $this->on(self::getEvent($action), self::getChecker($name));
67
    }
68
69
    /**
70
     * @return self
71
     */
72
    public function editedMessage(Closure $action)
73
    {
74
        return $this->on(self::getEditedMessageEvent($action), self::getEditedMessageChecker());
75
    }
76
77
    /**
78
     * @return self
79
     */
80
    public function callbackQuery(Closure $action)
81
    {
82
        return $this->on(self::getCallbackQueryEvent($action), self::getCallbackQueryChecker());
83
    }
84
85
    /**
86
     * @return self
87
     */
88
    public function channelPost(Closure $action)
89
    {
90
        return $this->on(self::getChannelPostEvent($action), self::getChannelPostChecker());
91
    }
92
93
    /**
94
     * @return self
95
     */
96
    public function editedChannelPost(Closure $action)
97
    {
98
        return $this->on(self::getEditedChannelPostEvent($action), self::getEditedChannelPostChecker());
99
    }
100
101
    /**
102
     * @return self
103
     */
104
    public function inlineQuery(Closure $action)
105
    {
106
        return $this->on(self::getInlineQueryEvent($action), self::getInlineQueryChecker());
107
    }
108
109
    /**
110
     * @return self
111
     */
112
    public function chosenInlineResult(Closure $action)
113 1
    {
114
        return $this->on(self::getChosenInlineResultEvent($action), self::getChosenInlineResultChecker());
115 1
    }
116
117 1
    /**
118
     * @return self
119
     */
120
    public function shippingQuery(Closure $action)
121
    {
122
        return $this->on(self::getShippingQueryEvent($action), self::getShippingQueryChecker());
123
    }
124
125 4
    /**
126
     * @return self
127 4
     */
128
    public function preCheckoutQuery(Closure $action)
129 4
    {
130 4
        return $this->on(self::getPreCheckoutQueryEvent($action), self::getPreCheckoutQueryChecker());
131 4
    }
132
133
    /**
134
     * Use this method to add an event.
135
     * If second closure will return true (or if you are passed null instead of closure), first one will be executed.
136
     *
137
     * @param \Closure $event
138
     * @param \Closure|null $checker
139
     *
140
     * @return \TelegramBot\Api\Client
141
     */
142
    public function on(Closure $event, Closure $checker = null)
143
    {
144
        $this->events->add($event, $checker);
145
146
        return $this;
147
    }
148
149
    /**
150
     * Handle updates
151
     *
152
     * @param Update[] $updates
153
     *
154
     * @return void
155
     */
156
    public function handle(array $updates)
157
    {
158 4
        foreach ($updates as $update) {
159
            /* @var \TelegramBot\Api\Types\Update $update */
160
            $this->events->handle($update);
161 4
        }
162 4
    }
163 1
164
    /**
165
     * Webhook handler
166 3
     *
167
     * @return void
168 3
     * @throws \TelegramBot\Api\InvalidJsonException
169 1
     */
170 1
    public function run()
171 2
    {
172
        if ($data = BotApi::jsonValidate((string) $this->getRawBody(), true)) {
173
            /** @var array $data */
174 3
            $this->handle([Update::fromResponse($data)]);
175
        }
176 3
    }
177
178 3
    /**
179 3
     * @return false|string
180 3
     */
181
    public function getRawBody()
182 3
    {
183 4
        return file_get_contents('php://input');
184
    }
185
186
    /**
187
     * Returns event function to handling the command.
188
     *
189
     * @param \Closure $action
190
     *
191
     * @return \Closure
192
     */
193
    protected static function getEvent(Closure $action)
194
    {
195
        return function (Update $update) use ($action) {
196
            $message = $update->getMessage();
197
            if (!$message) {
198
                return true;
199
            }
200
201
            preg_match(self::REGEXP, (string) $message->getText(), $matches);
202
203
            if (isset($matches[3]) && !empty($matches[3])) {
204
                $parameters = str_getcsv($matches[3], chr(32));
205
            } else {
206
                $parameters = [];
207
            }
208
209
            array_unshift($parameters, $message);
210
211
            $action = new ReflectionFunction($action);
212
213
            if (count($parameters) >= $action->getNumberOfRequiredParameters()) {
214
                $action->invokeArgs($parameters);
215
            }
216
217
            return false;
218
        };
219
    }
220
221
    /**
222
     * @return Closure
223
     */
224
    protected static function getEditedMessageEvent(Closure $action)
225
    {
226
        return function (Update $update) use ($action) {
227
            if (!$update->getEditedMessage()) {
228
                return true;
229
            }
230
231
            $reflectionAction = new ReflectionFunction($action);
232
            $reflectionAction->invokeArgs([$update->getEditedMessage()]);
233
            return false;
234
        };
235
    }
236
237
    /**
238 4
     * @return Closure
239
     *
240
     * @psalm-return Closure(Update):bool
241 4
     */
242 3
    protected static function getChannelPostEvent(Closure $action)
243
    {
244
        return function (Update $update) use ($action) {
245 1
            if (!$update->getChannelPost()) {
246 1
                return true;
247 1
            }
248 4
249
            $reflectionAction = new ReflectionFunction($action);
250
            $reflectionAction->invokeArgs([$update->getChannelPost()]);
251
            return false;
252
        };
253
    }
254
255
    /**
256
     * @return Closure
257
     */
258
    protected static function getCallbackQueryEvent(Closure $action)
259
    {
260
        return function (Update $update) use ($action) {
261
            if (!$update->getCallbackQuery()) {
262
                return true;
263
            }
264
265
            $reflectionAction = new ReflectionFunction($action);
266
            $reflectionAction->invokeArgs([$update->getCallbackQuery()]);
267
            return false;
268
        };
269
    }
270
271
    /**
272
     * @return Closure
273
     *
274
     * @psalm-return Closure(Update):bool
275
     */
276
    protected static function getEditedChannelPostEvent(Closure $action)
277
    {
278
        return function (Update $update) use ($action) {
279
            if (!$update->getEditedChannelPost()) {
280
                return true;
281
            }
282
283
            $reflectionAction = new ReflectionFunction($action);
284
            $reflectionAction->invokeArgs([$update->getEditedChannelPost()]);
285
            return false;
286
        };
287
    }
288
289
    /**
290
     * @return Closure
291
     */
292
    protected static function getInlineQueryEvent(Closure $action)
293
    {
294
        return function (Update $update) use ($action) {
295
            if (!$update->getInlineQuery()) {
296
                return true;
297 4
            }
298
299
            $reflectionAction = new ReflectionFunction($action);
300 4
            $reflectionAction->invokeArgs([$update->getInlineQuery()]);
301 4
            return false;
302 1
        };
303
    }
304
305 3
    /**
306
     * @return Closure
307 3
     *
308 4
     * @psalm-return Closure(Update):bool
309
     */
310
    protected static function getChosenInlineResultEvent(Closure $action)
311
    {
312
        return function (Update $update) use ($action) {
313
            if (!$update->getChosenInlineResult()) {
314
                return true;
315
            }
316
317
            $reflectionAction = new ReflectionFunction($action);
318
            $reflectionAction->invokeArgs([$update->getChosenInlineResult()]);
319
            return false;
320
        };
321
    }
322
323
    /**
324
     * @return Closure
325
     */
326
    protected static function getShippingQueryEvent(Closure $action)
327
    {
328
        return function (Update $update) use ($action) {
329
            if (!$update->getShippingQuery()) {
330
                return true;
331
            }
332
333
            $reflectionAction = new ReflectionFunction($action);
334
            $reflectionAction->invokeArgs([$update->getShippingQuery()]);
335
            return false;
336
        };
337
    }
338
339
    /**
340
     * @return Closure
341
     *
342
     * @psalm-return Closure(Update):bool
343
     */
344
    protected static function getPreCheckoutQueryEvent(Closure $action)
345
    {
346
        return function (Update $update) use ($action) {
347
            if (!$update->getPreCheckoutQuery()) {
348
                return true;
349
            }
350
351
            $reflectionAction = new ReflectionFunction($action);
352
            $reflectionAction->invokeArgs([$update->getPreCheckoutQuery()]);
353
            return false;
354
        };
355
    }
356
357
    /**
358
     * Returns check function to handling the command.
359
     *
360
     * @param string $name
361
     *
362
     * @return \Closure
363
     */
364
    protected static function getChecker($name)
365
    {
366
        return function (Update $update) use ($name) {
367
            $message = $update->getMessage();
368
            if (!$message) {
369
                return false;
370
            }
371
            $text = $message->getText();
372
            if (empty($text)) {
373
                return false;
374
            }
375
376 4
            preg_match(self::REGEXP, $text, $matches);
377
378
            return !empty($matches) && $matches[1] == $name;
379 4
        };
380 4
    }
381
382
    /**
383
     * Returns check function to handling the edited message.
384
     *
385
     * @return Closure
386
     */
387
    protected static function getEditedMessageChecker()
388
    {
389
        return function (Update $update) {
390
            return !is_null($update->getEditedMessage());
391
        };
392
    }
393
394
    /**
395
     * Returns check function to handling the channel post.
396
     *
397
     * @return Closure
398
     */
399
    protected static function getChannelPostChecker()
400
    {
401
        return function (Update $update) {
402
            return !is_null($update->getChannelPost());
403
        };
404
    }
405
406
    /**
407 1
     * Returns check function to handling the callbackQuery.
408
     *
409 1
     * @return Closure
410
     */
411 1
    protected static function getCallbackQueryChecker()
412
    {
413
        return function (Update $update) {
414 1
            return !is_null($update->getCallbackQuery());
415
        };
416
    }
417
418
    /**
419
     * Returns check function to handling the edited channel post.
420
     *
421
     * @return Closure
422
     */
423
    protected static function getEditedChannelPostChecker()
424
    {
425
        return function (Update $update) {
426
            return !is_null($update->getEditedChannelPost());
427
        };
428
    }
429
430
    /**
431
     * Returns check function to handling the chosen inline result.
432
     *
433
     * @return Closure
434
     */
435
    protected static function getChosenInlineResultChecker()
436
    {
437
        return function (Update $update) {
438
            return !is_null($update->getChosenInlineResult());
439
        };
440
    }
441
442
    /**
443
     * Returns check function to handling the inline queries.
444
     *
445
     * @return Closure
446
     */
447
    protected static function getInlineQueryChecker()
448
    {
449
        return function (Update $update) {
450
            return !is_null($update->getInlineQuery());
451
        };
452
    }
453
454
    /**
455
     * Returns check function to handling the shipping queries.
456
     *
457
     * @return Closure
458
     */
459
    protected static function getShippingQueryChecker()
460
    {
461
        return function (Update $update) {
462
            return !is_null($update->getShippingQuery());
463
        };
464
    }
465
466
    /**
467
     * Returns check function to handling the pre checkout queries.
468
     *
469
     * @return Closure
470
     */
471
    protected static function getPreCheckoutQueryChecker()
472
    {
473
        return function (Update $update) {
474
            return !is_null($update->getPreCheckoutQuery());
475
        };
476
    }
477
478
    /**
479
     * @param string $name
480
     * @param array $arguments
481
     * @return mixed
482
     * @throws BadMethodCallException
483
     */
484
    public function __call($name, array $arguments)
485
    {
486
        if (method_exists($this, $name)) {
487
            return call_user_func_array([$this, $name], $arguments);
488
        } elseif (method_exists($this->api, $name)) {
489
            return call_user_func_array([$this->api, $name], $arguments);
490
        }
491
        throw new BadMethodCallException("Method {$name} not exists");
492
    }
493
}
494