diff --git a/composer.json b/composer.json index bad67c512..80158b853 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,8 @@ "nikic/php-parser": "^5.0.2", "revolt/event-loop": "^1.0.6", "danog/async-orm": "^1.0.2", - "symfony/thanks": "^1.3" + "symfony/thanks": "^1.3", + "danog/telegram-entities": "^1.0" }, "require-dev": { "ext-ctype": "*", @@ -72,7 +73,8 @@ "amphp/http-server": "^3.3", "revolt/event-loop-adapter-react": "^1.1.1", "dg/bypass-finals": "dev-master", - "brianium/paratest": "^6.11.1" + "brianium/paratest": "^6.11.1", + "vimeo/psalm": "dev-master" }, "suggest": { "ext-primemodule": "Install the primemodule and FFI extensions to speed up MadelineProto (https://prime.madelineproto.xyz)", @@ -132,11 +134,6 @@ "post-install-cmd": ["@composer bin all install --ansi"], "post-update-cmd": ["@composer bin all update --ansi"] }, - "extra": { - "phabel": { - "revision": 0 - } - }, "config": { "allow-plugins": { "bamarni/composer-bin-plugin": true, diff --git a/docs b/docs index 11626857a..87f2e3f97 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 11626857a0bfe4d094f4f43ad63b6df6364b6547 +Subproject commit 87f2e3f97142013572b6f5615fc8a336eeebc18e diff --git a/psalm.xml b/psalm.xml index c4f35f530..424bf1803 100644 --- a/psalm.xml +++ b/psalm.xml @@ -8,9 +8,9 @@ ignoreInternalFunctionNullReturn="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" - xsi:schemaLocation="https://getpsalm.org/schema/config vendor-bin/check/vendor/vimeo/psalm/config.xsd" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" errorBaseline="psalm-baseline.xml" - autoloader="vendor-bin/check/vendor/autoload.php" + autoloader="vendor/autoload.php" > diff --git a/src/BotApiFileId.php b/src/BotApiFileId.php index ca3eaa2bc..d7cc4ba96 100644 --- a/src/BotApiFileId.php +++ b/src/BotApiFileId.php @@ -16,6 +16,7 @@ namespace danog\MadelineProto; +use AssertionError; use danog\Decoder\FileId; use danog\Decoder\FileIdType; use danog\MadelineProto\EventHandler\Media; @@ -54,7 +55,8 @@ final class BotApiFileId */ public function getTypeClass(): string { - return match (FileId::fromBotAPI($this->fileId)->type) { + $f = FileId::fromBotAPI($this->fileId); + return match ($f->type) { FileIdType::PHOTO => Photo::class, FileIdType::VOICE => Voice::class, FileIdType::VIDEO => Video::class, @@ -62,7 +64,8 @@ final class BotApiFileId FileIdType::STICKER => AbstractSticker::class, FileIdType::VIDEO_NOTE => RoundVideo::class, FileIdType::AUDIO => Audio::class, - FileIdType::ANIMATION => Gif::class + FileIdType::ANIMATION => Gif::class, + default => throw new AssertionError("Cannot use bot API file ID of type ".$f->type->value) }; } } diff --git a/src/Conversion.php b/src/Conversion.php index dac0aae0b..a46f2a5c7 100644 --- a/src/Conversion.php +++ b/src/Conversion.php @@ -31,7 +31,7 @@ use function stream_get_contents; final class Conversion { /** - * Prepare API instance. + * Import authorization from raw auth key and DC id. * * @param array $authorization Authorization info, DC ID => auth key */ diff --git a/src/DataCenter.php b/src/DataCenter.php index 646551c9d..11ebfd279 100644 --- a/src/DataCenter.php +++ b/src/DataCenter.php @@ -140,7 +140,7 @@ final class DataCenter * * @internal */ - private static function normalizeBindToOption(string $bindTo = null): ?string + private static function normalizeBindToOption(?string $bindTo = null): ?string { if ($bindTo === null) { return null; diff --git a/src/DoHWrapper.php b/src/DoHWrapper.php index d12c589ab..22d309ee0 100644 --- a/src/DoHWrapper.php +++ b/src/DoHWrapper.php @@ -128,7 +128,7 @@ final class DoHWrapper * * @return ConnectionContext[] */ - public function generateContexts(string $uri, ConnectContext $context = null): array + public function generateContexts(string $uri, ?ConnectContext $context = null): array { $ctxs = []; $combos = [ diff --git a/src/StrTools.php b/src/StrTools.php index 41a98dbb1..342196ac1 100644 --- a/src/StrTools.php +++ b/src/StrTools.php @@ -40,8 +40,9 @@ 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; +use danog\TelegramEntities\Entities; +use danog\TelegramEntities\EntityTools; use Throwable; -use Webmozart\Assert\Assert; /** * Some tools. @@ -55,15 +56,7 @@ abstract class StrTools extends Extension */ public static function mbStrlen(string $text): int { - $length = 0; - $textlength = \strlen($text); - for ($x = 0; $x < $textlength; $x++) { - $char = \ord($text[$x]); - if (($char & 0xc0) != 0x80) { - $length += 1 + ($char >= 0xf0 ? 1 : 0); - } - } - return $length; + return EntityTools::mbStrlen($text); } /** * Telegram UTF-8 multibyte substring. @@ -74,15 +67,7 @@ abstract class StrTools extends Extension */ public static function mbSubstr(string $text, int $offset, ?int $length = null): string { - return mb_convert_encoding( - substr( - mb_convert_encoding($text, 'UTF-16'), - $offset<<1, - $length === null ? null : ($length<<1), - ), - 'UTF-8', - 'UTF-16', - ); + return EntityTools::mbSubstr($text, $offset, $length); } /** * Telegram UTF-8 multibyte split. @@ -93,13 +78,7 @@ abstract class StrTools extends Extension */ public static function mbStrSplit(string $text, int $length): array { - $result = []; - foreach (str_split(mb_convert_encoding($text, 'UTF-16'), $length<<1) as $chunk) { - $chunk = mb_convert_encoding($chunk, 'UTF-8', 'UTF-16'); - Assert::string($chunk); - $result []= $chunk; - } - return $result; + return EntityTools::mbStrSplit($text, $length); } /** * Manually convert HTML to a message and a set of entities. @@ -222,7 +201,7 @@ abstract class StrTools extends Extension */ public static function htmlEscape(string $what): string { - return htmlspecialchars($what, ENT_QUOTES|ENT_SUBSTITUTE|ENT_XML1); + return EntityTools::htmlEscape($what); } /** * Escape string for markdown. @@ -231,51 +210,7 @@ abstract class StrTools extends Extension */ public static function markdownEscape(string $what): string { - return str_replace( - [ - '\\', - '_', - '*', - '[', - ']', - '(', - ')', - '~', - '`', - '>', - '#', - '+', - '-', - '=', - '|', - '{', - '}', - '.', - '!', - ], - [ - '\\\\', - '\\_', - '\\*', - '\\[', - '\\]', - '\\(', - '\\)', - '\\~', - '\\`', - '\\>', - '\\#', - '\\+', - '\\-', - '\\=', - '\\|', - '\\{', - '\\}', - '\\.', - '\\!', - ], - $what - ); + return EntityTools::markdownEscape($what); } /** * Escape string for markdown codeblock. @@ -284,7 +219,7 @@ abstract class StrTools extends Extension */ public static function markdownCodeblockEscape(string $what): string { - return str_replace('```', '\\```', $what); + return EntityTools::markdownCodeblockEscape($what); } /** * Escape string for markdown code section. @@ -293,7 +228,7 @@ abstract class StrTools extends Extension */ public static function markdownCodeEscape(string $what): string { - return str_replace('`', '\\`', $what); + return EntityTools::markdownCodeEscape($what); } /** * Escape string for URL. @@ -302,7 +237,7 @@ abstract class StrTools extends Extension */ public static function markdownUrlEscape(string $what): string { - return str_replace(')', '\\)', $what); + return EntityTools::markdownUrlEscape($what); } /** * Escape type name. diff --git a/vendor-bin/check/composer.json b/vendor-bin/check/composer.json index fb3a499fd..2a3061de1 100644 --- a/vendor-bin/check/composer.json +++ b/vendor-bin/check/composer.json @@ -1,8 +1,6 @@ { "require": { - "vimeo/psalm": "dev-master", "ennexa/amp-update-cache": "dev-master", - "phpunit/phpunit": "^9", "amphp/php-cs-fixer-config": "v2.x-dev", "slevomat/coding-standard": "^8.7", "squizlabs/php_codesniffer": "^3.7",