From c0c512aa7de8ca5a4f98b78774d6ee76c896999d Mon Sep 17 00:00:00 2001 From: Steven Ngesera Date: Tue, 22 Oct 2024 18:20:05 +0300 Subject: [PATCH 1/2] [FIX] Fixed jmap quota display --- modules/imap/handler_modules.php | 34 ++++++++++++++++++++++++-------- modules/imap/hm-jmap.php | 27 +++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index d418cb502d..b5a54119c6 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -750,14 +750,32 @@ public function process() { $this->out('can_share_folders', stripos($imap->get_capability(), 'ACL') !== false); if (imap_authed($imap)) { $quota_root = $imap->get_quota_root($folder ? $folder : 'INBOX'); - if ($quota_root && isset($quota_root[0]['name'])) { - $quota = $imap->get_quota($quota_root[0]['name']); - if ($quota) { - $current = floatval($quota[0]['current']); - $max = floatval($quota[0]['max']); - if ($max > 0) { - $this->out('quota', ceil(($current / $max) * 100)); - $this->out('quota_max', $max / 1024); + if($imap instanceof Hm_JMAP) { + if (!empty($quota_root["methodResponses"][0][1]["list"])) { + $quota = $quota_root["methodResponses"][0][1]["list"][0]; + + if ($quota) { + $used = floatval($quota['used']); + $max = floatval($quota['hardLimit']); + if ($max > 0) { + $quotaPercentage = ceil(($used / $max) * 100); + $quotaMaxInMB = $max / (1024 * 1024); + + $this->out('quota', $quotaPercentage); + $this->out('quota_max', $quotaMaxInMB); + } + } + } + }else { + if ($quota_root && isset($quota_root[0]['name'])) { + $quota = $imap->get_quota($quota_root[0]['name']); + if ($quota) { + $current = floatval($quota[0]['current']); + $max = floatval($quota[0]['max']); + if ($max > 0) { + $this->out('quota', ceil(($current / $max) * 100)); + $this->out('quota_max', $max / 1024); + } } } } diff --git a/modules/imap/hm-jmap.php b/modules/imap/hm-jmap.php index 46b28040e9..4c6121431f 100644 --- a/modules/imap/hm-jmap.php +++ b/modules/imap/hm-jmap.php @@ -69,7 +69,8 @@ class Hm_JMAP { ); private $default_caps = array( 'urn:ietf:params:jmap:core', - 'urn:ietf:params:jmap:mail' + 'urn:ietf:params:jmap:mail', + 'urn:ietf:params:jmap:quota' ); public $selected_mailbox; @@ -376,6 +377,28 @@ public function get_folder_list_by_level($level=false) { return $this->parse_folder_list_by_level($level); } + public function get_quota_root($mailbox) { + if (!is_array($this->session)) { + throw new Exception("Not authenticated. Please authenticate first."); + } + $methods = [ + [ + "Quota/get", + [ + "accountId"=> (string)$this->account_id, + "name" => $this->session['username'], + "scope" => "folder", + "folder" => $mailbox + ], + "0" + ] + ]; + $response = $this->send_command($this->session['apiUrl'], $methods, 'POST'); + return $response; + } + public function get_capability() { + //TODO: Implement + } /** * Return cached data * @return array @@ -452,7 +475,7 @@ public function get_folder_list() { $methods = array(array( 'Mailbox/get', array( - 'accountId' => $this->account_id, + 'accountId' => (string)$this->account_id, 'ids' => NULL ), 'fl' From f48362c6d7c8c47d0a3264ea29f336cb74df4b3e Mon Sep 17 00:00:00 2001 From: Steven Ngesera Date: Sat, 23 Nov 2024 08:30:46 +0300 Subject: [PATCH 2/2] Unify the interface/data scheme for both IMAP and JSON --- modules/imap/handler_modules.php | 34 ++++----------- modules/imap/hm-jmap.php | 73 +++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 27 deletions(-) diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index b5a54119c6..d418cb502d 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -750,32 +750,14 @@ public function process() { $this->out('can_share_folders', stripos($imap->get_capability(), 'ACL') !== false); if (imap_authed($imap)) { $quota_root = $imap->get_quota_root($folder ? $folder : 'INBOX'); - if($imap instanceof Hm_JMAP) { - if (!empty($quota_root["methodResponses"][0][1]["list"])) { - $quota = $quota_root["methodResponses"][0][1]["list"][0]; - - if ($quota) { - $used = floatval($quota['used']); - $max = floatval($quota['hardLimit']); - if ($max > 0) { - $quotaPercentage = ceil(($used / $max) * 100); - $quotaMaxInMB = $max / (1024 * 1024); - - $this->out('quota', $quotaPercentage); - $this->out('quota_max', $quotaMaxInMB); - } - } - } - }else { - if ($quota_root && isset($quota_root[0]['name'])) { - $quota = $imap->get_quota($quota_root[0]['name']); - if ($quota) { - $current = floatval($quota[0]['current']); - $max = floatval($quota[0]['max']); - if ($max > 0) { - $this->out('quota', ceil(($current / $max) * 100)); - $this->out('quota_max', $max / 1024); - } + if ($quota_root && isset($quota_root[0]['name'])) { + $quota = $imap->get_quota($quota_root[0]['name']); + if ($quota) { + $current = floatval($quota[0]['current']); + $max = floatval($quota[0]['max']); + if ($max > 0) { + $this->out('quota', ceil(($current / $max) * 100)); + $this->out('quota_max', $max / 1024); } } } diff --git a/modules/imap/hm-jmap.php b/modules/imap/hm-jmap.php index 4c6121431f..776bb7a438 100644 --- a/modules/imap/hm-jmap.php +++ b/modules/imap/hm-jmap.php @@ -377,16 +377,73 @@ public function get_folder_list_by_level($level=false) { return $this->parse_folder_list_by_level($level); } + /** + * Use the JMAP Quota/get method to fetch quota information for a specific quota root. + * + * This method sends a request to the JMAP server to retrieve quota information + * for a specified quota root (e.g., a specific folder like INBOX or Sent). + * The response is parsed to extract details about the quota, including the used space and hard limit. + * + * @param array $quota_root from get_quota_root + * @return array list of quota details + */ + public function get_quota($quota_root='') { + if (!is_array($this->session)) { + throw new Exception("Not authenticated. Please authenticate first."); + } + $quotas = array(); + $methods = [ + [ + "Quota/get", + [ + "accountId"=> (string)$this->account_id, + "name" => $this->session['username'], + "ids" => [$quota_root] + ], + "0" + ] + ]; + $response = $this->send_command($this->session['apiUrl'], $methods, 'POST'); + if (!empty($response["methodResponses"][0][1]["list"])) { + $quota = $response["methodResponses"][0][1]["list"][0]; + if (isset($quota['used']) && isset($quota['hardLimit'])) { + $quotas[] = [ + 'name' => $quota['id'], + 'max' => floatval($quota['hardLimit']), + 'current' => floatval($quota['used']), + ]; + } + } + + + foreach($quota_root as $key => $value) { + $quotas[$key] = $value; + } + return $quotas; + } + + /** + * Use the JMAP Quota/get method to fetch quota root information for all available quotas. + * + * This method sends a request to the JMAP server to retrieve quota information + * for all quotas associated with the account. The response is parsed to extract details about each quota, + * including the used space and hard limit. + * + * @param string $mailbox The mailbox identifier for which the quota information is being fetched. + * @return array An array of quota details + */ public function get_quota_root($mailbox) { if (!is_array($this->session)) { throw new Exception("Not authenticated. Please authenticate first."); } + $quotas = array(); $methods = [ [ "Quota/get", [ "accountId"=> (string)$this->account_id, "name" => $this->session['username'], + "ids" => null, "scope" => "folder", "folder" => $mailbox ], @@ -394,8 +451,22 @@ public function get_quota_root($mailbox) { ] ]; $response = $this->send_command($this->session['apiUrl'], $methods, 'POST'); - return $response; + if (!empty($response["methodResponses"][0][1]["list"])) { + $quotasRes = $response["methodResponses"][0][1]["list"]; + foreach($quotasRes as $quota) { + if (isset($quota['used']) && isset($quota['hardLimit'])) { + $quotas[] = [ + 'name' => $quota['id'], + 'max' => floatval($quota['hardLimit']), + 'current' => floatval($quota['used']), + ]; + } + } + } + + return $quotas; } + public function get_capability() { //TODO: Implement }