Completed
Pull Request — develop (#860)
by Armando
02:20
created

Message   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 260
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 83.61%

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 2
dl 0
loc 260
ccs 51
cts 61
cp 0.8361
rs 9.76
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A subEntities() 0 29 1
A __construct() 0 4 1
A getPhoto() 0 6 2
A getNewChatPhoto() 0 6 2
A getNewChatMembers() 0 6 2
A getEntities() 0 6 2
A getCaptionEntities() 0 6 2
A getFullCommand() 0 13 3
A getCommand() 0 26 5
A getText() 0 14 4
A botAddedInChat() 0 10 4
B getType() 0 41 5
1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\TelegramBot\Entities;
12
13
use Longman\TelegramBot\Entities\Games\Game;
14
use Longman\TelegramBot\Entities\Payments\Invoice;
15
use Longman\TelegramBot\Entities\Payments\SuccessfulPayment;
16
17
/**
18
 * Class Message
19
 *
20
 * @link https://core.telegram.org/bots/api#message
21
 *
22
 * @method int               getMessageId()             Unique message identifier
23
 * @method User              getFrom()                  Optional. Sender, can be empty for messages sent to channels
24
 * @method int               getDate()                  Date the message was sent in Unix time
25
 * @method Chat              getChat()                  Conversation the message belongs to
26
 * @method User              getForwardFrom()           Optional. For forwarded messages, sender of the original message
27
 * @method Chat              getForwardFromChat()       Optional. For messages forwarded from a channel, information about the original channel
28
 * @method int               getForwardFromMessageId()  Optional. For forwarded channel posts, identifier of the original message in the channel
29
 * @method string            getForwardSignature()      Optional. For messages forwarded from channels, signature of the post author if present
30
 * @method int               getForwardDate()           Optional. For forwarded messages, date the original message was sent in Unix time
31
 * @method Message           getReplyToMessage()        Optional. For replies, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply.
32
 * @method int               getEditDate()              Optional. Date the message was last edited in Unix time
33
 * @method string            getMediaGroupId()          Optional. The unique identifier of a media message group this message belongs to
34
 * @method string            getAuthorSignature()       Optional. Signature of the post author for messages in channels
35
 * @method Audio             getAudio()                 Optional. Message is an audio file, information about the file
36
 * @method Document          getDocument()              Optional. Message is a general file, information about the file
37
 * @method Game              getGame()                  Optional. Message is a game, information about the game.
38
 * @method Sticker           getSticker()               Optional. Message is a sticker, information about the sticker
39
 * @method Video             getVideo()                 Optional. Message is a video, information about the video
40
 * @method Voice             getVoice()                 Optional. Message is a voice message, information about the file
41
 * @method VideoNote         getVideoNote()             Optional. Message is a video note message, information about the video
42
 * @method string            getCaption()               Optional. Caption for the document, photo or video, 0-200 characters
43
 * @method Contact           getContact()               Optional. Message is a shared contact, information about the contact
44
 * @method Location          getLocation()              Optional. Message is a shared location, information about the location
45
 * @method Venue             getVenue()                 Optional. Message is a venue, information about the venue
46
 * @method User              getLeftChatMember()        Optional. A member was removed from the group, information about them (this member may be the bot itself)
47
 * @method string            getNewChatTitle()          Optional. A chat title was changed to this value
48
 * @method bool              getDeleteChatPhoto()       Optional. Service message: the chat photo was deleted
49
 * @method bool              getGroupChatCreated()      Optional. Service message: the group has been created
50
 * @method bool              getSupergroupChatCreated() Optional. Service message: the supergroup has been created. This field can't be received in a message coming through updates, because bot can’t be a member of a supergroup when it is created. It can only be found in reply_to_message if someone replies to a very first message in a directly created supergroup.
51
 * @method bool              getChannelChatCreated()    Optional. Service message: the channel has been created. This field can't be received in a message coming through updates, because bot can’t be a member of a channel when it is created. It can only be found in reply_to_message if someone replies to a very first message in a channel.
52
 * @method int               getMigrateToChatId()       Optional. The group has been migrated to a supergroup with the specified identifier. This number may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier.
53
 * @method int               getMigrateFromChatId()     Optional. The supergroup has been migrated from a group with the specified identifier. This number may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier.
54
 * @method Message           getPinnedMessage()         Optional. Specified message was pinned. Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply.
55
 * @method Invoice           getInvoice()               Optional. Message is an invoice for a payment, information about the invoice.
56
 * @method SuccessfulPayment getSuccessfulPayment()     Optional. Message is a service message about a successful payment, information about the payment.
57
 * @method string            getConnectedWebsite()      Optional. The domain name of the website on which the user has logged in.
58
 */
59
class Message extends Entity
60
{
61
    /**
62
     * {@inheritdoc}
63
     */
64 10
    protected function subEntities()
65
    {
66
        return [
67 10
            'from'               => User::class,
68
            'chat'               => Chat::class,
69
            'forward_from'       => User::class,
70
            'forward_from_chat'  => Chat::class,
71
            'reply_to_message'   => ReplyToMessage::class,
72
            'entities'           => MessageEntity::class,
73
            'caption_entities'   => MessageEntity::class,
74
            'audio'              => Audio::class,
75
            'document'           => Document::class,
76
            'game'               => Game::class,
77
            'photo'              => PhotoSize::class,
78
            'sticker'            => Sticker::class,
79
            'video'              => Video::class,
80
            'voice'              => Voice::class,
81
            'video_note'         => VideoNote::class,
82
            'contact'            => Contact::class,
83
            'location'           => Location::class,
84
            'venue'              => Venue::class,
85
            'new_chat_members'   => User::class,
86
            'left_chat_member'   => User::class,
87
            'new_chat_photo'     => PhotoSize::class,
88
            'pinned_message'     => Message::class,
89
            'invoice'            => Invoice::class,
90
            'successful_payment' => SuccessfulPayment::class,
91
        ];
92
    }
93
94
    /**
95
     * Message constructor
96
     *
97
     * @param array  $data
98
     * @param string $bot_username
99
     *
100
     * @throws \Longman\TelegramBot\Exception\TelegramException
101
     */
102 12
    public function __construct(array $data, $bot_username = '')
103
    {
104 12
        parent::__construct($data, $bot_username);
105 12
    }
106
107
    /**
108
     * Optional. Message is a photo, available sizes of the photo
109
     *
110
     * This method overrides the default getPhoto method
111
     * and returns a nice array of PhotoSize objects.
112
     *
113
     * @return null|PhotoSize[]
114
     */
115 6
    public function getPhoto()
116
    {
117 6
        $pretty_array = $this->makePrettyObjectArray(PhotoSize::class, 'photo');
118
119 6
        return empty($pretty_array) ? null : $pretty_array;
120
    }
121
122
    /**
123
     * Optional. A chat photo was changed to this value
124
     *
125
     * This method overrides the default getNewChatPhoto method
126
     * and returns a nice array of PhotoSize objects.
127
     *
128
     * @return null|PhotoSize[]
129
     */
130 6
    public function getNewChatPhoto()
131
    {
132 6
        $pretty_array = $this->makePrettyObjectArray(PhotoSize::class, 'new_chat_photo');
133
134 6
        return empty($pretty_array) ? null : $pretty_array;
135
    }
136
137
    /**
138
     * Optional. A new member(s) was added to the group, information about them (one of this members may be the bot itself)
139
     *
140
     * This method overrides the default getNewChatMembers method
141
     * and returns a nice array of User objects.
142
     *
143
     * @return null|User[]
144
     */
145 6
    public function getNewChatMembers()
146
    {
147 6
        $pretty_array = $this->makePrettyObjectArray(User::class, 'new_chat_members');
148
149 6
        return empty($pretty_array) ? null : $pretty_array;
150
    }
151
152
    /**
153
     * Optional. For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text
154
     *
155
     * This method overrides the default getEntities method
156
     * and returns a nice array of MessageEntity objects.
157
     *
158
     * @return null|MessageEntity[]
159
     */
160 6
    public function getEntities()
161
    {
162 6
        $pretty_array = $this->makePrettyObjectArray(MessageEntity::class, 'entities');
163
164 6
        return empty($pretty_array) ? null : $pretty_array;
165
    }
166
167
    /**
168
     * Optional. For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
169
     *
170
     * This method overrides the default getCaptionEntities method
171
     * and returns a nice array of MessageEntity objects.
172
     *
173
     * @return null|MessageEntity[]
174
     */
175
    public function getCaptionEntities()
176
    {
177
        $pretty_array = $this->makePrettyObjectArray(MessageEntity::class, 'caption_entities');
178
179
        return empty($pretty_array) ? null : $pretty_array;
180
    }
181
182
    /**
183
     * return the entire command like /echo or /echo@bot1 if specified
184
     *
185
     * @return string|null
186
     */
187 2
    public function getFullCommand()
188
    {
189 2
        $text = $this->getProperty('text');
190 2
        if (strpos($text, '/') !== 0) {
191 2
            return null;
192
        }
193
194 2
        $no_EOL   = strtok($text, PHP_EOL);
195 2
        $no_space = strtok($text, ' ');
196
197
        //try to understand which separator \n or space divide /command from text
198 2
        return strlen($no_space) < strlen($no_EOL) ? $no_space : $no_EOL;
199
    }
200
201
    /**
202
     * Get command
203
     *
204
     * @return string|null
205
     */
206 2
    public function getCommand()
207
    {
208 2
        if ($command = $this->getProperty('command')) {
209
            return $command;
210
        }
211
212 2
        $full_command = $this->getFullCommand();
213 2
        if (strpos($full_command, '/') !== 0) {
214 2
            return null;
215
        }
216 2
        $full_command = substr($full_command, 1);
217
218
        //check if command is followed by bot username
219 2
        $split_cmd = explode('@', $full_command);
220 2
        if (!isset($split_cmd[1])) {
221
            //command is not followed by name
222 2
            return $full_command;
223
        }
224
225 1
        if (strtolower($split_cmd[1]) === strtolower($this->getBotUsername())) {
226
            //command is addressed to me
227 1
            return $split_cmd[0];
228
        }
229
230
        return null;
231
    }
232
233
    /**
234
     * For text messages, the actual UTF-8 text of the message, 0-4096 characters.
235
     *
236
     * @param bool $without_cmd
237
     *
238
     * @return string
239
     */
240 9
    public function getText($without_cmd = false)
241
    {
242 9
        $text = $this->getProperty('text');
243
244 9
        if ($without_cmd && $command = $this->getFullCommand()) {
245 1
            if (strlen($command) + 1 < strlen($text)) {
246 1
                return substr($text, strlen($command) + 1);
247
            }
248
249 1
            return '';
250
        }
251
252 9
        return $text;
253
    }
254
255
    /**
256
     * Bot added in chat
257
     *
258
     * @return bool
259
     * @throws \Longman\TelegramBot\Exception\TelegramException
260
     */
261
    public function botAddedInChat()
262
    {
263
        foreach ($this->getNewChatMembers() as $member) {
264
            if ($member instanceof User && $member->getUsername() === $this->getBotUsername()) {
265
                return true;
266
            }
267
        }
268
269
        return false;
270
    }
271
272
    /**
273
     * Detect type based on properties.
274
     *
275
     * @return string
276
     */
277 1
    public function getType()
278
    {
279
        $types = [
280 1
            'text',
281
            'audio',
282
            'document',
283
            'photo',
284
            'sticker',
285
            'video',
286
            'voice',
287
            'contact',
288
            'location',
289
            'venue',
290
            'new_chat_members',
291
            'left_chat_member',
292
            'new_chat_title',
293
            'new_chat_photo',
294
            'delete_chat_photo',
295
            'group_chat_created',
296
            'supergroup_chat_created',
297
            'channel_chat_created',
298
            'migrate_to_chat_id',
299
            'migrate_from_chat_id',
300
            'pinned_message',
301
            'invoice',
302
            'successful_payment',
303
        ];
304
305 1
        $is_command = strlen($this->getCommand()) > 0;
306 1
        foreach ($types as $type) {
307 1
            if ($this->getProperty($type)) {
308 1
                if ($is_command && $type === 'text') {
309 1
                    return 'command';
310
                }
311
312 1
                return $type;
313
            }
314
        }
315
316 1
        return 'message';
317
    }
318
}
319