Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bot API 6.0 #1318

Merged
merged 16 commits into from
Apr 24, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/Entities/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ abstract class Factory
{
abstract public static function make(array $data, string $bot_username): Entity;

public static function resolveEntityClass(string $class, array $property, string $bot_username = ''): Entity
public static function resolveEntityClass(string $class, mixed $property, string $bot_username = ''): Entity
{
if (is_subclass_of($class, Factory::class)) {
if (is_a($property, $class)) {
return $property;
} elseif (is_subclass_of($class, Factory::class)) {
TiiFuchs marked this conversation as resolved.
Show resolved Hide resolved
return $class::make($property, $bot_username);
}

Expand Down
13 changes: 8 additions & 5 deletions src/Entities/InlineKeyboardButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@
* @method string getUrl() Optional. HTTP url to be opened when button is pressed
* @method LoginUrl getLoginUrl() Optional. An HTTP URL used to automatically authorize the user. Can be used as a replacement for the Telegram Login Widget.
* @method string getCallbackData() Optional. Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes
* @method WebAppInfo getWebApp() Optional. Description of the Web App that will be launched when the user presses the button. The Web App will be able to send an arbitrary message on behalf of the user using the method answerWebAppQuery. Available only in private chats between a user and the bot.
* @method string getSwitchInlineQuery() Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot's username and the specified inline query in the input field. Can be empty, in which case just the bot’s username will be inserted.
* @method string getSwitchInlineQueryCurrentChat() Optional. If set, pressing the button will insert the bot‘s username and the specified inline query in the current chat's input field. Can be empty, in which case only the bot’s username will be inserted.
* @method CallbackGame getCallbackGame() Optional. Description of the game that will be launched when the user presses the button.
* @method bool getPay() Optional. Specify True, to send a Pay button.
*
* @method $this setText(string $text) Label text on the button
* @method $this setUrl(string $url) Optional. HTTP url to be opened when button is pressed
* @method $this setLoginUrl(LoginUrl $login_url) Optional. HTTP url to be opened when button is pressed
* @method $this setLoginUrl(LoginUrl $login_url) Optional. HTTP url to be opened when button is pressed
* @method $this setCallbackData(string $callback_data) Optional. Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes
* @method $this setWebApp(WebAppInfo $web_app) Optional. Description of the Web App that will be launched when the user presses the button. The Web App will be able to send an arbitrary message on behalf of the user using the method answerWebAppQuery. Available only in private chats between a user and the bot.
* @method $this setSwitchInlineQuery(string $switch_inline_query) Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot's username and the specified inline query in the input field. Can be empty, in which case just the bot’s username will be inserted.
* @method $this setSwitchInlineQueryCurrentChat(string $switch_inline_query_current_chat) Optional. If set, pressing the button will insert the bot‘s username and the specified inline query in the current chat's input field. Can be empty, in which case only the bot’s username will be inserted.
* @method $this setCallbackGame(CallbackGame $callback_game) Optional. Description of the game that will be launched when the user presses the button.
Expand All @@ -52,6 +54,7 @@ public static function couldBe(array $data): bool
array_key_exists('url', $data) ||
array_key_exists('login_url', $data) ||
array_key_exists('callback_data', $data) ||
array_key_exists('web_app', $data) ||
array_key_exists('switch_inline_query', $data) ||
array_key_exists('switch_inline_query_current_chat', $data) ||
array_key_exists('callback_game', $data) ||
Expand All @@ -70,7 +73,7 @@ protected function validate(): void

$num_params = 0;

foreach (['url', 'login_url', 'callback_data', 'callback_game', 'pay'] as $param) {
foreach (['url', 'login_url', 'callback_data', 'web_app', 'callback_game', 'pay'] as $param) {
if ($this->getProperty($param, '') !== '') {
$num_params++;
}
Expand All @@ -83,7 +86,7 @@ protected function validate(): void
}

if ($num_params !== 1) {
throw new TelegramException('You must use only one of these fields: url, login_url, callback_data, switch_inline_query, switch_inline_query_current_chat, callback_game, pay!');
throw new TelegramException('You must use only one of these fields: url, login_url, callback_data, web_app, switch_inline_query, switch_inline_query_current_chat, callback_game, pay!');
}
}

Expand All @@ -93,8 +96,8 @@ protected function validate(): void
public function __call($method, $args)
{
// Only 1 of these can be set, so clear the others when setting a new one.
if (in_array($method, ['setUrl', 'setLoginUrl', 'setCallbackData', 'setSwitchInlineQuery', 'setSwitchInlineQueryCurrentChat', 'setCallbackGame', 'setPay'], true)) {
unset($this->url, $this->login_url, $this->callback_data, $this->switch_inline_query, $this->switch_inline_query_current_chat, $this->callback_game, $this->pay);
if (in_array($method, ['setUrl', 'setLoginUrl', 'setCallbackData', 'setWebApp', 'setSwitchInlineQuery', 'setSwitchInlineQueryCurrentChat', 'setCallbackGame', 'setPay'], true)) {
unset($this->url, $this->login_url, $this->callback_data, $this->web_app, $this->switch_inline_query, $this->switch_inline_query_current_chat, $this->callback_game, $this->pay);
}

return parent::__call($method, $args);
Expand Down
28 changes: 20 additions & 8 deletions src/Entities/KeyboardButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,27 @@
*
* @link https://core.telegram.org/bots/api#keyboardbutton
*
* @property bool $request_contact
* @property bool $request_location
* @property bool $request_contact
* @property bool $request_location
* @property KeyboardButtonPollType $request_poll
* @property WebAppInfo $web_app
*
* @method string getText() Text of the button. If none of the optional fields are used, it will be sent to the bot as a message when the button is pressed
* @method bool getRequestContact() Optional. If True, the user's phone number will be sent as a contact when the button is pressed. Available in private chats only
* @method bool getRequestLocation() Optional. If True, the user's current location will be sent when the button is pressed. Available in private chats only
* @method KeyboardButtonPollType getRequestPoll() Optional. If specified, the user will be asked to create a poll and send it to the bot when the button is pressed. Available in private chats only
* @method KeyboardButtonPollType getRequestPoll() Optional. If specified, the user will be asked to create a poll and send it to the bot when the button is pressed. Available in private chats only
* @method WebAppInfo getWebApp() Optional. If specified, the described Web App will be launched when the button is pressed. The Web App will be able to send a “web_app_data” service message. Available in private chats only.
*
* @method $this setText(string $text) Text of the button. If none of the optional fields are used, it will be sent to the bot as a message when the button is pressed
* @method $this setRequestContact(bool $request_contact) Optional. If True, the user's phone number will be sent as a contact when the button is pressed. Available in private chats only
* @method $this setRequestLocation(bool $request_location) Optional. If True, the user's current location will be sent when the button is pressed. Available in private chats only
* @method $this setRequestPoll(KeyboardButtonPollType $request_poll) Optional. If specified, the user will be asked to create a poll and send it to the bot when the button is pressed. Available in private chats only
* @method $this setWebApp(WebAppInfo $web_app) Optional. If specified, the described Web App will be launched when the button is pressed. The Web App will be able to send a “web_app_data” service message. Available in private chats only.
*/
class KeyboardButton extends Entity
{
/**
* @param array|string $data
* @param array|string $data
*/
public function __construct($data)
{
Expand All @@ -47,10 +50,18 @@ public function __construct($data)
parent::__construct($data);
}

protected function subEntities(): array
{
return [
'request_poll' => KeyboardButtonPollType::class,
'web_app' => WebAppInfo::class,
];
}

/**
* Check if the passed data array could be a KeyboardButton.
*
* @param array $data
* @param array $data
*
* @return bool
*/
Expand All @@ -73,9 +84,10 @@ protected function validate(): void
$this->getRequestContact(),
$this->getRequestLocation(),
$this->getRequestPoll(),
$this->getWebApp(),
]);
if (count($field_count) > 1) {
throw new TelegramException('You must use only one of these fields: request_contact, request_location, request_poll!');
throw new TelegramException('You must use only one of these fields: request_contact, request_location, request_poll, web_app!');
}
}

Expand All @@ -85,8 +97,8 @@ protected function validate(): void
public function __call($method, $args)
{
// Only 1 of these can be set, so clear the others when setting a new one.
if (in_array($method, ['setRequestContact', 'setRequestLocation', 'setRequestPoll'], true)) {
unset($this->request_contact, $this->request_location, $this->request_poll);
if (in_array($method, ['setRequestContact', 'setRequestLocation', 'setRequestPoll', 'setWebApp'], true)) {
unset($this->request_contact, $this->request_location, $this->request_poll, $this->web_app);
}

return parent::__call($method, $args);
Expand Down
19 changes: 19 additions & 0 deletions src/Entities/WebAppInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Longman\TelegramBot\Entities;

/**
* Class WebAppInfo
*
* @link https://core.telegram.org/bots/api#webappinfo
*
* @property string $url An HTTPS URL of a Web App to be opened with additional data as specified in Initializing Web Apps
*
* @method string getUrl() An HTTPS URL of a Web App to be opened with additional data as specified in Initializing Web Apps
*
* @method $this setUrl(string $url) An HTTPS URL of a Web App to be opened with additional data as specified in Initializing Web Apps
*/
class WebAppInfo extends Entity
{

}
14 changes: 13 additions & 1 deletion tests/Unit/Entities/KeyboardButtonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Longman\TelegramBot\Entities\KeyboardButton;
use Longman\TelegramBot\Entities\KeyboardButtonPollType;
use Longman\TelegramBot\Entities\WebAppInfo;
use Longman\TelegramBot\Exception\TelegramException;
use Longman\TelegramBot\Tests\Unit\TestCase;

Expand All @@ -35,7 +36,7 @@ public function testKeyboardButtonNoTextFail(): void
public function testKeyboardButtonTooManyParametersFail(): void
{
$this->expectException(TelegramException::class);
$this->expectExceptionMessage('You must use only one of these fields: request_contact, request_location, request_poll!');
$this->expectExceptionMessage('You must use only one of these fields: request_contact, request_location, request_poll, web_app!');
new KeyboardButton(['text' => 'message', 'request_contact' => true, 'request_location' => true]);
}

Expand All @@ -45,6 +46,7 @@ public function testKeyboardButtonSuccess(): void
new KeyboardButton(['text' => 'message', 'request_contact' => true]);
new KeyboardButton(['text' => 'message', 'request_location' => true]);
new KeyboardButton(['text' => 'message', 'request_poll' => new KeyboardButtonPollType([])]);
new KeyboardButton(['text' => 'message', 'web_app' => new WebAppInfo([])]);
self::assertTrue(true);
}

Expand All @@ -61,6 +63,7 @@ public function testKeyboardButtonParameterSetting(): void
self::assertEmpty($button->getRequestContact());
self::assertEmpty($button->getRequestLocation());
self::assertEmpty($button->getRequestPoll());
self::assertEmpty($button->getWebApp());

$button->setText('new message');
self::assertSame('new message', $button->getText());
Expand All @@ -69,15 +72,24 @@ public function testKeyboardButtonParameterSetting(): void
self::assertTrue($button->getRequestContact());
self::assertEmpty($button->getRequestLocation());
self::assertEmpty($button->getRequestPoll());
self::assertEmpty($button->getWebApp());

$button->setRequestLocation(true);
self::assertEmpty($button->getRequestContact());
self::assertTrue($button->getRequestLocation());
self::assertEmpty($button->getRequestPoll());
self::assertEmpty($button->getWebApp());

$button->setRequestPoll(new KeyboardButtonPollType([]));
self::assertEmpty($button->getRequestContact());
self::assertEmpty($button->getRequestLocation());
self::assertInstanceOf(KeyboardButtonPollType::class, $button->getRequestPoll());
self::assertEmpty($button->getWebApp());

$button->setWebApp(new WebAppInfo([]));
self::assertEmpty($button->getRequestContact());
self::assertEmpty($button->getRequestLocation());
self::assertEmpty($button->getRequestPoll());
self::assertInstanceOf(WebAppInfo::class, $button->getWebApp());
}
}