diff --git a/src/danog/MadelineProto/TL/Conversion/DOMEntities.php b/src/danog/MadelineProto/TL/Conversion/DOMEntities.php new file mode 100644 index 000000000..f6c2c3340 --- /dev/null +++ b/src/danog/MadelineProto/TL/Conversion/DOMEntities.php @@ -0,0 +1,95 @@ +loadxml("" . \str_replace(['&', ''', '"', '&'], ['&', '\'', "\"", '&'], \trim($html)) . ""); + $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]; + } +} diff --git a/tests/danog/MadelineProto/MadelineTestCase.php b/tests/danog/MadelineProto/MadelineTestCase.php new file mode 100644 index 000000000..9a8636a79 --- /dev/null +++ b/tests/danog/MadelineProto/MadelineTestCase.php @@ -0,0 +1,52 @@ + [ + '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()); + } +}