Completed
Push — api_3.0_basic_changes ( 9bd403 )
by Armando
03:05
created

Message::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.7898

Importance

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