summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2025-09-25 13:38:24 +0200
committerDaniel Weipert <git@mail.dweipert.de>2025-09-25 13:38:24 +0200
commitb19a8f63ad727a3633885d3f2b81edf8181a53b9 (patch)
tree6b5fd70224a125a16010a291e5fd0df834e9436f
parentb08047ba485f86038f33175162943c0a9878ab1a (diff)
matrix-specification split work in progress
-rw-r--r--composer.json3
-rw-r--r--composer.lock108
-rw-r--r--matrix-specification/AccountData.php16
-rw-r--r--matrix-specification/Data/AccountData.php23
-rw-r--r--matrix-specification/Data/Contact.php28
-rw-r--r--matrix-specification/Data/DeviceKeys.php31
-rw-r--r--matrix-specification/Data/DeviceLists.php24
-rw-r--r--matrix-specification/Data/DiscoveryInformation.php30
-rw-r--r--matrix-specification/Data/Filters/EventFilter.php36
-rw-r--r--matrix-specification/Data/Filters/RoomEventFilter.php50
-rw-r--r--matrix-specification/Data/Filters/RoomFilter.php39
-rw-r--r--matrix-specification/Data/HomeServerInformation.php18
-rw-r--r--matrix-specification/Data/IdentityServerInformation.php18
-rw-r--r--matrix-specification/Data/KeyObject.php32
-rw-r--r--matrix-specification/Data/LoginFlow.php (renamed from matrix-specification/Responses/LoginFlow.php)2
-rw-r--r--matrix-specification/Data/Presence.php23
-rw-r--r--matrix-specification/Data/Room/Ephemeral.php21
-rw-r--r--matrix-specification/Data/Room/InviteState.php23
-rw-r--r--matrix-specification/Data/Room/InvitedRoom.php18
-rw-r--r--matrix-specification/Data/Room/JoinedRoom.php37
-rw-r--r--matrix-specification/Data/Room/KnockState.php23
-rw-r--r--matrix-specification/Data/Room/KnockedRoom.php18
-rw-r--r--matrix-specification/Data/Room/LeftRoom.php30
-rw-r--r--matrix-specification/Data/Room/RoomSummary.php25
-rw-r--r--matrix-specification/Data/Room/Rooms.php62
-rw-r--r--matrix-specification/Data/Room/State.php23
-rw-r--r--matrix-specification/Data/Room/ThreadNotificationCounts.php20
-rw-r--r--matrix-specification/Data/Room/Timeline.php27
-rw-r--r--matrix-specification/Data/Room/UnreadNotificationCounts.php20
-rw-r--r--matrix-specification/Data/ToDevice.php23
-rw-r--r--matrix-specification/Data/UserId.php17
-rw-r--r--matrix-specification/Data/UserIdentifier.php (renamed from matrix-specification/UserIdentifier.php)2
-rw-r--r--matrix-specification/Enums/ApiPathVersion.php11
-rw-r--r--matrix-specification/Enums/EventType.php4
-rw-r--r--matrix-specification/Enums/Role.php14
-rw-r--r--matrix-specification/Events/PresenceEvent.php14
-rw-r--r--matrix-specification/Events/StrippedStateEvent.php31
-rw-r--r--matrix-specification/Request.php26
-rw-r--r--matrix-specification/Requests/ClientDirectoryRoomAliasGetRequest.php29
-rw-r--r--matrix-specification/Requests/ClientKeysUploadPostRequest.php29
-rw-r--r--matrix-specification/Requests/ClientLoginGetRequest.php6
-rw-r--r--matrix-specification/Requests/ClientLoginPostRequest.php2
-rw-r--r--matrix-specification/Requests/ClientRefreshPostRequest.php18
-rw-r--r--matrix-specification/Requests/ClientSyncGetRequest.php34
-rw-r--r--matrix-specification/Requests/ClientUserIdFilterPostRequest.php34
-rw-r--r--matrix-specification/Requests/RequiresAuthentication.php2
-rw-r--r--matrix-specification/Responses/ClientAccountWhoamiGetResponse.php22
-rw-r--r--matrix-specification/Responses/ClientDirectoryRoomAliasGetResponse.php23
-rw-r--r--matrix-specification/Responses/ClientKeysUploadPostResponse.php21
-rw-r--r--matrix-specification/Responses/ClientLoginGetResponse.php2
-rw-r--r--matrix-specification/Responses/ClientLoginPostResponse.php30
-rw-r--r--matrix-specification/Responses/ClientRefreshPostResponse.php22
-rw-r--r--matrix-specification/Responses/ClientSyncGetResponse.php35
-rw-r--r--matrix-specification/Responses/ClientUserIdFilterPostResponse.php22
-rw-r--r--matrix-specification/Responses/ClientVersionsGetResponse.php24
-rw-r--r--matrix-specification/Responses/WellKnownMatrixClientGetResponse.php18
-rw-r--r--matrix-specification/Responses/WellKnownMatrixSupportGetResponse.php33
57 files changed, 1284 insertions, 92 deletions
diff --git a/composer.json b/composer.json
index 14c1b94..49923a9 100644
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,8 @@
"psr/log": "^3.0",
"symfony/dotenv": "^7.3",
"symfony/http-foundation": "^7.3",
- "symfony/routing": "^7.3"
+ "symfony/routing": "^7.3",
+ "psr/http-message": "^2.0"
},
"require-dev": {
"guzzlehttp/guzzle": "^7.9",
diff --git a/composer.lock b/composer.lock
index c80924c..398e061 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,9 +4,62 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "b8c9f3de980f8dc287642ead631cec2e",
+ "content-hash": "1e6280a905a847ca703c88bbef0521b2",
"packages": [
{
+ "name": "psr/http-message",
+ "version": "2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/2.0"
+ },
+ "time": "2023-04-04T09:54:51+00:00"
+ },
+ {
"name": "psr/log",
"version": "3.0.2",
"source": {
@@ -1636,59 +1689,6 @@
"time": "2024-04-15T12:06:14+00:00"
},
{
- "name": "psr/http-message",
- "version": "2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
- "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-message/tree/2.0"
- },
- "time": "2023-04-04T09:54:51+00:00"
- },
- {
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
diff --git a/matrix-specification/AccountData.php b/matrix-specification/AccountData.php
deleted file mode 100644
index b29e7fe..0000000
--- a/matrix-specification/AccountData.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-namespace Matrix;
-
-use Matrix\Events\Event;
-
-class AccountData
-{
- /**
- * @param Event[] $events
- */
- public function __construct(
- private array $events
- )
- {}
-}
diff --git a/matrix-specification/Data/AccountData.php b/matrix-specification/Data/AccountData.php
new file mode 100644
index 0000000..fa3e4a3
--- /dev/null
+++ b/matrix-specification/Data/AccountData.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Data;
+
+use Matrix\Events\Event;
+
+class AccountData implements \JsonSerializable
+{
+ /**
+ * @param Event[] $events
+ */
+ public function __construct(
+ private array $events
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Contact.php b/matrix-specification/Data/Contact.php
new file mode 100644
index 0000000..9eeefe5
--- /dev/null
+++ b/matrix-specification/Data/Contact.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Matrix\Data;
+
+use Matrix\Enums\Role;
+
+class Contact implements \JsonSerializable
+{
+ public function __construct(
+ private Role|string $role,
+ private ?string $emailAddress = null,
+ private ?string $matrixId = null,
+ )
+ {
+ if (is_null($emailAddress) && is_null($matrixId)) {
+ throw new \InvalidArgumentException("at least one of emailAddress or matrixId is required");
+ }
+ }
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "email_address" => $this->emailAddress,
+ "matrix_id" => $this->matrixId,
+ "role" => $this->role,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/DeviceKeys.php b/matrix-specification/Data/DeviceKeys.php
new file mode 100644
index 0000000..034263e
--- /dev/null
+++ b/matrix-specification/Data/DeviceKeys.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Matrix\Data;
+
+class DeviceKeys implements \JsonSerializable
+{
+ /**
+ * @param string[] $algorithms
+ * @param array<string, string> $keys
+ * @param array<string, array<string, string>> $signatures
+ */
+ public function __construct(
+ private array $algorithms,
+ private string $deviceId,
+ private array $keys,
+ private array $signatures,
+ private string $userId,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "algorithms" => $this->algorithms,
+ "device_id" => $this->deviceId,
+ "keys" => $this->keys,
+ "signatures" => $this->signatures,
+ "user_id" => $this->userId,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/DeviceLists.php b/matrix-specification/Data/DeviceLists.php
new file mode 100644
index 0000000..33d9459
--- /dev/null
+++ b/matrix-specification/Data/DeviceLists.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Matrix\Data;
+
+class DeviceLists implements \JsonSerializable
+{
+ /**
+ * @param string[] $changed
+ * @param string[] $left
+ */
+ public function __construct(
+ private array $changed = [],
+ private array $left = [],
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "changed" => $this->events,
+ "left" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/DiscoveryInformation.php b/matrix-specification/Data/DiscoveryInformation.php
new file mode 100644
index 0000000..42a3dc2
--- /dev/null
+++ b/matrix-specification/Data/DiscoveryInformation.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Matrix\Data;
+
+class DiscoveryInformation implements \JsonSerializable
+{
+ /**
+ * @param array<string, array<mixed, mixed>> $otherProperties
+ */
+ public function __construct(
+ private HomeServerInformation $homeServerInformation,
+ private IdentityServerInformation $identityServerInformation,
+ private ?array $otherProperties = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter(
+ array_merge(
+ [
+ "m.homeserver" => $this->homeServerInformation,
+ "m.identity_server" => $this->identityServerInformation,
+ ],
+ $this->otherProperties ?? [],
+ ),
+ "is_null"
+ );
+ }
+}
diff --git a/matrix-specification/Data/Filters/EventFilter.php b/matrix-specification/Data/Filters/EventFilter.php
new file mode 100644
index 0000000..98788ad
--- /dev/null
+++ b/matrix-specification/Data/Filters/EventFilter.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Matrix\Data\Filters;
+
+class EventFilter implements \JsonSerializable
+{
+ /**
+ * @param string[] $notSenders
+ * @param string[] $notTypes
+ * @param string[] $senders
+ * @param string[] $types
+ */
+ public function __construct(
+ private ?int $limit = null,
+ private ?array $notSenders = null,
+ private ?array $notTypes = null,
+ private ?array $senders = null,
+ private ?array $types = null,
+ )
+ {
+ if (! is_null($limit) && $limit <= 0) {
+ throw new \InvalidArgumentException("limit must be an integer greater than 0");
+ }
+ }
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "limit" => $this->limit,
+ "not_senders" => $this->notSenders,
+ "not_types" => $this->notTypes,
+ "senders" => $this->senders,
+ "types" => $this->types,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Filters/RoomEventFilter.php b/matrix-specification/Data/Filters/RoomEventFilter.php
new file mode 100644
index 0000000..915c9a0
--- /dev/null
+++ b/matrix-specification/Data/Filters/RoomEventFilter.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Matrix\Data\Filters;
+
+class RoomEventFilter extends EventFilter
+{
+ /**
+ * @param string[] $notRooms
+ * @param string[] $notSenders
+ * @param string[] $notTypes
+ * @param string[] $rooms
+ * @param string[] $senders
+ * @param string[] $types
+ */
+ public function __construct(
+ private ?bool $containsUrl = null,
+ private ?bool $includeRedundantMembers = null,
+ private ?bool $lazyLoadMembers = null,
+ ?int $limit = null,
+ private ?array $notRooms = null,
+ ?array $notSenders = null,
+ ?array $notTypes = null,
+ private ?array $rooms = null,
+ ?array $senders = null,
+ ?array $types = null,
+ private ?bool $unreadThreadNotifications = null,
+ )
+ {
+ parent::__construct($limit, $notSenders, $notTypes, $senders, $types);
+ }
+
+ public function setDefaults(): void
+ {
+ $this->includeRedundantMembers ??= false;
+ $this->lazyLoadMembers ??= false;
+ $this->unreadThreadNotifications ??= false;
+ }
+
+ public function jsonSerialize(): array
+ {
+ return parent::jsonSerialize() + array_filter([
+ "contains_url" => $this->containsUrl,
+ "include_redundant_members" => $this->includeRedundantMembers,
+ "lazy_load_members" => $this->lazyLoadMembers,
+ "not_rooms" => $this->notRooms,
+ "rooms" => $this->rooms,
+ "unread_thread_notifications" => $this->unreadThreadNotifications,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Filters/RoomFilter.php b/matrix-specification/Data/Filters/RoomFilter.php
new file mode 100644
index 0000000..dd110bd
--- /dev/null
+++ b/matrix-specification/Data/Filters/RoomFilter.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Matrix\Data\Filters;
+
+class RoomFilter
+{
+ /**
+ * @param string[] $notRooms
+ * @param string[] $rooms
+ */
+ public function __construct(
+ private ?RoomEventFilter $accountData = null,
+ private ?RoomEventFilter $ephemeral = null,
+ private ?bool $includeLeave = null,
+ private ?array $notRooms = null,
+ private ?array $rooms = null,
+ private ?RoomEventFilter $state = null,
+ private ?RoomEventFilter $timeline = null,
+ )
+ {}
+
+ public function setDefaults(): void
+ {
+ $this->includeLeave ??= false;
+ }
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "account_data" => $this->accountData,
+ "ephemeral" => $this->ephemeral,
+ "include_leave" => $this->includeLeave,
+ "not_rooms" => $this->notRooms,
+ "rooms" => $this->rooms,
+ "state" => $this->state,
+ "timeline" => $this->timeline,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/HomeServerInformation.php b/matrix-specification/Data/HomeServerInformation.php
new file mode 100644
index 0000000..15c9f10
--- /dev/null
+++ b/matrix-specification/Data/HomeServerInformation.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Matrix\Data;
+
+class HomeServerInformation implements \JsonSerializable
+{
+ public function __construct(
+ private string $baseUrl,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "base_url" => $this->baseUrl,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/IdentityServerInformation.php b/matrix-specification/Data/IdentityServerInformation.php
new file mode 100644
index 0000000..bed8323
--- /dev/null
+++ b/matrix-specification/Data/IdentityServerInformation.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Matrix\Data;
+
+class IdentityServerInformation implements \JsonSerializable
+{
+ public function __construct(
+ private string $baseUrl,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "base_url" => $this->baseUrl,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/KeyObject.php b/matrix-specification/Data/KeyObject.php
new file mode 100644
index 0000000..120350c
--- /dev/null
+++ b/matrix-specification/Data/KeyObject.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Matrix\Data;
+
+class KeyObject implements \JsonSerializable
+{
+ /**
+ * @param array<string, array> $signatures
+ */
+ public function __construct(
+ private string $key,
+ private array $signatures,
+ private bool $isFallback = false,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ $keyObject = [
+ "key" => $this->key,
+ "signatures" => $this->signatures,
+ ];
+
+ if ($this->isFallback) {
+ $keyObject += [
+ "fallback" => true,
+ ];
+ }
+
+ return $keyObject;
+ }
+}
diff --git a/matrix-specification/Responses/LoginFlow.php b/matrix-specification/Data/LoginFlow.php
index 6ddb703..6874aad 100644
--- a/matrix-specification/Responses/LoginFlow.php
+++ b/matrix-specification/Data/LoginFlow.php
@@ -1,6 +1,6 @@
<?php
-namespace Matrix\Responses;
+namespace Matrix\Data;
use Matrix\Enums\LoginType;
diff --git a/matrix-specification/Data/Presence.php b/matrix-specification/Data/Presence.php
new file mode 100644
index 0000000..971343f
--- /dev/null
+++ b/matrix-specification/Data/Presence.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Data;
+
+use Matrix\Events\PresenceEvent;
+
+class Presence implements \JsonSerializable
+{
+ /**
+ * @param PresenceEvent[] $events
+ */
+ public function __construct(
+ private array $events
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/Ephemeral.php b/matrix-specification/Data/Room/Ephemeral.php
new file mode 100644
index 0000000..bcaf22f
--- /dev/null
+++ b/matrix-specification/Data/Room/Ephemeral.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class Ephemeral implements \JsonSerializable
+{
+ /**
+ * @param Event[] $events
+ */
+ public function __construct(
+ private array $events,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/InviteState.php b/matrix-specification/Data/Room/InviteState.php
new file mode 100644
index 0000000..ca468ee
--- /dev/null
+++ b/matrix-specification/Data/Room/InviteState.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+use Matrix\Events\StrippedStateEvent;
+
+class InviteState implements \JsonSerializable
+{
+ /**
+ * @param StrippedStateEvent[] $events
+ */
+ public function __construct(
+ private array $events,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/InvitedRoom.php b/matrix-specification/Data/Room/InvitedRoom.php
new file mode 100644
index 0000000..f081861
--- /dev/null
+++ b/matrix-specification/Data/Room/InvitedRoom.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class InvitedRoom implements \JsonSerializable
+{
+ public function __construct(
+ private InviteState $inviteState,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "invite_state" => $this->inviteState,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/JoinedRoom.php b/matrix-specification/Data/Room/JoinedRoom.php
new file mode 100644
index 0000000..89f64b9
--- /dev/null
+++ b/matrix-specification/Data/Room/JoinedRoom.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+use Matrix\Data\AccountData;
+
+class JoinedRoom implements \JsonSerializable
+{
+ /**
+ * @param array<string, ThreadNotificationCounts>
+ */
+ public function __construct(
+ private ?AccountData $accountData = null,
+ private ?Ephemeral $ephemeral = null,
+ private ?State $state = null,
+ private ?State $stateAfter = null,
+ private ?RoomSummary $summary = null,
+ private ?Timeline $timeline = null,
+ private ?UnreadNotificationCounts $unreadNotifications = null,
+ private ?array $unreadThreadNotifications = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "account_data" => $this->inviteState,
+ "ephemeral" => $this->ephemeral,
+ "state" => $this->state,
+ "state_after" => $this->stateAfter,
+ "summary" => $this->summary,
+ "timeline" => $this->timeline,
+ "unread_notifications" => $this->unreadNotifications,
+ "unreadThreadNotifications" => $this->unreadThreadNotifications,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Room/KnockState.php b/matrix-specification/Data/Room/KnockState.php
new file mode 100644
index 0000000..e294da8
--- /dev/null
+++ b/matrix-specification/Data/Room/KnockState.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+use Matrix\Events\StrippedStateEvent;
+
+class KnockState implements \JsonSerializable
+{
+ /**
+ * @param StrippedStateEvent[] $events
+ */
+ public function __construct(
+ private array $events,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/KnockedRoom.php b/matrix-specification/Data/Room/KnockedRoom.php
new file mode 100644
index 0000000..cbea19f
--- /dev/null
+++ b/matrix-specification/Data/Room/KnockedRoom.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class KnockedRoom implements \JsonSerializable
+{
+ public function __construct(
+ private KnockState $knockState,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "knock_state" => $this->knockState,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/LeftRoom.php b/matrix-specification/Data/Room/LeftRoom.php
new file mode 100644
index 0000000..18e97b5
--- /dev/null
+++ b/matrix-specification/Data/Room/LeftRoom.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+use Matrix\Data\AccountData;
+
+/**
+ * @see https://spec.matrix.org/v1.16/client-server-api/#get_matrixclientv3sync_response-200_left-room
+ * TODO: validate against request. add ValidatesAgainstRequest interface? and MatrixRequest base class?
+ */
+class LeftRoom implements \JsonSerializable
+{
+ public function __construct(
+ private ?AccountData $accountData = null,
+ private ?State $state = null,
+ private ?State $stateAfter = null,
+ private ?Timeline $timeline = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "account_data" => $this->inviteState,
+ "state" => $this->state,
+ "state_after" => $this->stateAfter,
+ "timeline" => $this->timeline,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Room/RoomSummary.php b/matrix-specification/Data/Room/RoomSummary.php
new file mode 100644
index 0000000..91d170f
--- /dev/null
+++ b/matrix-specification/Data/Room/RoomSummary.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class RoomSummary implements \JsonSerializable
+{
+ /**
+ * @param string[] $heroes
+ */
+ public function __construct(
+ private ?array $heroes = null,
+ private ?int $invitedMemberCount = null,
+ private ?int $joinedMemberCount = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "m.heroes" => $this->heroes,
+ "m.invited_member_count" => $this->invitedMemberCount,
+ "m.joined_member_count" => $this->joinedMemberCount,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Room/Rooms.php b/matrix-specification/Data/Room/Rooms.php
new file mode 100644
index 0000000..1a84608
--- /dev/null
+++ b/matrix-specification/Data/Room/Rooms.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class Rooms implements \JsonSerializable
+{
+ /**
+ * @param array<string, InvitedRoom> $invite
+ * @param array<string, JoinedRoom> $join
+ * @param array<string, KnockedRoom> $knock
+ * @param array<string, LeftRoom> $leave
+ */
+ public function __construct(
+ private ?array $invite = null,
+ private ?array $join = null,
+ private ?array $knock = null,
+ private ?array $leave = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "invite" => $this->invite ?? new \stdClass(),
+ "join" => $this->join ?? new \stdClass(),
+ "knock" => $this->knock ?? new \stdClass(),
+ "leave" => $this->leave ?? new \stdClass(),
+ ];
+ }
+
+ /**
+ * @return InvitedRoom[]
+ */
+ public function getInvite(): ?array
+ {
+ return $this->invite;
+ }
+
+ /**
+ * @return JoinedRoom[]
+ */
+ public function getJoined(): ?array
+ {
+ return $this->join;
+ }
+
+ /**
+ * @return KnockedRoom[]
+ */
+ public function getKnocked(): ?array
+ {
+ return $this->knock;
+ }
+
+ /**
+ * @return LeftRoom[]
+ */
+ public function getLeft(): ?array
+ {
+ return $this->leave;
+ }
+}
diff --git a/matrix-specification/Data/Room/State.php b/matrix-specification/Data/Room/State.php
new file mode 100644
index 0000000..be9f0ef
--- /dev/null
+++ b/matrix-specification/Data/Room/State.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+use Matrix\Events\ClientEventWithoutRoomId;
+
+class State implements \JsonSerializable
+{
+ /**
+ * @param ClientEventWithoutRoomId[] $events
+ */
+ public function __construct(
+ private array $events,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/Room/ThreadNotificationCounts.php b/matrix-specification/Data/Room/ThreadNotificationCounts.php
new file mode 100644
index 0000000..346aeb3
--- /dev/null
+++ b/matrix-specification/Data/Room/ThreadNotificationCounts.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class ThreadNotificationCounts implements \JsonSerializable
+{
+ public function __construct(
+ private ?int $highlightCount = null,
+ private ?int $notificationCount = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "highlight_count" => $this->highlightCount,
+ "notification_count" => $this->notificationCount,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Room/Timeline.php b/matrix-specification/Data/Room/Timeline.php
new file mode 100644
index 0000000..cc88472
--- /dev/null
+++ b/matrix-specification/Data/Room/Timeline.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+use Matrix\Events\ClientEventWithoutRoomId;
+
+class Timeline implements \JsonSerializable
+{
+ /**
+ * @param ClientEventWithoutRoomId[] $events
+ */
+ public function __construct(
+ private array $events,
+ private ?bool $limited = null,
+ private ?string $previousBatch = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "events" => $this->events,
+ "limited" => $this->limited,
+ "prev_batch" => $this->previousBatch,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/Room/UnreadNotificationCounts.php b/matrix-specification/Data/Room/UnreadNotificationCounts.php
new file mode 100644
index 0000000..d2600e6
--- /dev/null
+++ b/matrix-specification/Data/Room/UnreadNotificationCounts.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Matrix\Data\Room;
+
+class UnreadNotificationCounts implements \JsonSerializable
+{
+ public function __construct(
+ private ?int $highlightCount = null,
+ private ?int $notificationCount = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "highlight_count" => $this->highlightCount,
+ "notification_count" => $this->notificationCount,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Data/ToDevice.php b/matrix-specification/Data/ToDevice.php
new file mode 100644
index 0000000..362ce06
--- /dev/null
+++ b/matrix-specification/Data/ToDevice.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Data;
+
+use Matrix\Events\SenderEvent;
+
+class ToDevice implements \JsonSerializable
+{
+ /**
+ * @param SenderEvent[] $events
+ */
+ public function __construct(
+ private array $events
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "events" => $this->events,
+ ];
+ }
+}
diff --git a/matrix-specification/Data/UserId.php b/matrix-specification/Data/UserId.php
new file mode 100644
index 0000000..01a5e9e
--- /dev/null
+++ b/matrix-specification/Data/UserId.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Matrix\Data;
+
+class UserId
+{
+ public static function validate(): bool
+ {}
+
+ public static function parse(): array
+ {}
+
+ public static function build(string $username, string $serverName): string
+ {
+ return "@$username:$serverName";
+ }
+}
diff --git a/matrix-specification/UserIdentifier.php b/matrix-specification/Data/UserIdentifier.php
index 63f939a..8fcdae0 100644
--- a/matrix-specification/UserIdentifier.php
+++ b/matrix-specification/Data/UserIdentifier.php
@@ -1,6 +1,6 @@
<?php
-namespace Matrix;
+namespace Matrix\Data;
use Matrix\Enums\UserIdentifierType;
diff --git a/matrix-specification/Enums/ApiPathVersion.php b/matrix-specification/Enums/ApiPathVersion.php
new file mode 100644
index 0000000..5664688
--- /dev/null
+++ b/matrix-specification/Enums/ApiPathVersion.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Matrix\Enums;
+
+enum ApiPathVersion: string
+{
+ case R0 = "r0";
+ case V1 = "v1";
+ case V2 = "v2";
+ case V3 = "v3";
+}
diff --git a/matrix-specification/Enums/EventType.php b/matrix-specification/Enums/EventType.php
index bf805b2..da199dd 100644
--- a/matrix-specification/Enums/EventType.php
+++ b/matrix-specification/Enums/EventType.php
@@ -5,11 +5,15 @@ namespace Matrix\Enums;
enum EventType: string implements \JsonSerializable
{
case PRESENCE = "m.presence";
+ case RECEIPT = "m.receipt";
case ROOM_MEMBER = "m.room.member";
case ROOM_MESSAGE = "m.room.message";
case ROOM_NAME = "m.room.name";
+ case TAG = "m.tag";
+ case TYPING = "m.typing";
+
public function jsonSerialize(): string
{
return $this->value;
diff --git a/matrix-specification/Enums/Role.php b/matrix-specification/Enums/Role.php
new file mode 100644
index 0000000..f2abf9b
--- /dev/null
+++ b/matrix-specification/Enums/Role.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Matrix\Enums;
+
+enum Role: string implements \JsonSerializable
+{
+ case ADMIN = "m.role.admin";
+ case SECURITY = "m.role.security";
+
+ public function jsonSerialize(): string
+ {
+ return $this->value;
+ }
+}
diff --git a/matrix-specification/Events/PresenceEvent.php b/matrix-specification/Events/PresenceEvent.php
index f71d4bd..c8c2023 100644
--- a/matrix-specification/Events/PresenceEvent.php
+++ b/matrix-specification/Events/PresenceEvent.php
@@ -10,22 +10,22 @@ class PresenceEvent extends SenderEvent
public function __construct(
string $sender,
PresenceState $presence,
- string $avatarUrl = "",
- bool $currentlyActive = false,
- string $displayName = "",
- int $lastActiveAgo = 0,
- string $statusMessage = "",
+ ?string $avatarUrl = null,
+ ?bool $currentlyActive = null,
+ ?string $displayName = null,
+ ?int $lastActiveAgo = null,
+ ?string $statusMessage = null,
)
{
parent::__construct(
- [
+ array_filter([
"avatar_url" => $avatarUrl,
"currently_active" => $currentlyActive,
"display_name" => $displayName,
"last_active_ago" => $lastActiveAgo,
"presence" => $presence,
"status_msg" => $statusMessage,
- ],
+ ], "is_null"),
$sender,
EventType::PRESENCE
);
diff --git a/matrix-specification/Events/StrippedStateEvent.php b/matrix-specification/Events/StrippedStateEvent.php
new file mode 100644
index 0000000..6e8aea6
--- /dev/null
+++ b/matrix-specification/Events/StrippedStateEvent.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Matrix\Events;
+
+use Matrix\Enums\EventType;
+
+class StrippedStateEvent extends SenderEvent
+{
+ /**
+ * @param array<string, mixed> $content
+ */
+ public function __construct(
+ array $content,
+ string $sender,
+ private string $stateKey,
+ EventType $type,
+ )
+ {
+ parent::__construct($content, $sender, $type);
+ }
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "content" => $this->content,
+ "sender" => $this->sender,
+ "state_key" => $this->stateKey,
+ "type" => $this->type,
+ ];
+ }
+}
diff --git a/matrix-specification/Request.php b/matrix-specification/Request.php
new file mode 100644
index 0000000..c9f315f
--- /dev/null
+++ b/matrix-specification/Request.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Matrix;
+
+use Matrix\Enums\ApiPathVersion;
+use Psr\Http\Message\RequestInterface;
+
+abstract class Request implements RequestInterface, \JsonSerializable
+{
+ abstract public function getUri(string $serverName, ApiPathVersion $version): string;
+
+ /**
+ * @return array<string, string>
+ */
+ abstract public function getQueryParameters(): array;
+
+ /**
+ * @return array<string, string>
+ */
+ abstract public function getBody(): array;
+
+ public function jsonSerialize(): array
+ {
+ return $this->getBody();
+ }
+}
diff --git a/matrix-specification/Requests/ClientDirectoryRoomAliasGetRequest.php b/matrix-specification/Requests/ClientDirectoryRoomAliasGetRequest.php
new file mode 100644
index 0000000..174a5c2
--- /dev/null
+++ b/matrix-specification/Requests/ClientDirectoryRoomAliasGetRequest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Matrix\Requests;
+
+use Matrix\Enums\ApiPathVersion;
+use Matrix\Request;
+
+class ClientDirectoryRoomAliasGetRequest extends Request
+{
+ public function __construct(
+ private string $roomAlias,
+ )
+ {}
+
+ public function getUri(string $serverName, ApiPathVersion $version): string
+ {
+ return "https://$serverName/_matrix/client/{$version}/directory/room/{$this->roomAlias}";
+ }
+
+ public function getQueryParameters(): array
+ {
+ return [];
+ }
+
+ public function getBody(): array
+ {
+ return [];
+ }
+}
diff --git a/matrix-specification/Requests/ClientKeysUploadPostRequest.php b/matrix-specification/Requests/ClientKeysUploadPostRequest.php
new file mode 100644
index 0000000..40d9eae
--- /dev/null
+++ b/matrix-specification/Requests/ClientKeysUploadPostRequest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Matrix\Requests;
+
+use Matrix\Data\DeviceKeys;
+use Matrix\Data\KeyObject;
+
+class ClientKeysUploadPostRequest implements RateLimited, RequiresAuthentication, \JsonSerializable
+{
+ /**
+ * @param array<string, string|KeyObject> $fallbackKeys
+ * @param array<string, string|KeyObject> $oneTimeKeys
+ */
+ public function __construct(
+ private ?DeviceKeys $deviceKeys = null,
+ private ?array $fallbackKeys = null,
+ private ?array $oneTimeKeys = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "device_keys" => $this->deviceKeys,
+ "fallback_keys" => $this->fallbackKeys,
+ "one_time_keys" => $this->oneTimeKeys,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Requests/ClientLoginGetRequest.php b/matrix-specification/Requests/ClientLoginGetRequest.php
deleted file mode 100644
index 73cc24c..0000000
--- a/matrix-specification/Requests/ClientLoginGetRequest.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-namespace Matrix\Requests;
-
-class ClientLoginGetRequest implements RateLimited
-{}
diff --git a/matrix-specification/Requests/ClientLoginPostRequest.php b/matrix-specification/Requests/ClientLoginPostRequest.php
index d17c558..44497e7 100644
--- a/matrix-specification/Requests/ClientLoginPostRequest.php
+++ b/matrix-specification/Requests/ClientLoginPostRequest.php
@@ -2,8 +2,8 @@
namespace Matrix\Requests;
+use Matrix\Data\UserIdentifier;
use Matrix\Enums\LoginType;
-use Matrix\UserIdentifier;
class ClientLoginPostRequest implements RateLimited, \JsonSerializable
{
diff --git a/matrix-specification/Requests/ClientRefreshPostRequest.php b/matrix-specification/Requests/ClientRefreshPostRequest.php
new file mode 100644
index 0000000..733ca75
--- /dev/null
+++ b/matrix-specification/Requests/ClientRefreshPostRequest.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Matrix\Requests;
+
+class ClientRefreshPostRequest implements RateLimited, \JsonSerializable
+{
+ public function __construct(
+ private string $refreshToken,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "refresh_token" => $this->refreshToken,
+ ];
+ }
+}
diff --git a/matrix-specification/Requests/ClientSyncGetRequest.php b/matrix-specification/Requests/ClientSyncGetRequest.php
index 2921fcf..2ab7d9e 100644
--- a/matrix-specification/Requests/ClientSyncGetRequest.php
+++ b/matrix-specification/Requests/ClientSyncGetRequest.php
@@ -2,7 +2,37 @@
namespace Matrix\Requests;
-class ClientSyncGetRequest
+use Matrix\Enums\PresenceState;
+
+class ClientSyncGetRequest implements RequiresAuthentication
{
- # TODO
+ public function __construct(
+ private ?string $filter = null,
+ private ?bool $fullState = null,
+ private ?PresenceState $setPresence = null,
+ private ?string $since = null,
+ private ?int $timeout = null,
+ private ?bool $useStateAfter = null,
+ )
+ {}
+
+ public function setDefaults(): void
+ {
+ $this->fullState ??= false;
+ $this->setPresence ??= PresenceState::ONLINE;
+ $this->timeout ??= 0;
+ $this->useStateAfter ??= false;
+ }
+
+ public function getQueryParameters(): array
+ {
+ return array_filter([
+ "filter" => $this->filter,
+ "full_state" => $this->fullState,
+ "set_presence" => $this->setPresence,
+ "since" => $this->since,
+ "timeout" => $this->timeout,
+ "use_state_after" => $this->useStateAfter,
+ ], "is_null");
+ }
}
diff --git a/matrix-specification/Requests/ClientUserIdFilterPostRequest.php b/matrix-specification/Requests/ClientUserIdFilterPostRequest.php
new file mode 100644
index 0000000..2edc4c5
--- /dev/null
+++ b/matrix-specification/Requests/ClientUserIdFilterPostRequest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Matrix\Requests;
+
+use Matrix\Data\Filters\EventFilter;
+use Matrix\Data\Filters\RoomFilter;
+
+ # ClientUserUserIdFilterPostRequest?
+class ClientUserIdFilterPostRequest implements RequiresAuthentication, \JsonSerializable
+{
+ /**
+ * @param string[] $eventFields
+ */
+ public function __construct(
+ private string $userId,
+ private ?EventFilter $accountData = null,
+ private ?array $eventFields = null,
+ private ?string $eventFormat = null,
+ private ?EventFilter $presence = null,
+ private ?RoomFilter $room = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "account_data" => $this->accountData,
+ "event_fields" => $this->eventFields,
+ "event_format" => $this->eventFormat,
+ "presence" => $this->presence,
+ "room" => $this->room,
+ ];
+ }
+}
diff --git a/matrix-specification/Requests/RequiresAuthentication.php b/matrix-specification/Requests/RequiresAuthentication.php
index c494f13..a762405 100644
--- a/matrix-specification/Requests/RequiresAuthentication.php
+++ b/matrix-specification/Requests/RequiresAuthentication.php
@@ -4,5 +4,5 @@ namespace Matrix\Requests;
interface RequiresAuthentication
{
- public function authenticateUser(): bool;
+ //public function authenticateUser(): bool;
}
diff --git a/matrix-specification/Responses/ClientAccountWhoamiGetResponse.php b/matrix-specification/Responses/ClientAccountWhoamiGetResponse.php
new file mode 100644
index 0000000..48fbbde
--- /dev/null
+++ b/matrix-specification/Responses/ClientAccountWhoamiGetResponse.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Matrix\Responses;
+
+class ClientAccountWhoamiGetResponse implements \JsonSerializable
+{
+ public function __construct(
+ private string $userId,
+ private ?string $deviceId = null,
+ private ?bool $isGuest = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "device_id" => $this->deviceId,
+ "is_guest" => $this->isGuest,
+ "user_id" => $this->userId,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Responses/ClientDirectoryRoomAliasGetResponse.php b/matrix-specification/Responses/ClientDirectoryRoomAliasGetResponse.php
new file mode 100644
index 0000000..a2a6346
--- /dev/null
+++ b/matrix-specification/Responses/ClientDirectoryRoomAliasGetResponse.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Matrix\Responses;
+
+class ClientDirectoryRoomAliasGetResponse implements \JsonSerializable
+{
+ /**
+ * @param string[] $servers
+ */
+ public function __construct(
+ private string $roomId,
+ private array $servers,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "room_id" => $this->roomId,
+ "servers" => $this->servers,
+ ];
+ }
+}
diff --git a/matrix-specification/Responses/ClientKeysUploadPostResponse.php b/matrix-specification/Responses/ClientKeysUploadPostResponse.php
new file mode 100644
index 0000000..ff81734
--- /dev/null
+++ b/matrix-specification/Responses/ClientKeysUploadPostResponse.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Matrix\Responses;
+
+class ClientKeysUploadPostResponse implements \JsonSerializable
+{
+ /**
+ * @param array<string, integer> $oneTimeKeyCounts
+ */
+ public function __construct(
+ private array $oneTimeKeyCounts,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "one_time_keys_counts" => $this->oneTimeKeyCounts,
+ ];
+ }
+}
diff --git a/matrix-specification/Responses/ClientLoginGetResponse.php b/matrix-specification/Responses/ClientLoginGetResponse.php
index e0ccc26..b3b65c3 100644
--- a/matrix-specification/Responses/ClientLoginGetResponse.php
+++ b/matrix-specification/Responses/ClientLoginGetResponse.php
@@ -2,6 +2,8 @@
namespace Matrix\Responses;
+use Matrix\Data\LoginFlow;
+
class ClientLoginGetResponse implements \JsonSerializable
{
/**
diff --git a/matrix-specification/Responses/ClientLoginPostResponse.php b/matrix-specification/Responses/ClientLoginPostResponse.php
new file mode 100644
index 0000000..4bb893d
--- /dev/null
+++ b/matrix-specification/Responses/ClientLoginPostResponse.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Matrix\Responses;
+
+use Matrix\Data\DiscoveryInformation;
+
+class ClientLoginPostResponse implements \JsonSerializable
+{
+ public function __construct(
+ private string $accessToken,
+ private string $deviceId,
+ private string $userId,
+ private ?int $expiresInMilliseconds = null,
+ private ?string $refreshToken = null,
+ private ?DiscoveryInformation $wellKnown = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "access_token" => $this->accessToken,
+ "device_id" => $this->deviceId,
+ "expires_in_ms" => $this->expiresInMilliseconds,
+ "refresh_token" => $this->refreshToken,
+ "user_id" => $this->userId,
+ "well_known" => $this->wellKnown,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Responses/ClientRefreshPostResponse.php b/matrix-specification/Responses/ClientRefreshPostResponse.php
new file mode 100644
index 0000000..b1e1154
--- /dev/null
+++ b/matrix-specification/Responses/ClientRefreshPostResponse.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Matrix\Responses;
+
+class ClientRefreshPostResponse implements \JsonSerializable
+{
+ public function __construct(
+ private string $accessToken,
+ private ?int $expiresInMilliseconds = null,
+ private ?string $refreshToken = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "access_token" => $this->accessToken,
+ "expires_in_ms" => $this->expiresInMilliseconds,
+ "refresh_token" => $this->refreshToken,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Responses/ClientSyncGetResponse.php b/matrix-specification/Responses/ClientSyncGetResponse.php
index 27464c1..ccdc5e6 100644
--- a/matrix-specification/Responses/ClientSyncGetResponse.php
+++ b/matrix-specification/Responses/ClientSyncGetResponse.php
@@ -2,7 +2,38 @@
namespace Matrix\Responses;
-class ClientSyncGetResponse
+use Matrix\Data\AccountData;
+use Matrix\Data\DeviceLists;
+use Matrix\Data\Presence;
+use Matrix\Data\Room\Rooms;
+use Matrix\Data\ToDevice;
+
+class ClientSyncGetResponse implements \JsonSerializable
{
- # TODO
+ /**
+ * @param array<string, int> $deviceOneTimeKeysCount
+ */
+ public function __construct(
+ private string $nextBatch,
+ private ?AccountData $accountData = null,
+ private ?DeviceLists $deviceLists = null,
+ private ?array $deviceOneTimeKeysCount = null,
+ private ?Presence $presence = null,
+ private ?Rooms $rooms = null,
+ private ?ToDevice $toDevice = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "account_data" => $this->accountData,
+ "device_lists" => $this->deviceLists,
+ "device_one_time_keys_count" => $this->deviceOneTimeKeysCount,
+ "next_batch" => $this->nextBatch,
+ "presence" => $this->presence,
+ "rooms" => $this->rooms,
+ "to_device" => $this->toDevice,
+ ], "is_null");
+ }
}
diff --git a/matrix-specification/Responses/ClientUserIdFilterPostResponse.php b/matrix-specification/Responses/ClientUserIdFilterPostResponse.php
new file mode 100644
index 0000000..ed7ba37
--- /dev/null
+++ b/matrix-specification/Responses/ClientUserIdFilterPostResponse.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Matrix\Responses;
+
+class ClientUserIdFilterPostResponse implements \JsonSerializable
+{
+ public function __construct(
+ private string $filterId,
+ )
+ {
+ if (str_starts_with($filterId, "{")) {
+ throw new \InvalidArgumentException("filterId cannot start with a { as this character is used to determine if the filter provided is inline JSON or a previously declared filter by homeservers on some APIs");
+ }
+ }
+
+ public function jsonSerialize(): array
+ {
+ return [
+ "filter_id" => $this->filterId,
+ ];
+ }
+}
diff --git a/matrix-specification/Responses/ClientVersionsGetResponse.php b/matrix-specification/Responses/ClientVersionsGetResponse.php
new file mode 100644
index 0000000..9ec701d
--- /dev/null
+++ b/matrix-specification/Responses/ClientVersionsGetResponse.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Matrix\Responses;
+
+class ClientVersionsGetResponse implements \JsonSerializable
+{
+ /**
+ * @param string[] $versions
+ * @param array<string, bool> $unstableFeatures
+ */
+ public function __construct(
+ private array $versions,
+ private ?array $unstableFeatures = null,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "unstable_features" => $this->unstableFeatures,
+ "versions" => $this->versions,
+ ], "is_null");
+ }
+}
diff --git a/matrix-specification/Responses/WellKnownMatrixClientGetResponse.php b/matrix-specification/Responses/WellKnownMatrixClientGetResponse.php
new file mode 100644
index 0000000..769268f
--- /dev/null
+++ b/matrix-specification/Responses/WellKnownMatrixClientGetResponse.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Matrix\Responses;
+
+use Matrix\Data\DiscoveryInformation;
+
+class WellKnownMatrixClientGetResponse implements \JsonSerializable
+{
+ public function __construct(
+ private DiscoveryInformation $discoveryInformation,
+ )
+ {}
+
+ public function jsonSerialize(): array
+ {
+ return $this->discoveryInformation;
+ }
+}
diff --git a/matrix-specification/Responses/WellKnownMatrixSupportGetResponse.php b/matrix-specification/Responses/WellKnownMatrixSupportGetResponse.php
new file mode 100644
index 0000000..f38e2b0
--- /dev/null
+++ b/matrix-specification/Responses/WellKnownMatrixSupportGetResponse.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Matrix\Responses;
+
+use Matrix\Data\Contact;
+
+class WellKnownMatrixSupportGetResponse implements \JsonSerializable
+{
+ /**
+ * @param Contact[] $contacts
+ */
+ public function __construct(
+ private ?array $contacts = null,
+ private ?string $supportPage = null,
+ )
+ {
+ if (is_null($contacts) && is_null($supportPage)) {
+ throw new \InvalidArgumentException("at least one of contacts or supportPage is required");
+ }
+
+ if (! is_null($contacts) && is_null($supportPage) && empty($contacts)) {
+ throw new \InvalidArgumentException("if only contacts is set, it must contain at least one item");
+ }
+ }
+
+ public function jsonSerialize(): array
+ {
+ return array_filter([
+ "contacts" => $this->contacts,
+ "support_page" => $this->supportPage,
+ ], "is_null");
+ }
+}