Completed
Push — master ( 1f7e67...a1b9db )
by
unknown
07:31
created

Client::getShippingQueryChecker()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
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
     * Use this method to add command. Parameters will be automatically parsed and passed to closure.
46
     *
47
     * @param string $name
48
     * @param \Closure $action
49
     *
50
     * @return \TelegramBot\Api\Client
51
     */
52
    public function command($name, Closure $action)
53
    {
54
        return $this->on(self::getEvent($action), self::getChecker($name));
55
    }
56
57
    public function inlineQuery(Closure $action)
58
    {
59
        return $this->on(self::getInlineQueryEvent($action), self::getInlineQueryChecker());
60
    }
61
62
    public function shippingQuery(Closure $action)
63
    {
64
        return $this->on(self::getShippingQueryEvent($action), self::getInlineQueryChecker());
65
    }
66
67
    public function preCheckoutQuery(Closure $action)
68
    {
69
        return $this->on(self::getPreCheckoutQueryEvent($action), self::getPreCheckoutQueryChecker());
70
    }
71
72
    /**
73
     * Use this method to add an event.
74
     * If second closure will return true (or if you are passed null instead of closure), first one will be executed.
75
     *
76
     * @param \Closure $event
77
     * @param \Closure|null $checker
78
     *
79
     * @return \TelegramBot\Api\Client
80
     */
81 1
    public function on(Closure $event, Closure $checker = null)
82
    {
83 1
        $this->events->add($event, $checker);
84
85 1
        return $this;
86
    }
87
88
    /**
89
     * Handle updates
90
     *
91
     * @param Update[] $updates
92
     */
93 4
    public function handle(array $updates)
94
    {
95 4
        foreach ($updates as $update) {
96
            /* @var \TelegramBot\Api\Types\Update $update */
97 4
            $this->events->handle($update);
98 4
        }
99 4
    }
100
101
    /**
102
     * Webhook handler
103
     *
104
     * @return array
105
     * @throws \TelegramBot\Api\InvalidJsonException
106
     */
107
    public function run()
108
    {
109
        if ($data = BotApi::jsonValidate($this->getRawBody(), true)) {
110
            $this->handle([Update::fromResponse($data)]);
111
        }
112
    }
113
114
    public function getRawBody()
115
    {
116
        return file_get_contents('php://input');
117
    }
118
119
    /**
120
     * Returns event function to handling the command.
121
     *
122
     * @param \Closure $action
123
     *
124
     * @return \Closure
125
     */
126 4
    protected static function getEvent(Closure $action)
127
    {
128
        return function (Update $update) use ($action) {
129 4
            $message = $update->getMessage();
130 4
            if (!$message) {
131 1
                return true;
132
            }
133
134 3
            preg_match(self::REGEXP, $message->getText(), $matches);
135
136 3
            if (isset($matches[3]) && !empty($matches[3])) {
137 1
                $parameters = str_getcsv($matches[3], chr(32));
138 1
            } else {
139 2
                $parameters = [];
140
            }
141
142 3
            array_unshift($parameters, $message);
143
144 3
            $action = new ReflectionFunction($action);
145
146 3
            if (count($parameters) >= $action->getNumberOfRequiredParameters()) {
147 3
                $action->invokeArgs($parameters);
148 3
            }
149
150 3
            return false;
151 4
        };
152
    }
153
154 4 View Code Duplication
    protected static function getInlineQueryEvent(Closure $action)
155
    {
156
        return function (Update $update) use ($action) {
157 4
            if (!$update->getInlineQuery()) {
158 3
                return true;
159
            }
160
161 1
            $reflectionAction = new ReflectionFunction($action);
162 1
            $reflectionAction->invokeArgs([$update->getInlineQuery()]);
163 1
            return false;
164 4
        };
165
    }
166
167 View Code Duplication
    protected static function getShippingQueryEvent(Closure $action)
168
    {
169
        return function (Update $update) use ($action) {
170
            if (!$update->getShippingQuery()) {
171
                return true;
172
            }
173
174
            $reflectionAction = new ReflectionFunction($action);
175
            $reflectionAction->invokeArgs([$update->getShippingQuery()]);
176
            return false;
177
        };
178
    }
179
180 View Code Duplication
    protected static function getPreCheckoutQueryEvent(Closure $action)
181
    {
182
        return function (Update $update) use ($action) {
183
            if (!$update->getPreCheckoutQuery()) {
184
                return true;
185
            }
186
187
            $reflectionAction = new ReflectionFunction($action);
188
            $reflectionAction->invokeArgs([$update->getPreCheckoutQuery()]);
189
            return false;
190
        };
191
    }
192
193
    /**
194
     * Returns check function to handling the command.
195
     *
196
     * @param string $name
197
     *
198
     * @return \Closure
199
     */
200 4
    protected static function getChecker($name)
201
    {
202
        return function (Update $update) use ($name) {
203 4
            $message = $update->getMessage();
204 4
            if (is_null($message) || !strlen($message->getText())) {
205 1
                return false;
206
            }
207
208 3
            preg_match(self::REGEXP, $message->getText(), $matches);
209
210 3
            return !empty($matches) && $matches[1] == $name;
211 4
        };
212
    }
213
214
    /**
215
     * Returns check function to handling the inline queries.
216
     *
217
     * @return Closure
218
     */
219 4
    protected static function getInlineQueryChecker()
220
    {
221
        return function (Update $update) {
222 4
            return !is_null($update->getInlineQuery());
223 4
        };
224
    }
225
226
    /**
227
     * Returns check function to handling the shipping queries.
228
     *
229
     * @return Closure
230
     */
231
    protected static function getShippingQueryChecker()
232
    {
233
        return function (Update $update) {
234
            return !is_null($update->getShippingQuery());
235
        };
236
    }
237
238
    /**
239
     * Returns check function to handling the pre checkout queries.
240
     *
241
     * @return Closure
242
     */
243
    protected static function getPreCheckoutQueryChecker()
244
    {
245
        return function (Update $update) {
246
            return !is_null($update->getPreCheckoutQuery());
247
        };
248
    }
249
250 1
    public function __call($name, array $arguments)
251
    {
252 1
        if (method_exists($this, $name)) {
253
            return call_user_func_array([$this, $name], $arguments);
254 1
        } elseif (method_exists($this->api, $name)) {
255
            return call_user_func_array([$this->api, $name], $arguments);
256
        }
257 1
        throw new BadMethodCallException("Method {$name} not exists");
258
    }
259
}
260