Passed
Pull Request — master (#69)
by
unknown
03:20
created

Client::channelPost()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

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
eloc 2
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
     * 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 channelPost(Closure $action)
58
    {
59
        return $this->on(self::getChannelPostEvent($action), self::getChannelPostChecker());
60
    }
61
62
    public function inlineQuery(Closure $action)
63
    {
64
        return $this->on(self::getInlineQueryEvent($action), self::getInlineQueryChecker());
65
    }
66
67
    public function shippingQuery(Closure $action)
68
    {
69
        return $this->on(self::getShippingQueryEvent($action), self::getShippingQueryChecker());
70
    }
71
72
    public function preCheckoutQuery(Closure $action)
73
    {
74
        return $this->on(self::getPreCheckoutQueryEvent($action), self::getPreCheckoutQueryChecker());
75
    }
76
77
    /**
78
     * Use this method to add an event.
79
     * If second closure will return true (or if you are passed null instead of closure), first one will be executed.
80
     *
81
     * @param \Closure $event
82
     * @param \Closure|null $checker
83
     *
84
     * @return \TelegramBot\Api\Client
85
     */
86 1
    public function on(Closure $event, Closure $checker = null)
87
    {
88 1
        $this->events->add($event, $checker);
89
90 1
        return $this;
91
    }
92
93
    /**
94
     * Handle updates
95
     *
96
     * @param Update[] $updates
97
     */
98 4
    public function handle(array $updates)
99
    {
100 4
        foreach ($updates as $update) {
101
            /* @var \TelegramBot\Api\Types\Update $update */
102 4
            $this->events->handle($update);
103 4
        }
104 4
    }
105
106
    /**
107
     * Webhook handler
108
     *
109
     * @return array
110
     * @throws \TelegramBot\Api\InvalidJsonException
111
     */
112
    public function run()
113
    {
114
        if ($data = BotApi::jsonValidate($this->getRawBody(), true)) {
115
            $this->handle([Update::fromResponse($data)]);
116
        }
117
    }
118
119
    public function getRawBody()
120
    {
121
        return file_get_contents('php://input');
122
    }
123
124
    /**
125
     * Returns event function to handling the command.
126
     *
127
     * @param \Closure $action
128
     *
129
     * @return \Closure
130
     */
131 4
    protected static function getEvent(Closure $action)
132
    {
133
        return function (Update $update) use ($action) {
134 4
            $message = $update->getMessage();
135 4
            if (!$message) {
136 1
                return true;
137
            }
138
139 3
            preg_match(self::REGEXP, $message->getText(), $matches);
140
141 3
            if (isset($matches[3]) && !empty($matches[3])) {
142 1
                $parameters = str_getcsv($matches[3], chr(32));
143 1
            } else {
144 2
                $parameters = [];
145
            }
146
147 3
            array_unshift($parameters, $message);
148
149 3
            $action = new ReflectionFunction($action);
150
151 3
            if (count($parameters) >= $action->getNumberOfRequiredParameters()) {
152 3
                $action->invokeArgs($parameters);
153 3
            }
154
155 3
            return false;
156 4
        };
157
    }
158
159 View Code Duplication
    protected static function getChannelPostEvent(Closure $action)
160
    {
161
        return function (Update $update) use ($action) {
162
            if (!$update->getChannelPost()) {
163
                return true;
164
            }
165
166
            $action = new ReflectionFunction($action);
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $action, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
167
            $action->invokeArgs([$update->getChannelPost()]);
168
            return false;
169
        };
170
    }
171
172 4 View Code Duplication
    protected static function getInlineQueryEvent(Closure $action)
173
    {
174
        return function (Update $update) use ($action) {
175 4
            if (!$update->getInlineQuery()) {
176 3
                return true;
177
            }
178
179 1
            $reflectionAction = new ReflectionFunction($action);
180 1
            $reflectionAction->invokeArgs([$update->getInlineQuery()]);
181 1
            return false;
182 4
        };
183
    }
184
185 View Code Duplication
    protected static function getShippingQueryEvent(Closure $action)
186
    {
187
        return function (Update $update) use ($action) {
188
            if (!$update->getShippingQuery()) {
189
                return true;
190
            }
191
192
            $reflectionAction = new ReflectionFunction($action);
193
            $reflectionAction->invokeArgs([$update->getShippingQuery()]);
194
            return false;
195
        };
196
    }
197
198 View Code Duplication
    protected static function getPreCheckoutQueryEvent(Closure $action)
199
    {
200
        return function (Update $update) use ($action) {
201
            if (!$update->getPreCheckoutQuery()) {
202
                return true;
203
            }
204
205
            $reflectionAction = new ReflectionFunction($action);
206
            $reflectionAction->invokeArgs([$update->getPreCheckoutQuery()]);
207
            return false;
208
        };
209
    }
210
211
    /**
212
     * Returns check function to handling the command.
213
     *
214
     * @param string $name
215
     *
216
     * @return \Closure
217
     */
218 4
    protected static function getChecker($name)
219
    {
220
        return function (Update $update) use ($name) {
221 4
            $message = $update->getMessage();
222 4
            if (is_null($message) || !strlen($message->getText())) {
223 1
                return false;
224
            }
225
226 3
            preg_match(self::REGEXP, $message->getText(), $matches);
227
228 3
            return !empty($matches) && $matches[1] == $name;
229 4
        };
230
    }
231
232
    /**
233
     * Returns check function to handling the inline queries.
234
     *
235
     * @return Closure
236
     */
237
    protected static function getChannelPostChecker()
238
    {
239
        return function (Update $update) {
240
            return !is_null($update->getChannelPost());
241
        };
242
    }
243
    
244
    /**
245
     * Returns check function to handling the inline queries.
246
     *
247
     * @return Closure
248
     */
249 4
    protected static function getInlineQueryChecker()
250
    {
251
        return function (Update $update) {
252 4
            return !is_null($update->getInlineQuery());
253 4
        };
254
    }
255
256
    /**
257
     * Returns check function to handling the shipping queries.
258
     *
259
     * @return Closure
260
     */
261
    protected static function getShippingQueryChecker()
262
    {
263
        return function (Update $update) {
264
            return !is_null($update->getShippingQuery());
265
        };
266
    }
267
268
    /**
269
     * Returns check function to handling the pre checkout queries.
270
     *
271
     * @return Closure
272
     */
273
    protected static function getPreCheckoutQueryChecker()
274
    {
275
        return function (Update $update) {
276
            return !is_null($update->getPreCheckoutQuery());
277
        };
278
    }
279
280 1
    public function __call($name, array $arguments)
281
    {
282 1
        if (method_exists($this, $name)) {
283
            return call_user_func_array([$this, $name], $arguments);
284 1
        } elseif (method_exists($this->api, $name)) {
285
            return call_user_func_array([$this->api, $name], $arguments);
286
        }
287 1
        throw new BadMethodCallException("Method {$name} not exists");
288
    }
289
}
290