Telegram::sendPhoto()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
dl 11
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 5
1
<?php
2
/**
3
 * A wrapper class for telegram bot api
4
 *
5
 * @home page : https://github.com/smoqadam/php-telegram-bot
6
 * @author : Saeed Moqadam <[email protected]>
7
 * @licence : MIT Licence
8
 *
9
 */
10
namespace Smoqadam;
11
12
class Telegram {
13
14
    const PARSE_MARKDOWN = 'Markdown';
15
    const PARSE_HTML     = 'HTML';
16
17
    const ACTION_TYPING         = 'typing';
18
    const ACTION_UPLOAD_PHOTO   = 'upload_photo';
19
    const ACTION_RECORD_VIDEO   = 'record_video';
20
    const ACTION_UPLOAD_VIDEO   = 'upload_video';
21
    const ACTION_RECORD_AUDIO   = 'record_audio';
22
    const ACTION_UPLOAD_AUDIO   = 'upload_audio';
23
    const ACTION_UPLOAD_DOC     = 'upload_document';
24
    const ACTION_FIND_LOCATION  = 'find_location';
25
26
    public $api = 'https://api.telegram.org/bot';
27
28
    /**
29
     * returned json from telegram api parse to object and save to result
30
     * @var
31
     */
32
    public $result;
33
34
    /**
35
     * @name State of bot
36
     * state of bot
37
     * @var object
38
     */
39
    public $state;
40
41
    /**
42
     * commands in regex and callback
43
     * @var array
44
     */
45
    private $commands = [];
46
47
    /**
48
     * InlineQuery in regex and callback
49
     * @var array
50
     */
51
    private $inlines = [];
52
53
    /**
54
     * callbacks
55
     * @var array
56
     */
57
    private $callbacks = [];
0 ignored issues
show
Unused Code introduced by
The property $callbacks is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
58
59
    /**
60
     * available telegram bot commands
61
     * @var array
62
     */
63
    private $available_commands = [
64
        'getMe',
65
        'sendMessage',
66
        'forwardMessage',
67
        'sendPhoto',
68
        'sendAudio',
69
        'sendDocument',
70
        'sendSticker',
71
        'sendVideo',
72
        'sendLocation',
73
        'sendChatAction',
74
        'getUserProfilePhotos',
75
        'answerInlineQuery',
76
        'getUpdates',
77
        'setWebhook',
78
    ];
79
80
    /**
81
     * pre patterns you can use in regex
82
     * @var array
83
     */
84
    private $patterns = [
85
        ':any' => '.*',
86
        ':num' => '[0-9]{0,}',
87
        ':str' => '[a-zA-z]{0,}',
88
    ];
89
90
    /**
91
     *
92
     * @param String $token Telegram api token , taken by botfather
93
     */
94
    public function __construct($token) {
95
        $this->api .= $token;
96
    }
97
98
    /**
99
     * add new command to the bot
100
     * @param String $cmd
101
     * @param \Closure $func
102
     */
103
    public function cmd($cmd, $func) {
104
        $this->commands[] = new Trigger($cmd, $func);
105
    }
106
107
108
    public function PDO(){
109
110
        $servername ='YOUR_SERVER_NAME';
111
        $username = 'YOUR_USERNAME';
112
        $password ='YOUR_PASSWORD';
113
        $dbname = 'YOUR_DATABASE_NAME';
114
        try {
115
            $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password, [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"]);
116
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
117
118
            return $conn;
119
        }
120
        catch(PDOException $e)
0 ignored issues
show
Bug introduced by
The class Smoqadam\PDOException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
121
        {
122
            return $e->getMessage();
123
        }
124
    }
125
126
    /**
127
     * add new InlineQuery to the bot
128
     * @param String $cmd
129
     * @param \Closure $func
130
     */
131
    public function inlineQuery($cmd, $func) {
132
        $this->inlines[] = new Trigger($cmd, $func);
133
    }
134
135
    /**
136
     * this method check for received payload(command, inlinequery and so on) and
137
     * then execute the correct function
138
     *
139
     * @param bool $sleep
140
     */
141
    public function run($sleep = false) {
142
        $result = $this->getUpdates();
143
        while (true) {
144
            $update_id = isset($result->update_id) ? $result->update_id : 1;
145
            $result = $this->getUpdates($update_id + 1);
146
147
            $this->processPayload($result);
148
149
            if ($sleep !== false)
150
                sleep($sleep);
151
        }
152
    }
153
154
    /**
155
     * this method used for setWebhook sended payload
156
     */
157
    public function process($payload) {
158
        $result = $this->convertToObject($payload, true);
159
160
        return $this->processPayload($result);
161
    }
162
163
    private function processPayload($result) {
164
        if ($result) {
165
            try {
166
                $this->result = $result;
167
168
                // now i select the right triggers for payload received by Telegram
169
                if( isset($this->result->message->text) ) {
170
                    $payload = $this->result->message->text;
171
                    $triggers = $this->commands;
172
                } elseif ( isset($this->result->inline_query) ) {
173
                    $payload = $this->result->inline_query->query;
174
                    $triggers = $this->inlines;
175
                } else {
176
                    throw new \Exception("Error Processing Request", 1);
177
                }
178
179
                $args = null;
180
181
                foreach ($triggers as &$trigger) {
182
                    // replace public patterns to regex pattern
183
                    $searchs = array_keys($this->patterns);
184
                    $replaces = array_values($this->patterns);
185
                    $pattern = str_replace($searchs, $replaces, $trigger->pattern);
186
187
                    //find args pattern
188
                    $args = $this->getArgs($pattern, $payload);
189
190
                    $pattern = '/^' . $pattern . '/i';
191
192
                    preg_match($pattern, $payload, $matches);
193
194
                    if (isset($matches[0])) {
195
                        $func = $trigger->callback;
196
                        return call_user_func($func, $args);
197
                    }
198
                }
199
            } catch (\Exception $e) {
200
                error_log($e->getMessage());
201
                echo "\r\n Exception :: " . $e->getMessage();
202
            }
203
        } else {
204
            echo "\r\nNo new message\r\n";
205
        }
206
    }
207
208
    /**
209
     * get arguments part in regex
210
     * @param $pattern
211
     * @param $payload
212
     * @return mixed|null
213
     */
214
    private function getArgs(&$pattern, $payload) {
215
        $args = null;
216
        // if command has argument
217
        if (preg_match('/<<.*>>/', $pattern, $matches)) {
218
219
            $args_pattern = $matches[0];
220
            //remove << and >> from patterns
221
            $tmp_args_pattern = str_replace(['<<', '>>'], ['(', ')'], $pattern);
222
223
            //if args set
224
            if (preg_match('/' . $tmp_args_pattern . '/i', $payload, $matches)) {
225
                //remove first element
226
                array_shift($matches);
227
                if (isset($matches[0])) {
228
                    //set args
229
                    $args = array_shift($matches);
230
231
                    //remove args pattern from main pattern
232
                    $pattern = str_replace($args_pattern, '', $pattern);
233
                }
234
            }
235
        }
236
        return $args;
237
    }
238
239
    /**
240
     * execute telegram api commands
241
     * @param $command
242
     * @param array $params
243
     */
244
    private function exec($command, $params = []) {
245
        if (in_array($command, $this->available_commands)) {
246
            // convert json to array then get the last messages info
247
            $output = json_decode($this->curl_get_contents($this->api . '/' . $command, $params), true);
248
249
            return $this->convertToObject($output);
250
        } else {
251
            echo 'command not found';
252
        }
253
    }
254
255
    private function convertToObject($jsonObject , $webhook = false) {
256
        if( ! $webhook) {
257
            if ($jsonObject['ok']) {
258
                //error_log(print_r($jsonObject, true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
259
260
                // remove unwanted array elements
261
                $output = end($jsonObject);
262
263
                $result = is_array($output) ? end($output) : $output;
264
                if ( ! empty($result)) {
265
                    // convert to object
266
                    return json_decode(json_encode($result));
267
                }
268
            }
269
        } else {
270
            return json_decode(json_encode($jsonObject));
271
        }
272
    }
273
274
    /**
275
     * get the $url content with CURL
276
     * @param $url
277
     * @param $params
278
     * @return mixed
279
     */
280
    private function curl_get_contents($url, $params) {
281
        $ch = curl_init();
282
283
        curl_setopt($ch, CURLOPT_URL, $url);
284
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
285
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
286
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
287
        curl_setopt($ch, CURLOPT_POST, count($params));
288
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
289
290
        $result = curl_exec($ch);
291
292
        curl_close($ch);
293
294
        return $result;
295
    }
296
297
    /**
298
     * Get current chat id
299
     * @param null $chat_id
300
     * @return int
301
     */
302
    public function getChatId($chat_id = null) {
303
        try {
304
            if ($chat_id)
305
                return $chat_id;
306
307
            if( isset($this->result->message) ) {
308
                return $this->result->message->chat->id;
309
            } elseif ( isset($this->result->inline_query) ) {
310
                return $this->result->inline_query->from->id;
311
            } else {
312
                throw new \Exception("Error Processing Request", 1);
313
            }
314
        } catch (\Exception $e) {
315
            error_log($e->getMessage());
316
        }
317
    }
318
319
    /**
320
     * @param null $offset
321
     * @param int $limit
322
     * @param int $timeout
323
     */
324
    public function getUpdates($offset = null, $limit = 1, $timeout = 1) {
325
        return $this->exec('getUpdates', [
326
            'offset' => $offset,
327
            'limit' => $limit,
328
            'timeout' => $timeout
329
        ]);
330
    }
331
332
    /**
333
     * send message
334
     * @param $text
335
     * @param $chat_id
336
     * @param bool $disable_web_page_preview
337
     * @param null $reply_to_message_id
338
     * @param null $reply_markup
339
     * @param null $parse_mode
340
     */
341
    public function sendMessage($text, $chat_id = null, $disable_web_page_preview = false, $reply_to_message_id = null, $reply_markup = null, $parse_mode = null) {
342
        $this->sendChatAction(self::ACTION_TYPING, $chat_id);
343
        return $this->exec('sendMessage', [
344
            'chat_id' => $this->getChatId($chat_id),
345
            'text' => $text,
346
            'parse_mode' => $parse_mode,
347
            'disable_web_page_preview' => $disable_web_page_preview,
348
            'reply_to_message_id' => $reply_to_message_id,
349
            'reply_markup' => json_encode($reply_markup)
350
        ]);
351
    }
352
353
    /**
354
     * Get me
355
     */
356
    public function getMe() {
357
        return $this->exec('getMe');
358
    }
359
360
    /**
361
     * @param $from_id
362
     * @param $message_id
363
     * @param null $chat_id
364
     */
365
    public function forwardMessage($from_id, $message_id, $chat_id = null) {
366
        return $this->exec('forwardMessage', [
367
            'chat_id' => $this->getChatId($chat_id),
368
            'from_chat_id' => $from_id,
369
            'message_id' => $message_id,
370
        ]);
371
    }
372
373
    /**
374
     * @param $photo photo file patch
375
     * @param null $chat_id
376
     * @param null $caption
377
     * @param null $reply_to_message_id
378
     * @param null $reply_markup
379
     */
380 View Code Duplication
    public function sendPhoto($photo, $chat_id = null, $caption = null, $reply_to_message_id = null, $reply_markup = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
381
        $res = $this->exec('sendPhoto', [
382
            'chat_id' => $this->getChatId($chat_id),
383
            'photo' => $photo,
384
            'caption' => $caption,
385
            'reply_to_message_id' => $reply_to_message_id,
386
            'reply_markup' => json_encode($reply_markup)
387
        ]);
388
389
        return $res;
390
    }
391
392
    /**
393
     * @param $video video file path
394
     * @param null $chat_id
395
     * @param null $reply_to_message_id
396
     * @param null $reply_markup
397
     */
398
    public function sendVideo($video, $chat_id = null, $reply_to_message_id = null, $reply_markup = null) {
399
        $res = $this->exec('sendVideo', [
400
            'chat_id' => $this->getChatId($chat_id),
401
            'video' => $video,
402
            'reply_to_message_id' => $reply_to_message_id,
403
            'reply_markup' => json_encode($reply_markup)
404
        ]);
405
406
        return $res;
407
    }
408
409
    /**
410
     *
411
     * @param $sticker
412
     * @param null $chat_id
413
     * @param null $reply_to_message_id
414
     * @param null $reply_markup
415
     */
416
    public function sendSticker($sticker, $chat_id = null, $reply_to_message_id = null, $reply_markup = null) {
417
        $res = $this->exec('sendSticker', [
418
            'chat_id' => $this->getChatId($chat_id),
419
            'sticker' => $sticker,
420
            'reply_to_message_id' => $reply_to_message_id,
421
            'reply_markup' => json_encode($reply_markup)
422
        ]);
423
424
        return $res;
425
        // as soons as possible
426
    }
427
428
    /**
429
     * @param $latitude
430
     * @param $longitude
431
     * @param null $chat_id
432
     * @param null $reply_to_message_id
433
     * @param null $reply_markup
434
     */
435 View Code Duplication
    public function sendLocation($latitude, $longitude, $chat_id = null, $reply_to_message_id = null, $reply_markup = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
436
        $res = $this->exec('sendLocation', [
437
            'chat_id' => $this->getChatId($chat_id),
438
            'latitude' => $latitude,
439
            'longitude' => $longitude,
440
            'reply_to_message_id' => $reply_to_message_id,
441
            'reply_markup' => json_encode($reply_markup)
442
        ]);
443
444
        return $res;
445
    }
446
447
    /**
448
     * @param $document
449
     * @param null $chat_id
450
     * @param null $reply_to_message_id
451
     * @param null $reply_markup
452
     */
453
    public function sendDocument($document, $chat_id = null, $reply_to_message_id = null, $reply_markup = null) {
454
        $res = $this->exec('sendDocument', [
455
            'chat_id' => $this->getChatId($chat_id),
456
            'document' => $document,
457
            'reply_to_message_id' => $reply_to_message_id,
458
            'reply_markup' => json_encode($reply_markup)
459
        ]);
460
461
        return $res;
462
    }
463
464
    public function sendAudio($audio, $chat_id = null, $reply_to_message_id = null, $reply_markup = null) {
465
        $res = $this->exec('sendAudio', [
466
            'chat_id' => $this->getChatId($chat_id),
467
            'audio' => $audio,
468
            'reply_to_message_id' => $reply_to_message_id,
469
            'reply_markup' => json_encode($reply_markup)
470
        ]);
471
472
        return $res;
473
    }
474
475
    /**
476
     * send chat action : Telegram::ACTION_TYPING , ...
477
     * @param $action
478
     * @param null $chat_id
479
     */
480
    public function sendChatAction($action, $chat_id = null) {
481
        $res = $this->exec('sendChatAction', [
482
            'chat_id' => $this->getChatId($chat_id),
483
            'action' => $action
484
        ]);
485
486
        return $res;
487
    }
488
489
    /**
490
     * @param $user_id
491
     * @param null $offset
492
     * @param null $limit
493
     */
494
    public function getUserProfilePhotos($user_id, $offset = null, $limit = null) {
495
        $res = $this->exec('getUserProfilePhotos', [
496
            'user_id' => $user_id,
497
            'offset' => $offset,
498
            'limit' => $limit
499
        ]);
500
501
        return $res;
502
    }
503
504
505
    public function answerInlineQuery($inline_query_id, $results, $cache_time = 0, $is_personal = false, $next_offset = '', $switch_pm_text = '', $switch_pm_parameter = '') {
506
        $res = $this->exec('answerInlineQuery', [
507
            'inline_query_id' => $inline_query_id,
508
            'results' => json_encode($results),
509
            'cache_time' => $cache_time,
510
            'is_personal' => $is_personal,
511
            'next_offset' => $next_offset,
512
            'switch_pm_text' => $switch_pm_text,
513
            'switch_pm_parameter' => $switch_pm_parameter
514
        ]);
515
516
        return $res;
517
    }
518
519
    /**
520
     * @param $url
521
     */
522
    public function setWebhook($url) {
523
        $res = $this->exec('setWebhook', [
524
            'url' => $url
525
        ]);
526
527
        return $res;
528
    }
529
530
}
531