Passed
Pull Request — master (#292)
by
unknown
02:58
created

Client::chosenInlineResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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