Completed
Push — master ( 7a67a4...253eb0 )
by
unknown
15s
created

Send::sendInvoice()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 40
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 8.8571
c 0
b 0
f 0
ccs 0
cts 16
cp 0
cc 3
eloc 27
nc 3
nop 5
crap 12
1
<?php
2
3
/*
4
 * This file is part of the PhpBotFramework.
5
 *
6
 * PhpBotFramework is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, version 3.
9
 *
10
 * PhpBotFramework is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace PhpBotFramework\Core;
20
21
use PhpBotFramework\Entities\Message;
22
23
use PhpBotFramework\Entities\File as TelegramFile;
24
25
/**
26
 * \class Send
27
 * \brief All API Methods that send a message (text based or not).
28
 */
29
trait Send
30
{
31
    abstract protected function execRequest(string $url);
32
33
    abstract protected function processRequest(string $method, string $class, $file);
34
35
    abstract protected function checkCurrentFile(TelegramFile $file);
36
37
    /** @internal
38
      * \brief Contains parameters of the next request. */
39
    protected $parameters;
40
41
    /** @internal
42
     * \brief Represents the provider token for payments. */
43
    protected $_provider_token;
44
45
    /** @internal
46
     * \brief Represents currency used for payments. */
47
    protected $_payment_currency;
48
49
    /**
50
     * \addtogroup Api Api Methods
51
     * @{
52
     */
53
54
    /**
55
     * \brief Set data for bot payments used across 'sendInvoice'.
56
     * @param string $provider_token The token for the payment provider got using BotFather.
57
     * @param string $currency The payment currency (represented with 'ISO 4217 currency mode').
58
     */
59
    public function setPayment(string $provider_token, string $currency = 'EUR')
60
    {
61
        $this->_provider_token = $provider_token;
62
        $this->_payment_currency = $currency;
63
    }
64
65
    /**
66
     * \brief Set currency for bot payments.
67
     * \details It's used in place of 'setPayment' in order to specify only the currency.
68
     * @param string $currency The payment currency (represented with 'ISO 4217 currency mode').
69
     */
70
    public function setPaymentCurrency(string $currency = 'EUR')
71
    {
72
        $this->_payment_currency = $currency;
73
    }
74
75
    /**
76
     * \brief Send an invoice.
77
     * \details Send an invoice in order receive real money. [API reference](https://core.telegram.org/bots/api#sendinvoice).
78
     * @param $title The title of product or service to pay (e.g. Free Donation to Telegram).
79
     * @param $description A description of product or service to pay.
80
     * @param $payload Bot-defined invoice payload.
81
     * @param $start_parameter Unique deep-linking parameter used to generate this invoice.
82
     * @param $prices The various prices to pay (e.g array('Donation' => 14.50, 'Taxes' => 0.50)).
83
     * @return string The payload for that specific invoice.
84
     * @return Message|false message sent on success, false otherwise.
85
     */
86
    public function sendInvoice(string $title, string $description, string $start_parameter, $prices, $optionals = [])
87
    {
88
        $OPTIONAL_FIELDS = [
89
            'photo_url',
90
            'photo_width',
91
            'photo_height',
92
            'need_name',
93
            'need_phone_number',
94
            'need_email',
95
            'need_shipping_address',
96
            'is_flexible',
97
            'disable_notification',
98
            'reply_to_message_id',
99
            'reply_markup'
100
          ];
101
102
        $payload = $this->generateSecurePayload();
103
104
        $this->parameters = [
105
            'chat_id' => $this->_chat_id,
0 ignored issues
show
Bug introduced by
The property _chat_id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
106
            'title' => $title,
107
            'description' => $description,
108
            'payload' => $payload,
109
            'provider_token' => $this->_provider_token,
110
            'start_parameter' => $start_parameter,
111
            'currency' => $this->_payment_currency,
112
            'prices' => $this->generateLabeledPrices($prices)
113
        ];
114
115
        // Add optional fields if available
116
        foreach ($OPTIONAL_FIELDS as $field)
117
        {
118
            if (isset($optionals[$field]))
119
            {
120
                $this->parameters[$field] = $optionals[$field];
121
            }
122
        }
123
124
        return [$payload, $this->processRequest('sendInvoice', 'Message')];
0 ignored issues
show
Bug introduced by
The call to processRequest() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
125
    }
126
127
    /**
128
     * \brief Generate a secure and unique payload string.
129
     * @return string The generated payload.
130
     */
131
    private function generateSecurePayload()
132
    {
133
        return bin2hex(random_bytes(32));
134
    }
135
136
    /**
137
     * \brief Convert a matrix of prices in a JSON string object accepted by 'sendInvoice'.
138
     * @param $prices The matrix of prices.
139
     * @return string The JSON string response.
140
     */
141 1
    private function generateLabeledPrices(array $prices)
142
    {
143 1
        $response = [];
144
145 1
        foreach ($prices as $item => $price)
146
        {
147 1
            if ($price < 0)
148
            {
149 1
                throw new \Exception('Invalid negative price passed to "sendInvoice"');
150
            }
151
152
            // Format the price value following the official guideline:
153
            // https://core.telegram.org/bots/api#labeledprice
154 1
            $formatted_price = intval($price * 100);
155 1
            array_push($response, ['label' => $item, 'amount' => $formatted_price]);
156
        }
157
158 1
        return json_encode($response);
159
    }
160
161
    /**
162
     * \brief Send a text message.
163
     * \details Use this method to send text messages. [API reference](https://core.telegram.org/bots/api#sendmessage)
164
     * @param $text Text of the message.
165
     * @param $reply_markup <i>Optional</i>. Reply_markup of the message.
166
     * @param $parse_mode <i>Optional</i>. Parse mode of the message.
167
     * @param $disable_web_preview <i>Optional</i>. Disables link previews for links in this message.
168
     * @param $disable_notification <i>Optional</i>. Sends the message silently.
169
     * @return Message|false Message sent on success, false otherwise.
170
     */
171 9
    public function sendMessage($text, string $reply_markup = null, int $reply_to = null, string $parse_mode = 'HTML', bool $disable_web_preview = true, bool $disable_notification = false)
172
    {
173 9
        $this->parameters = [
174 9
            'chat_id' => $this->_chat_id,
175 9
            'text' => $text,
176 9
            'parse_mode' => $parse_mode,
177 9
            'disable_web_page_preview' => $disable_web_preview,
178 9
            'reply_markup' => $reply_markup,
179 9
            'reply_to_message_id' => $reply_to,
180 9
            'disable_notification' => $disable_notification
181
        ];
182
183 9
        return $this->processRequest('sendMessage', 'Message');
0 ignored issues
show
Bug introduced by
The call to processRequest() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
184
    }
185
186
    /**
187
     * \brief Forward a message.
188
     * \details Use this method to forward messages of any kind. [API reference](https://core.telegram.org/bots/api#forwardmessage)
189
     * @param $from_chat_id The chat where the original message was sent.
190
     * @param $message_id Message identifier (id).
191
     * @param $disable_notification <i>Optional</i>. Sends the message silently.
192
     * @return Message|false Message sent on success, false otherwise.
193
     */
194
    public function forwardMessage($from_chat_id, int $message_id, bool $disable_notification = false)
195
    {
196
        $this->parameters = [
197
            'chat_id' => $this->_chat_id,
198
            'message_id' => $message_id,
199
            'from_chat_id' => $from_chat_id,
200
            'disable_notification' => $disable_notification
201
        ];
202
203
        return $this->processRequest('forwardMessage', 'Message');
0 ignored issues
show
Bug introduced by
The call to processRequest() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
204
    }
205
206
    /**
207
     * \brief Send a photo.
208
     * \details Use this method to send photos. [API reference](https://core.telegram.org/bots/api#sendphoto)
209
     * @param $photo Photo to send, can be a file_id or a string referencing the location of that image(both local or remote path).
210
     * @param $reply_markup <i>Optional</i>. Reply markup of the message.
211
     * @param $caption <i>Optional</i>. Photo caption (may also be used when resending photos by file_id), 0-200 characters.
212
     * @param $disable_notification <i>Optional<i>. Sends the message silently.
213
     * @return Message|false Message sent on success, false otherwise.
214
     */
215 4 View Code Duplication
    public function sendPhoto(&$photo, string $reply_markup = null, string $caption = '', bool $disable_notification = false)
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...
216
    {
217 4
        $this->_file->init($photo, 'photo');
0 ignored issues
show
Bug introduced by
The property _file does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
218
219 4
        $this->parameters = [
220 4
            'chat_id' => $this->_chat_id,
221 4
            'caption' => $caption,
222 4
            'reply_markup' => $reply_markup,
223 4
            'disable_notification' => $disable_notification,
224
        ];
225
226 4
        return $this->processRequest('sendPhoto', 'Message', $this->checkCurrentFile());
0 ignored issues
show
Bug introduced by
The call to checkCurrentFile() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
227
    }
228
229
    /**
230
     * \brief Send an audio.
231
     * \details Use this method to send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. [API reference](https://core.telegram.org/bots/api/#sendaudio)
232
     * Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
233
     * @param $audio Audio file to send. Pass a file_id as String to send an audio file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an audio file from the Internet, or give the local path of an audio to upload.
234
     * @param $caption <i>Optional</i>. Audio caption, 0-200 characters.
235
     * @param $reply_markup <i>Optional</i>. Reply markup of the message.
236
     * @param $duration <i>Optional</i>. Duration of the audio in seconds.
237
     * @param $performer <i>Optional</i>. Performer.
238
     * @param $title <i>Optional</i>. Track name.
239
     * @param $disable_notification <i>Optional</i>. Sends the message silently.
240
     * @param $reply_to_message_id <i>Optional</i>. If the message is a reply, ID of the original message.
241
     * @return Message|false Message sent on success, false otherwise.
242
     */
243
    public function sendAudio($audio, string $caption = null, string $reply_markup = null, int $duration = null, string $performer, string $title = null, bool $disable_notification = false, int $reply_to_message_id = null)
244
    {
245
        $this->_file->init($audio, 'audio');
246
247
        $this->parameters = [
248
            'chat_id' => $this->_chat_id,
249
            'caption' => $caption,
250
            'duration' => $duration,
251
            'performer' => $performer,
252
            'title' => $title,
253
            'reply_to_message_id' => $reply_to_message_id,
254
            'reply_markup' => $reply_markup,
255
            'disable_notification' => $disable_notification,
256
        ];
257
258
        return $this->processRequest('sendAudio', 'Message', $this->checkCurrentFile());
0 ignored issues
show
Bug introduced by
The call to checkCurrentFile() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
259
    }
260
261
    /**
262
     * \brief Send a document.
263
     * \details Use this method to send general files. [API reference](https://core.telegram.org/bots/api/#senddocument)
264
     * @param string $document File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or give the local path of an document to upload it.
265
     * Only some document are allowed through url sending (this is a Telegram limitation).
266
     * @param string $caption <i>Optional</i>. Document caption (may also be used when resending documents by file_id), 0-200 characters.
267
     *
268
     * @param string $reply_markup <i>Optional</i>. Reply markup of the message.
269
     * @param bool $disable_notification <i>Optional</i>. Sends the message silently.
270
     * @param int $reply_to_message_id <i>Optional</i>. If the message is a reply, ID of the original message.
271
     * @return Message|false Message sent on success, false otherwise.
272
     */
273 3 View Code Duplication
    public function sendDocument(string $document, string $caption = '', string $reply_markup = null, bool $disable_notification = false, int $reply_to_message_id = null)
274
    {
275 3
        $this->_file->init($document, 'document');
276
277 3
        $this->parameters = [
278 3
            'chat_id' => $this->_chat_id,
279 3
            'caption' => $caption,
280 3
            'reply_to_message_id' => $reply_to_message_id,
281 3
            'reply_markup' => $reply_markup,
282 3
            'disable_notification' => $disable_notification,
283
        ];
284
285 3
        return $this->processRequest('sendDocument', 'Message', $this->checkCurrentFile());
0 ignored issues
show
Bug introduced by
The call to checkCurrentFile() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
286
    }
287
288
289
    /**
290
     * \brief Send a sticker
291
     * \details Use this method to send .webp stickers. [API reference](https://core.telegram.org/bots/api/#sendsticker)
292
     * @param mixed $sticker Sticker to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a .webp file from the Internet, or upload a new one using multipart/form-data.
293
     * @param string $reply_markup <i>Optional</i>. Reply markup of the message.
294
     * @param bool $disable_notification Sends the message silently.
295
     * @param int $reply_to_message_id <i>Optional</i>. If the message is a reply, ID of the original message.
296
     * @param bool On success, the sent message.
297
     * @return Message|false Message sent on success, false otherwise.
298
     */
299 View Code Duplication
    public function sendSticker($sticker, string $reply_markup = null, bool $disable_notification = false, int $reply_to_message_id = 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...
300
    {
301
        $this->parameters = [
302
            'chat_id' => $this->_chat_id,
303
            'sticker' => $sticker,
304
            'disable_notification' => $disable_notification,
305
            'reply_to_message_id' => $reply_to_message_id,
306
            'reply_markup' => $reply_markup
307
        ];
308
309
        return $this->processRequest('sendSticker', 'Message');
0 ignored issues
show
Bug introduced by
The call to processRequest() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
310
    }
311
312
    /**
313
     * \brief Send audio files.
314
     * \details Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Audio or Document).o
315
     * Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future.
316
     * @param mixed $voice Audio file to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or the local path of a voice to upload.
317
     * @param string $caption <i>Optional</i>. Voice message caption, 0-200 characters
318
     * @param int $duration <i>Optional</i>. Duration of the voice message in seconds
319
     * @param string $reply_markup <i>Optional</i>. Reply markup of the message.
320
     * @param bool $disable_notification <i>Optional</i>. Sends the message silently.
321
     * @param int $reply_to_message_id <i>Optional</i>. If the message is a reply, ID of the original message.
322
     * @return Message|false Message sent on success, false otherwise.
323
     */
324
    public function sendVoice($voice, string $caption, int $duration, string $reply_markup = null, bool $disable_notification, int $reply_to_message_id = 0)
325
    {
326
        $this->_file->init($voice, 'voice');
327
328
        $this->parameters = [
329
            'chat_id' => $this->_chat_id,
330
            'caption' => $caption,
331
            'duration' => $duration,
332
            'disable_notification', $disable_notification,
333
            'reply_to_message_id' => $reply_to_message_id,
334
            'reply_markup' => $reply_markup
335
        ];
336
337
        return $this->processRequest('sendVoice', 'Message', $this->checkCurrentFile());
0 ignored issues
show
Bug introduced by
The call to checkCurrentFile() misses a required argument $file.

This check looks for function calls that miss required arguments.

Loading history...
338
    }
339
340
    /**
341
     * \brief Say the user what action bot's going to do.
342
     * \details Use this method when you need to tell the user that something is happening on the bot's side.
343
     * The status is set for 5 seconds or less (when a message arrives from your bot,
344
     * Telegram clients clear its typing status). [API reference](https://core.telegram.org/bots/api#sendchataction)
345
     *
346
     * @param string $action Type of action to broadcast. Choose one, depending on what the user is about to receive:
347
     * - <code>typing</code> for text messages
348
     * - <code>upload_photo</code> for photos
349
     * - <code>record_video</code> or <code>upload_video</code> for videos
350
     * - <code>record_audio</code> or <code>upload_audio</code> for audio files
351
     * - <code>upload_document</code> for general files
352
     * - <code>find_location</code> for location data
353
     * @return bool True on success.
354
     */
355
    public function sendChatAction(string $action) : bool
356
    {
357
358
        $parameters = [
359
            'chat_id' => $this->_chat_id,
360
            'action' => $action
361
        ];
362
363
        return $this->execRequest('sendChatAction?' . http_build_query($parameters));
364
    }
365
366
    /** @} */
367
}
368