Skip to content

Commit 488f68d

Browse files
authored
Merge pull request #948 from noplanman/944-bot_api_4.2_polls
API 4.2 - Polls
2 parents acde132 + 50d732e commit 488f68d

File tree

10 files changed

+195
-9
lines changed

10 files changed

+195
-9
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
44
Exclamation symbols (:exclamation:) note something of importance e.g. breaking changes. Click them to learn more.
55

66
## [Unreleased]
7+
:exclamation: After updating to this version, you will need to execute the [SQL migration script][unreleased-sql-migration] on your database.
78
### Added
9+
- Bot API 4.2 (Polls).
10+
- `getIsMember()` method to `ChatMember` entity.
11+
- `getForwardSenderName()` method to `Message` entity.
12+
- `forward_sender_name` (and forgotten `forward_signature`) DB fields.
813
### Changed
914
### Deprecated
1015
### Removed
@@ -249,6 +254,7 @@ Exclamation symbols (:exclamation:) note something of importance e.g. breaking c
249254
### Deprecated
250255
- Move `hideKeyboard` to `removeKeyboard`.
251256

257+
[unreleased-sql-migration]: https://github.com/php-telegram-bot/core/tree/develop/utils/db-schema-update/unreleased.sql
252258
[0.55.0-sql-migration]: https://github.com/php-telegram-bot/core/tree/master/utils/db-schema-update/0.54.1-0.55.0.sql
253259
[0.55.0-bc-move-animation-out-of-games-namespace]: https://github.com/php-telegram-bot/core/wiki/Breaking-backwards-compatibility#move-animation-out-of-games-namespace
254260
[0.54.0-sql-migration]: https://github.com/php-telegram-bot/core/tree/master/utils/db-schema-update/0.53.0-0.54.0.sql

src/DB.php

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Longman\TelegramBot\Entities\ChosenInlineResult;
1818
use Longman\TelegramBot\Entities\InlineQuery;
1919
use Longman\TelegramBot\Entities\Message;
20+
use Longman\TelegramBot\Entities\Poll;
2021
use Longman\TelegramBot\Entities\ReplyToMessage;
2122
use Longman\TelegramBot\Entities\Update;
2223
use Longman\TelegramBot\Entities\User;
@@ -141,6 +142,7 @@ protected static function defineTables()
141142
'edited_message',
142143
'inline_query',
143144
'message',
145+
'poll',
144146
'request_limiter',
145147
'telegram_update',
146148
'user',
@@ -309,6 +311,7 @@ public static function entitiesArrayToJson($entities, $default = null)
309311
* @param string $chosen_inline_result_id
310312
* @param string $callback_query_id
311313
* @param string $edited_message_id
314+
* @param string $poll_id
312315
*
313316
* @return bool If the insert was successful
314317
* @throws TelegramException
@@ -320,10 +323,11 @@ public static function insertTelegramUpdate(
320323
$inline_query_id = null,
321324
$chosen_inline_result_id = null,
322325
$callback_query_id = null,
323-
$edited_message_id = null
326+
$edited_message_id = null,
327+
$poll_id = null
324328
) {
325-
if ($message_id === null && $inline_query_id === null && $chosen_inline_result_id === null && $callback_query_id === null && $edited_message_id === null) {
326-
throw new TelegramException('message_id, inline_query_id, chosen_inline_result_id, callback_query_id, edited_message_id are all null');
329+
if ($message_id === null && $inline_query_id === null && $chosen_inline_result_id === null && $callback_query_id === null && $edited_message_id === null && $poll_id === null) {
330+
throw new TelegramException('message_id, inline_query_id, chosen_inline_result_id, callback_query_id, edited_message_id, poll_id are all null');
327331
}
328332

329333
if (!self::isDbConnected()) {
@@ -333,9 +337,9 @@ public static function insertTelegramUpdate(
333337
try {
334338
$sth = self::$pdo->prepare('
335339
INSERT IGNORE INTO `' . TB_TELEGRAM_UPDATE . '`
336-
(`id`, `chat_id`, `message_id`, `inline_query_id`, `chosen_inline_result_id`, `callback_query_id`, `edited_message_id`)
340+
(`id`, `chat_id`, `message_id`, `inline_query_id`, `chosen_inline_result_id`, `callback_query_id`, `edited_message_id`, `poll_id`)
337341
VALUES
338-
(:id, :chat_id, :message_id, :inline_query_id, :chosen_inline_result_id, :callback_query_id, :edited_message_id)
342+
(:id, :chat_id, :message_id, :inline_query_id, :chosen_inline_result_id, :callback_query_id, :edited_message_id, :poll_id)
339343
');
340344

341345
$sth->bindValue(':id', $id);
@@ -345,6 +349,7 @@ public static function insertTelegramUpdate(
345349
$sth->bindValue(':inline_query_id', $inline_query_id);
346350
$sth->bindValue(':chosen_inline_result_id', $chosen_inline_result_id);
347351
$sth->bindValue(':callback_query_id', $callback_query_id);
352+
$sth->bindValue(':poll_id', $poll_id);
348353

349354
return $sth->execute();
350355
} catch (PDOException $e) {
@@ -599,6 +604,23 @@ public static function insertRequest(Update $update)
599604
$callback_query_id
600605
);
601606
}
607+
} elseif ($update_type === 'poll') {
608+
$poll = $update->getPoll();
609+
610+
if (self::insertPollRequest($poll)) {
611+
$poll_id = $poll->getId();
612+
613+
return self::insertTelegramUpdate(
614+
$update_id,
615+
null,
616+
null,
617+
null,
618+
null,
619+
null,
620+
null,
621+
$poll_id
622+
);
623+
}
602624
}
603625

604626
return false;
@@ -759,6 +781,43 @@ public static function insertCallbackQueryRequest(CallbackQuery $callback_query)
759781
}
760782
}
761783

784+
/**
785+
* Insert poll request into database
786+
*
787+
* @param Poll $poll
788+
*
789+
* @return bool If the insert was successful
790+
* @throws TelegramException
791+
*/
792+
public static function insertPollRequest(Poll $poll)
793+
{
794+
if (!self::isDbConnected()) {
795+
return false;
796+
}
797+
798+
try {
799+
$sth = self::$pdo->prepare('
800+
INSERT INTO `' . TB_POLL . '`
801+
(`id`, `question`, `options`, `is_closed`, `created_at`)
802+
VALUES
803+
(:id, :question, :options, :is_closed, :created_at)
804+
ON DUPLICATE KEY UPDATE
805+
`options` = VALUES(`options`),
806+
`is_closed` = VALUES(`is_closed`)
807+
');
808+
809+
$sth->bindValue(':id', $poll->getId());
810+
$sth->bindValue(':question', $poll->getQuestion());
811+
$sth->bindValue(':options', self::entitiesArrayToJson($poll->getOptions(), null));
812+
$sth->bindValue(':is_closed', $poll->getIsClosed());
813+
$sth->bindValue(':created_at', self::getTimestamp());
814+
815+
return $sth->execute();
816+
} catch (PDOException $e) {
817+
throw new TelegramException($e->getMessage());
818+
}
819+
}
820+
762821
/**
763822
* Insert Message request in db
764823
*
@@ -828,17 +887,19 @@ public static function insertMessageRequest(Message $message)
828887
INSERT IGNORE INTO `' . TB_MESSAGE . '`
829888
(
830889
`id`, `user_id`, `chat_id`, `date`, `forward_from`, `forward_from_chat`, `forward_from_message_id`,
831-
`forward_date`, `reply_to_chat`, `reply_to_message`, `media_group_id`, `text`, `entities`, `audio`, `document`,
890+
`forward_signature`, `forward_sender_name`, `forward_date`,
891+
`reply_to_chat`, `reply_to_message`, `media_group_id`, `text`, `entities`, `audio`, `document`,
832892
`animation`, `game`, `photo`, `sticker`, `video`, `voice`, `video_note`, `caption`, `contact`,
833-
`location`, `venue`, `new_chat_members`, `left_chat_member`,
893+
`location`, `venue`, `poll`, `new_chat_members`, `left_chat_member`,
834894
`new_chat_title`,`new_chat_photo`, `delete_chat_photo`, `group_chat_created`,
835895
`supergroup_chat_created`, `channel_chat_created`,
836896
`migrate_from_chat_id`, `migrate_to_chat_id`, `pinned_message`, `connected_website`, `passport_data`
837897
) VALUES (
838898
:message_id, :user_id, :chat_id, :date, :forward_from, :forward_from_chat, :forward_from_message_id,
839-
:forward_date, :reply_to_chat, :reply_to_message, :media_group_id, :text, :entities, :audio, :document,
899+
:forward_signature, :forward_sender_name, :forward_date,
900+
:reply_to_chat, :reply_to_message, :media_group_id, :text, :entities, :audio, :document,
840901
:animation, :game, :photo, :sticker, :video, :voice, :video_note, :caption, :contact,
841-
:location, :venue, :new_chat_members, :left_chat_member,
902+
:location, :venue, :poll, :new_chat_members, :left_chat_member,
842903
:new_chat_title, :new_chat_photo, :delete_chat_photo, :group_chat_created,
843904
:supergroup_chat_created, :channel_chat_created,
844905
:migrate_from_chat_id, :migrate_to_chat_id, :pinned_message, :connected_website, :passport_data
@@ -867,6 +928,8 @@ public static function insertMessageRequest(Message $message)
867928
$sth->bindValue(':forward_from', $forward_from);
868929
$sth->bindValue(':forward_from_chat', $forward_from_chat);
869930
$sth->bindValue(':forward_from_message_id', $message->getForwardFromMessageId());
931+
$sth->bindValue(':forward_signature', $message->getForwardSignature());
932+
$sth->bindValue(':forward_sender_name', $message->getForwardSenderName());
870933
$sth->bindValue(':forward_date', $forward_date);
871934

872935
$reply_to_chat_id = null;
@@ -892,6 +955,7 @@ public static function insertMessageRequest(Message $message)
892955
$sth->bindValue(':contact', $message->getContact());
893956
$sth->bindValue(':location', $message->getLocation());
894957
$sth->bindValue(':venue', $message->getVenue());
958+
$sth->bindValue(':poll', $message->getPoll());
895959
$sth->bindValue(':new_chat_members', $new_chat_members_ids);
896960
$sth->bindValue(':left_chat_member', $left_chat_member_id);
897961
$sth->bindValue(':new_chat_title', $message->getNewChatTitle());

src/Entities/ChatMember.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* @method bool getCanRestrictMembers() Optional. Administrators only. True, if the administrator can restrict, ban or unban chat members
2828
* @method bool getCanPinMessages() Optional. Administrators only. True, if the administrator can pin messages, supergroups only
2929
* @method bool getCanPromoteMembers() Optional. Administrators only. True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user)
30+
* @method bool getIsMember() Optional. Restricted only. True, if the user is a member of the chat at the moment of the request
3031
* @method bool getCanSendMessages() Optional. Restricted only. True, if the user can send text messages, contacts, locations and venues
3132
* @method bool getCanSendMediaMessages() Optional. Restricted only. True, if the user can send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages
3233
* @method bool getCanSendOtherMessages() Optional. Restricted only. True, if the user can send animations, games, stickers and use inline bots, implies can_send_media_messages

src/Entities/Message.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* @method Chat getForwardFromChat() Optional. For messages forwarded from a channel, information about the original channel
2929
* @method int getForwardFromMessageId() Optional. For forwarded channel posts, identifier of the original message in the channel
3030
* @method string getForwardSignature() Optional. For messages forwarded from channels, signature of the post author if present
31+
* @method string getForwardSenderName() Optional. Sender's name for messages forwarded from users who disallow adding a link to their account in forwarded messages
3132
* @method int getForwardDate() Optional. For forwarded messages, date the original message was sent in Unix time
3233
* @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.
3334
* @method int getEditDate() Optional. Date the message was last edited in Unix time
@@ -45,6 +46,7 @@
4546
* @method Contact getContact() Optional. Message is a shared contact, information about the contact
4647
* @method Location getLocation() Optional. Message is a shared location, information about the location
4748
* @method Venue getVenue() Optional. Message is a venue, information about the venue
49+
* @method Poll getPoll() Optional. Message is a native poll, information about the poll
4850
* @method User getLeftChatMember() Optional. A member was removed from the group, information about them (this member may be the bot itself)
4951
* @method string getNewChatTitle() Optional. A chat title was changed to this value
5052
* @method bool getDeleteChatPhoto() Optional. Service message: the chat photo was deleted
@@ -86,6 +88,7 @@ protected function subEntities()
8688
'contact' => Contact::class,
8789
'location' => Location::class,
8890
'venue' => Venue::class,
91+
'poll' => Poll::class,
8992
'new_chat_members' => User::class,
9093
'left_chat_member' => User::class,
9194
'new_chat_photo' => PhotoSize::class,
@@ -295,6 +298,7 @@ public function getType()
295298
'contact',
296299
'location',
297300
'venue',
301+
'poll',
298302
'new_chat_members',
299303
'left_chat_member',
300304
'new_chat_title',

src/Entities/Poll.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 Poll
15+
*
16+
* This entity contains information about a poll.
17+
*
18+
* @link https://core.telegram.org/bots/api#poll
19+
*
20+
* @method string getId() Unique poll identifier
21+
* @method string getQuestion() Poll question, 1-255 characters
22+
* @method bool getIsClosed() True, if the poll is closed
23+
*/
24+
class Poll extends Entity
25+
{
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
protected function subEntities()
30+
{
31+
return [
32+
'options' => PollOption::class,
33+
];
34+
}
35+
36+
/**
37+
* List of poll options
38+
*
39+
* This method overrides the default getOptions method
40+
* and returns a nice array of PollOption objects.
41+
*
42+
* @return null|PollOption[]
43+
*/
44+
public function getOptions()
45+
{
46+
$pretty_array = $this->makePrettyObjectArray(PollOption::class, 'options');
47+
48+
return empty($pretty_array) ? null : $pretty_array;
49+
}
50+
}

src/Entities/PollOption.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 PollOption
15+
*
16+
* This entity contains information about one answer option in a poll.
17+
*
18+
* @link https://core.telegram.org/bots/api#polloption
19+
*
20+
* @method string getText() Option text, 1-100 characters
21+
* @method int getVoterCount() Number of users that voted for this option
22+
*/
23+
class PollOption extends Entity
24+
{
25+
26+
}

src/Entities/Update.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* @method CallbackQuery getCallbackQuery() Optional. New incoming callback query
2929
* @method ShippingQuery getShippingQuery() Optional. New incoming shipping query. Only for invoices with flexible price
3030
* @method PreCheckoutQuery getPreCheckoutQuery() Optional. New incoming pre-checkout query. Contains full information about checkout
31+
* @method Poll getPoll() Optional. New poll state. Bots receive only updates about polls, which are sent or stopped by the bot
3132
*/
3233
class Update extends Entity
3334
{
@@ -46,6 +47,7 @@ protected function subEntities()
4647
'callback_query' => CallbackQuery::class,
4748
'shipping_query' => ShippingQuery::class,
4849
'pre_checkout_query' => PreCheckoutQuery::class,
50+
'poll' => Poll::class,
4951
];
5052
}
5153

@@ -66,6 +68,7 @@ public function getUpdateType()
6668
'callback_query',
6769
'shipping_query',
6870
'pre_checkout_query',
71+
'poll',
6972
];
7073
foreach ($types as $type) {
7174
if ($this->getProperty($type)) {

0 commit comments

Comments
 (0)