1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-22 11:51:17 +01:00

Add DOMEntities parser
Some checks failed
ci/woodpecker/push/build Pipeline failed

This commit is contained in:
Daniil Gentili 2022-07-28 17:37:52 +02:00
parent a3137cb5b8
commit eaeebea2c5
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
2 changed files with 147 additions and 0 deletions

View File

@ -0,0 +1,95 @@
<?php
namespace danog\MadelineProto\TL\Conversion;
use danog\MadelineProto\StrTools;
use DOMNode;
use DOMText;
final class DOMEntities
{
/**
* @readonly
*/
public array $entities = [];
/**
* @readonly
*/
public array $buttons = [];
/**
* @readonly
*/
public string $message = '';
public function __construct(string $html)
{
$dom = new \DOMDocument();
$dom->loadxml("<body>" . \str_replace(['&amp;', '&#039;', '&quot;', '&'], ['&', '\'', "\"", '&amp;'], \trim($html)) . "</body>");
$this->parseNode($dom->getElementsByTagName('body')->item(0), 0);
}
/**
* @return integer Length of the node
*/
private function parseNode(DOMNode|DOMText $node, int $offset): int
{
if ($node instanceof DOMText) {
$this->message .= $node->wholeText;
return StrTools::mbStrlen($node->wholeText);
}
if ($node->nodeName === 'br') {
$this->message .= "\n";
return 1;
}
$entity = match ($node->nodeName) {
's', 'strike', 'del' =>['_' => 'messageEntityStrike'],
'u' => ['_' => 'messageEntityUnderline'],
'blockquote' => ['_' => 'messageEntityBlockquote'],
'b', 'strong' => ['_' => 'messageEntityBold'],
'i', 'em' => ['_' => 'messageEntityItalic'],
'code' => ['_' => 'messageEntityCode'],
'spoiler', 'tg-spoiler' => ['_' => 'messageEntitySpoiler'],
'pre' => ['_' => 'messageEntityPre', 'language' => $node->getAttribute('language') ?? ''],
'a' => $this->handleA($node),
default => null,
};
$length = 0;
foreach ($node->childNodes as $sub) {
$length += $this->parseNode($sub, $offset+$length);
}
if ($entity !== null) {
$lengthReal = $length;
for ($x = \strlen($this->message)-1; $x >= 0; $x--) {
if (!(
$this->message[$x] === ' '
|| $this->message[$x] === "\r"
|| $this->message[$x] === "\n"
)) {
break;
}
$lengthReal--;
}
if ($lengthReal > 0) {
$entity['offset'] = $offset;
$entity['length'] = $lengthReal;
$this->entities []= $entity;
}
}
return $length;
}
private function handleA(DOMNode $node): array
{
$href = $node->getAttribute('href');
if (\preg_match('|mention:(.*)|', $href, $matches) || \preg_match('|tg://user\\?id=(.*)|', $href, $matches)) {
return ['_' => 'inputMessageEntityMentionName', 'user_id' => $matches[1]];
}
if (\preg_match('|buttonurl:(.*)|', $href)) {
if (\strpos(\substr($href, -4), '|:new|') !== false) {
$this->buttons[] = ['_' => 'keyboardButtonUrl', 'text' => $text, 'url' => \str_replace(['buttonurl:', ':new'], '', $href), 'new' => true];
} else {
$this->buttons[] = ['_' => 'keyboardButtonUrl', 'text' => $text, 'url' => \str_replace('buttonurl:', '', $href)];
}
return null;
}
return ['_' => 'messageEntityTextUrl', 'url' => $href];
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace danog\MadelineProto\Test;
use danog\MadelineProto\API;
use danog\MadelineProto\Logger;
use PHPUnit\Framework\TestCase;
abstract class MadelineTestCase extends TestCase
{
/**
* MadelineProto instance.
*
* @var API
*/
protected static $MadelineProto;
/**
* Setup MadelineProto instance.
*
* @return void
*/
public static function setUpBeforeClass(): void
{
self::$MadelineProto = new API(
'testing.madeline',
[
'app_info' => [
'api_id' => \getenv('API_ID'),
'api_hash' => \getenv('API_HASH'),
],
'logger' => [
'logger' => Logger::FILE_LOGGER,
'logger_param' => __DIR__.'/../../MadelineProto.log',
'logger_level' => Logger::ULTRA_VERBOSE
]
]
);
self::$MadelineProto->botLogin(\getenv('BOT_TOKEN'));
}
/**
* Teardown.
*
* @return void
*/
public static function tearDownAfterClass(): void
{
self::$MadelineProto = null;
while (\gc_collect_cycles());
}
}