Message   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 92.59%

Importance

Changes 0
Metric Value
wmc 29
c 0
b 0
f 0
lcom 2
cbo 2
dl 0
loc 228
ccs 50
cts 54
cp 0.9259
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
B subEntities() 0 24 1
A __construct() 0 14 3
A getPhoto() 0 6 2
A getNewChatPhoto() 0 6 2
A getEntities() 0 6 2
A getFullCommand() 0 13 3
B getCommand() 0 27 5
A botAddedInChat() 0 6 2
B getType() 0 38 5
A getText() 0 14 4
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
/**
14
 * Class Message
15
 *
16
 * @link https://core.telegram.org/bots/api#message
17
 *
18
 * @method int      getMessageId()             Unique message identifier
19
 * @method User     getFrom()                  Optional. Sender, can be empty for messages sent to channels
20
 * @method int      getDate()                  Date the message was sent in Unix time
21
 * @method Chat     getChat()                  Conversation the message belongs to
22
 * @method User     getForwardFrom()           Optional. For forwarded messages, sender of the original message
23
 * @method Chat     getForwardFromChat()       Optional. For messages forwarded from a channel, information about the original channel
24
 * @method int      getForwardFromMessageId()  Optional. For forwarded channel posts, identifier of the original message in the channel
25
 * @method int      getForwardDate()           Optional. For forwarded messages, date the original message was sent in Unix time
26
 * @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.
27
 * @method int      getEditDate()              Optional. Date the message was last edited in Unix time
28
 * @method Audio    getAudio()                 Optional. Message is an audio file, information about the file
29
 * @method Document getDocument()              Optional. Message is a general file, information about the file
30
 * @method Sticker  getSticker()               Optional. Message is a sticker, information about the sticker
31
 * @method Video    getVideo()                 Optional. Message is a video, information about the video
32
 * @method Voice    getVoice()                 Optional. Message is a voice message, information about the file
33
 * @method string   getCaption()               Optional. Caption for the document, photo or video, 0-200 characters
34
 * @method Contact  getContact()               Optional. Message is a shared contact, information about the contact
35
 * @method Location getLocation()              Optional. Message is a shared location, information about the location
36
 * @method Venue    getVenue()                 Optional. Message is a venue, information about the venue
37
 * @method User     getNewChatMember()         Optional. A new member was added to the group, information about them (this member may be the bot itself)
38
 * @method User     getLeftChatMember()        Optional. A member was removed from the group, information about them (this member may be the bot itself)
39
 * @method string   getNewChatTitle()          Optional. A chat title was changed to this value
40
 * @method bool     getDeleteChatPhoto()       Optional. Service message: the chat photo was deleted
41
 * @method bool     getGroupChatCreated()      Optional. Service message: the group has been created
42
 * @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.
43
 * @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.
44
 * @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.
45
 * @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.
46
 * @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.
47
 */
48
class Message extends Entity
49
{
50
    /**
51
     * {@inheritdoc}
52
     */
53 16
    protected function subEntities()
54
    {
55
        return [
56 16
            'from'              => User::class,
57
            'chat'              => Chat::class,
58
            'forward_from'      => User::class,
59
            'forward_from_chat' => Chat::class,
60
            'reply_to_message'  => self::class,
61
            'entities'          => MessageEntity::class,
62
            'audio'             => Audio::class,
63
            'document'          => Document::class,
64
            'photo'             => PhotoSize::class,
65
            'sticker'           => Sticker::class,
66
            'video'             => Video::class,
67
            'voice'             => Voice::class,
68
            'contact'           => Contact::class,
69
            'location'          => Location::class,
70
            'venue'             => Venue::class,
71
            'new_chat_member'   => User::class,
72
            'left_chat_member'  => User::class,
73
            'new_chat_photo'    => PhotoSize::class,
74
            'pinned_message'    => Message::class,
75
        ];
76
    }
77
78
    /**
79
     * Message constructor
80
     *
81
     * @param array  $data
82
     * @param string $bot_name
83
     *
84
     * @throws \Longman\TelegramBot\Exception\TelegramException
85
     */
86 18
    public function __construct(array $data, $bot_name = '')
87
    {
88
        //Retro-compatibility
89 18
        if (isset($data['new_chat_participant'])) {
90
            $data['new_chat_member'] = $data['new_chat_participant'];
91
            unset($data['new_chat_participant']);
92
        }
93 18
        if (isset($data['left_chat_participant'])) {
94
            $data['left_chat_member'] = $data['left_chat_participant'];
95
            unset($data['left_chat_participant']);
96
        }
97
98 18
        parent::__construct($data, $bot_name);
99 18
    }
100
101
    /**
102
     * Optional. Message is a photo, available sizes of the photo
103
     *
104
     * This method overrides the default getPhoto method
105
     * and returns a nice array of PhotoSize objects.
106
     *
107
     * @return null|PhotoSize[]
108
     */
109 6
    public function getPhoto()
110
    {
111 6
        $pretty_array = $this->makePrettyObjectArray(PhotoSize::class, 'photo');
112
113 6
        return empty($pretty_array) ? null : $pretty_array;
114
    }
115
116
    /**
117
     * Optional. A chat photo was changed to this value
118
     *
119
     * This method overrides the default getNewChatPhoto method
120
     * and returns a nice array of PhotoSize objects.
121
     *
122
     * @return null|PhotoSize[]
123
     */
124 6
    public function getNewChatPhoto()
125
    {
126 6
        $pretty_array = $this->makePrettyObjectArray(PhotoSize::class, 'new_chat_photo');
127
128 6
        return empty($pretty_array) ? null : $pretty_array;
129
    }
130
131
    /**
132
     * Optional. For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text
133
     *
134
     * This method overrides the default getEntities method
135
     * and returns a nice array of MessageEntity objects.
136
     *
137
     * @return null|MessageEntity[]
138
     */
139 6
    public function getEntities()
140
    {
141 6
        $pretty_array = $this->makePrettyObjectArray(MessageEntity::class, 'entities');
142
143 6
        return empty($pretty_array) ? null : $pretty_array;
144
    }
145
146
    /**
147
     * return the entire command like /echo or /echo@bot1 if specified
148
     *
149
     * @return string|null
150
     */
151 8
    public function getFullCommand()
152
    {
153 8
        $text = $this->getProperty('text');
154 8
        if (strpos($text, '/') === 0) {
155 8
            $no_EOL = strtok($text, PHP_EOL);
156 8
            $no_space = strtok($text, ' ');
157
158
            //try to understand which separator \n or space divide /command from text
159 8
            return strlen($no_space) < strlen($no_EOL) ? $no_space : $no_EOL;
160
        }
161
162 2
        return null;
163
    }
164
165
    /**
166
     * Get command
167
     *
168
     * @return bool|string
169
     */
170 2
    public function getCommand()
171
    {
172 2
        $command = $this->getProperty('command');
173 2
        if (!empty($command)) {
174
            return $command;
175
        }
176
177 2
        $full_command = $this->getFullCommand();
178
179 2
        if (strpos($full_command, '/') === 0) {
180 2
            $full_command = substr($full_command, 1);
181
182
            //check if command is follow by botname
183 2
            $split_cmd = explode('@', $full_command);
184 2
            if (isset($split_cmd[1])) {
185
                //command is followed by name check if is addressed to me
186 1
                if (strtolower($split_cmd[1]) === strtolower($this->getBotName())) {
187 1
                    return $split_cmd[0];
188
                }
189
            } else {
190
                //command is not followed by name
191 2
                return $full_command;
192
            }
193
        }
194
195 2
        return false;
196
    }
197
198
    /**
199
     * For text messages, the actual UTF-8 text of the message, 0-4096 characters.
200
     *
201
     * @param bool $without_cmd
202
     *
203
     * @return string
204
     */
205 15
    public function getText($without_cmd = false)
206
    {
207 15
        $text = $this->getProperty('text');
208
209 15
        if ($without_cmd && $command = $this->getFullCommand()) {
210 7
            if (strlen($command) + 1 < strlen($text)) {
211 5
                return substr($text, strlen($command) + 1);
212
            }
213
214 4
            return '';
215
        }
216
217 15
        return $text;
218
    }
219
220
    /**
221
     * Bot added in chat
222
     *
223
     * @return bool
224
     */
225
    public function botAddedInChat()
226
    {
227
        $member = $this->getNewChatMember();
228
229
        return $member !== null && $member->getUsername() === $this->getBotName();
230
    }
231
232
    /**
233
     * Detect type based on properties.
234
     *
235
     * @return string|null
236
     */
237 1
    public function getType()
238
    {
239
        $types = [
240 1
            'text',
241
            'audio',
242
            'document',
243
            'photo',
244
            'sticker',
245
            'video',
246
            'voice',
247
            'contact',
248
            'location',
249
            'venue',
250
            'new_chat_member',
251
            'left_chat_member',
252
            'new_chat_title',
253
            'new_chat_photo',
254
            'delete_chat_photo',
255
            'group_chat_created',
256
            'supergroup_chat_created',
257
            'channel_chat_created',
258
            'migrate_to_chat_id',
259
            'migrate_from_chat_id',
260
            'pinned_message',
261
        ];
262
263 1
        foreach ($types as $type) {
264 1
            if ($this->getProperty($type)) {
265 1
                if ($type === 'text' && $this->getCommand()) {
266 1
                    return 'command';
267
                }
268
269 1
                return $type;
270
            }
271
        }
272
273 1
        return 'message';
274
    }
275
}
276