Completed
Push — master ( 8fbc07...04de59 )
by Armando
03:05 queued 01:27
created

Message::getEntities()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

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

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
278 1
                    return 'command';
279
                }
280
281 1
                return $type;
282
            }
283
        }
284
285 1
        return 'message';
286
    }
287
}
288