From 1110a70bcdcde172965e667ff41359998f2da664 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Fri, 27 Dec 2019 20:29:22 +0100 Subject: [PATCH] Document file methods --- src/danog/MadelineProto/InternalDoc.php | 397 +++++++++++++++--- .../MadelineProto/MTProtoTools/Crypt.php | 55 ++- .../MadelineProto/MTProtoTools/Files.php | 183 +++++++- .../MTProtoTools/PasswordCalculator.php | 3 +- .../MTProtoTools/PeerHandler.php | 88 +++- src/danog/MadelineProto/Wrappers/Callback.php | 9 +- src/danog/MadelineProto/Wrappers/Loop.php | 35 +- src/danog/MadelineProto/Wrappers/Noop.php | 14 +- src/danog/MadelineProto/Wrappers/Start.php | 7 +- .../MadelineProto/Wrappers/Templates.php | 20 +- src/danog/MadelineProto/Wrappers/Webhook.php | 10 +- 11 files changed, 714 insertions(+), 107 deletions(-) diff --git a/src/danog/MadelineProto/InternalDoc.php b/src/danog/MadelineProto/InternalDoc.php index 44a5b329..099b3e05 100644 --- a/src/danog/MadelineProto/InternalDoc.php +++ b/src/danog/MadelineProto/InternalDoc.php @@ -4452,43 +4452,101 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$method, $args, $aargs, $extra]); } - - public function aesCalculate($msg_key, $auth_key, $to_server = true, array $extra = []) + /** + * AES KDF function for MTProto v2. + * + * @param string $msg_key Message key + * @param string $auth_key Auth key + * @param boolean $to_server To server/from server direction + * + * @return array + */ + public function aesCalculate(string $msg_key, string $auth_key, bool $to_server = true, array $extra = []): array { return $this->__call(__FUNCTION__, [$msg_key, $auth_key, $to_server, $extra]); } - - public function oldAesCalculate($msg_key, $auth_key, $to_server = true, array $extra = []) + /** + * AES KDF function for MTProto v1. + * + * @param string $msg_key Message key + * @param string $auth_key Auth key + * @param boolean $to_server To server/from server direction + * + * @return array + */ + public function oldAesCalculate(string $msg_key, string $auth_key, bool $to_server = true, array $extra = []): array { return $this->__call(__FUNCTION__, [$msg_key, $auth_key, $to_server, $extra]); } - - public function ctrEncrypt($message, $key, $iv, array $extra = []) + /** + * CTR encrypt. + * + * @param string $message Message to encrypt + * @param string $key Key + * @param string $iv IV + * + * @return string + */ + public function ctrEncrypt(string $message, string $key, string $iv, array $extra = []): string { return $this->__call(__FUNCTION__, [$message, $key, $iv, $extra]); } - - public function igeEncrypt($message, $key, $iv, array $extra = []) + /** + * IGE encrypt. + * + * @param string $message Message to encrypt + * @param string $key Key + * @param string $iv IV + * + * @return string + */ + public function igeEncrypt(string $message, string $key, string $iv, array $extra = []): string { return $this->__call(__FUNCTION__, [$message, $key, $iv, $extra]); } - - public function igeDecrypt($message, $key, $iv, array $extra = []) + /** + * CTR decrypt. + * + * @param string $message Message to encrypt + * @param string $key Key + * @param string $iv IV + * + * @return string + */ + public function igeDecrypt(string $message, string $key, string $iv, array $extra = []): string { return $this->__call(__FUNCTION__, [$message, $key, $iv, $extra]); } - + /** + * Convert MTProto channel ID to bot API channel ID. + * + * @param int $id MTProto channel ID + * + * @return int + */ public function toSupergroup($id, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $extra]); } - + /** + * Convert bot API channel ID to MTProto channel ID. + * + * @param int $id Bot API channel ID + * + * @return int + */ public function fromSupergroup($id, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $extra]); } - - public function isSupergroup($id, array $extra = []) + /** + * Check whether provided bot API ID is a channel. + * + * @param int $id Bot API ID + * + * @return boolean + */ + public function isSupergroup($id, array $extra = []): bool { return $this->__call(__FUNCTION__, [$id, $extra]); } @@ -4512,7 +4570,13 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$id, $full_fetch, $send, $extra]); } - + /** + * Check if peer is present in internal peer database. + * + * @param mixed $id Peer + * + * @return \Generator + */ public function peerIsset($id, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $extra]); @@ -4527,17 +4591,38 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$fwd, $extra]); } - + /** + * Get folder ID from object. + * + * @param mixed $id Object + * + * @return ?int + */ public function getFolderId($id, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $extra]); } - + /** + * Get bot API ID from peer object. + * + * @param mixed $id Peer + * + * @return int + */ public function getId($id, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $extra]); } - + /** + * Get info about peer, returns an Info object. + * + * @param mixed $id Peer + * @param boolean $recursive Internal + * + * @see https://docs.madelineproto.xyz/Info.html + * + * @return \Generator Info object + */ public function getInfo($id, $recursive = true, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $recursive, $extra]); @@ -4552,12 +4637,28 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$id, $extra]); } - + /** + * Get full info about peer, returns an FullInfo object. + * + * @param mixed $id Peer + * + * @see https://docs.madelineproto.xyz/FullInfo.html + * + * @return \Generator FullInfo object + */ public function getFullInfo($id, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $extra]); } - + /** + * Get full info about peer (including full list of channel members), returns a Chat object. + * + * @param mixed $id Peer + * + * @see https://docs.madelineproto.xyz/Chat.html + * + * @return \Generator Chat object + */ public function getPwrChat($id, $fullfetch = true, $send = true, array $extra = []) { return $this->__call(__FUNCTION__, [$id, $fullfetch, $send, $extra]); @@ -4664,33 +4765,91 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$update, $extra]); } - - public function upload($file, $file_name = '', $cb = null, $encrypted = false, array $extra = []) + /** + * Upload file. + * + * @param FileCallbackInterface|string|array $file File, URL or Telegram file to upload + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ + public function upload($file, string $file_name = '', $cb = null, bool $encrypted = false, array $extra = []) { return $this->__call(__FUNCTION__, [$file, $file_name, $cb, $encrypted, $extra]); } - + /** + * Upload file from URL. + * + * @param string|FileCallbackInterface $url URL of file + * @param integer $size Size of file + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ public function uploadFromUrl($url, int $size = 0, string $file_name = '', $cb = null, bool $encrypted = false, array $extra = []) { return $this->__call(__FUNCTION__, [$url, $size, $file_name, $cb, $encrypted, $extra]); } - + /** + * Upload file from stream. + * + * @param mixed $stream Stream + * @param integer $size File size + * @param string $mime Mime type + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ public function uploadFromStream($stream, int $size, string $mime, string $file_name = '', $cb = null, bool $encrypted = false, array $extra = []) { return $this->__call(__FUNCTION__, [$stream, $size, $mime, $file_name, $cb, $encrypted, $extra]); } - + /** + * Upload file from callable. + * + * @param mixed $callable Callable + * @param integer $size File size + * @param string $mime Mime type + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $refetchable Whether each chunk can be refetched more than once + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ public function uploadFromCallable($callable, int $size, string $mime, string $file_name = '', $cb = null, bool $refetchable = true, bool $encrypted = false, array $extra = []) { return $this->__call(__FUNCTION__, [$callable, $size, $mime, $file_name, $cb, $refetchable, $encrypted, $extra]); } - - public function uploadEncrypted($file, $file_name = '', $cb = null, array $extra = []) + /** + * Upload file to secret chat. + * + * @param FileCallbackInterface|string|array $file File, URL or Telegram file to upload + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * + * @return array + */ + public function uploadEncrypted($file, string $file_name = '', $cb = null, array $extra = []) { return $this->__call(__FUNCTION__, [$file, $file_name, $cb, $extra]); } - - public function uploadFromTgfile($media, $cb = null, $encrypted = false, array $extra = []) + /** + * Reupload telegram file. + * + * @param mixed $media Telegram file + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ + public function uploadFromTgfile($media, $cb = null, bool $encrypted = false, array $extra = []) { return $this->__call(__FUNCTION__, [$media, $cb, $encrypted, $extra]); } @@ -4704,12 +4863,36 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$constructor, $extra]); } - + /** + * Get download info of the propic of a user + * Returns an array with the following structure:. + * + * `$info['ext']` - The file extension + * `$info['name']` - The file name, without the extension + * `$info['mime']` - The file mime type + * `$info['size']` - The file size + * + * @param mixed $message_media File ID + * + * @return \Generator + */ public function getPropicInfo($data, array $extra = []) { return $this->__call(__FUNCTION__, [$data, $extra]); } - + /** + * Get download info of file + * Returns an array with the following structure:. + * + * `$info['ext']` - The file extension + * `$info['name']` - The file name, without the extension + * `$info['mime']` - The file mime type + * `$info['size']` - The file size + * + * @param mixed $message_media File ID + * + * @return \Generator + */ public function getDownloadInfo($message_media, array $extra = []) { return $this->__call(__FUNCTION__, [$message_media, $extra]); @@ -4719,25 +4902,66 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$photo, $extra]); } - + /** + * Download file to directory. + * + * @param mixed $message_media File to download + * @param string|FileCallbackInterface $dir Directory where to download the file + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * + * @return \Generator Downloaded file path + */ public function downloadToDir($message_media, $dir, $cb = null, array $extra = []) { return $this->__call(__FUNCTION__, [$message_media, $dir, $cb, $extra]); } - + /** + * Download file. + * + * @param mixed $message_media File to download + * @param string|FileCallbackInterface $file Downloaded file path + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * + * @return \Generator Downloaded file path + */ public function downloadToFile($message_media, $file, $cb = null, array $extra = []) { return $this->__call(__FUNCTION__, [$message_media, $file, $cb, $extra]); } - - public function downloadToStream($message_media, $stream, $cb = null, $offset = 0, $end = -1, array $extra = []) + /** + * Download file to stream. + * + * @param mixed $message_media File to download + * @param mixed|FileCallbackInterface $stream Stream where to download file + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param int $offset Offset where to start downloading + * @param int $end Offset where to end download + * + * @return \Generator + */ + public function downloadToStream($message_media, $stream, $cb = null, int $offset = 0, int $end = -1, array $extra = []) { return $this->__call(__FUNCTION__, [$message_media, $stream, $cb, $offset, $end, $extra]); } - - public function downloadToCallable($message_media, $callable, $cb = null, $parallelize = true, $offset = 0, $end = -1, ?int $part_size = null, array $extra = []) + /** + * Download file to callable. + * The callable must accept two parameters: string $payload, int $offset + * The callable will be called (possibly out of order, depending on the value of $seekable). + * The callable should return the number of written bytes. + * + * @param mixed $message_media File to download + * @param callable|FileCallbackInterface $callable Chunk callback + * @param callable $cb Status callback (DEPRECATED, use FileCallbackInterface) + * @param bool $seekable Whether the callable can be called out of order + * @param int $offset Offset where to start downloading + * @param int $end Offset where to stop downloading (inclusive) + * @param int $part_size Size of each chunk + * + * @return \Generator + */ + public function downloadToCallable($message_media, $callable, $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null, array $extra = []) { - return $this->__call(__FUNCTION__, [$message_media, $callable, $cb, $parallelize, $offset, $end, $part_size, $extra]); + return $this->__call(__FUNCTION__, [$message_media, $callable, $cb, $seekable, $offset, $end, $part_size, $extra]); } /** * Accept secret chat. @@ -5577,13 +5801,26 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$update, $extra]); } - - public function setWebhook($hook_url, $pem_path = null, array $extra = []) + /** + * Set webhook update handler. + * + * @param string $hook_url Webhook URL + * @param string $pem_path PEM path for self-signed certificate + * + * @return void + */ + public function setWebhook($hook_url, $pem_path = null, array $extra = []): void { return $this->__call(__FUNCTION__, [$hook_url, $pem_path, $extra]); } - - public function setCallback($callback, array $extra = []) + /** + * Set update handling callback. + * + * @param callable $callback Callback + * + * @return void + */ + public function setCallback($callback, array $extra = []): void { return $this->__call(__FUNCTION__, [$callback, $extra]); } @@ -5639,32 +5876,62 @@ class InternalDoc extends APIFactory { return $this->__call(__FUNCTION__, [$params, $extra]); } - - public function setLoopCallback($callback, array $extra = []) + /** + * Set loop callback (DEPRECATED). + * + * @param callable $callback Callback + * + * @return void + */ + public function setLoopCallback($callback, array $extra = []): void { return $this->__call(__FUNCTION__, [$callback, $extra]); } - - public function loop($max_forks = 0, array $extra = []) + /** + * Start MadelineProto's update handling loop, or run the provided async callable. + * + * @param callable $callback Async callable to run + * + * @return mixed + */ + public function loop($callback = null, array $extra = []) { - return $this->__call(__FUNCTION__, [$max_forks, $extra]); + return $this->__call(__FUNCTION__, [$callback, $extra]); } - - public function closeConnection($message = 'OK!', array $extra = []) + /** + * Close connection with server. + * + * @param string $message Message + * + * @return void + */ + public function closeConnection($message = 'OK!', array $extra = []): void { return $this->__call(__FUNCTION__, [$message, $extra]); } - - public function setNoop(array $extra = []) + /** + * Set NOOP update handler, ignoring all updates. + * + * @return void + */ + public function setNoop(array $extra = []): void { return $this->__call(__FUNCTION__, [$extra]); } - - public function noop(array $extra = []) + /** + * Noop update handler. + * + * @return void + */ + public function noop(array $extra = []): void { return $this->__call(__FUNCTION__, [$extra]); } - + /** + * Log in to telegram (via CLI or web). + * + * @return \Generator + */ public function start(array $extra = []) { return $this->__call(__FUNCTION__, [$extra]); @@ -5695,22 +5962,32 @@ class InternalDoc extends APIFactory return $this->__call(__FUNCTION__, [$extra]); } - public function webEcho($message = '', array $extra = []) + public function webEcho(string $message = '', array $extra = []) { return $this->__call(__FUNCTION__, [$message, $extra]); } - public function webEchoTemplate($message, $form, array $extra = []) + public function webEchoTemplate($message, $form, array $extra = []): string { return $this->__call(__FUNCTION__, [$message, $form, $extra]); } - - public function getWebTemplate(array $extra = []) + /** + * Get web template. + * + * @return string + */ + public function getWebTemplate(array $extra = []): string { return $this->__call(__FUNCTION__, [$extra]); } - - public function setWebTemplate($template, array $extra = []) + /** + * Set web template. + * + * @param string $template Template + * + * @return void + */ + public function setWebTemplate(string $template, array $extra = []): void { return $this->__call(__FUNCTION__, [$template, $extra]); } diff --git a/src/danog/MadelineProto/MTProtoTools/Crypt.php b/src/danog/MadelineProto/MTProtoTools/Crypt.php index 2bd1d4e2..7255e3d6 100644 --- a/src/danog/MadelineProto/MTProtoTools/Crypt.php +++ b/src/danog/MadelineProto/MTProtoTools/Crypt.php @@ -21,7 +21,16 @@ namespace danog\MadelineProto\MTProtoTools; trait Crypt { - public static function aesCalculate($msg_key, $auth_key, $to_server = true) + /** + * AES KDF function for MTProto v2. + * + * @param string $msg_key Message key + * @param string $auth_key Auth key + * @param boolean $to_server To server/from server direction + * + * @return array + */ + public static function aesCalculate(string $msg_key, string $auth_key, bool $to_server = true): array { $x = $to_server ? 0 : 8; $sha256_a = \hash('sha256', $msg_key.\substr($auth_key, $x, 36), true); @@ -32,7 +41,16 @@ trait Crypt return [$aes_key, $aes_iv]; } - public static function oldAesCalculate($msg_key, $auth_key, $to_server = true) + /** + * AES KDF function for MTProto v1. + * + * @param string $msg_key Message key + * @param string $auth_key Auth key + * @param boolean $to_server To server/from server direction + * + * @return array + */ + public static function oldAesCalculate(string $msg_key, string $auth_key, bool $to_server = true): array { $x = $to_server ? 0 : 8; $sha1_a = \sha1($msg_key.\substr($auth_key, $x, 32), true); @@ -45,7 +63,16 @@ trait Crypt return [$aes_key, $aes_iv]; } - public static function ctrEncrypt($message, $key, $iv) + /** + * CTR encrypt. + * + * @param string $message Message to encrypt + * @param string $key Key + * @param string $iv IV + * + * @return string + */ + public static function ctrEncrypt(string $message, string $key, string $iv): string { $cipher = new \tgseclib\Crypt\AES('ctr'); $cipher->setKey($key); @@ -54,7 +81,16 @@ trait Crypt return @$cipher->encrypt($message); } - public static function igeEncrypt($message, $key, $iv) + /** + * IGE encrypt. + * + * @param string $message Message to encrypt + * @param string $key Key + * @param string $iv IV + * + * @return string + */ + public static function igeEncrypt(string $message, string $key, string $iv): string { $cipher = new \tgseclib\Crypt\AES('ige'); $cipher->setKey($key); @@ -62,7 +98,16 @@ trait Crypt return @$cipher->encrypt($message); } - public static function igeDecrypt($message, $key, $iv) + /** + * CTR decrypt. + * + * @param string $message Message to encrypt + * @param string $key Key + * @param string $iv IV + * + * @return string + */ + public static function igeDecrypt(string $message, string $key, string $iv): string { $cipher = new \tgseclib\Crypt\AES('ige'); $cipher->setKey($key); diff --git a/src/danog/MadelineProto/MTProtoTools/Files.php b/src/danog/MadelineProto/MTProtoTools/Files.php index 56af1c80..6d09454a 100644 --- a/src/danog/MadelineProto/MTProtoTools/Files.php +++ b/src/danog/MadelineProto/MTProtoTools/Files.php @@ -48,7 +48,17 @@ use function Amp\Promise\all; */ trait Files { - public function upload($file, $file_name = '', $cb = null, $encrypted = false) + /** + * Upload file. + * + * @param FileCallbackInterface|string|array $file File, URL or Telegram file to upload + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ + public function upload($file, string $file_name = '', $cb = null, bool $encrypted = false): \Generator { if (\is_object($file) && $file instanceof FileCallbackInterface) { $cb = $file; @@ -86,7 +96,18 @@ trait Files yield $stream->close(); } } - public function uploadFromUrl($url, int $size = 0, string $file_name = '', $cb = null, bool $encrypted = false) + /** + * Upload file from URL. + * + * @param string|FileCallbackInterface $url URL of file + * @param integer $size Size of file + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ + public function uploadFromUrl($url, int $size = 0, string $file_name = '', $cb = null, bool $encrypted = false): \Generator { if (\is_object($url) && $url instanceof FileCallbackInterface) { $cb = $url; @@ -122,14 +143,26 @@ trait Files return yield $this->uploadFromStream($stream, $size, $mime, $file_name, $cb, $encrypted); } - public function uploadFromStream($stream, int $size, string $mime, string $file_name = '', $cb = null, bool $encrypted = false) + /** + * Upload file from stream. + * + * @param mixed $stream Stream + * @param integer $size File size + * @param string $mime Mime type + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ + public function uploadFromStream($stream, int $size, string $mime, string $file_name = '', $cb = null, bool $encrypted = false): \Generator { if (\is_object($stream) && $stream instanceof FileCallbackInterface) { $cb = $stream; $stream = $stream->getFile(); } - /** @var $stream \Amp\ByteStream\OutputStream */ + /* @var $stream \Amp\ByteStream\OutputStream */ if (!\is_object($stream)) { $stream = new ResourceOutputStream($stream); } @@ -182,6 +215,19 @@ trait Files } return $res; } + /** + * Upload file from callable. + * + * @param mixed $callable Callable + * @param integer $size File size + * @param string $mime Mime type + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $refetchable Whether each chunk can be refetched more than once + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ public function uploadFromCallable($callable, int $size, string $mime, string $file_name = '', $cb = null, bool $refetchable = true, bool $encrypted = false) { if (\is_object($callable) && $callable instanceof FileCallbackInterface) { @@ -304,12 +350,30 @@ trait Files return $constructor; } - public function uploadEncrypted($file, $file_name = '', $cb = null) + /** + * Upload file to secret chat. + * + * @param FileCallbackInterface|string|array $file File, URL or Telegram file to upload + * @param string $file_name File name + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * + * @return array + */ + public function uploadEncrypted($file, string $file_name = '', $cb = null) { return $this->upload($file, $file_name, $cb, true); } - public function uploadFromTgfile($media, $cb = null, $encrypted = false) + /** + * Reupload telegram file. + * + * @param mixed $media Telegram file + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param boolean $encrypted Whether to encrypt file for secret chats + * + * @return array + */ + public function uploadFromTgfile($media, $cb = null, bool $encrypted = false) { if (\is_object($media) && $media instanceof FileCallbackInterface) { $cb = $media; @@ -492,11 +556,37 @@ trait Files return yield $this->genAllFile($constructor); } - public function getPropicInfo($data) + /** + * Get download info of the propic of a user + * Returns an array with the following structure:. + * + * `$info['ext']` - The file extension + * `$info['name']` - The file name, without the extension + * `$info['mime']` - The file mime type + * `$info['size']` - The file size + * + * @param mixed $message_media File ID + * + * @return \Generator + */ + public function getPropicInfo($data): \Generator { return yield $this->getDownloadInfo($this->chats[(yield $this->getInfo($data))['bot_api_id']]); } - public function getDownloadInfo($message_media) + /** + * Get download info of file + * Returns an array with the following structure:. + * + * `$info['ext']` - The file extension + * `$info['name']` - The file name, without the extension + * `$info['mime']` - The file mime type + * `$info['size']` - The file size + * + * @param mixed $message_media File ID + * + * @return \Generator + */ + public function getDownloadInfo($message_media): \Generator { if (\is_string($message_media)) { $message_media = $this->unpackFileId($message_media)['MessageMedia']; @@ -842,7 +932,16 @@ trait Files public function extractPhotosize($photo) { } - public function downloadToDir($message_media, $dir, $cb = null) + /** + * Download file to directory. + * + * @param mixed $message_media File to download + * @param string|FileCallbackInterface $dir Directory where to download the file + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * + * @return \Generator Downloaded file path + */ + public function downloadToDir($message_media, $dir, $cb = null): \Generator { if (\is_object($dir) && $dir instanceof FileCallbackInterface) { $cb = $dir; @@ -854,7 +953,16 @@ trait Files return yield $this->downloadToFile($message_media, $dir.'/'.$message_media['name'].$message_media['ext'], $cb); } - public function downloadToFile($message_media, $file, $cb = null) + /** + * Download file. + * + * @param mixed $message_media File to download + * @param string|FileCallbackInterface $file Downloaded file path + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * + * @return \Generator Downloaded file path + */ + public function downloadToFile($message_media, $file, $cb = null): \Generator { if (\is_object($file) && $file instanceof FileCallbackInterface) { $cb = $file; @@ -885,7 +993,18 @@ trait Files return $file; } - public function downloadToStream($message_media, $stream, $cb = null, $offset = 0, $end = -1) + /** + * Download file to stream. + * + * @param mixed $message_media File to download + * @param mixed|FileCallbackInterface $stream Stream where to download file + * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) + * @param int $offset Offset where to start downloading + * @param int $end Offset where to end download + * + * @return \Generator + */ + public function downloadToStream($message_media, $stream, $cb = null, int $offset = 0, int $end = -1): \Generator { $message_media = yield $this->getDownloadInfo($message_media); @@ -920,7 +1039,23 @@ trait Files return yield $this->downloadToCallable($message_media, $callable, $cb, $seekable, $offset, $end); } - public function downloadToCallable($message_media, $callable, $cb = null, $parallelize = true, $offset = 0, $end = -1, int $part_size = null) + /** + * Download file to callable. + * The callable must accept two parameters: string $payload, int $offset + * The callable will be called (possibly out of order, depending on the value of $seekable). + * The callable should return the number of written bytes. + * + * @param mixed $message_media File to download + * @param callable|FileCallbackInterface $callable Chunk callback + * @param callable $cb Status callback (DEPRECATED, use FileCallbackInterface) + * @param bool $seekable Whether the callable can be called out of order + * @param int $offset Offset where to start downloading + * @param int $end Offset where to stop downloading (inclusive) + * @param int $part_size Size of each chunk + * + * @return \Generator + */ + public function downloadToCallable($message_media, $callable, $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, int $part_size = null): \Generator { $message_media = yield $this->getDownloadInfo($message_media); @@ -960,7 +1095,7 @@ trait Files $ige->setIV($message_media['iv']); $ige->setKey($message_media['key']); $ige->enableContinuousBuffer(); - $parallelize = false; + $seekable = false; } if ($offset === $end) { @@ -1010,7 +1145,7 @@ trait Files $params[0]['previous_promise'] = new Success(true); $start = \microtime(true); - $size = yield $this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, \array_shift($params), $callable, $parallelize); + $size = yield $this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, \array_shift($params), $callable, $seekable); if ($params) { $previous_promise = new Success(true); @@ -1018,7 +1153,7 @@ trait Files $promises = []; foreach ($params as $key => $param) { $param['previous_promise'] = $previous_promise; - $previous_promise = \danog\MadelineProto\Tools::call($this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $parallelize)); + $previous_promise = \danog\MadelineProto\Tools::call($this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $seekable)); $previous_promise->onResolve(static function ($e, $res) use (&$size) { if ($res) { $size += $res; @@ -1053,7 +1188,23 @@ trait Files return true; } - private function downloadPart(&$message_media, &$cdn, &$datacenter, &$old_dc, &$ige, $cb, $offset, $callable, $seekable, $postpone = false) + /** + * Download file part. + * + * @param array $message_media File object + * @param bool $cdn Whether this is a CDN file + * @param string $datacenter DC ID + * @param string $old_dc Previous DC ID + * @param AES $ige IGE decryptor instance + * @param callable $cb Status callback + * @param int $offset Offset + * @param callable $callable Chunk callback + * @param boolean $seekable Whether the download file is seekable + * @param boolean $postpone Whether to postpone method call + * + * @return \Generator + */ + private function downloadPart(&$message_media, bool &$cdn, &$datacenter, &$old_dc, &$ige, $cb, int $offset, $callable, bool $seekable, bool $postpone = false): \Generator { static $method = [ false => 'upload.getFile', // non-cdn diff --git a/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php b/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php index ecee34f2..5b24b6ed 100644 --- a/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php +++ b/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php @@ -94,9 +94,10 @@ class PasswordCalculator * Popupate 2FA configuration. * * @param array $object 2FA configuration object obtained using account.getPassword + * * @return void */ - public function addInfo(array $object) + public function addInfo(array $object): void { if ($object['_'] !== 'account.password') { throw new Exception('Wrong constructor'); diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index 7e4552dd..9fb6d29d 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -32,17 +32,38 @@ trait PeerHandler public $caching_full_info = []; - public function toSupergroup($id) + /** + * Convert MTProto channel ID to bot API channel ID. + * + * @param int $id MTProto channel ID + * + * @return int + */ + public static function toSupergroup($id) { return -($id + \pow(10, (int) \floor(\log($id, 10) + 3))); } - public function fromSupergroup($id) + /** + * Convert bot API channel ID to MTProto channel ID. + * + * @param int $id Bot API channel ID + * + * @return int + */ + public static function fromSupergroup($id) { return -$id - \pow(10, (int) \floor(\log(-$id, 10))); } - public function isSupergroup($id) + /** + * Check whether provided bot API ID is a channel. + * + * @param int $id Bot API ID + * + * @return boolean + */ + public static function isSupergroup($id): bool { $log = \log(-$id, 10); @@ -174,7 +195,14 @@ trait PeerHandler })()); } - public function peerIsset($id) + /** + * Check if peer is present in internal peer database. + * + * @param mixed $id Peer + * + * @return \Generator + */ + public function peerIsset($id): \Generator { try { return isset($this->chats[(yield $this->getInfo($id))['bot_api_id']]); @@ -192,7 +220,7 @@ trait PeerHandler } } - public function entitiesPeerIsset($entities) + public function entitiesPeerIsset($entities): \Generator { try { foreach ($entities as $entity) { @@ -209,7 +237,7 @@ trait PeerHandler return true; } - public function fwdPeerIsset($fwd) + public function fwdPeerIsset($fwd): \Generator { try { if (isset($fwd['user_id']) && !yield $this->peerIsset($fwd['user_id'])) { @@ -225,6 +253,13 @@ trait PeerHandler return true; } + /** + * Get folder ID from object. + * + * @param mixed $id Object + * + * @return ?int + */ public function getFolderId($id) { if (!\is_array($id)) { @@ -235,6 +270,13 @@ trait PeerHandler } return $id['folder_id']; } + /** + * Get bot API ID from peer object. + * + * @param mixed $id Peer + * + * @return int + */ public function getId($id) { if (\is_array($id)) { @@ -377,7 +419,17 @@ trait PeerHandler return false; } - public function getInfo($id, $recursive = true) + /** + * Get info about peer, returns an Info object. + * + * @param mixed $id Peer + * @param boolean $recursive Internal + * + * @see https://docs.madelineproto.xyz/Info.html + * + * @return \Generator Info object + */ + public function getInfo($id, $recursive = true): \Generator { if (\is_array($id)) { switch ($id['_']) { @@ -608,7 +660,16 @@ trait PeerHandler return isset($this->full_chats[$id]['last_update']) ? $this->full_chats[$id]['last_update'] : 0; } - public function getFullInfo($id) + /** + * Get full info about peer, returns an FullInfo object. + * + * @param mixed $id Peer + * + * @see https://docs.madelineproto.xyz/FullInfo.html + * + * @return \Generator FullInfo object + */ + public function getFullInfo($id): \Generator { $partial = yield $this->getInfo($id); if (\time() - $this->fullChatLastUpdated($partial['bot_api_id']) < (isset($this->settings['peer']['full_info_cache_time']) ? $this->settings['peer']['full_info_cache_time'] : 0)) { @@ -638,7 +699,16 @@ trait PeerHandler return \array_merge($partial, $res); } - public function getPwrChat($id, $fullfetch = true, $send = true) + /** + * Get full info about peer (including full list of channel members), returns a Chat object. + * + * @param mixed $id Peer + * + * @see https://docs.madelineproto.xyz/Chat.html + * + * @return \Generator Chat object + */ + public function getPwrChat($id, $fullfetch = true, $send = true): \Generator { $full = $fullfetch ? yield $this->getFullInfo($id) : yield $this->getInfo($id); $res = ['id' => $full['bot_api_id'], 'type' => $full['type']]; diff --git a/src/danog/MadelineProto/Wrappers/Callback.php b/src/danog/MadelineProto/Wrappers/Callback.php index e18a0aca..4dec9069 100644 --- a/src/danog/MadelineProto/Wrappers/Callback.php +++ b/src/danog/MadelineProto/Wrappers/Callback.php @@ -24,7 +24,14 @@ namespace danog\MadelineProto\Wrappers; */ trait Callback { - public function setCallback($callback) + /** + * Set update handling callback. + * + * @param callable $callback Callback + * + * @return void + */ + public function setCallback($callback): void { $this->settings['updates']['callback'] = $callback; $this->settings['updates']['run_callback'] = true; diff --git a/src/danog/MadelineProto/Wrappers/Loop.php b/src/danog/MadelineProto/Wrappers/Loop.php index d1e7ce28..cf6c0f67 100644 --- a/src/danog/MadelineProto/Wrappers/Loop.php +++ b/src/danog/MadelineProto/Wrappers/Loop.php @@ -30,22 +30,36 @@ trait Loop { private $loop_callback; - public function setLoopCallback($callback) + /** + * Set loop callback (DEPRECATED). + * + * @param callable $callback Callback + * + * @return void + */ + public function setLoopCallback($callback): void { $this->loop_callback = $callback; } - public function loop($max_forks = 0) + /** + * Start MadelineProto's update handling loop, or run the provided async callable. + * + * @param callable $callback Async callable to run + * + * @return mixed + */ + public function loop($callback = null) { - if (\is_callable($max_forks)) { + if (\is_callable($max_fcallbackorks)) { $this->logger->logger('Running async callable'); - return yield $max_forks(); + return yield $callback(); } - if ($max_forks instanceof Promise) { + if ($callback instanceof Promise) { $this->logger->logger('Resolving async promise'); - return yield $max_forks; + return yield $callback; } if (!$this->authorized) { $this->logger->logger('Not authorized, not starting event loop', \danog\MadelineProto\Logger::FATAL_ERROR); @@ -169,7 +183,14 @@ trait Loop } } - public function closeConnection($message = 'OK!') + /** + * Close connection with server. + * + * @param string $message Message + * + * @return void + */ + public function closeConnection($message = 'OK!'): void { if (PHP_SAPI === 'cli' || isset($GLOBALS['exited']) || \headers_sent()) { return; diff --git a/src/danog/MadelineProto/Wrappers/Noop.php b/src/danog/MadelineProto/Wrappers/Noop.php index 54c5a629..8b83d4e9 100644 --- a/src/danog/MadelineProto/Wrappers/Noop.php +++ b/src/danog/MadelineProto/Wrappers/Noop.php @@ -21,7 +21,12 @@ namespace danog\MadelineProto\Wrappers; trait Noop { - public function setNoop() + /** + * Set NOOP update handler, ignoring all updates. + * + * @return void + */ + public function setNoop(): void { $this->settings['updates']['callback'] = [$this, 'noop']; $this->settings['updates']['run_callback'] = false; @@ -29,7 +34,12 @@ trait Noop $this->startUpdateSystem(); } - public function noop() + /** + * Noop update handler. + * + * @return void + */ + public function noop(): void { } } diff --git a/src/danog/MadelineProto/Wrappers/Start.php b/src/danog/MadelineProto/Wrappers/Start.php index b7286873..07dbb939 100644 --- a/src/danog/MadelineProto/Wrappers/Start.php +++ b/src/danog/MadelineProto/Wrappers/Start.php @@ -26,7 +26,12 @@ use danog\MadelineProto\Tools; */ trait Start { - public function start() + /** + * Log in to telegram (via CLI or web). + * + * @return \Generator + */ + public function start(): \Generator { if ($this->authorized === self::LOGGED_IN) { return yield $this->getSelf(); diff --git a/src/danog/MadelineProto/Wrappers/Templates.php b/src/danog/MadelineProto/Wrappers/Templates.php index 6237c5b1..11f1453c 100644 --- a/src/danog/MadelineProto/Wrappers/Templates.php +++ b/src/danog/MadelineProto/Wrappers/Templates.php @@ -23,7 +23,7 @@ use function Amp\ByteStream\getOutputBufferStream; trait Templates { - public function webEcho($message = '') + public function webEcho(string $message = '') { $stdout = getOutputBufferStream(); switch ($this->authorized) { @@ -68,17 +68,29 @@ trait Templates '; - public function webEchoTemplate($message, $form) + public function webEchoTemplate($message, $form): string { return \sprintf($this->web_template, $form, $message); } - public function getWebTemplate() + /** + * Get web template. + * + * @return string + */ + public function getWebTemplate(): string { return $this->web_template; } - public function setWebTemplate($template) + /** + * Set web template. + * + * @param string $template Template + * + * @return void + */ + public function setWebTemplate(string $template): void { $this->web_template = $template; } diff --git a/src/danog/MadelineProto/Wrappers/Webhook.php b/src/danog/MadelineProto/Wrappers/Webhook.php index 19908ed7..4512fc7f 100644 --- a/src/danog/MadelineProto/Wrappers/Webhook.php +++ b/src/danog/MadelineProto/Wrappers/Webhook.php @@ -24,7 +24,15 @@ namespace danog\MadelineProto\Wrappers; */ trait Webhook { - public function setWebhook($hook_url, $pem_path = null) + /** + * Set webhook update handler. + * + * @param string $hook_url Webhook URL + * @param string $pem_path PEM path for self-signed certificate + * + * @return void + */ + public function setWebhook($hook_url, $pem_path = null): void { $this->pem_path = $pem_path; $this->hook_url = $hook_url;