mirror of
https://github.com/danog/tg-file-decoder.git
synced 2024-11-26 12:24:40 +01:00
Modernize
This commit is contained in:
parent
500f131d85
commit
464800a3c5
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@ -44,5 +44,6 @@ jobs:
|
||||
TOKEN: ${{ secrets.TOKEN }}
|
||||
DEST: ${{ secrets.DEST }}
|
||||
run: |
|
||||
vendor/bin/psalm --no-cache
|
||||
vendor/bin/phpunit --coverage-text --coverage-clover build/logs/clover.xml
|
||||
vendor/bin/php-cs-fixer --diff --dry-run -v fix
|
||||
|
@ -15,14 +15,15 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
"amphp/php-cs-fixer-config": "^2"
|
||||
"amphp/php-cs-fixer-config": "^2",
|
||||
"vimeo/psalm": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"danog\\Decoder\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/type.php"
|
||||
"src/functions.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
|
8
psalm-baseline.xml
Normal file
8
psalm-baseline.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="dev-master@ef3b018e89c4ffc157332c13e2ebf9cf22320d17">
|
||||
<file src="src/functions.php">
|
||||
<UnusedVariable>
|
||||
<code><![CDATA[$BIG_ENDIAN]]></code>
|
||||
</UnusedVariable>
|
||||
</file>
|
||||
</files>
|
@ -5,6 +5,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
errorBaseline="psalm-baseline.xml"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
|
@ -26,8 +26,10 @@ use danog\Decoder\PhotoSizeSource\PhotoSizeSourceThumbnail;
|
||||
|
||||
/**
|
||||
* Represents decoded bot API file ID.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class FileId
|
||||
final class FileId
|
||||
{
|
||||
/**
|
||||
* Bot API file ID version.
|
||||
@ -51,7 +53,7 @@ class FileId
|
||||
* File type.
|
||||
*
|
||||
*/
|
||||
private int $type = 0;
|
||||
private FileIdType $type = FileIdType::NONE;
|
||||
|
||||
/**
|
||||
* File reference.
|
||||
@ -123,7 +125,7 @@ class FileId
|
||||
}
|
||||
$result->setId($resultArray['id']);
|
||||
|
||||
if ($result->getType() <= PHOTO) {
|
||||
if ($result->getType()->value <= FileIdType::PHOTO->value) {
|
||||
if (isset($resultArray['volume_id'])) {
|
||||
$result->setVolumeId($resultArray['volume_id']);
|
||||
}
|
||||
@ -131,31 +133,31 @@ class FileId
|
||||
$result->setLocalId($resultArray['local_id']);
|
||||
}
|
||||
switch ($resultArray['photosize_source']) {
|
||||
case PHOTOSIZE_SOURCE_LEGACY:
|
||||
case PHOTOSIZE_SOURCE_FULL_LEGACY:
|
||||
case PhotoSizeSourceType::LEGACY:
|
||||
case PhotoSizeSourceType::FULL_LEGACY:
|
||||
$photoSizeSource = new PhotoSizeSourceLegacy($resultArray['photosize_source']);
|
||||
$photoSizeSource->setSecret($resultArray['secret']);
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_THUMBNAIL:
|
||||
case PhotoSizeSourceType::THUMBNAIL:
|
||||
$photoSizeSource = new PhotoSizeSourceThumbnail($resultArray['photosize_source']);
|
||||
$photoSizeSource->setThumbType($resultArray['thumbnail_type']);
|
||||
$photoSizeSource->setThumbFileType($resultArray['file_type']);
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_BIG_LEGACY:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_SMALL_LEGACY:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_BIG:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_SMALL:
|
||||
$photoSizeSource = new PhotoSizeSourceDialogPhoto($resultArray['photosize_source']);
|
||||
$photoSizeSource->setDialogId($resultArray['dialog_id']);
|
||||
$photoSizeSource->setDialogAccessHash($resultArray['dialog_access_hash']);
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL_LEGACY:
|
||||
$photoSizeSource = new PhotoSizeSourceStickersetThumbnail($resultArray['photosize_source']);
|
||||
$photoSizeSource->setStickerSetId($resultArray['sticker_set_id']);
|
||||
$photoSizeSource->setStickerSetAccessHash($resultArray['sticker_set_access_hash']);
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL_VERSION:
|
||||
$photoSizeSource = new PhotoSizeSourceStickersetThumbnailVersion($resultArray['photosize_source']);
|
||||
$photoSizeSource->setStickerSetId($resultArray['sticker_set_id']);
|
||||
$photoSizeSource->setStickerSetAccessHash($resultArray['sticker_set_access_hash']);
|
||||
@ -174,7 +176,7 @@ class FileId
|
||||
*/
|
||||
public function getBotAPI(): string
|
||||
{
|
||||
$type = $this->getType();
|
||||
$type = $this->getType()->value;
|
||||
if ($this->hasFileReference()) {
|
||||
$type |= FILE_REFERENCE_FLAG;
|
||||
}
|
||||
@ -195,40 +197,46 @@ class FileId
|
||||
$fileId .= packLong($this->getId());
|
||||
$fileId .= packLong($this->getAccessHash());
|
||||
|
||||
if ($this->getType() <= PHOTO) {
|
||||
if ($this->getType()->value <= FileIdType::PHOTO->value) {
|
||||
$photoSize = $this->getPhotoSizeSource();
|
||||
$fileId .= \pack('V', $photoSize->getType());
|
||||
switch ($photoSize->getType()) {
|
||||
case PHOTOSIZE_SOURCE_LEGACY:
|
||||
case PhotoSizeSourceType::LEGACY:
|
||||
assert($photoSize instanceof PhotoSizeSourceLegacy);
|
||||
$fileId .= packLong($photoSize->getSecret());
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_FULL_LEGACY:
|
||||
case PhotoSizeSourceType::FULL_LEGACY:
|
||||
assert($photoSize instanceof PhotoSizeSourceLegacy);
|
||||
$fileId .= packLong($this->getVolumeId());
|
||||
$fileId .= packLong($photoSize->getSecret());
|
||||
$fileId .= \pack('l', $this->getLocalId());
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_THUMBNAIL:
|
||||
case PhotoSizeSourceType::THUMBNAIL:
|
||||
assert($photoSize instanceof PhotoSizeSourceThumbnail);
|
||||
$fileId .= \pack('Va4', $photoSize->getThumbFileType(), $photoSize->getThumbType());
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_BIG:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_SMALL:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_BIG_LEGACY:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_SMALL_LEGACY:
|
||||
assert($photoSize instanceof PhotoSizeSourceDialogPhoto);
|
||||
$fileId .= packLongBig($photoSize->getDialogId());
|
||||
$fileId .= packLong($photoSize->getDialogAccessHash());
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL_LEGACY:
|
||||
assert($photoSize instanceof PhotoSizeSourceStickersetThumbnail);
|
||||
$fileId .= packLong($photoSize->getStickerSetId());
|
||||
$fileId .= packLong($photoSize->getStickerSetAccessHash());
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL_VERSION:
|
||||
assert($photoSize instanceof PhotoSizeSourceStickersetThumbnailVersion);
|
||||
$fileId .= packLong($photoSize->getStickerSetId());
|
||||
$fileId .= packLong($photoSize->getStickerSetAccessHash());
|
||||
$fileId .= \pack('l', $photoSize->getStickerSetVersion());
|
||||
break;
|
||||
}
|
||||
if ($photoSize->getType() >= PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY && $photoSize->getType() <= PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY) {
|
||||
if ($photoSize->getType() >= PhotoSizeSourceType::DIALOGPHOTO_SMALL_LEGACY && $photoSize->getType()->value <= PhotoSizeSourceType::STICKERSET_THUMBNAIL_LEGACY->value) {
|
||||
$fileId .= packLong($this->getVolumeId());
|
||||
$fileId .= \pack('l', $this->getLocalId());
|
||||
}
|
||||
@ -314,27 +322,18 @@ class FileId
|
||||
* Get file type.
|
||||
*
|
||||
*/
|
||||
public function getType(): int
|
||||
public function getType(): FileIdType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file type as string.
|
||||
*
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
return TYPES[$this->type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file type.
|
||||
*
|
||||
* @param int $type File type.
|
||||
* @param FileIdType $type File type.
|
||||
*
|
||||
*/
|
||||
public function setType(int $type): self
|
||||
public function setType(FileIdType $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
|
132
src/FileIdType.php
Normal file
132
src/FileIdType.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Type enum + helper functions.
|
||||
*
|
||||
* This file is part of tg-file-decoder.
|
||||
* tg-file-decoder is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* tg-file-decoder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with tg-file-decoder.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2019 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://github.com/tg-file-decoder Documentation
|
||||
*/
|
||||
|
||||
namespace danog\Decoder;
|
||||
|
||||
use AssertionError;
|
||||
|
||||
enum FileIdType: int
|
||||
{
|
||||
/**
|
||||
* Thumbnail.
|
||||
*/
|
||||
case THUMBNAIL = 0;
|
||||
/**
|
||||
* Profile photo.
|
||||
* Used for users and channels, chat photos are normal PHOTOs.
|
||||
*/
|
||||
case PROFILE_PHOTO = 1;
|
||||
/**
|
||||
* Normal photos.
|
||||
*/
|
||||
case PHOTO = 2;
|
||||
|
||||
/**
|
||||
* Voice messages.
|
||||
*/
|
||||
case VOICE = 3;
|
||||
/**
|
||||
* Video.
|
||||
*/
|
||||
case VIDEO = 4;
|
||||
/**
|
||||
* Document.
|
||||
*/
|
||||
case DOCUMENT = 5;
|
||||
/**
|
||||
* Secret chat document.
|
||||
*/
|
||||
case ENCRYPTED = 6;
|
||||
/**
|
||||
* Temporary document.
|
||||
*/
|
||||
case TEMP = 7;
|
||||
/**
|
||||
* Sticker.
|
||||
*/
|
||||
case STICKER = 8;
|
||||
/**
|
||||
* Music.
|
||||
*/
|
||||
case AUDIO = 9;
|
||||
/**
|
||||
* GIF.
|
||||
*/
|
||||
case ANIMATION = 10;
|
||||
/**
|
||||
* Encrypted thumbnail.
|
||||
*/
|
||||
case ENCRYPTED_THUMBNAIL = 11;
|
||||
/**
|
||||
* Wallpaper.
|
||||
*/
|
||||
case WALLPAPER = 12;
|
||||
/**
|
||||
* Round video.
|
||||
*/
|
||||
case VIDEO_NOTE = 13;
|
||||
/**
|
||||
* Passport raw file.
|
||||
*/
|
||||
case SECURE_RAW = 14;
|
||||
/**
|
||||
* Passport file.
|
||||
*/
|
||||
case SECURE = 15;
|
||||
/**
|
||||
* Background.
|
||||
*/
|
||||
case BACKGROUND = 16;
|
||||
/**
|
||||
* Size.
|
||||
*/
|
||||
case SIZE = 17;
|
||||
case NONE = 18;
|
||||
|
||||
/**
|
||||
* Convert file ID type to unique file ID type.
|
||||
*/
|
||||
public function toUnique(): UniqueFileIdType
|
||||
{
|
||||
return match ($this) {
|
||||
self::PHOTO => UniqueFileIdType::PHOTO,
|
||||
self::PROFILE_PHOTO => UniqueFileIdType::PHOTO,
|
||||
self::THUMBNAIL => UniqueFileIdType::PHOTO,
|
||||
self::ENCRYPTED_THUMBNAIL => UniqueFileIdType::PHOTO,
|
||||
self::WALLPAPER => UniqueFileIdType::PHOTO,
|
||||
|
||||
self::VIDEO => UniqueFileIdType::DOCUMENT,
|
||||
self::VOICE => UniqueFileIdType::DOCUMENT,
|
||||
self::DOCUMENT => UniqueFileIdType::DOCUMENT,
|
||||
self::STICKER => UniqueFileIdType::DOCUMENT,
|
||||
self::AUDIO => UniqueFileIdType::DOCUMENT,
|
||||
self::ANIMATION => UniqueFileIdType::DOCUMENT,
|
||||
self::VIDEO_NOTE => UniqueFileIdType::DOCUMENT,
|
||||
self::BACKGROUND => UniqueFileIdType::DOCUMENT,
|
||||
|
||||
self::SECURE => UniqueFileIdType::SECURE,
|
||||
self::SECURE_RAW => UniqueFileIdType::SECURE,
|
||||
|
||||
self::ENCRYPTED => UniqueFileIdType::ENCRYPTED,
|
||||
|
||||
self::TEMP => UniqueFileIdType::TEMP,
|
||||
|
||||
default => throw new AssertionError("Cannot convert file ID of type ".$this->name." to a unique file ID!")
|
||||
};
|
||||
}
|
||||
}
|
@ -31,18 +31,16 @@ abstract class PhotoSizeSource
|
||||
* Source type.
|
||||
*
|
||||
*/
|
||||
private int $type;
|
||||
private PhotoSizeSourceType $type;
|
||||
|
||||
/**
|
||||
* Set photosize source type.
|
||||
*
|
||||
* @param integer $type Type
|
||||
* @param PhotoSizeSourceType $type Type
|
||||
*/
|
||||
public function __construct(int $type)
|
||||
public function __construct(PhotoSizeSourceType $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Get photosize source type.
|
||||
@ -51,18 +49,18 @@ abstract class PhotoSizeSource
|
||||
*
|
||||
* @psalm-return (
|
||||
* T is PhotoSizeSourceLegacy ?
|
||||
* ? \danog\Decoder\PHOTOSIZE_SOURCE_LEGACY
|
||||
* ? \danog\Decoder\PhotoSizeSourceType::LEGACY
|
||||
* : (T is PhotoSizeSourceDialogPhoto
|
||||
* ? \danog\Decoder\PHOTOSIZE_SOURCE_DIALOGPHOTO_*
|
||||
* ? \danog\Decoder\PhotoSizeSourceType::DIALOGPHOTO_*
|
||||
* (T is PhotoSizeSourceStickersetThumbnail
|
||||
* ? \danog\Decoder\PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL
|
||||
* : \danog\Decoder\PHOTOSIZE_SOURCE_THUMBNAIL
|
||||
* ? \danog\Decoder\PhotoSizeSourceType::STICKERSET_THUMBNAIL
|
||||
* : \danog\Decoder\PhotoSizeSourceType::THUMBNAIL
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @internal Internal use
|
||||
*/
|
||||
public function getType(): int
|
||||
public function getType(): PhotoSizeSourceType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
@ -19,16 +19,16 @@
|
||||
namespace danog\Decoder\PhotoSizeSource;
|
||||
|
||||
use danog\Decoder\PhotoSizeSource;
|
||||
|
||||
use const danog\Decoder\PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL;
|
||||
use const danog\Decoder\PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY;
|
||||
use danog\Decoder\PhotoSizeSourceType;
|
||||
|
||||
/**
|
||||
* Represents source of photosize.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @extends PhotoSizeSource<PhotoSizeSourceDialogPhoto>
|
||||
*/
|
||||
class PhotoSizeSourceDialogPhoto extends PhotoSizeSource
|
||||
final class PhotoSizeSourceDialogPhoto extends PhotoSizeSource
|
||||
{
|
||||
/**
|
||||
* ID of dialog.
|
||||
@ -90,6 +90,6 @@ class PhotoSizeSourceDialogPhoto extends PhotoSizeSource
|
||||
*/
|
||||
public function isSmallDialogPhoto(): bool
|
||||
{
|
||||
return \in_array($this->getType(), [PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY, PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL]);
|
||||
return \in_array($this->getType(), [PhotoSizeSourceType::DIALOGPHOTO_SMALL_LEGACY, PhotoSizeSourceType::DIALOGPHOTO_SMALL], true);
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,11 @@ use danog\Decoder\PhotoSizeSource;
|
||||
/**
|
||||
* Represents source of photosize.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @extends PhotoSizeSource<PhotoSizeSourceLegacy>
|
||||
*/
|
||||
class PhotoSizeSourceLegacy extends PhotoSizeSource
|
||||
final class PhotoSizeSourceLegacy extends PhotoSizeSource
|
||||
{
|
||||
/**
|
||||
* Secret legacy ID.
|
||||
|
@ -23,9 +23,11 @@ use danog\Decoder\PhotoSizeSource;
|
||||
/**
|
||||
* Represents source of photosize.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @extends PhotoSizeSource<PhotoSizeSourceStickersetThumbnail>
|
||||
*/
|
||||
class PhotoSizeSourceStickersetThumbnail extends PhotoSizeSource
|
||||
final class PhotoSizeSourceStickersetThumbnail extends PhotoSizeSource
|
||||
{
|
||||
/**
|
||||
* Stickerset ID.
|
||||
|
@ -23,9 +23,11 @@ use danog\Decoder\PhotoSizeSource;
|
||||
/**
|
||||
* Represents source of photosize.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @extends PhotoSizeSource<PhotoSizeSourceStickersetThumbnailVersion>
|
||||
*/
|
||||
class PhotoSizeSourceStickersetThumbnailVersion extends PhotoSizeSource
|
||||
final class PhotoSizeSourceStickersetThumbnailVersion extends PhotoSizeSource
|
||||
{
|
||||
/**
|
||||
* Stickerset ID.
|
||||
|
@ -18,20 +18,23 @@
|
||||
|
||||
namespace danog\Decoder\PhotoSizeSource;
|
||||
|
||||
use danog\Decoder\FileIdType;
|
||||
use danog\Decoder\PhotoSizeSource;
|
||||
|
||||
use const danog\Decoder\TYPES;
|
||||
|
||||
/**
|
||||
* Represents source of photosize.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @extends PhotoSizeSource<PhotoSizeSourceThumbnail>
|
||||
*/
|
||||
class PhotoSizeSourceThumbnail extends PhotoSizeSource
|
||||
final class PhotoSizeSourceThumbnail extends PhotoSizeSource
|
||||
{
|
||||
/**
|
||||
* File type of original file.
|
||||
*
|
||||
*/
|
||||
private int $thumbFileType;
|
||||
private FileIdType $thumbFileType;
|
||||
/**
|
||||
* Thumbnail size.
|
||||
*
|
||||
@ -42,26 +45,17 @@ class PhotoSizeSourceThumbnail extends PhotoSizeSource
|
||||
* Get file type of original file.
|
||||
*
|
||||
*/
|
||||
public function getThumbFileType(): int
|
||||
public function getThumbFileType(): FileIdType
|
||||
{
|
||||
return $this->thumbFileType;
|
||||
}
|
||||
/**
|
||||
* Get file type of original file as string.
|
||||
*
|
||||
*/
|
||||
public function getThumbFileTypeString(): string
|
||||
{
|
||||
return TYPES[$this->thumbFileType];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file type of original file.
|
||||
*
|
||||
* @param int $thumbFileType File type of original file
|
||||
* @param FileIdType $thumbFileType File type of original file
|
||||
*
|
||||
*/
|
||||
public function setThumbFileType(int $thumbFileType): self
|
||||
public function setThumbFileType(FileIdType $thumbFileType): self
|
||||
{
|
||||
$this->thumbFileType = $thumbFileType;
|
||||
|
||||
|
34
src/PhotoSizeSourceType.php
Normal file
34
src/PhotoSizeSourceType.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Type enum + helper functions.
|
||||
*
|
||||
* This file is part of tg-file-decoder.
|
||||
* tg-file-decoder is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* tg-file-decoder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with tg-file-decoder.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2019 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://github.com/tg-file-decoder Documentation
|
||||
*/
|
||||
|
||||
namespace danog\Decoder;
|
||||
|
||||
enum PhotoSizeSourceType: int
|
||||
{
|
||||
case LEGACY = 0;
|
||||
case THUMBNAIL = 1;
|
||||
case DIALOGPHOTO_SMALL = 2;
|
||||
case DIALOGPHOTO_BIG = 3;
|
||||
case STICKERSET_THUMBNAIL = 4;
|
||||
case FULL_LEGACY = 5;
|
||||
case DIALOGPHOTO_SMALL_LEGACY = 6;
|
||||
case DIALOGPHOTO_BIG_LEGACY = 7;
|
||||
case STICKERSET_THUMBNAIL_LEGACY = 8;
|
||||
case STICKERSET_THUMBNAIL_VERSION = 9;
|
||||
}
|
@ -24,14 +24,16 @@ use danog\Decoder\PhotoSizeSource\PhotoSizeSourceThumbnail;
|
||||
|
||||
/**
|
||||
* Represents decoded unique bot API file ID.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class UniqueFileId
|
||||
final class UniqueFileId
|
||||
{
|
||||
/**
|
||||
* File type.
|
||||
*
|
||||
*/
|
||||
private int $type = NONE;
|
||||
private UniqueFileIdType $type;
|
||||
/**
|
||||
* File ID.
|
||||
*
|
||||
@ -90,9 +92,9 @@ class UniqueFileId
|
||||
public function getUniqueBotAPI(): string
|
||||
{
|
||||
$fileId = \pack('V', $this->getType());
|
||||
if ($this->getType() === UNIQUE_WEB) {
|
||||
if ($this->getType() === UniqueFileIdType::WEB) {
|
||||
$fileId .= packTLString($this->getUrl());
|
||||
} elseif ($this->getType() === UNIQUE_PHOTO) {
|
||||
} elseif ($this->getType() === UniqueFileIdType::PHOTO) {
|
||||
if ($this->hasVolumeId()) {
|
||||
$fileId .= packLong($this->getVolumeId());
|
||||
$fileId .= \pack('l', $this->getLocalId());
|
||||
@ -122,9 +124,9 @@ class UniqueFileId
|
||||
$result = new self();
|
||||
$resultArray = internalDecodeUnique($fileId);
|
||||
$result->setType($resultArray['typeId']);
|
||||
if ($result->getType() === UNIQUE_WEB) {
|
||||
if ($result->getType() === UniqueFileIdType::WEB) {
|
||||
$result->setUrl($resultArray['url']);
|
||||
} elseif ($result->getType() === UNIQUE_PHOTO) {
|
||||
} elseif ($result->getType() === UniqueFileIdType::PHOTO) {
|
||||
if (isset($resultArray['volume_id'])) {
|
||||
$result->setVolumeId($resultArray['volume_id']);
|
||||
$result->setLocalId($resultArray['local_id']);
|
||||
@ -163,13 +165,13 @@ class UniqueFileId
|
||||
public static function fromFileId(FileId $fileId): self
|
||||
{
|
||||
$result = new self();
|
||||
$result->setType(FULL_UNIQUE_MAP[$fileId->getType()]);
|
||||
$result->setType($fileId->getType()->toUnique());
|
||||
if ($result->hasUrl()) {
|
||||
$result->setType(UNIQUE_WEB);
|
||||
$result->setType(UniqueFileIdType::WEB);
|
||||
}
|
||||
if ($result->getType() === UNIQUE_WEB) {
|
||||
if ($result->getType() === UniqueFileIdType::WEB) {
|
||||
$result->setUrl($fileId->getUrl());
|
||||
} elseif ($result->getType() === UNIQUE_PHOTO) {
|
||||
} elseif ($result->getType() === UniqueFileIdType::PHOTO) {
|
||||
if ($fileId->hasVolumeId()) {
|
||||
$result->setVolumeId($fileId->getVolumeId());
|
||||
$result->setLocalId($fileId->getLocalId());
|
||||
@ -201,20 +203,11 @@ class UniqueFileId
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique file type as string.
|
||||
*
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
return UNIQUE_TYPES[$this->type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique file type.
|
||||
*
|
||||
*/
|
||||
public function getType(): int
|
||||
public function getType(): UniqueFileIdType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
@ -222,10 +215,10 @@ class UniqueFileId
|
||||
/**
|
||||
* Set file type.
|
||||
*
|
||||
* @param int $type File type.
|
||||
* @param UniqueFileIdType $type File type.
|
||||
*
|
||||
*/
|
||||
public function setType(int $type): self
|
||||
public function setType(UniqueFileIdType $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
|
29
src/UniqueFileIdType.php
Normal file
29
src/UniqueFileIdType.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Type enum + helper functions.
|
||||
*
|
||||
* This file is part of tg-file-decoder.
|
||||
* tg-file-decoder is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* tg-file-decoder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with tg-file-decoder.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2019 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://github.com/tg-file-decoder Documentation
|
||||
*/
|
||||
|
||||
namespace danog\Decoder;
|
||||
|
||||
enum UniqueFileIdType: int
|
||||
{
|
||||
case WEB = 0;
|
||||
case PHOTO = 1;
|
||||
case DOCUMENT = 2;
|
||||
case SECURE = 3;
|
||||
case ENCRYPTED = 4;
|
||||
case TEMP = 5;
|
||||
}
|
@ -1,204 +1,12 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Type enum + helper functions.
|
||||
*
|
||||
* This file is part of tg-file-decoder.
|
||||
* tg-file-decoder is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* tg-file-decoder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with tg-file-decoder.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2019 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://github.com/tg-file-decoder Documentation
|
||||
*/
|
||||
|
||||
namespace danog\Decoder;
|
||||
|
||||
/**
|
||||
* Thumbnail.
|
||||
*/
|
||||
const THUMBNAIL = 0;
|
||||
/**
|
||||
* Profile photo.
|
||||
* Used for users and channels, chat photos are normal PHOTOs.
|
||||
*/
|
||||
const PROFILE_PHOTO = 1;
|
||||
/**
|
||||
* Normal photos.
|
||||
*/
|
||||
const PHOTO = 2;
|
||||
|
||||
/**
|
||||
* Voice messages.
|
||||
*/
|
||||
const VOICE = 3;
|
||||
/**
|
||||
* Video.
|
||||
*/
|
||||
const VIDEO = 4;
|
||||
/**
|
||||
* Document.
|
||||
*/
|
||||
const DOCUMENT = 5;
|
||||
/**
|
||||
* Secret chat document.
|
||||
*/
|
||||
const ENCRYPTED = 6;
|
||||
/**
|
||||
* Temporary document.
|
||||
*/
|
||||
const TEMP = 7;
|
||||
/**
|
||||
* Sticker.
|
||||
*/
|
||||
const STICKER = 8;
|
||||
/**
|
||||
* Music.
|
||||
*/
|
||||
const AUDIO = 9;
|
||||
/**
|
||||
* GIF.
|
||||
*/
|
||||
const ANIMATION = 10;
|
||||
/**
|
||||
* Encrypted thumbnail.
|
||||
*/
|
||||
const ENCRYPTED_THUMBNAIL = 11;
|
||||
/**
|
||||
* Wallpaper.
|
||||
*/
|
||||
const WALLPAPER = 12;
|
||||
/**
|
||||
* Round video.
|
||||
*/
|
||||
const VIDEO_NOTE = 13;
|
||||
/**
|
||||
* Passport raw file.
|
||||
*/
|
||||
const SECURE_RAW = 14;
|
||||
/**
|
||||
* Passport file.
|
||||
*/
|
||||
const SECURE = 15;
|
||||
/**
|
||||
* Background.
|
||||
*/
|
||||
const BACKGROUND = 16;
|
||||
/**
|
||||
* Size.
|
||||
*/
|
||||
const SIZE = 17;
|
||||
const NONE = 18;
|
||||
|
||||
const TYPES = [
|
||||
THUMBNAIL => 'thumbnail',
|
||||
PROFILE_PHOTO => 'profile_photo',
|
||||
PHOTO => 'photo',
|
||||
VOICE => 'voice',
|
||||
VIDEO => 'video',
|
||||
DOCUMENT => 'document',
|
||||
ENCRYPTED => 'encrypted',
|
||||
TEMP => 'temp',
|
||||
STICKER => 'sticker',
|
||||
AUDIO => 'audio',
|
||||
ANIMATION => 'animation',
|
||||
ENCRYPTED_THUMBNAIL => 'encrypted_thumbnail',
|
||||
WALLPAPER => 'wallpaper',
|
||||
VIDEO_NOTE => 'video_note',
|
||||
SECURE_RAW => 'secure_raw',
|
||||
SECURE => 'secure',
|
||||
BACKGROUND => 'background',
|
||||
SIZE => 'size'
|
||||
];
|
||||
const TYPES_IDS = [
|
||||
'thumbnail' => THUMBNAIL,
|
||||
'profile_photo' => PROFILE_PHOTO,
|
||||
'photo' => PHOTO,
|
||||
'voice' => VOICE,
|
||||
'video' => VIDEO,
|
||||
'document' => DOCUMENT,
|
||||
'encrypted' => ENCRYPTED,
|
||||
'temp' => TEMP,
|
||||
'sticker' => STICKER,
|
||||
'audio' => AUDIO,
|
||||
'animation' => ANIMATION,
|
||||
'encrypted_thumbnail' => ENCRYPTED_THUMBNAIL,
|
||||
'wallpaper' => WALLPAPER,
|
||||
'video_note' => VIDEO_NOTE,
|
||||
'secure_raw' => SECURE_RAW,
|
||||
'secure' => SECURE,
|
||||
'background' => BACKGROUND,
|
||||
'size' => SIZE
|
||||
];
|
||||
|
||||
const UNIQUE_WEB = 0;
|
||||
const UNIQUE_PHOTO = 1;
|
||||
const UNIQUE_DOCUMENT = 2;
|
||||
const UNIQUE_SECURE = 3;
|
||||
const UNIQUE_ENCRYPTED = 4;
|
||||
const UNIQUE_TEMP = 5;
|
||||
|
||||
const UNIQUE_TYPES = [
|
||||
UNIQUE_WEB => 'web',
|
||||
UNIQUE_PHOTO => 'photo',
|
||||
UNIQUE_DOCUMENT => 'document',
|
||||
UNIQUE_SECURE => 'secure',
|
||||
UNIQUE_ENCRYPTED => 'encrypted',
|
||||
UNIQUE_TEMP => 'temp'
|
||||
];
|
||||
|
||||
const UNIQUE_TYPES_IDS = [
|
||||
'web' => UNIQUE_WEB,
|
||||
'photo' => UNIQUE_PHOTO,
|
||||
'document' => UNIQUE_DOCUMENT,
|
||||
'secure' => UNIQUE_SECURE,
|
||||
'encrypted' => UNIQUE_ENCRYPTED,
|
||||
'temp' => UNIQUE_TEMP
|
||||
];
|
||||
|
||||
const FULL_UNIQUE_MAP = [
|
||||
PHOTO => UNIQUE_PHOTO,
|
||||
PROFILE_PHOTO => UNIQUE_PHOTO,
|
||||
THUMBNAIL => UNIQUE_PHOTO,
|
||||
ENCRYPTED_THUMBNAIL => UNIQUE_PHOTO,
|
||||
WALLPAPER => UNIQUE_PHOTO,
|
||||
|
||||
VIDEO => UNIQUE_DOCUMENT,
|
||||
VOICE => UNIQUE_DOCUMENT,
|
||||
DOCUMENT => UNIQUE_DOCUMENT,
|
||||
STICKER => UNIQUE_DOCUMENT,
|
||||
AUDIO => UNIQUE_DOCUMENT,
|
||||
ANIMATION => UNIQUE_DOCUMENT,
|
||||
VIDEO_NOTE => UNIQUE_DOCUMENT,
|
||||
BACKGROUND => UNIQUE_DOCUMENT,
|
||||
|
||||
SECURE => UNIQUE_SECURE,
|
||||
SECURE_RAW => UNIQUE_SECURE,
|
||||
|
||||
ENCRYPTED => UNIQUE_ENCRYPTED,
|
||||
|
||||
TEMP => UNIQUE_TEMP
|
||||
];
|
||||
|
||||
const PHOTOSIZE_SOURCE_LEGACY = 0;
|
||||
const PHOTOSIZE_SOURCE_THUMBNAIL = 1;
|
||||
const PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL = 2;
|
||||
const PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG = 3;
|
||||
const PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL = 4;
|
||||
const PHOTOSIZE_SOURCE_FULL_LEGACY = 5;
|
||||
const PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY = 6;
|
||||
const PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY = 7;
|
||||
const PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY = 8;
|
||||
const PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION = 9;
|
||||
|
||||
const WEB_LOCATION_FLAG = 1 << 24;
|
||||
const FILE_REFERENCE_FLAG = 1 << 25;
|
||||
const LONG = PHP_INT_SIZE === 8 ? 'Q' : 'l2';
|
||||
|
||||
/** @psalm-suppress UnusedVariable */
|
||||
$BIG_ENDIAN = \pack('L', 1) === \pack('N', 1);
|
||||
|
||||
/**
|
||||
@ -361,7 +169,6 @@ function rleEncode(string $string): string
|
||||
}
|
||||
if ($count > 0) {
|
||||
$new .= $null.\chr($count);
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
return $new;
|
||||
@ -404,15 +211,16 @@ function readTLString(mixed $stream): string
|
||||
$x = \stream_get_contents($stream, $long_len);
|
||||
$resto = posmod(-$long_len, 4);
|
||||
if ($resto > 0) {
|
||||
\stream_get_contents($stream, $resto);
|
||||
\fseek($stream, $resto, SEEK_CUR);
|
||||
}
|
||||
} else {
|
||||
$x = $l ? \stream_get_contents($stream, $l) : '';
|
||||
$resto = posmod(-($l + 1), 4);
|
||||
if ($resto > 0) {
|
||||
\stream_get_contents($stream, $resto);
|
||||
\fseek($stream, $resto, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
\assert($x !== false);
|
||||
return $x;
|
||||
}
|
||||
|
||||
@ -462,10 +270,7 @@ function internalDecode(string $fileId): array
|
||||
$result['hasWebLocation'] = (bool) ($result['typeId'] & WEB_LOCATION_FLAG);
|
||||
$result['typeId'] &= ~FILE_REFERENCE_FLAG;
|
||||
$result['typeId'] &= ~WEB_LOCATION_FLAG;
|
||||
if (!isset(TYPES[$result['typeId']])) {
|
||||
throw new \InvalidArgumentException("Invalid file type provided: {$result['typeId']}");
|
||||
}
|
||||
$result['type'] = TYPES[$result['typeId']];
|
||||
$result['type'] = FileIdType::from($result['typeId']);
|
||||
$res = \fopen('php://memory', 'rw+b');
|
||||
\fwrite($res, \substr($fileId, 8));
|
||||
\fseek($res, 0);
|
||||
@ -485,38 +290,38 @@ function internalDecode(string $fileId): array
|
||||
fixLong($result, 'id');
|
||||
fixLong($result, 'access_hash');
|
||||
|
||||
if ($result['typeId'] <= PHOTO) {
|
||||
if ($result['typeId'] <= FileIdType::PHOTO->value) {
|
||||
$parsePhotoSize = function () use (&$result, &$fileId) {
|
||||
$result['photosize_source'] = $result['subVersion'] >= 4 ? \unpack('V', \stream_get_contents($fileId, 4))[1] : 0;
|
||||
switch ($result['photosize_source']) {
|
||||
case PHOTOSIZE_SOURCE_LEGACY:
|
||||
case PhotoSizeSourceType::LEGACY:
|
||||
$result += \unpack(LONG.'secret', \stream_get_contents($fileId, 8));
|
||||
fixLong($result, 'secret');
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_THUMBNAIL:
|
||||
case PhotoSizeSourceType::THUMBNAIL:
|
||||
$result += \unpack('Vfile_type/athumbnail_type', \stream_get_contents($fileId, 8));
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
|
||||
$result['photo_size'] = $result['photosize_source'] === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL ? 'photo_small' : 'photo_big';
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_BIG:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_SMALL:
|
||||
$result['photo_size'] = $result['photosize_source'] === PhotoSizeSourceType::DIALOGPHOTO_SMALL ? 'photo_small' : 'photo_big';
|
||||
$result['dialog_id'] = unpackLong(\stream_get_contents($fileId, 8));
|
||||
$result['dialog_access_hash'] = \unpack(LONG, \stream_get_contents($fileId, 8))[1];
|
||||
fixLong($result, 'dialog_access_hash');
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL:
|
||||
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash', \stream_get_contents($fileId, 16));
|
||||
fixLong($result, 'sticker_set_id');
|
||||
fixLong($result, 'sticker_set_access_hash');
|
||||
break;
|
||||
|
||||
case PHOTOSIZE_SOURCE_FULL_LEGACY:
|
||||
case PhotoSizeSourceType::FULL_LEGACY:
|
||||
$result += \unpack(LONG.'volume_id/'.LONG.'secret/llocal_id', \stream_get_contents($fileId, 20));
|
||||
fixLong($result, 'volume_id');
|
||||
fixLong($result, 'secret');
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY:
|
||||
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY:
|
||||
$result['photo_size'] = $result['photosize_source'] === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY ? 'photo_small' : 'photo_big';
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_BIG_LEGACY:
|
||||
case PhotoSizeSourceType::DIALOGPHOTO_SMALL_LEGACY:
|
||||
$result['photo_size'] = $result['photosize_source'] === PhotoSizeSourceType::DIALOGPHOTO_SMALL_LEGACY ? 'photo_small' : 'photo_big';
|
||||
$result['dialog_id'] = unpackLong(\stream_get_contents($fileId, 8));
|
||||
$result['dialog_access_hash'] = \unpack(LONG, \stream_get_contents($fileId, 8))[1];
|
||||
fixLong($result, 'dialog_access_hash');
|
||||
@ -524,7 +329,7 @@ function internalDecode(string $fileId): array
|
||||
$result += \unpack(LONG.'volume_id/llocal_id', \stream_get_contents($fileId, 12));
|
||||
fixLong($result, 'volume_id');
|
||||
break;
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL_LEGACY:
|
||||
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash', \stream_get_contents($fileId, 16));
|
||||
fixLong($result, 'sticker_set_id');
|
||||
fixLong($result, 'sticker_set_access_hash');
|
||||
@ -533,7 +338,7 @@ function internalDecode(string $fileId): array
|
||||
fixLong($result, 'volume_id');
|
||||
break;
|
||||
|
||||
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION:
|
||||
case PhotoSizeSourceType::STICKERSET_THUMBNAIL_VERSION:
|
||||
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash/lsticker_version', \stream_get_contents($fileId, 20));
|
||||
fixLong($result, 'sticker_set_id');
|
||||
fixLong($result, 'sticker_set_access_hash');
|
||||
@ -579,13 +384,10 @@ function internalDecodeUnique(string $fileId): array
|
||||
$fileId = rleDecode(base64urlDecode($fileId));
|
||||
|
||||
$result = \unpack('VtypeId', $fileId);
|
||||
if (!isset(UNIQUE_TYPES[$result['typeId']])) {
|
||||
throw new \InvalidArgumentException("Invalid file type provided: {$result['typeId']}");
|
||||
}
|
||||
$result['type'] = UNIQUE_TYPES[$result['typeId']];
|
||||
$result['type'] = UniqueFileIdType::from($result['typeId']);
|
||||
|
||||
$fileId = \substr($fileId, 4);
|
||||
if ($result['typeId'] === UNIQUE_WEB) {
|
||||
if ($result['typeId'] === UniqueFileIdType::WEB) {
|
||||
$res = \fopen('php://memory', 'rw+b');
|
||||
\fwrite($res, $fileId);
|
||||
\fseek($res, 0);
|
||||
@ -624,5 +426,6 @@ function internalDecodeUnique(string $fileId): array
|
||||
\trigger_error("Unique file ID $orig has $l bytes of leftover data");
|
||||
}
|
||||
|
||||
\assert($result !== false);
|
||||
return $result;
|
||||
}
|
Loading…
Reference in New Issue
Block a user