From 58d28297a3fe117485b32b811811237ff0a932b2 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 29 Mar 2024 16:18:20 +0100 Subject: [PATCH] Code improvements, PHPDoc fixes --- phpstan-baseline.neon | 260 ------------------ plugins/markasjunk/drivers/cmd_learn.php | 1 + program/actions/mail/headers.php | 5 +- program/actions/settings/folder_edit.php | 2 +- program/lib/Roundcube/rcube_image.php | 14 +- program/lib/Roundcube/rcube_imap.php | 197 ++++++------- program/lib/Roundcube/rcube_imap_cache.php | 26 +- program/lib/Roundcube/rcube_imap_search.php | 12 +- .../lib/Roundcube/rcube_message_header.php | 60 ++-- program/lib/Roundcube/rcube_storage.php | 149 +++++----- tests/Browser/bootstrap.php | 1 + 11 files changed, 243 insertions(+), 484 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index afa5db9438c..ec53bf567c4 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -220,11 +220,6 @@ parameters: count: 1 path: program/actions/mail/group_expand.php - - - message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" - count: 1 - path: program/actions/mail/headers.php - - message: "#^Foreach overwrites \\$m with its value variable\\.$#" count: 1 @@ -235,16 +230,6 @@ parameters: count: 1 path: program/actions/mail/index.php - - - message: "#^Property rcube_message_header\\:\\:\\$parent_uid \\(int\\) does not accept string\\.$#" - count: 1 - path: program/actions/mail/index.php - - - - message: "#^Property rcube_message_header\\:\\:\\$uid \\(int\\) does not accept string\\.$#" - count: 1 - path: program/actions/mail/index.php - - message: "#^Right side of && is always true\\.$#" count: 1 @@ -290,26 +275,6 @@ parameters: count: 1 path: program/actions/mail/show.php - - - message: "#^Strict comparison using \\!\\=\\= between int and false will always evaluate to true\\.$#" - count: 1 - path: program/actions/settings/folder_edit.php - - - - message: "#^Strict comparison using \\!\\=\\= between string and null will always evaluate to true\\.$#" - count: 1 - path: program/actions/settings/folder_edit.php - - - - message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" - count: 1 - path: program/actions/settings/folder_edit.php - - - - message: "#^Strict comparison using \\!\\=\\= between int and false will always evaluate to true\\.$#" - count: 1 - path: program/actions/settings/folder_size.php - - message: "#^For loop initial assignment overwrites variable \\$i\\.$#" count: 1 @@ -840,226 +805,6 @@ parameters: count: 1 path: program/lib/Roundcube/rcube_html2text.php - - - message: "#^Implicit array creation is not allowed \\- variable \\$p does not exist\\.$#" - count: 2 - path: program/lib/Roundcube/rcube_image.php - - - - message: "#^Call to function is_array\\(\\) with array will always evaluate to true\\.$#" - count: 3 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Call to function is_array\\(\\) with string\\|null will always evaluate to false\\.$#" - count: 2 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Call to function is_object\\(\\) with rcube_result_index\\|rcube_result_multifolder\\|rcube_result_thread will always evaluate to true\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Call to function is_string\\(\\) with string will always evaluate to true\\.$#" - count: 13 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^For loop initial assignment overwrites variable \\$count\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Foreach overwrites \\$folder with its key variable\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Foreach overwrites \\$ns with its value variable\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Implicit array creation is not allowed \\- variable \\$mime_part_headers might not exist\\.$#" - count: 3 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Left side of && is always true\\.$#" - count: 5 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:folder_data\\(\\) should return array but returns null\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:folder_size\\(\\) should return int but returns false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:get_acl\\(\\) should return array but returns null\\.$#" - count: 2 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:get_cache\\(\\) should return mixed but return statement is missing\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:get_fetch_headers\\(\\) should return string but returns array\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:id2uid\\(\\) should return int but returns null\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:list_rights\\(\\) should return array but returns null\\.$#" - count: 2 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Method rcube_imap\\:\\:my_rights\\(\\) should return array but returns null\\.$#" - count: 2 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^PHPDoc type rcube_imap_generic of property rcube_imap\\:\\:\\$conn is not the same as PHPDoc type mixed of overridden property rcube_storage\\:\\:\\$conn\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^PHPDoc type rcube_result_index\\|rcube_result_multifolder\\|rcube_result_thread of property rcube_imap\\:\\:\\$search_set is not the same as PHPDoc type mixed of overridden property rcube_storage\\:\\:\\$search_set\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Parameter \\#1 \\$set \\(array\\) of method rcube_imap\\:\\:set_search_set\\(\\) should be contravariant with parameter \\$set \\(mixed\\) of method rcube_storage\\:\\:set_search_set\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Property rcube_imap\\:\\:\\$search_set \\(rcube_result_index\\|rcube_result_multifolder\\|rcube_result_thread\\) in empty\\(\\) is not falsy\\.$#" - count: 3 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Property rcube_message_header\\:\\:\\$bodystructure \\(string\\) does not accept array\\|bool\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(array\\|null\\) of method rcube_imap\\:\\:get_metadata\\(\\) should be covariant with return type \\(array\\) of method rcube_storage\\:\\:get_metadata\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(array\\|null\\) of method rcube_imap\\:\\:get_search_set\\(\\) should be covariant with return type \\(array\\) of method rcube_storage\\:\\:get_search_set\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(rcube_message_header\\|false\\) of method rcube_imap\\:\\:get_message_headers\\(\\) should be covariant with return type \\(rcube_message_header\\) of method rcube_storage\\:\\:get_message_headers\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(rcube_message_header\\|null\\) of method rcube_imap\\:\\:get_message\\(\\) should be covariant with return type \\(rcube_message_header\\) of method rcube_storage\\:\\:get_message\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(rcube_result_index\\|rcube_result_multifolder\\) of method rcube_imap\\:\\:search_once\\(\\) should be covariant with return type \\(rcube_result_index\\) of method rcube_storage\\:\\:search_once\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(string\\|null\\) of method rcube_imap\\:\\:get_raw_body\\(\\) should be covariant with return type \\(string\\) of method rcube_storage\\:\\:get_raw_body\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(string\\|null\\) of method rcube_imap\\:\\:get_raw_headers\\(\\) should be covariant with return type \\(string\\) of method rcube_storage\\:\\:get_raw_headers\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Return type \\(string\\|null\\) of method rcube_imap\\:\\:get_vendor\\(\\) should be covariant with return type \\(string\\) of method rcube_storage\\:\\:get_vendor\\(\\)$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Right side of && is always true\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Strict comparison using \\!\\=\\= between string and null will always evaluate to true\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap.php - - - - message: "#^Call to function is_object\\(\\) with rcube_message_header will always evaluate to true\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^Comparison operation \"\\>\" between int\\<1, max\\> and 0 is always true\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^If condition is always false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^Method rcube_imap_cache\\:\\:get_index\\(\\) should return array but returns null\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^Property rcube_imap_cache\\:\\:\\$icache \\(array\\) does not accept null\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^Property rcube_message_header\\:\\:\\$body \\(string\\) does not accept null\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^Right side of && is always true\\.$#" - count: 3 - path: program/lib/Roundcube/rcube_imap_cache.php - - - - message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_search.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_imap_search.php - - message: "#^Call to function is_array\\(\\) with array will always evaluate to true\\.$#" count: 1 @@ -1175,11 +920,6 @@ parameters: count: 1 path: program/lib/Roundcube/rcube_message.php - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: program/lib/Roundcube/rcube_message.php - - message: "#^Strict comparison using \\!\\=\\= between string and null will always evaluate to true\\.$#" count: 2 diff --git a/plugins/markasjunk/drivers/cmd_learn.php b/plugins/markasjunk/drivers/cmd_learn.php index 4dafb2f22fd..28d9655390e 100644 --- a/plugins/markasjunk/drivers/cmd_learn.php +++ b/plugins/markasjunk/drivers/cmd_learn.php @@ -74,6 +74,7 @@ private function _do_salearn($uids, $spam, $src_mbox) } if (!empty($header_names)) { + /** @var rcube_imap $storage */ $storage = $rcube->get_storage(); $storage->check_connection(); $headers = $storage->conn->fetchHeader($src_mbox, $uid, true, false, $header_names); diff --git a/program/actions/mail/headers.php b/program/actions/mail/headers.php index 3e73d413cb1..a908192dbc6 100644 --- a/program/actions/mail/headers.php +++ b/program/actions/mail/headers.php @@ -39,7 +39,10 @@ public function run($args = []) if ($pos = strpos($uid, '.')) { $message = new rcube_message($uid); $source = $message->get_part_body(substr($uid, $pos + 1)); - $source = substr($source, 0, strpos($source, "\r\n\r\n")); + + if (is_string($source)) { + $source = substr($source, 0, strpos($source, "\r\n\r\n")); + } } else { $source = $rcmail->storage->get_raw_headers($uid); } diff --git a/program/actions/settings/folder_edit.php b/program/actions/settings/folder_edit.php index 7e22e1f089a..0f5ecf98d93 100644 --- a/program/actions/settings/folder_edit.php +++ b/program/actions/settings/folder_edit.php @@ -304,7 +304,7 @@ public static function folder_form($attrib) $rcmail->output->set_env('messagecount', $msgcount); $rcmail->output->set_env('folder', $mbox); - if ($mbox !== null && empty($_POST)) { + if ($mbox !== '' && empty($_POST)) { $rcmail->output->command('parent.set_quota', self::quota_content(null, $mbox)); } diff --git a/program/lib/Roundcube/rcube_image.php b/program/lib/Roundcube/rcube_image.php index 9f036bc72fc..7f2e22c4cae 100644 --- a/program/lib/Roundcube/rcube_image.php +++ b/program/lib/Roundcube/rcube_image.php @@ -118,8 +118,10 @@ public function resize($size, $filename = null, $browser_compat = false) // use Imagemagick if ($convert || class_exists('Imagick', false)) { - $p['out'] = $filename; - $p['in'] = $this->image_file; + $p = [ + 'out' => $filename, + 'in' => $this->image_file, + ]; $type = $props['type']; if (!$type && ($data = $this->identify())) { @@ -316,9 +318,11 @@ public function convert($type, $filename = null) // use ImageMagick in command line if ($convert) { - $p['in'] = $this->image_file; - $p['out'] = $filename; - $p['type'] = self::$extensions[$type]; + $p = [ + 'in' => $this->image_file, + 'out' => $filename, + 'type' => self::$extensions[$type], + ]; $result = rcube::exec($convert . ' 2>&1 -colorspace sRGB -strip -flatten -quality 75 {in} {type}:{out}', $p); diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index 110cbdcc933..e0f76f36c8e 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -31,20 +31,16 @@ class rcube_imap extends rcube_storage */ public $conn; - /** - * @var ?rcube_imap_cache Instance of rcube_imap_cache */ + /** @var ?rcube_imap_cache IMAP messages cache */ protected $mcache; - /** @var ?rcube_cache Instance of rcube_cache */ + /** @var ?rcube_cache IMAP cache */ protected $cache; protected $plugins; protected $delimiter; protected $namespace; protected $struct_charset; - - /** @var rcube_result_thread|rcube_result_index|rcube_result_multifolder Search result */ - protected $search_set; protected $search_string = ''; protected $search_charset = ''; protected $search_sort_field = ''; @@ -52,7 +48,6 @@ class rcube_imap extends rcube_storage protected $search_sorted = false; protected $sort_field = ''; protected $sort_order = 'DESC'; - protected $options = ['auth_type' => 'check', 'skip_deleted' => false]; protected $caching = false; protected $messages_caching = false; protected $threading = false; @@ -590,8 +585,8 @@ protected function set_env() // - for prefix_in get the first one but only // if there is no non-prefixed namespace root (#5403) $roots = []; - foreach ($this->namespace['personal'] as $ns) { - $roots[] = $ns[0]; + foreach ($this->namespace['personal'] as $namespace) { + $roots[] = $namespace[0]; } if (!in_array('', $roots)) { @@ -610,7 +605,7 @@ protected function set_env() /** * Returns IMAP server vendor name * - * @return ?string Vendor name + * @return string|null Vendor name * * @since 1.2 */ @@ -628,7 +623,7 @@ public function get_vendor() } if (!$this->check_connection()) { - return ''; + return null; } if (isset($this->conn->data['ID'])) { @@ -661,15 +656,15 @@ public function get_vendor() /** * Get message count for a specific folder * - * @param string $folder Folder name - * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS] - * @param bool $force Force reading from server and update cache - * @param bool $status Enables storing folder status info (max UID/count), - * required for folder_status() + * @param ?string $folder Folder name + * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS] + * @param bool $force Force reading from server and update cache + * @param bool $status Enables storing folder status info (max UID/count), + * required for folder_status() * * @return int Number of messages */ - public function count($folder = '', $mode = 'ALL', $force = false, $status = true) + public function count($folder = null, $mode = 'ALL', $force = false, $status = true) { if (!is_string($folder) || !strlen($folder)) { $folder = $this->folder; @@ -800,9 +795,9 @@ protected function countmessages($folder, $mode = 'ALL', $force = false, $status /** * Public method for listing message flags * - * @param string $folder Folder name - * @param array $uids Message UIDs - * @param int $mod_seq Optional MODSEQ value (of last flag update) + * @param ?string $folder Folder name + * @param array $uids Message UIDs + * @param int $mod_seq Optional MODSEQ value (of last flag update) * * @return array Indexed array with message flags */ @@ -834,15 +829,15 @@ public function list_flags($folder, $uids, $mod_seq = null) /** * Public method for listing headers * - * @param string $folder Folder name - * @param int $page Current page to list - * @param string $sort_field Header field to sort by - * @param string $sort_order Sort order [ASC|DESC] - * @param int $slice Number of slice items to extract from result array + * @param ?string $folder Folder name + * @param int $page Current page to list + * @param string $sort_field Header field to sort by + * @param string $sort_order Sort order [ASC|DESC] + * @param int $slice Number of slice items to extract from result array * * @return array Indexed array with message header objects */ - public function list_messages($folder = '', $page = null, $sort_field = null, $sort_order = null, $slice = 0) + public function list_messages($folder = null, $page = null, $sort_field = null, $sort_order = null, $slice = 0) { if (!is_string($folder) || !strlen($folder)) { $folder = $this->folder; @@ -864,12 +859,8 @@ public function list_messages($folder = '', $page = null, $sort_field = null, $s * * @see rcube_imap::list_messages */ - protected function _list_messages($folder = '', $page = null, $sort_field = null, $sort_order = null, $slice = 0) + protected function _list_messages($folder, $page = null, $sort_field = null, $sort_order = null, $slice = 0) { - if (!is_string($folder) || !strlen($folder)) { - return []; - } - $this->set_sort_order($sort_field, $sort_order); $page = $page ?: $this->list_page; @@ -1054,7 +1045,7 @@ protected function set_thread_flags(&$headers, $threads) */ protected function list_search_messages($folder, $page, $slice = 0) { - if (!is_string($folder) || !strlen($folder) || empty($this->search_set) || $this->search_set->is_empty()) { + if (!strlen($folder) || empty($this->search_set) || $this->search_set->is_empty()) { return []; } @@ -1110,8 +1101,8 @@ protected function list_search_messages($folder, $page, $slice = 0) // ... and fetch the requested set of headers $a_msg_headers = []; - foreach ($fetch as $folder => $a_index) { - $a_msg_headers = array_merge($a_msg_headers, array_values($this->fetch_headers($folder, $a_index))); + foreach ($fetch as $folder_name => $a_index) { + $a_msg_headers = array_merge($a_msg_headers, array_values($this->fetch_headers($folder_name, $a_index))); } // Re-sort the result according to the original search set order @@ -1214,7 +1205,7 @@ protected function list_search_messages($folder, $page, $slice = 0) $a_msg_headers = $this->fetch_headers($folder, $a_index, false); // return empty array if no messages found - if (!is_array($a_msg_headers) || empty($a_msg_headers)) { + if (empty($a_msg_headers)) { return []; } @@ -1383,15 +1374,15 @@ protected function get_folder_stats($folder) /** * Return sorted list of message UIDs * - * @param string $folder Folder to get index from - * @param string $sort_field Sort column - * @param string $sort_order Sort order [ASC, DESC] - * @param bool $no_threads Get not threaded index - * @param bool $no_search Get index not limited to search result (optionally) + * @param ?string $folder Folder to get index from + * @param string $sort_field Sort column + * @param string $sort_order Sort order [ASC, DESC] + * @param bool $no_threads Get not threaded index + * @param bool $no_search Get index not limited to search result (optionally) * * @return rcube_result_index|rcube_result_thread List of messages (UIDs) */ - public function index($folder = '', $sort_field = null, $sort_order = null, + public function index($folder = null, $sort_field = null, $sort_order = null, $no_threads = false, $no_search = false ) { if (!$no_threads && $this->threading) { @@ -1522,13 +1513,13 @@ public function index_direct($folder, $sort_field = null, $sort_order = null, $s /** * Return index of threaded message UIDs * - * @param string $folder Folder to get index from - * @param string $sort_field Sort column - * @param string $sort_order Sort order [ASC, DESC] + * @param ?string $folder Folder to get index from + * @param string $sort_field Sort column + * @param string $sort_order Sort order [ASC, DESC] * * @return rcube_result_thread Message UIDs */ - public function thread_index($folder = '', $sort_field = null, $sort_order = null) + public function thread_index($folder = null, $sort_field = null, $sort_order = null) { if (!is_string($folder) || !strlen($folder)) { $folder = $this->folder; @@ -1655,8 +1646,8 @@ public function search($folder = '', $search = 'ALL', $charset = null, $sort_fie /** * Direct (real and simple) SEARCH request (without result sorting and caching). * - * @param string $folder Mailbox name to search in - * @param string $str Search string + * @param array|string|null $folder Mailbox name to search in + * @param string $str Search string * * @return rcube_result_index|rcube_result_multifolder Search result (UIDs) */ @@ -1781,7 +1772,7 @@ public static function convert_criteria($str, $charset, $dest_charset = 'US-ASCI $string = substr($str, $string_offset - 1, $m[0]); $string = rcube_charset::convert($string, $charset, $dest_charset); - if ($string === false || !strlen($string)) { + if (!strlen($string)) { continue; } @@ -1877,7 +1868,7 @@ public function get_message_headers($uid, $folder = null, $force = false) * @param int $uid Message UID to fetch * @param string $folder Folder to read from * - * @return ?rcube_message_header Message data + * @return rcube_message_header|false Message data, False on error */ public function get_message($uid, $folder = null) { @@ -1891,7 +1882,7 @@ public function get_message($uid, $folder = null) } // Check internal cache - if (!empty($this->icache['message']) && ($headers = $this->icache['message'])) { + if (isset($this->icache['message']) && ($headers = $this->icache['message'])) { // Make sure the folder and UID is what we expect. // In case when the same process works with folders that are personal // and shared two folders can contain the same UIDs. @@ -1904,7 +1895,7 @@ public function get_message($uid, $folder = null) // message doesn't exist? if (empty($headers)) { - return null; + return false; } // structure might be cached @@ -2044,6 +2035,7 @@ protected function structure_part($part, $count = 0, $parent = '', $mime_headers } $struct->mimetype = 'multipart/' . $struct->ctype_secondary; + $mime_part_headers = []; // build parts list for headers pre-fetching for ($i = 0; $i < count($part); $i++) { @@ -2067,7 +2059,9 @@ protected function structure_part($part, $count = 0, $parent = '', $mime_headers } $struct->parts = []; - for ($i = 0, $count = 0; $i < count($part); $i++) { + $count = 0; + + for ($i = 0; $i < count($part); $i++) { if (!is_array($part[$i])) { break; } @@ -2169,6 +2163,7 @@ protected function structure_part($part, $count = 0, $parent = '', $mime_headers // get message/rfc822's child-parts if (isset($part[8]) && is_array($part[8]) && $di != 8) { $struct->parts = []; + $mime_part_headers = []; for ($i = 0; $i < count($part[8]); $i++) { if (!is_array($part[8][$i])) { @@ -2295,14 +2290,14 @@ protected function structure_charset($structure) /** * Fetch message body of a specific message from the server * - * @param int $uid Message UID - * @param string $part Part number - * @param rcube_message_part $o_part Part object created by get_structure() - * @param mixed $print True to print part, resource to write part contents in - * @param resource $fp File pointer to save the message part - * @param bool $skip_charset_conv Disables charset conversion - * @param int $max_bytes Only read this number of bytes - * @param bool $formatted Enables formatting of text/* parts bodies + * @param int $uid Message UID + * @param string $part Part number + * @param ?rcube_message_part $o_part Part object created by get_structure() + * @param mixed $print True to print part, resource to write part contents in + * @param resource $fp File pointer to save the message part + * @param bool $skip_charset_conv Disables charset conversion + * @param int $max_bytes Only read this number of bytes + * @param bool $formatted Enables formatting of text/* parts bodies * * @return string|true|null Message/part body if not printed */ @@ -2318,6 +2313,10 @@ public function get_message_part($uid, $part, $o_part = null, $print = null, $fp $structure = $this->conn->getStructure($this->folder, $uid, true); $part_data = rcube_imap_generic::getStructurePartData($structure, $part); + if (empty($part_data)) { + return null; + } + $o_part = new rcube_message_part(); $o_part->ctype_primary = $part_data['type'] ?? null; $o_part->ctype_secondary = $part_data['subtype'] ?? null; @@ -2329,7 +2328,7 @@ public function get_message_part($uid, $part, $o_part = null, $print = null, $fp $body = ''; // Note: multipart/* parts will have size=0, we don't want to ignore them - if ($o_part && ($o_part->size || $o_part->ctype_primary == 'multipart')) { + if ($o_part->size || $o_part->ctype_primary == 'multipart') { $formatted = $formatted && $o_part->ctype_primary == 'text'; $body = $this->conn->handlePartBody($this->folder, $uid, true, $part ?: 'TEXT', $o_part->encoding, $print, $fp, $formatted, $max_bytes); @@ -2370,12 +2369,12 @@ public function get_message_part($uid, $part, $o_part = null, $print = null, $fp * @param resource $fp File pointer to save the message * @param string $part Optional message part ID * - * @return ?string Message source string + * @return string|false Message source string */ public function get_raw_body($uid, $fp = null, $part = null) { if (!$this->check_connection()) { - return null; + return false; } return $this->conn->handlePartBody($this->folder, $uid, @@ -2388,12 +2387,12 @@ public function get_raw_body($uid, $fp = null, $part = null) * @param int $uid Message UID * @param string $part Optional message part ID * - * @return ?string Message headers string + * @return string|false Message headers string */ public function get_raw_headers($uid, $part = null) { if (!$this->check_connection()) { - return null; + return false; } return $this->conn->fetchPartHeader($this->folder, $uid, true, $part); @@ -2473,7 +2472,7 @@ public function set_flag($uids, $flag, $folder = null, $skip_cache = false) /** * Append a mail message (source) to a specific folder * - * @param string $folder Target folder + * @param ?string $folder Target folder * @param string|array $message The message source string or filename * or array (of strings and file pointers) * @param string $headers Headers string if $message contains only the body @@ -2642,12 +2641,12 @@ public function copy_message($uids, $to_mbox, $from_mbox = '') /** * Mark messages as deleted and expunge them * - * @param mixed $uids Message UIDs as array or comma-separated string, or '*' - * @param string $folder Source folder + * @param array|string $uids Message UIDs as array or comma-separated string, or '*' + * @param ?string $folder Source folder * * @return bool True on success, False on error */ - public function delete_message($uids, $folder = '') + public function delete_message($uids, $folder = null) { if (!is_string($folder) || !strlen($folder)) { $folder = $this->folder; @@ -2864,6 +2863,7 @@ public function list_folders_subscribed_direct($root = '', $name = '*') // Try to make sure the list of existing folders is not malformed, // we don't want to unsubscribe existing folders on error + // @phpstan-ignore-next-line if (is_array($existing) && (!empty($root) || count($existing) > 1)) { $nonexisting = array_diff($result, $existing); $result = array_diff($result, $nonexisting); @@ -3077,7 +3077,7 @@ protected function filter_rights($a_folders, $rights) $myrights = implode('', (array) $this->my_rights($folder)); - if ($myrights !== null && !preg_match($regex, $myrights)) { + if (!preg_match($regex, $myrights)) { unset($a_folders[$idx]); } } @@ -3106,16 +3106,16 @@ public function get_quota($folder = null) * * @param string $folder Folder name * - * @return int Folder size in bytes, False on error + * @return int|false Folder size in bytes, False on error */ public function folder_size($folder) { - if (!is_string($folder) || !strlen($folder)) { + if (!strlen($folder)) { return false; } if (!$this->check_connection()) { - return 0; + return false; } if ($this->get_capability('STATUS=SIZE')) { @@ -3131,7 +3131,7 @@ public function folder_size($folder) $result = $this->get_metadata($folder, $idx, [], true); if (!empty($result) && isset($result[$folder][$idx]) && is_numeric($result[$folder][$idx])) { - return $result[$folder][$idx]; + return (int) $result[$folder][$idx]; } } @@ -3572,7 +3572,7 @@ public function folder_attributes($folder, $force = false) * * @param string $folder Folder name * - * @return array Data + * @return array Folder properties */ public function folder_data($folder) { @@ -3588,7 +3588,7 @@ public function folder_data($folder) if ($this->conn->select($folder)) { $this->folder = $folder; } else { - return null; + return []; } } @@ -3674,15 +3674,11 @@ public function folder_info($folder) $options['noselect'] = false; // Set 'noselect' flag - if (is_array($options['attributes'])) { - foreach ($options['attributes'] as $attrib) { - $attrib = strtolower($attrib); - if ($attrib == '\noselect' || $attrib == '\nonexistent') { - $options['noselect'] = true; - } + foreach ($options['attributes'] as $attrib) { + $attrib = strtolower($attrib); + if ($attrib == '\noselect' || $attrib == '\nonexistent') { + $options['noselect'] = true; } - } else { - $options['noselect'] = true; } // Get folder rights (MYRIGHTS) @@ -3754,7 +3750,7 @@ public function folder_validate($folder, &$char = null) /** * Get message header names for rcube_imap_generic::fetchHeader(s) * - * @return string Space-separated list of header names + * @return array List of header names */ protected function get_fetch_headers() { @@ -3831,7 +3827,7 @@ public function delete_acl($folder, $user) * * @param string $folder Folder name * - * @return array User-rights array on success, NULL on error + * @return array|null User-rights array on success, NULL on error * * @since 0.5-beta */ @@ -3855,7 +3851,7 @@ public function get_acl($folder) * @param string $folder Folder name * @param string $user User name * - * @return array List of user rights + * @return array|null List of user rights * * @since 0.5-beta */ @@ -3878,7 +3874,7 @@ public function list_rights($folder, $user) * * @param string $folder Folder name * - * @return array MYRIGHTS response on success, NULL on error + * @return array|null MYRIGHTS response on success, NULL on error * * @since 0.5-beta */ @@ -3898,8 +3894,8 @@ public function my_rights($folder) /** * Sets IMAP metadata/annotations (SETMETADATA/SETANNOTATION) * - * @param string $folder Folder name (empty for server metadata) - * @param array $entries Entry-value array (use NULL value as NIL) + * @param ?string $folder Folder name (empty for server metadata) + * @param array $entries Entry-value array (use NULL value as NIL) * * @return bool True on success, False on failure * @@ -3934,8 +3930,8 @@ public function set_metadata($folder, $entries) /** * Unsets IMAP metadata/annotations (SETMETADATA/SETANNOTATION) * - * @param string $folder Folder name (empty for server metadata) - * @param array $entries Entry names array + * @param ?string $folder Folder name (empty for server metadata) + * @param array $entries Entry names array * * @return bool True on success, False on failure * @@ -3970,10 +3966,10 @@ public function delete_metadata($folder, $entries) /** * Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION) * - * @param string $folder Folder name (empty for server metadata) - * @param array $entries Entries - * @param array $options Command options (with MAXSIZE and DEPTH keys) - * @param bool $force Disables cache use + * @param ?string $folder Folder name (empty for server metadata) + * @param array $entries Entries + * @param array $options Command options (with MAXSIZE and DEPTH keys) + * @param bool $force Disables cache use * * @return array|null Metadata entry-value hash array on success, NULL on error * @@ -4084,6 +4080,8 @@ public function set_caching($type) /** * Getter for IMAP cache object + * + * @return rcube_cache|null */ protected function get_cache_engine() { @@ -4108,6 +4106,8 @@ public function get_cache($key) if ($cache = $this->get_cache_engine()) { return $cache->get($key); } + + return null; } /** @@ -4171,7 +4171,8 @@ protected function get_mcache_engine() { if ($this->messages_caching && !$this->mcache) { $rcube = rcube::get_instance(); - if (($dbh = $rcube->get_dbh()) && ($userid = $rcube->get_user_id())) { + $dbh = $rcube->get_dbh(); + if ($userid = $rcube->get_user_id()) { $ttl = $rcube->config->get('messages_cache_ttl', '10d'); $threshold = $rcube->config->get('messages_cache_threshold', 50); $this->mcache = new rcube_imap_cache( @@ -4400,7 +4401,7 @@ protected function sort_folder_comparator($str1, $str2) * @param int $id Message (sequence) ID * @param string $folder Folder name * - * @return int Message UID + * @return int|null Message UID if found */ public function id2uid($id, $folder = null) { diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php index 4ffb2a30c4d..a99f554a2d8 100644 --- a/program/lib/Roundcube/rcube_imap_cache.php +++ b/program/lib/Roundcube/rcube_imap_cache.php @@ -68,8 +68,10 @@ class rcube_imap_cache */ private $icache = []; + /** @var int */ + private $mode = 0; + private $skip_deleted = false; - private $mode; private $index_table; private $thread_table; private $messages_table; @@ -139,7 +141,7 @@ public function __construct($db, $imap, $userid, $skip_deleted, $ttl = 0, $thres public function close() { $this->save_icache(); - $this->icache = null; + $this->icache = []; } /** @@ -161,7 +163,7 @@ public function set_mode($mode) * @param string $sort_order Sorting order (ASC|DESC) * @param bool $existing Skip index initialization if it doesn't exist in DB * - * @return array Messages index + * @return rcube_result_index|null Messages index */ public function get_index($mailbox, $sort_field = null, $sort_order = null, $existing = false) { @@ -274,7 +276,7 @@ public function get_index($mailbox, $sort_field = null, $sort_order = null, $exi * * @param string $mailbox Folder name * - * @return array Messages threaded index + * @return rcube_result_thread Messages threaded index */ public function get_thread($mailbox) { @@ -377,6 +379,7 @@ public function get_messages($mailbox, $msgs = []) // Insert to DB and add to result list if (!empty($messages)) { foreach ($messages as $msg) { + // @phpstan-ignore-next-line if ($this->mode & self::MODE_MESSAGE) { $this->add_message($mailbox, $msg, !array_key_exists($msg->uid, $result)); } @@ -462,9 +465,9 @@ public function get_message($mailbox, $uid, $update = true, $cache = true) /** * Saves the message in cache. * - * @param string $mailbox Folder name - * @param rcube_message_header $message Message data - * @param bool $force Skips message in-cache existence check + * @param string $mailbox Folder name + * @param ?rcube_message_header $message Message data + * @param bool $force Skips message in-cache existence check */ public function add_message($mailbox, $message, $force = false) { @@ -530,7 +533,7 @@ public function change_flag($mailbox, $uids, $flag, $enabled = false) // Internal cache update if ( - !empty($this->icache['__message']) + isset($this->icache['__message']) && ($message = $this->icache['__message']) && $message['mailbox'] === $mailbox && in_array($message['object']->uid, $uids) @@ -548,6 +551,7 @@ public function change_flag($mailbox, $uids, $flag, $enabled = false) . ', `flags` = `flags` ' . ($enabled ? "+ {$idx}" : "- {$idx}") . ' WHERE `user_id` = ?' . ' AND `mailbox` = ?' + // @phpstan-ignore-next-line . (count($uids) > 0 ? ' AND `uid` IN (' . $this->db->array2list($uids, 'integer') . ')' : '') . " AND (`flags` & {$idx}) = " . ($enabled ? '0' : $idx), $this->userid, $mailbox @@ -558,7 +562,7 @@ public function change_flag($mailbox, $uids, $flag, $enabled = false) * Removes message(s) from cache. * * @param string $mailbox Folder name - * @param array $uids Message UIDs, NULL removes all messages + * @param ?array $uids Message UIDs, NULL removes all messages */ public function remove_message($mailbox = null, $uids = null) { @@ -575,7 +579,7 @@ public function remove_message($mailbox = null, $uids = null) // Remove the message from internal cache if ( !empty($uids) - && !empty($this->icache['__message']) + && isset($this->icache['__message']) && ($message = $this->icache['__message']) && $message['mailbox'] === $mailbox && in_array($message['object']->uid, (array) $uids) @@ -1202,7 +1206,7 @@ private function message_object_prepare(&$msg, &$size = 0) unset($msg->replaces); - if (!empty($msg->structure) && is_object($msg->structure)) { + if (is_object($msg->structure)) { $this->message_object_prepare($msg->structure, $size); } diff --git a/program/lib/Roundcube/rcube_imap_search.php b/program/lib/Roundcube/rcube_imap_search.php index 9ac31d243ce..0f38925ee7e 100644 --- a/program/lib/Roundcube/rcube_imap_search.php +++ b/program/lib/Roundcube/rcube_imap_search.php @@ -53,11 +53,11 @@ public function __construct($options, $conn) /** * Invoke search request to IMAP server * - * @param array $folders List of IMAP folders to search in - * @param string $str Search criteria - * @param string $charset Search charset - * @param string $sort_field Header field to sort by - * @param bool $threading True if threaded listing is active + * @param array $folders List of IMAP folders to search in + * @param array|string $str Search criteria + * @param string $charset Search charset + * @param string $sort_field Header field to sort by + * @param bool $threading True if threaded listing is active * * @return rcube_result_multifolder */ @@ -73,7 +73,7 @@ public function exec($folders, $str, $charset = null, $sort_field = null, $threa if ($result && !$result->incomplete) { $results->add($result); } else { - $search = is_array($str) && $str[$folder] ? $str[$folder] : $str; + $search = is_array($str) && !empty($str[$folder]) ? $str[$folder] : $str; $job = new rcube_imap_search_job($folder, $search, $charset, $sort_field, $threading); $job->worker = $this; $this->jobs[] = $job; diff --git a/program/lib/Roundcube/rcube_message_header.php b/program/lib/Roundcube/rcube_message_header.php index 1b8282e7da6..f79918b0ba2 100644 --- a/program/lib/Roundcube/rcube_message_header.php +++ b/program/lib/Roundcube/rcube_message_header.php @@ -26,126 +26,126 @@ class rcube_message_header /** * Message sequence number * - * @var int + * @var ?int */ public $id; /** * Message unique identifier * - * @var int + * @var int|string|null */ public $uid; /** * Message subject * - * @var string + * @var ?string */ public $subject; /** * Message sender (From) * - * @var string + * @var ?string */ public $from; /** * Message recipient (To) * - * @var string + * @var ?string */ public $to; /** * Message additional recipients (Cc) * - * @var string + * @var ?string */ public $cc; /** * Message hidden recipients (Bcc) * - * @var string + * @var ?string */ public $bcc; /** * Message Reply-To header * - * @var string + * @var ?string */ public $replyto; /** * Message In-Reply-To header * - * @var string + * @var ?string */ public $in_reply_to; /** * Message date (Date) * - * @var string + * @var ?string */ public $date; /** * Message identifier (Message-ID) * - * @var string + * @var ?string */ public $messageID; /** * Message size * - * @var int + * @var ?int */ public $size; /** * Message encoding * - * @var string + * @var ?string */ public $encoding; /** * Message charset * - * @var string + * @var ?string */ public $charset; /** * Message Content-type * - * @var string + * @var ?string */ public $ctype; /** * Message timestamp (based on message date) * - * @var int + * @var ?int */ public $timestamp; /** * IMAP bodystructure string * - * @var string + * @var ?array */ public $bodystructure; /** * IMAP body (RFC822.TEXT) * - * @var string + * @var ?string */ public $body; @@ -159,14 +159,14 @@ class rcube_message_header /** * IMAP internal date * - * @var string + * @var ?string */ public $internaldate; /** * Message References header * - * @var string + * @var ?string */ public $references; @@ -180,14 +180,14 @@ class rcube_message_header /** * Message receipt recipient * - * @var string + * @var ?string */ public $mdn_to; /** * IMAP folder this message is stored in * - * @var string + * @var ?string */ public $folder; @@ -233,47 +233,47 @@ class rcube_message_header * * @var int */ - public $depth; + public $depth = 0; /** * Whether the message has references in the thread * * @var bool */ - public $has_children; + public $has_children = false; /** * Number of flagged children (in a thread) * * @var int */ - public $flagged_children; + public $flagged_children = 0; /** * Number of unread children (in a thread) * * @var int */ - public $unread_children; + public $unread_children = 0; /** * UID of the message parent (in a thread) * - * @var int + * @var int|string|null */ public $parent_uid; /** * IMAP MODSEQ value * - * @var int + * @var ?int */ public $modseq; /** * IMAP ENVELOPE * - * @var string + * @var ?string */ public $envelope; @@ -309,7 +309,7 @@ class rcube_message_header * @param string $name Header name * @param bool $decode Decode the header content * - * @return string|null Header content + * @return array|string|int|null Header content */ public function get($name, $decode = true) { diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php index 5858a08df29..2df02285575 100644 --- a/program/lib/Roundcube/rcube_storage.php +++ b/program/lib/Roundcube/rcube_storage.php @@ -24,33 +24,47 @@ */ abstract class rcube_storage { - /** - * Instance of connection object e.g. rcube_imap_generic - * - * @var mixed - */ - public $conn; + public const UNKNOWN = 0; + public const NOPERM = 1; + public const READONLY = 2; + public const TRYCREATE = 3; + public const INUSE = 4; + public const OVERQUOTA = 5; + public const ALREADYEXISTS = 6; + public const NONEXISTENT = 7; + public const CONTACTADMIN = 8; - /** - * List of supported special folder types - * - * @var array - */ + public const DUAL_USE_FOLDERS = 'X-DUAL-USE-FOLDERS'; + + /** @var array List of supported special folder types */ public static $folder_types = ['drafts', 'sent', 'junk', 'trash']; - protected $folder = 'INBOX'; - protected $default_charset = 'ISO-8859-1'; - protected $options = ['auth_type' => 'check', 'language' => 'en_US']; + /** @var string Current folder */ + protected $folder = ''; + + /** @var string Default character set name */ + protected $default_charset = RCUBE_CHARSET; + + /** @var array Object configuration options */ + protected $options = [ + 'auth_type' => 'check', + 'language' => 'en_US', + 'skip_deleted' => false, + ]; + + /** @var int Page size */ protected $page_size = 10; + + /** @var int Current page */ protected $list_page = 1; + + /** @var bool Enabled/Disable threading mode */ protected $threading = false; + + /** @var rcube_result_index|rcube_result_multifolder|rcube_result_thread|null Search result set */ protected $search_set; - /** - * Internal (in-memory) cache - * - * @var array - */ + /** @var array Internal (in-memory) cache */ protected $icache = []; /** @@ -74,18 +88,6 @@ abstract class rcube_storage 'X-DRAFT-INFO', ]; - public const UNKNOWN = 0; - public const NOPERM = 1; - public const READONLY = 2; - public const TRYCREATE = 3; - public const INUSE = 4; - public const OVERQUOTA = 5; - public const ALREADYEXISTS = 6; - public const NONEXISTENT = 7; - public const CONTACTADMIN = 8; - - public const DUAL_USE_FOLDERS = 'X-DUAL-USE-FOLDERS'; - /** * Connect to the server * @@ -142,11 +144,11 @@ abstract public function get_response_code(); /** * Returns storage server vendor name * - * @return string Vendor name + * @return string|null Vendor name */ public function get_vendor() { - return ''; + return null; } /** @@ -260,14 +262,14 @@ public function get_pagesize() /** * Save a search result for future message listing methods. * - * @param mixed $set Search set in driver specific format + * @param array $set Search set in driver specific format */ abstract public function set_search_set($set); /** * Return the saved search set. * - * @return array Search set in driver specific format, NULL if search wasn't initialized + * @return array|null Search set in driver specific format, NULL if search wasn't initialized */ abstract public function get_search_set(); @@ -342,11 +344,11 @@ abstract public function get_namespace($name = null); /** * Get messages count for a specific folder. * - * @param string $folder Folder name - * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS] - * @param bool $force Force reading from server and update cache - * @param bool $status Enables storing folder status info (max UID/count), - * required for folder_status() + * @param ?string $folder Folder name + * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS] + * @param bool $force Force reading from server and update cache + * @param bool $status Enables storing folder status info (max UID/count), + * required for folder_status() * * @return int Number of messages */ @@ -367,9 +369,9 @@ abstract public function fetch_headers($folder, $msgs, $sort = true, $force = fa /** * Public method for listing message flags * - * @param string $folder Folder name - * @param array $uids Message UIDs - * @param int $mod_seq Optional MODSEQ value + * @param ?string $folder Folder name + * @param array $uids Message UIDs + * @param int $mod_seq Optional MODSEQ value * * @return array Indexed array with message flags */ @@ -378,11 +380,11 @@ abstract public function list_flags($folder, $uids, $mod_seq = null); /** * Public method for listing headers. * - * @param string $folder Folder name - * @param int $page Current page to list - * @param string $sort_field Header field to sort by - * @param string $sort_order Sort order [ASC|DESC] - * @param int $slice Number of slice items to extract from result array + * @param ?string $folder Folder name + * @param int $page Current page to list + * @param string $sort_field Header field to sort by + * @param string $sort_order Sort order [ASC|DESC] + * @param int $slice Number of slice items to extract from result array * * @return array Indexed array with message header objects */ @@ -391,11 +393,11 @@ abstract public function list_messages($folder = null, $page = null, $sort_field /** * Return sorted list of message UIDs * - * @param string $folder Folder to get index from - * @param string $sort_field Sort column - * @param string $sort_order Sort order [ASC, DESC] - * @param bool $no_threads Get not threaded index - * @param bool $no_search Get index not limited to search result (optionally) + * @param ?string $folder Folder to get index from + * @param string $sort_field Sort column + * @param string $sort_order Sort order [ASC, DESC] + * @param bool $no_threads Get not threaded index + * @param bool $no_search Get index not limited to search result (optionally) * * @return rcube_result_index|rcube_result_thread List of messages (UIDs) */ @@ -416,10 +418,10 @@ abstract public function search($folder = null, $str = 'ALL', $charset = null, $ /** * Direct (real and simple) search request (without result sorting and caching). * - * @param string $folder Folder name to search in - * @param string $str Search string + * @param array|string|null $folder Folder name to search in + * @param string $str Search string * - * @return rcube_result_index Search result (UIDs) + * @return rcube_result_index|rcube_result_multifolder Search result (UIDs) */ abstract public function search_once($folder = null, $str = 'ALL'); @@ -441,7 +443,7 @@ abstract public function refresh_search(); * @param int $uid Message UID to fetch * @param string $folder Folder to read from * - * @return rcube_message_header Message data + * @return rcube_message_header|false Message data, False on error */ abstract public function get_message($uid, $folder = null); @@ -452,7 +454,7 @@ abstract public function get_message($uid, $folder = null); * @param string $folder Folder to read from * @param bool $force True to skip cache * - * @return rcube_message_header Message headers + * @return rcube_message_header|false Message headers, False on error */ abstract public function get_message_headers($uid, $folder = null, $force = false); @@ -478,15 +480,18 @@ abstract public function get_message_part($uid, $part, $o_part = null, $print = * * @param int $uid Message UID * - * @return string $part Message/part body + * @return string|false $part Message/part body, False on error * * @see rcube_imap::get_message_part() */ public function get_body($uid, $part = 1) { - $headers = $this->get_message_headers($uid); - return rcube_charset::convert($this->get_message_part($uid, $part, null), - $headers->charset ?: $this->default_charset); + if ($headers = $this->get_message_headers($uid)) { + return rcube_charset::convert($this->get_message_part($uid, $part, null), + $headers->charset ?: $this->default_charset); + } + + return false; } /** @@ -496,7 +501,7 @@ public function get_body($uid, $part = 1) * @param resource $fp File pointer to save the message * @param string $part Optional message part ID * - * @return string Message source string + * @return string|false Message source string */ abstract public function get_raw_body($uid, $fp = null, $part = null); @@ -506,7 +511,7 @@ abstract public function get_raw_body($uid, $fp = null, $part = null); * @param int $uid Message UID * @param string $part Optional message part ID * - * @return string Message headers string + * @return string|false Message headers string */ abstract public function get_raw_headers($uid, $part = null); @@ -549,7 +554,7 @@ public function unset_flag($uids, $flag, $folder = null) /** * Append a mail message (source) to a specific folder. * - * @param string $folder Target folder + * @param ?string $folder Target folder * @param string|array $message The message source string or filename * or array (of strings and file pointers) * @param string $headers Headers string if $message contains only the body @@ -586,8 +591,8 @@ abstract public function copy_message($uids, $to, $from = null); /** * Mark message(s) as deleted and expunge. * - * @param mixed $uids Message UIDs as array or comma-separated string, or '*' - * @param string $folder Source folder + * @param array|string $uids Message UIDs as array or comma-separated string, or '*' + * @param ?string $folder Source folder * * @return bool True on success, False on error */ @@ -763,7 +768,7 @@ abstract public function folder_exists($folder, $subscription = false); * * @param string $folder Folder name * - * @return int Folder size in bytes, False on error + * @return int|false Folder size in bytes, False on error */ abstract public function folder_size($folder); @@ -952,7 +957,7 @@ abstract public function delete_acl($folder, $user); * * @param string $folder Folder name * - * @return array User-rights array on success, NULL on error + * @return array|null User-rights array on success, NULL on error */ abstract public function get_acl($folder); @@ -963,7 +968,7 @@ abstract public function get_acl($folder); * @param string $folder Folder name * @param string $user User name * - * @return array List of user rights + * @return array|null List of user rights */ abstract public function list_rights($folder, $user); @@ -972,7 +977,7 @@ abstract public function list_rights($folder, $user); * * @param string $folder Folder name * - * @return array MYRIGHTS response on success, NULL on error + * @return array|null MYRIGHTS response on success, NULL on error */ abstract public function my_rights($folder); @@ -1004,7 +1009,7 @@ abstract public function delete_metadata($folder, $entries); * @param array $options Command options (with MAXSIZE and DEPTH keys) * @param bool $force Disables cache use * - * @return array Metadata entry-value hash array on success, NULL on error + * @return array|null Metadata entry-value hash array on success, NULL on error */ abstract public function get_metadata($folder, $entries, $options = [], $force = false); diff --git a/tests/Browser/bootstrap.php b/tests/Browser/bootstrap.php index b3dca8c32d9..50f2ec9b757 100644 --- a/tests/Browser/bootstrap.php +++ b/tests/Browser/bootstrap.php @@ -231,6 +231,7 @@ public static function reset_mailboxes() } $rcmail = rcmail::get_instance(); + /** @var rcube_imap $imap */ $imap = $rcmail->get_storage(); $got_defaults = $rcmail->config->get('create_default_folders'); $vendor = $imap->get_vendor();