From 749c0aab5bf8e85ede3366fef9c747e68d551a21 Mon Sep 17 00:00:00 2001 From: Timofey <57951811+smotim@users.noreply.github.com> Date: Mon, 28 Sep 2026 00:11:48 +0500 Subject: [PATCH] Allow users without last_activity_time Since schema 0.0.33 User.last_activity_time is nullable and not required. AbstractUser and its subclasses declared it as int, so a user object without it failed with "Argument #6 ($lastActivityTime) must be of type int, null given" and took the whole update with it. --- src/Models/AbstractUser.php | 4 ++-- src/Models/BotInfo.php | 4 ++-- src/Models/ChatMember.php | 4 ++-- src/Models/UserWithPhoto.php | 4 ++-- tests/Models/UserWithPhotoTest.php | 17 +++++++++++++++++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Models/AbstractUser.php b/src/Models/AbstractUser.php index dc243d7..11be745 100644 --- a/src/Models/AbstractUser.php +++ b/src/Models/AbstractUser.php @@ -12,7 +12,7 @@ abstract readonly class AbstractUser extends AbstractModel * @param string|null $lastName Users last name. * @param string|null $username Unique public user name. Can be `null` if user is not accessible or it is not set. * @param bool $isBot Is the user a bot. - * @param int $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds). + * @param int|null $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds). * Can be outdated if user disabled its "online" status in settings. */ public function __construct( @@ -21,7 +21,7 @@ abstract readonly class AbstractUser extends AbstractModel public ?string $lastName, public ?string $username, public bool $isBot, - public int $lastActivityTime, + public ?int $lastActivityTime, ) { } } diff --git a/src/Models/BotInfo.php b/src/Models/BotInfo.php index fafe2bf..dfea408 100644 --- a/src/Models/BotInfo.php +++ b/src/Models/BotInfo.php @@ -17,7 +17,7 @@ final readonly class BotInfo extends AbstractUser * @param string|null $lastName User's display last name. * @param string|null $username Unique public name of the user, may be null if the user is not available or no name is set. * @param bool $isBot Is the user a bot. - * @param int $lastActivityTime User last activity time in MAX (Unix time in milliseconds). May be irrelevant if the user has disabled the "online" status in the settings. + * @param int|null $lastActivityTime User last activity time in MAX (Unix time in milliseconds). May be irrelevant if the user has disabled the "online" status in the settings. * @param string|null $description User description, may be null if the user has not filled it in (up to 16000 characters). * @param string|null $avatarUrl Avatar URL. * @param string|null $fullAvatarUrl Larger Avatar URL. @@ -29,7 +29,7 @@ final readonly class BotInfo extends AbstractUser ?string $lastName, ?string $username, bool $isBot, - int $lastActivityTime, + ?int $lastActivityTime, public ?string $description, public ?string $avatarUrl, public ?string $fullAvatarUrl, diff --git a/src/Models/ChatMember.php b/src/Models/ChatMember.php index d682168..4c4734d 100644 --- a/src/Models/ChatMember.php +++ b/src/Models/ChatMember.php @@ -18,7 +18,7 @@ final readonly class ChatMember extends AbstractUser * @param string|null $lastName User's last name. * @param string|null $username User's public username. * @param bool $isBot True if the user is a bot. - * @param int $lastActivityTime Time of the user's last activity in Max. + * @param int|null $lastActivityTime Time of the user's last activity in Max. * @param string|null $description User's profile description. * @param string|null $avatarUrl URL of the user's avatar. * @param string|null $fullAvatarUrl URL of the user's full-sized avatar. @@ -35,7 +35,7 @@ final readonly class ChatMember extends AbstractUser ?string $lastName, ?string $username, bool $isBot, - int $lastActivityTime, + ?int $lastActivityTime, public ?string $description, public ?string $avatarUrl, public ?string $fullAvatarUrl, diff --git a/src/Models/UserWithPhoto.php b/src/Models/UserWithPhoto.php index 35c8438..b36bbb6 100644 --- a/src/Models/UserWithPhoto.php +++ b/src/Models/UserWithPhoto.php @@ -12,7 +12,7 @@ final readonly class UserWithPhoto extends AbstractUser * @param string|null $lastName Users last name. * @param string|null $username Unique public user name. Can be `null` if user is not accessible or it is not set. * @param bool $isBot `true` if user is bot. - * @param int $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds). + * @param int|null $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds). * @param string|null $description UserWithPhoto description. Can be `null` if user did not fill it out. * @param string|null $avatarUrl URL of avatar. * @param string|null $fullAvatarUrl URL of avatar of a bigger size. @@ -23,7 +23,7 @@ final readonly class UserWithPhoto extends AbstractUser ?string $lastName, ?string $username, bool $isBot, - int $lastActivityTime, + ?int $lastActivityTime, public ?string $description, public ?string $avatarUrl, public ?string $fullAvatarUrl, diff --git a/tests/Models/UserWithPhotoTest.php b/tests/Models/UserWithPhotoTest.php index a8efa46..a7fce9a 100644 --- a/tests/Models/UserWithPhotoTest.php +++ b/tests/Models/UserWithPhotoTest.php @@ -12,6 +12,23 @@ use PHPUnit\Framework\TestCase; #[CoversClass(UserWithPhoto::class)] final class UserWithPhotoTest extends TestCase { + #[Test] + public function optionalFieldsMayBeAbsent(): void + { + // Since schema 0.0.33 only user_id, first_name and is_bot are required + $user = UserWithPhoto::fromArray([ + 'user_id' => 123, + 'first_name' => 'John', + 'is_bot' => false, + ]); + + $this->assertSame(123, $user->userId); + $this->assertNull($user->lastName); + $this->assertNull($user->username); + $this->assertNull($user->lastActivityTime); + $this->assertNull($user->avatarUrl); + } + #[Test] public function canBeCreatedFromArray(): void {