Document file methods

This commit is contained in:
Daniil Gentili 2019-12-27 20:29:22 +01:00
parent c410730a58
commit 1110a70bcd
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 714 additions and 107 deletions

View File

@ -4452,43 +4452,101 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$method, $args, $aargs, $extra]); 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]); 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]); 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]); 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]); 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]); 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 = []) public function toSupergroup($id, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $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 = []) public function fromSupergroup($id, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $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]); return $this->__call(__FUNCTION__, [$id, $extra]);
} }
@ -4512,7 +4570,13 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$id, $full_fetch, $send, $extra]); return $this->__call(__FUNCTION__, [$id, $full_fetch, $send, $extra]);
} }
/**
* Check if peer is present in internal peer database.
*
* @param mixed $id Peer
*
* @return \Generator<boolean>
*/
public function peerIsset($id, array $extra = []) public function peerIsset($id, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $extra]); return $this->__call(__FUNCTION__, [$id, $extra]);
@ -4527,17 +4591,38 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$fwd, $extra]); return $this->__call(__FUNCTION__, [$fwd, $extra]);
} }
/**
* Get folder ID from object.
*
* @param mixed $id Object
*
* @return ?int
*/
public function getFolderId($id, array $extra = []) public function getFolderId($id, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $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 = []) public function getId($id, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $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<array> Info object
*/
public function getInfo($id, $recursive = true, array $extra = []) public function getInfo($id, $recursive = true, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $recursive, $extra]); return $this->__call(__FUNCTION__, [$id, $recursive, $extra]);
@ -4552,12 +4637,28 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$id, $extra]); 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<array> FullInfo object
*/
public function getFullInfo($id, array $extra = []) public function getFullInfo($id, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $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<array> Chat object
*/
public function getPwrChat($id, $fullfetch = true, $send = true, array $extra = []) public function getPwrChat($id, $fullfetch = true, $send = true, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $fullfetch, $send, $extra]); return $this->__call(__FUNCTION__, [$id, $fullfetch, $send, $extra]);
@ -4664,33 +4765,91 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$update, $extra]); 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]); 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 = []) 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]); 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 = []) 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]); 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 = []) 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]); 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]); 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]); return $this->__call(__FUNCTION__, [$media, $cb, $encrypted, $extra]);
} }
@ -4704,12 +4863,36 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$constructor, $extra]); 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<array>
*/
public function getPropicInfo($data, array $extra = []) public function getPropicInfo($data, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$data, $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<array>
*/
public function getDownloadInfo($message_media, array $extra = []) public function getDownloadInfo($message_media, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $extra]); return $this->__call(__FUNCTION__, [$message_media, $extra]);
@ -4719,25 +4902,66 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$photo, $extra]); 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<string> Downloaded file path
*/
public function downloadToDir($message_media, $dir, $cb = null, array $extra = []) public function downloadToDir($message_media, $dir, $cb = null, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $dir, $cb, $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<string> Downloaded file path
*/
public function downloadToFile($message_media, $file, $cb = null, array $extra = []) public function downloadToFile($message_media, $file, $cb = null, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $file, $cb, $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<bool>
*/
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]); 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<bool>
*/
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. * Accept secret chat.
@ -5577,13 +5801,26 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$update, $extra]); 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]); 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]); return $this->__call(__FUNCTION__, [$callback, $extra]);
} }
@ -5639,32 +5876,62 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$params, $extra]); 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]); 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]); 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]); 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]); return $this->__call(__FUNCTION__, [$extra]);
} }
/**
* Log in to telegram (via CLI or web).
*
* @return \Generator
*/
public function start(array $extra = []) public function start(array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$extra]); return $this->__call(__FUNCTION__, [$extra]);
@ -5695,22 +5962,32 @@ class InternalDoc extends APIFactory
return $this->__call(__FUNCTION__, [$extra]); return $this->__call(__FUNCTION__, [$extra]);
} }
public function webEcho($message = '', array $extra = []) public function webEcho(string $message = '', array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message, $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]); 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]); 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]); return $this->__call(__FUNCTION__, [$template, $extra]);
} }

View File

@ -21,7 +21,16 @@ namespace danog\MadelineProto\MTProtoTools;
trait Crypt 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; $x = $to_server ? 0 : 8;
$sha256_a = \hash('sha256', $msg_key.\substr($auth_key, $x, 36), true); $sha256_a = \hash('sha256', $msg_key.\substr($auth_key, $x, 36), true);
@ -32,7 +41,16 @@ trait Crypt
return [$aes_key, $aes_iv]; 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; $x = $to_server ? 0 : 8;
$sha1_a = \sha1($msg_key.\substr($auth_key, $x, 32), true); $sha1_a = \sha1($msg_key.\substr($auth_key, $x, 32), true);
@ -45,7 +63,16 @@ trait Crypt
return [$aes_key, $aes_iv]; 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 = new \tgseclib\Crypt\AES('ctr');
$cipher->setKey($key); $cipher->setKey($key);
@ -54,7 +81,16 @@ trait Crypt
return @$cipher->encrypt($message); 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 = new \tgseclib\Crypt\AES('ige');
$cipher->setKey($key); $cipher->setKey($key);
@ -62,7 +98,16 @@ trait Crypt
return @$cipher->encrypt($message); 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 = new \tgseclib\Crypt\AES('ige');
$cipher->setKey($key); $cipher->setKey($key);

View File

@ -48,7 +48,17 @@ use function Amp\Promise\all;
*/ */
trait Files 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) { if (\is_object($file) && $file instanceof FileCallbackInterface) {
$cb = $file; $cb = $file;
@ -86,7 +96,18 @@ trait Files
yield $stream->close(); 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) { if (\is_object($url) && $url instanceof FileCallbackInterface) {
$cb = $url; $cb = $url;
@ -122,14 +143,26 @@ trait Files
return yield $this->uploadFromStream($stream, $size, $mime, $file_name, $cb, $encrypted); 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) { if (\is_object($stream) && $stream instanceof FileCallbackInterface) {
$cb = $stream; $cb = $stream;
$stream = $stream->getFile(); $stream = $stream->getFile();
} }
/** @var $stream \Amp\ByteStream\OutputStream */ /* @var $stream \Amp\ByteStream\OutputStream */
if (!\is_object($stream)) { if (!\is_object($stream)) {
$stream = new ResourceOutputStream($stream); $stream = new ResourceOutputStream($stream);
} }
@ -182,6 +215,19 @@ trait Files
} }
return $res; 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) 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) { if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
@ -304,12 +350,30 @@ trait Files
return $constructor; 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); 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) { if (\is_object($media) && $media instanceof FileCallbackInterface) {
$cb = $media; $cb = $media;
@ -492,11 +556,37 @@ trait Files
return yield $this->genAllFile($constructor); 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<array>
*/
public function getPropicInfo($data): \Generator
{ {
return yield $this->getDownloadInfo($this->chats[(yield $this->getInfo($data))['bot_api_id']]); 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<array>
*/
public function getDownloadInfo($message_media): \Generator
{ {
if (\is_string($message_media)) { if (\is_string($message_media)) {
$message_media = $this->unpackFileId($message_media)['MessageMedia']; $message_media = $this->unpackFileId($message_media)['MessageMedia'];
@ -842,7 +932,16 @@ trait Files
public function extractPhotosize($photo) 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<string> Downloaded file path
*/
public function downloadToDir($message_media, $dir, $cb = null): \Generator
{ {
if (\is_object($dir) && $dir instanceof FileCallbackInterface) { if (\is_object($dir) && $dir instanceof FileCallbackInterface) {
$cb = $dir; $cb = $dir;
@ -854,7 +953,16 @@ trait Files
return yield $this->downloadToFile($message_media, $dir.'/'.$message_media['name'].$message_media['ext'], $cb); 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<string> Downloaded file path
*/
public function downloadToFile($message_media, $file, $cb = null): \Generator
{ {
if (\is_object($file) && $file instanceof FileCallbackInterface) { if (\is_object($file) && $file instanceof FileCallbackInterface) {
$cb = $file; $cb = $file;
@ -885,7 +993,18 @@ trait Files
return $file; 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<bool>
*/
public function downloadToStream($message_media, $stream, $cb = null, int $offset = 0, int $end = -1): \Generator
{ {
$message_media = yield $this->getDownloadInfo($message_media); $message_media = yield $this->getDownloadInfo($message_media);
@ -920,7 +1039,23 @@ trait Files
return yield $this->downloadToCallable($message_media, $callable, $cb, $seekable, $offset, $end); 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<bool>
*/
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); $message_media = yield $this->getDownloadInfo($message_media);
@ -960,7 +1095,7 @@ trait Files
$ige->setIV($message_media['iv']); $ige->setIV($message_media['iv']);
$ige->setKey($message_media['key']); $ige->setKey($message_media['key']);
$ige->enableContinuousBuffer(); $ige->enableContinuousBuffer();
$parallelize = false; $seekable = false;
} }
if ($offset === $end) { if ($offset === $end) {
@ -1010,7 +1145,7 @@ trait Files
$params[0]['previous_promise'] = new Success(true); $params[0]['previous_promise'] = new Success(true);
$start = \microtime(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) { if ($params) {
$previous_promise = new Success(true); $previous_promise = new Success(true);
@ -1018,7 +1153,7 @@ trait Files
$promises = []; $promises = [];
foreach ($params as $key => $param) { foreach ($params as $key => $param) {
$param['previous_promise'] = $previous_promise; $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) { $previous_promise->onResolve(static function ($e, $res) use (&$size) {
if ($res) { if ($res) {
$size += $res; $size += $res;
@ -1053,7 +1188,23 @@ trait Files
return true; 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 = [ static $method = [
false => 'upload.getFile', // non-cdn false => 'upload.getFile', // non-cdn

View File

@ -94,9 +94,10 @@ class PasswordCalculator
* Popupate 2FA configuration. * Popupate 2FA configuration.
* *
* @param array $object 2FA configuration object obtained using account.getPassword * @param array $object 2FA configuration object obtained using account.getPassword
*
* @return void * @return void
*/ */
public function addInfo(array $object) public function addInfo(array $object): void
{ {
if ($object['_'] !== 'account.password') { if ($object['_'] !== 'account.password') {
throw new Exception('Wrong constructor'); throw new Exception('Wrong constructor');

View File

@ -32,17 +32,38 @@ trait PeerHandler
public $caching_full_info = []; 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))); 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))); 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); $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<boolean>
*/
public function peerIsset($id): \Generator
{ {
try { try {
return isset($this->chats[(yield $this->getInfo($id))['bot_api_id']]); 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 { try {
foreach ($entities as $entity) { foreach ($entities as $entity) {
@ -209,7 +237,7 @@ trait PeerHandler
return true; return true;
} }
public function fwdPeerIsset($fwd) public function fwdPeerIsset($fwd): \Generator
{ {
try { try {
if (isset($fwd['user_id']) && !yield $this->peerIsset($fwd['user_id'])) { if (isset($fwd['user_id']) && !yield $this->peerIsset($fwd['user_id'])) {
@ -225,6 +253,13 @@ trait PeerHandler
return true; return true;
} }
/**
* Get folder ID from object.
*
* @param mixed $id Object
*
* @return ?int
*/
public function getFolderId($id) public function getFolderId($id)
{ {
if (!\is_array($id)) { if (!\is_array($id)) {
@ -235,6 +270,13 @@ trait PeerHandler
} }
return $id['folder_id']; return $id['folder_id'];
} }
/**
* Get bot API ID from peer object.
*
* @param mixed $id Peer
*
* @return int
*/
public function getId($id) public function getId($id)
{ {
if (\is_array($id)) { if (\is_array($id)) {
@ -377,7 +419,17 @@ trait PeerHandler
return false; 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<array> Info object
*/
public function getInfo($id, $recursive = true): \Generator
{ {
if (\is_array($id)) { if (\is_array($id)) {
switch ($id['_']) { switch ($id['_']) {
@ -608,7 +660,16 @@ trait PeerHandler
return isset($this->full_chats[$id]['last_update']) ? $this->full_chats[$id]['last_update'] : 0; 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<array> FullInfo object
*/
public function getFullInfo($id): \Generator
{ {
$partial = yield $this->getInfo($id); $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)) { 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); 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<array> Chat object
*/
public function getPwrChat($id, $fullfetch = true, $send = true): \Generator
{ {
$full = $fullfetch ? yield $this->getFullInfo($id) : yield $this->getInfo($id); $full = $fullfetch ? yield $this->getFullInfo($id) : yield $this->getInfo($id);
$res = ['id' => $full['bot_api_id'], 'type' => $full['type']]; $res = ['id' => $full['bot_api_id'], 'type' => $full['type']];

View File

@ -24,7 +24,14 @@ namespace danog\MadelineProto\Wrappers;
*/ */
trait Callback 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']['callback'] = $callback;
$this->settings['updates']['run_callback'] = true; $this->settings['updates']['run_callback'] = true;

View File

@ -30,22 +30,36 @@ trait Loop
{ {
private $loop_callback; 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; $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'); $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'); $this->logger->logger('Resolving async promise');
return yield $max_forks; return yield $callback;
} }
if (!$this->authorized) { if (!$this->authorized) {
$this->logger->logger('Not authorized, not starting event loop', \danog\MadelineProto\Logger::FATAL_ERROR); $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()) { if (PHP_SAPI === 'cli' || isset($GLOBALS['exited']) || \headers_sent()) {
return; return;

View File

@ -21,7 +21,12 @@ namespace danog\MadelineProto\Wrappers;
trait Noop 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']['callback'] = [$this, 'noop'];
$this->settings['updates']['run_callback'] = false; $this->settings['updates']['run_callback'] = false;
@ -29,7 +34,12 @@ trait Noop
$this->startUpdateSystem(); $this->startUpdateSystem();
} }
public function noop() /**
* Noop update handler.
*
* @return void
*/
public function noop(): void
{ {
} }
} }

View File

@ -26,7 +26,12 @@ use danog\MadelineProto\Tools;
*/ */
trait Start 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) { if ($this->authorized === self::LOGGED_IN) {
return yield $this->getSelf(); return yield $this->getSelf();

View File

@ -23,7 +23,7 @@ use function Amp\ByteStream\getOutputBufferStream;
trait Templates trait Templates
{ {
public function webEcho($message = '') public function webEcho(string $message = '')
{ {
$stdout = getOutputBufferStream(); $stdout = getOutputBufferStream();
switch ($this->authorized) { switch ($this->authorized) {
@ -68,17 +68,29 @@ trait Templates
</body> </body>
</html>'; </html>';
public function webEchoTemplate($message, $form) public function webEchoTemplate($message, $form): string
{ {
return \sprintf($this->web_template, $form, $message); return \sprintf($this->web_template, $form, $message);
} }
public function getWebTemplate() /**
* Get web template.
*
* @return string
*/
public function getWebTemplate(): string
{ {
return $this->web_template; 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; $this->web_template = $template;
} }

View File

@ -24,7 +24,15 @@ namespace danog\MadelineProto\Wrappers;
*/ */
trait Webhook 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->pem_path = $pem_path;
$this->hook_url = $hook_url; $this->hook_url = $hook_url;