mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-27 05:14:39 +01:00
Add Entities classes
- Make entity property as public - Add support for objects in getHTML method!
This commit is contained in:
parent
a42fe534b2
commit
e76146664f
@ -28,6 +28,7 @@ use danog\MadelineProto\EventHandler\Media\RoundVideo;
|
||||
use danog\MadelineProto\EventHandler\Media\Sticker;
|
||||
use danog\MadelineProto\EventHandler\Media\Video;
|
||||
use danog\MadelineProto\EventHandler\Media\Voice;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\MessageEntity;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use danog\MadelineProto\ParseMode;
|
||||
use danog\MadelineProto\StrTools;
|
||||
@ -97,6 +98,9 @@ abstract class Message extends AbstractMessage
|
||||
/** Author of the post, if signatures are enabled for messages from channels or forwarded from channels */
|
||||
public readonly ?string $signature;
|
||||
|
||||
/** @var array<MessageEntity> Message [entities](https://core.telegram.org/api/entities) for styled text */
|
||||
public readonly ?array $entities;
|
||||
|
||||
/** @internal */
|
||||
public function __construct(
|
||||
MTProto $API,
|
||||
@ -109,7 +113,9 @@ abstract class Message extends AbstractMessage
|
||||
$this->forwards = $rawMessage['forwards'] ?? null;
|
||||
$this->signature = $rawMessage['post_author'] ?? null;
|
||||
|
||||
$this->entities = $rawMessage['entities'] ?? null;
|
||||
$this->entities = isset($rawMessage['entities']) && !empty($entities = $rawMessage['entities'])
|
||||
? MessageEntity::fromRawEntities($entities)
|
||||
: null;
|
||||
$this->message = $rawMessage['message'];
|
||||
$this->fromScheduled = $rawMessage['from_scheduled'];
|
||||
$this->viaBotId = $rawMessage['via_bot_id'] ?? null;
|
||||
@ -118,7 +124,6 @@ abstract class Message extends AbstractMessage
|
||||
$this->keyboard = isset($rawMessage['reply_markup'])
|
||||
? Keyboard::fromRawReplyMarkup($rawMessage['reply_markup'])
|
||||
: null;
|
||||
|
||||
if (isset($rawMessage['fwd_from'])) {
|
||||
$fwdFrom = $rawMessage['fwd_from'];
|
||||
$this->fwdInfo = new ForwardedInfo(
|
||||
@ -342,7 +347,6 @@ abstract class Message extends AbstractMessage
|
||||
|
||||
protected readonly string $html;
|
||||
protected readonly string $htmlTelegram;
|
||||
protected readonly ?array $entities;
|
||||
|
||||
/**
|
||||
* Get an HTML version of the message.
|
||||
|
7
src/EventHandler/Message/Entities/BankCard.php
Normal file
7
src/EventHandler/Message/Entities/BankCard.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class BankCard extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Blockquote.php
Normal file
7
src/EventHandler/Message/Entities/Blockquote.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Blockquote extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Bold.php
Normal file
7
src/EventHandler/Message/Entities/Bold.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Bold extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/BotCommand.php
Normal file
7
src/EventHandler/Message/Entities/BotCommand.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class BotCommand extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Cashtag.php
Normal file
7
src/EventHandler/Message/Entities/Cashtag.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Cashtag extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Code.php
Normal file
7
src/EventHandler/Message/Entities/Code.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Code extends MessageEntity
|
||||
{
|
||||
}
|
14
src/EventHandler/Message/Entities/CustomEmoji.php
Normal file
14
src/EventHandler/Message/Entities/CustomEmoji.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class CustomEmoji extends MessageEntity
|
||||
{
|
||||
/** Document ID of the [custom emoji](https://core.telegram.org/api/custom-emoji). */
|
||||
public readonly int $documentId;
|
||||
protected function __construct(array $rawEntities)
|
||||
{
|
||||
parent::__construct($rawEntities);
|
||||
$this->documentId = $rawEntities['document_id'];
|
||||
}
|
||||
}
|
7
src/EventHandler/Message/Entities/Email.php
Normal file
7
src/EventHandler/Message/Entities/Email.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Email extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Hashtag.php
Normal file
7
src/EventHandler/Message/Entities/Hashtag.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Hashtag extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Italic.php
Normal file
7
src/EventHandler/Message/Entities/Italic.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Italic extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Mention.php
Normal file
7
src/EventHandler/Message/Entities/Mention.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Mention extends MessageEntity
|
||||
{
|
||||
}
|
14
src/EventHandler/Message/Entities/MentionName.php
Normal file
14
src/EventHandler/Message/Entities/MentionName.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class MentionName extends MessageEntity
|
||||
{
|
||||
/** Identifier of the user that was mentioned */
|
||||
public readonly int $userId;
|
||||
protected function __construct(array $rawEntities)
|
||||
{
|
||||
parent::__construct($rawEntities);
|
||||
$this->userId = $rawEntities['user_id'];
|
||||
}
|
||||
}
|
58
src/EventHandler/Message/Entities/MessageEntity.php
Normal file
58
src/EventHandler/Message/Entities/MessageEntity.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
use JsonSerializable;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
abstract class MessageEntity implements JsonSerializable
|
||||
{
|
||||
/** Offset of message entity within message (in UTF-16 code units) */
|
||||
public readonly int $offset;
|
||||
/** Length of message entity within message (in UTF-16 code units) */
|
||||
public readonly int $length;
|
||||
|
||||
protected function __construct(array $rawEntities)
|
||||
{
|
||||
$this->offset = $rawEntities['offset'];
|
||||
$this->length = $rawEntities['length'];
|
||||
}
|
||||
|
||||
public static function fromRawEntities(array $entities)
|
||||
{
|
||||
$create = static fn (array $entity): MessageEntity => match ($entity['_']) {
|
||||
'messageEntityMention' => new Mention($entity),
|
||||
'messageEntityHashtag' => new Hashtag($entity),
|
||||
'messageEntityBotCommand' => new BotCommand($entity),
|
||||
'messageEntityEmail' => new Email($entity),
|
||||
'messageEntityBold' => new Bold($entity),
|
||||
'messageEntityItalic' => new Italic($entity),
|
||||
'messageEntityUrl' => new Url($entity),
|
||||
'messageEntityCode' => new Code($entity),
|
||||
'messageEntityPre' => new Pre($entity),
|
||||
'messageEntityTextUrl' => new TextUrl($entity),
|
||||
'messageEntityMentionName','inputMessageEntityMentionName' => new MentionName($entity),
|
||||
'messageEntityPhone' => new Phone($entity),
|
||||
'messageEntityCashtag' => new Cashtag($entity),
|
||||
'messageEntityUnderline' => new Underline($entity),
|
||||
'messageEntityStrike' => new Strike($entity),
|
||||
'messageEntityBlockquote' => new Blockquote($entity),
|
||||
'messageEntityBankCard' => new BankCard($entity),
|
||||
'messageEntitySpoiler' => new Spoiler($entity),
|
||||
'messageEntityCustomEmoji' => new CustomEmoji($entity),
|
||||
default => new Unknown($entity)
|
||||
};
|
||||
return \array_map(fn (array $entity) => $create($entity), $entities);
|
||||
}
|
||||
/** @internal */
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
$res = ['_' => static::class];
|
||||
$refl = new ReflectionClass($this);
|
||||
foreach ($refl->getProperties(ReflectionProperty::IS_PUBLIC) as $prop) {
|
||||
$res[$prop->getName()] = $prop->getValue($this);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
7
src/EventHandler/Message/Entities/Phone.php
Normal file
7
src/EventHandler/Message/Entities/Phone.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Phone extends MessageEntity
|
||||
{
|
||||
}
|
14
src/EventHandler/Message/Entities/Pre.php
Normal file
14
src/EventHandler/Message/Entities/Pre.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Pre extends MessageEntity
|
||||
{
|
||||
/** Programming language of the code */
|
||||
public readonly string $language;
|
||||
protected function __construct(array $rawEntities)
|
||||
{
|
||||
parent::__construct($rawEntities);
|
||||
$this->language = $rawEntities['language'];
|
||||
}
|
||||
}
|
7
src/EventHandler/Message/Entities/Spoiler.php
Normal file
7
src/EventHandler/Message/Entities/Spoiler.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Spoiler extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Strike.php
Normal file
7
src/EventHandler/Message/Entities/Strike.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Strike extends MessageEntity
|
||||
{
|
||||
}
|
14
src/EventHandler/Message/Entities/TextUrl.php
Normal file
14
src/EventHandler/Message/Entities/TextUrl.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class TextUrl extends MessageEntity
|
||||
{
|
||||
/** The actual URL */
|
||||
public readonly string $url;
|
||||
protected function __construct(array $rawEntities)
|
||||
{
|
||||
parent::__construct($rawEntities);
|
||||
$this->url = $rawEntities['url'];
|
||||
}
|
||||
}
|
7
src/EventHandler/Message/Entities/Underline.php
Normal file
7
src/EventHandler/Message/Entities/Underline.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Underline extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Unknown.php
Normal file
7
src/EventHandler/Message/Entities/Unknown.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Unknown extends MessageEntity
|
||||
{
|
||||
}
|
7
src/EventHandler/Message/Entities/Url.php
Normal file
7
src/EventHandler/Message/Entities/Url.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Message\Entities;
|
||||
|
||||
final class Url extends MessageEntity
|
||||
{
|
||||
}
|
@ -20,6 +20,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Blockquote;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Bold;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Code;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\CustomEmoji;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Email;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Italic;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Mention;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\MentionName;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\MessageEntity;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Phone;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Pre;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Spoiler;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Strike;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\TextUrl;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Underline;
|
||||
use danog\MadelineProto\EventHandler\Message\Entities\Url;
|
||||
use danog\MadelineProto\TL\Conversion\DOMEntities;
|
||||
use danog\MadelineProto\TL\Conversion\Extension;
|
||||
use danog\MadelineProto\TL\Conversion\MarkdownEntities;
|
||||
@ -117,46 +133,46 @@ abstract class StrTools extends Extension
|
||||
/**
|
||||
* Convert a message and a set of entities to HTML.
|
||||
*
|
||||
* @param list<array{_: string, offset: int, length: int, ...}> $entities
|
||||
* @param list<MessageEntity> $entities
|
||||
* @param bool $allowTelegramTags Whether to allow telegram-specific tags like tg-spoiler, tg-emoji, mention links and so on...
|
||||
*/
|
||||
public static function entitiesToHtml(string $message, array $entities, bool $allowTelegramTags = false): string
|
||||
{
|
||||
$insertions = [];
|
||||
foreach ($entities as $entity) {
|
||||
['_' => $type, 'offset' => $offset, 'length' => $length] = $entity;
|
||||
[$offset, $length] = [$entity->offset, $entity->length];
|
||||
$insertions[$offset] ??= '';
|
||||
$insertions[$offset] .= match ($type) {
|
||||
'messageEntityBold' => '<b>',
|
||||
'messageEntityItalic' => '<i>',
|
||||
'messageEntityCode' => '<code>',
|
||||
'messageEntityPre' => $entity['language'] !== '' ? '<pre language="'.$entity['language'].'">' : '<pre>',
|
||||
'messageEntityTextUrl' => '<a href="'.$entity['url'].'">',
|
||||
'messageEntityStrike' => '<s>',
|
||||
'messageEntityUnderline' => '<u>',
|
||||
'messageEntityBlockquote' => '<blockquote>',
|
||||
'messageEntityUrl' => '<a href="'.\htmlspecialchars(self::mbSubstr($message, $offset, $length)).'">',
|
||||
'messageEntityEmail' => '<a href="mailto:'.\htmlspecialchars(self::mbSubstr($message, $offset, $length)).'">',
|
||||
'messageEntityPhone' => '<a href="phone:'.\htmlspecialchars(self::mbSubstr($message, $offset, $length)).'">',
|
||||
'messageEntityMention' => '<a href="https://t.me/'.\htmlspecialchars(self::mbSubstr($message, $offset+1, $length-1)).'">',
|
||||
'messageEntitySpoiler' => $allowTelegramTags ? '<tg-spoiler>' : '',
|
||||
'messageEntityCustomEmoji' => $allowTelegramTags ? '<tg-emoji emoji-id="'.$entity['document_id'].'">' : '',
|
||||
'messageEntityMentionName', 'inputMessageEntityMentionName' => $allowTelegramTags ? '<a href="tg://user?id='.$entity['user_id'].'">' : '',
|
||||
$insertions[$offset] .= match (true) {
|
||||
$entity instanceof Bold => '<b>',
|
||||
$entity instanceof Italic => '<i>',
|
||||
$entity instanceof Code => '<code>',
|
||||
$entity instanceof Pre => $entity->language !== '' ? '<pre language="'.$entity->language.'">' : '<pre>',
|
||||
$entity instanceof TextUrl => '<a href="'.$entity->url.'">',
|
||||
$entity instanceof Strike => '<s>',
|
||||
$entity instanceof Underline => '<u>',
|
||||
$entity instanceof Blockquote => '<blockquote>',
|
||||
$entity instanceof Url => '<a href="'.\htmlspecialchars(self::mbSubstr($message, $offset, $length)).'">',
|
||||
$entity instanceof Email => '<a href="mailto:'.\htmlspecialchars(self::mbSubstr($message, $offset, $length)).'">',
|
||||
$entity instanceof Phone => '<a href="phone:'.\htmlspecialchars(self::mbSubstr($message, $offset, $length)).'">',
|
||||
$entity instanceof Mention => '<a href="https://t.me/'.\htmlspecialchars(self::mbSubstr($message, $offset+1, $length-1)).'">',
|
||||
$entity instanceof Spoiler => $allowTelegramTags ? '<tg-spoiler>' : '',
|
||||
$entity instanceof CustomEmoji => $allowTelegramTags ? '<tg-emoji emoji-id="'.$entity->documentId.'">' : '',
|
||||
$entity instanceof MentionName => $allowTelegramTags ? '<a href="tg://user?id='.$entity->userId.'">' : '',
|
||||
default => '',
|
||||
};
|
||||
$offset += $length;
|
||||
$insertions[$offset] = match ($type) {
|
||||
'messageEntityBold' => '</b>',
|
||||
'messageEntityItalic' => '</i>',
|
||||
'messageEntityCode' => '</code>',
|
||||
'messageEntityPre' => '</pre>',
|
||||
'messageEntityTextUrl', 'messageEntityUrl', 'messageEntityEmail', 'messageEntityMention', 'messageEntityPhone' => '</a>',
|
||||
'messageEntityStrike' => '</s>',
|
||||
'messageEntityUnderline' => '</u>',
|
||||
'messageEntityBlockquote' => '</blockquote>',
|
||||
'messageEntitySpoiler' => $allowTelegramTags ? '</tg-spoiler>' : '',
|
||||
'messageEntityCustomEmoji' => $allowTelegramTags ? "</tg-emoji>" : '',
|
||||
'messageEntityMentionName', 'inputMessageEntityMentionName' => $allowTelegramTags ? '</a>' : '',
|
||||
$insertions[$offset] = match (true) {
|
||||
$entity instanceof Bold => '</b>',
|
||||
$entity instanceof Italic => '</i>',
|
||||
$entity instanceof Code => '</code>',
|
||||
$entity instanceof Pre => '</pre>',
|
||||
$entity instanceof TextUrl, $entity instanceof Url, $entity instanceof Email, $entity instanceof Mention, $entity instanceof Phone => '</a>',
|
||||
$entity instanceof Strike => '</s>',
|
||||
$entity instanceof Underline => '</u>',
|
||||
$entity instanceof Blockquote => '</blockquote>',
|
||||
$entity instanceof Spoiler => $allowTelegramTags ? '</tg-spoiler>' : '',
|
||||
$entity instanceof CustomEmoji => $allowTelegramTags ? "</tg-emoji>" : '',
|
||||
$entity instanceof MentionName => $allowTelegramTags ? '</a>' : '',
|
||||
default => '',
|
||||
} . ($insertions[$offset] ?? '');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user