Passed
Pull Request — master (#416)
by
unknown
01:51
created

Client::getShippingQueryChecker()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.125

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 4
cp 0.5
rs 10
cc 1
nc 1
nop 0
crap 1.125
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
use TelegramBot\Api\Types\Message;
10
use TelegramBot\Api\Types\Inline\InlineKeyboardMarkup;
11
use TelegramBot\Api\Types\ReplyKeyboardRemove;
12
use TelegramBot\Api\Types\ForceReply;
13
use TelegramBot\Api\Types\ReplyKeyboardHide;
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|ReplyKeyboardHide|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
     */
45 7
    public function __construct($token, $trackerToken = null)
46
    {
47 7
        $this->api = new BotApi($token);
48 7
        $this->events = new EventCollection($trackerToken);
49 7
    }
50
51
    /**
52
     * Use this method to add command. Parameters will be automatically parsed and passed to closure.
53
     *
54
     * @param string $name
55
     * @param \Closure $action
56
     *
57
     * @return \TelegramBot\Api\Client
58
     */
59
    public function command($name, Closure $action)
60
    {
61
        return $this->on(self::getEvent($action), self::getChecker($name));
62
    }
63
64
    public function editedMessage(Closure $action)
65
    {
66
        return $this->on(self::getEditedMessageEvent($action), self::getEditedMessageChecker());
67
    }
68
69
    public function callbackQuery(Closure $action)
70
    {
71
        return $this->on(self::getCallbackQueryEvent($action), self::getCallbackQueryChecker());
72
    }
73
74
    public function channelPost(Closure $action)
75
    {
76
        return $this->on(self::getChannelPostEvent($action), self::getChannelPostChecker());
77
    }
78
79
    public function editedChannelPost(Closure $action)
80
    {
81
        return $this->on(self::getEditedChannelPostEvent($action), self::getEditedChannelPostChecker());
82
    }
83
84
    public function inlineQuery(Closure $action)
85
    {
86
        return $this->on(self::getInlineQueryEvent($action), self::getInlineQueryChecker());
87
    }
88
89
    public function chosenInlineResult(Closure $action)
90
    {
91
        return $this->on(self::getChosenInlineResultEvent($action), self::getChosenInlineResultChecker());
92
    }
93
94
    public function shippingQuery(Closure $action)
95
    {
96
        return $this->on(self::getShippingQueryEvent($action), self::getShippingQueryChecker());
97
    }
98
99
    public function preCheckoutQuery(Closure $action)
100
    {
101
        return $this->on(self::getPreCheckoutQueryEvent($action), self::getPreCheckoutQueryChecker());
102
    }
103
104
    /**
105
     * Use this method to add an event.
106
     * If second closure will return true (or if you are passed null instead of closure), first one will be executed.
107
     *
108
     * @param \Closure $event
109
     * @param \Closure|null $checker
110
     *
111
     * @return \TelegramBot\Api\Client
112
     */
113 1
    public function on(Closure $event, Closure $checker = null)
114
    {
115 1
        $this->events->add($event, $checker);
116
117 1
        return $this;
118
    }
119
120
    /**
121
     * Handle updates
122
     *
123
     * @param Update[] $updates
124
     */
125 4
    public function handle(array $updates)
126
    {
127 4
        foreach ($updates as $update) {
128
            /* @var \TelegramBot\Api\Types\Update $update */
129 4
            $this->events->handle($update);
130 4
        }
131 4
    }
132
133
    /**
134
     * Webhook handler
135
     *
136
     * @return array
137
     * @throws \TelegramBot\Api\InvalidJsonException
138
     */
139
    public function run()
140
    {
141
        if ($data = BotApi::jsonValidate($this->getRawBody(), true)) {
142
            $this->handle([Update::fromResponse($data)]);
143
        }
144
    }
145
    /**
146
     * Use this method to get already added event by command.
147
     *
148
     * @return \TelegramBot\Api\Events\Event or false on non found event
149
     */
150
    public function get_event($command)
151
    {
152
	    $events = $this->events;
153
	
154
	    foreach($events->events as $event)
0 ignored issues
show
Bug introduced by
The property events is declared protected in TelegramBot\Api\Events\EventCollection and cannot be accessed from this context.
Loading history...
155
		{
156
		   $checker = $event->getChecker();
157
		   $closureReflection = new ReflectionFunction($checker);
158 4
           $variables = $closureReflection->getStaticVariables();
159
		    
160
		   if(preg_match('/'.$variables['name'].'/', $command))
161 4
			  return $event;
162 4
		}
163 1
	
164
        return false;
165
    }
166 3
167
    public function getRawBody()
168 3
    {
169 1
        return file_get_contents('php://input');
170 1
    }
171 2
172
    /**
173
     * Returns event function to handling the command.
174 3
     *
175
     * @param \Closure $action
176 3
     *
177
     * @return \Closure
178 3
     */
179 3
    protected static function getEvent(Closure $action)
180 3
    {
181
        return function (Update $update) use ($action) {
182 3
            $message = $update->getMessage();
183 4
            if (!$message) {
0 ignored issues
show
introduced by
$message is of type TelegramBot\Api\Types\Message, thus it always evaluated to true.
Loading history...
184
                return true;
185
            }
186
187
            preg_match(self::REGEXP, $message->getText(), $matches);
188
189
            if (isset($matches[3]) && !empty($matches[3])) {
190
                $parameters = str_getcsv($matches[3], chr(32));
191
            } else {
192
                $parameters = [];
193
            }
194
195
            array_unshift($parameters, $message);
196
197
            $action = new ReflectionFunction($action);
198
199
            if (count($parameters) >= $action->getNumberOfRequiredParameters()) {
200
                $action->invokeArgs($parameters);
201
            }
202
203
            return false;
204
        };
205
    }
206
207
    protected static function getEditedMessageEvent(Closure $action)
208
    {
209
        return function (Update $update) use ($action) {
210
            if (!$update->getEditedMessage()) {
211
                return true;
212
            }
213
214
            $reflectionAction = new ReflectionFunction($action);
215
            $reflectionAction->invokeArgs([$update->getEditedMessage()]);
216
            return false;
217
        };
218
    }
219
220
    protected static function getChannelPostEvent(Closure $action)
221
    {
222
        return function (Update $update) use ($action) {
223
            if (!$update->getChannelPost()) {
224
                return true;
225
            }
226
227
            $reflectionAction = new ReflectionFunction($action);
228
            $reflectionAction->invokeArgs([$update->getChannelPost()]);
229
            return false;
230
        };
231
    }
232
233
    protected static function getCallbackQueryEvent(Closure $action)
234
    {
235
        return function (Update $update) use ($action) {
236
            if (!$update->getCallbackQuery()) {
237
                return true;
238 4
            }
239
240
            $reflectionAction = new ReflectionFunction($action);
241 4
            $reflectionAction->invokeArgs([$update->getCallbackQuery()]);
242 3
            return false;
243
        };
244
    }
245 1
246 1
    protected static function getEditedChannelPostEvent(Closure $action)
247 1
    {
248 4
        return function (Update $update) use ($action) {
249
            if (!$update->getEditedChannelPost()) {
250
                return true;
251
            }
252
253
            $reflectionAction = new ReflectionFunction($action);
254
            $reflectionAction->invokeArgs([$update->getEditedChannelPost()]);
255
            return false;
256
        };
257
    }
258
259
    protected static function getInlineQueryEvent(Closure $action)
260
    {
261
        return function (Update $update) use ($action) {
262
            if (!$update->getInlineQuery()) {
263
                return true;
264
            }
265
266
            $reflectionAction = new ReflectionFunction($action);
267
            $reflectionAction->invokeArgs([$update->getInlineQuery()]);
268
            return false;
269
        };
270
    }
271
272
    protected static function getChosenInlineResultEvent(Closure $action)
273
    {
274
        return function (Update $update) use ($action) {
275
            if (!$update->getChosenInlineResult()) {
276
                return true;
277
            }
278
279
            $reflectionAction = new ReflectionFunction($action);
280
            $reflectionAction->invokeArgs([$update->getChosenInlineResult()]);
281
            return false;
282
        };
283
    }
284
285
    protected static function getShippingQueryEvent(Closure $action)
286
    {
287
        return function (Update $update) use ($action) {
288
            if (!$update->getShippingQuery()) {
289
                return true;
290
            }
291
292
            $reflectionAction = new ReflectionFunction($action);
293
            $reflectionAction->invokeArgs([$update->getShippingQuery()]);
294
            return false;
295
        };
296
    }
297 4
298
    protected static function getPreCheckoutQueryEvent(Closure $action)
299
    {
300 4
        return function (Update $update) use ($action) {
301 4
            if (!$update->getPreCheckoutQuery()) {
302 1
                return true;
303
            }
304
305 3
            $reflectionAction = new ReflectionFunction($action);
306
            $reflectionAction->invokeArgs([$update->getPreCheckoutQuery()]);
307 3
            return false;
308 4
        };
309
    }
310
311
    /**
312
     * Returns check function to handling the command.
313
     *
314
     * @param string $name
315
     *
316
     * @return \Closure
317
     */
318
    protected static function getChecker($name)
319
    {
320
        return function (Update $update) use ($name) {
321
            $message = $update->getMessage();
322
            if (is_null($message) || !strlen($message->getText())) {
323
                return false;
324
            }
325
326
            preg_match(self::REGEXP, $message->getText(), $matches);
327
328
            return !empty($matches) && $matches[1] == $name;
329
        };
330
    }
331
332
    /**
333
     * Returns check function to handling the edited message.
334
     *
335
     * @return Closure
336
     */
337
    protected static function getEditedMessageChecker()
338
    {
339
        return function (Update $update) {
340
            return !is_null($update->getEditedMessage());
341
        };
342
    }
343
344
    /**
345
     * Returns check function to handling the channel post.
346
     *
347
     * @return Closure
348
     */
349
    protected static function getChannelPostChecker()
350
    {
351
        return function (Update $update) {
352
            return !is_null($update->getChannelPost());
353
        };
354
    }
355
356
    /**
357
     * Returns check function to handling the callbackQuery.
358
     *
359
     * @return Closure
360
     */
361
    protected static function getCallbackQueryChecker()
362
    {
363
        return function (Update $update) {
364
            return !is_null($update->getCallbackQuery());
365
        };
366
    }
367
368
    /**
369
     * Returns check function to handling the edited channel post.
370
     *
371
     * @return Closure
372
     */
373
    protected static function getEditedChannelPostChecker()
374
    {
375
        return function (Update $update) {
376 4
            return !is_null($update->getEditedChannelPost());
377
        };
378
    }
379 4
380 4
    /**
381
     * Returns check function to handling the chosen inline result.
382
     *
383
     * @return Closure
384
     */
385
    protected static function getChosenInlineResultChecker()
386
    {
387
        return function (Update $update) {
388
            return !is_null($update->getChosenInlineResult());
389
        };
390
    }
391
392
    /**
393
     * Returns check function to handling the inline queries.
394
     *
395
     * @return Closure
396
     */
397
    protected static function getInlineQueryChecker()
398
    {
399
        return function (Update $update) {
400
            return !is_null($update->getInlineQuery());
401
        };
402
    }
403
404
    /**
405
     * Returns check function to handling the shipping queries.
406
     *
407 1
     * @return Closure
408
     */
409 1
    protected static function getShippingQueryChecker()
410
    {
411 1
        return function (Update $update) {
412
            return !is_null($update->getShippingQuery());
413
        };
414 1
    }
415
416
    /**
417
     * Returns check function to handling the pre checkout queries.
418
     *
419
     * @return Closure
420
     */
421
    protected static function getPreCheckoutQueryChecker()
422
    {
423
        return function (Update $update) {
424
            return !is_null($update->getPreCheckoutQuery());
425
        };
426
    }
427
428
    public function __call($name, array $arguments)
429
    {
430
        if (method_exists($this, $name)) {
431
            return call_user_func_array([$this, $name], $arguments);
432
        } elseif (method_exists($this->api, $name)) {
433
            return call_user_func_array([$this->api, $name], $arguments);
434
        }
435
        throw new BadMethodCallException("Method {$name} not exists");
436
    }
437
}
438