From 01c6cc86cebc9df2005ce22c0cd93b6ebf73e30f Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 13 Apr 2026 20:28:23 +0530 Subject: [PATCH] Presence api response models --- app/config/collections/projects.php | 2 +- src/Appwrite/Utopia/Response.php | 2 + .../Utopia/Response/Model/Presence.php | 120 ++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/Appwrite/Utopia/Response/Model/Presence.php diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 8379f5bb8e..25ffacbcf2 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -2840,7 +2840,7 @@ return [ 'filters' => ['json'], ], ], - // TODO: shall we create the perms_md5 now only for the upsertion based on perms_md5 or later via patch script? + // TODO: shall we create the perms_md5 now only for the upsertion based on perms_md5 or later via patch script? // permissions must be sorted before md5 conversion to have deterministic hashes 'indexes' => [ [ diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index c2fc520da3..12ef3dce2a 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -64,6 +64,8 @@ class Response extends SwooleResponse public const MODEL_COLUMN_INDEX_LIST = 'columnIndexList'; public const MODEL_DOCUMENT = 'document'; public const MODEL_DOCUMENT_LIST = 'documentList'; + public const MODEL_PRESENCE = 'presence'; + public const MODEL_PRESENCE_LIST = 'presenceList'; public const MODEL_ROW = 'row'; public const MODEL_ROW_LIST = 'rowList'; diff --git a/src/Appwrite/Utopia/Response/Model/Presence.php b/src/Appwrite/Utopia/Response/Model/Presence.php new file mode 100644 index 0000000000..d23328bebb --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/Presence.php @@ -0,0 +1,120 @@ +addRule('$id', [ + 'type' => self::TYPE_STRING, + 'description' => 'Presence ID.', + 'default' => '', + 'example' => '5e5ea5c16897e', + ]) + ->addRule('$sequence', [ + 'type' => self::TYPE_ID, + 'description' => 'Presence sequence ID.', + 'default' => '', + 'example' => '1', + 'readOnly' => true, + ]) + ->addRule('$createdAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Presence creation date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('$updatedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Presence update date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('$permissions', [ + 'type' => self::TYPE_STRING, + 'description' => 'Presence permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', + 'default' => '', + 'example' => ['read("any")'], + 'array' => true, + ]) + ->addRule('userInternalId', [ + 'type' => self::TYPE_STRING, + 'description' => 'User internal ID.', + 'default' => '', + 'example' => '1', + ]) + ->addRule('userId', [ + 'type' => self::TYPE_STRING, + 'description' => 'User ID.', + 'default' => '', + 'example' => '674af8f3e12a5f9ac0be', + ]) + ->addRule('status', [ + 'type' => self::TYPE_STRING, + 'description' => 'Presence status.', + 'required' => false, + 'default' => null, + 'example' => 'online', + ]) + ->addRule('source', [ + 'type' => self::TYPE_STRING, + 'description' => 'Presence source.', + 'default' => '', + 'example' => 'HTTP', + ]) + ->addRule('expiry', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Presence expiry date in ISO 8601 format.', + 'required' => false, + 'default' => null, + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + // not adding hostname here in the response model + ->addRule('metadata', [ + 'type' => self::TYPE_STRING, + 'description' => 'Presence metadata.', + 'required' => false, + 'default' => [], + 'example' => ['device' => 'web'], + ]); + } + + public function filter(DatabaseDocument $document): DatabaseDocument + { + $document->removeAttribute('$collection'); + $document->removeAttribute('$tenant'); + + if (!$document->isEmpty()) { + $document->setAttribute('$sequence', (string) $document->getAttribute('$sequence', '')); + } + + foreach ($document->getAttributes() as $attribute) { + if (\is_array($attribute)) { + foreach ($attribute as $subAttribute) { + if ($subAttribute instanceof DatabaseDocument) { + $this->filter($subAttribute); + } + } + } elseif ($attribute instanceof DatabaseDocument) { + $this->filter($attribute); + } + } + + return $document; + } +}