Mercurial > hg > rc2
changeset 23:929c05ba3b2f
fixed sort issue?
| author | Charlie Root |
|---|---|
| date | Fri, 17 Oct 2025 17:31:07 -0400 |
| parents | 303b85d5b561 |
| children | e53add5ddac5 |
| files | program/lib/Roundcube/rcube_result_thread.php |
| diffstat | 1 files changed, 61 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/program/lib/Roundcube/rcube_result_thread.php Wed Oct 15 14:06:27 2025 -0400 +++ b/program/lib/Roundcube/rcube_result_thread.php Fri Oct 17 17:31:07 2025 -0400 @@ -74,12 +74,12 @@ return; } - $data = array_shift($data); + $data = array_first($data); $data = trim($data); $data = preg_replace('/[\r\n]/', '', $data); $data = preg_replace('/\s+/', ' ', $data); - $this->raw_data = $this->parse_thread($data); + $this->raw_data = empty($data) ? '' : $this->parse_thread($data); } /** @@ -132,8 +132,9 @@ */ public function count_messages() { - if ($this->meta['messages'] !== null) + if (!empty($this->meta['messages'])) { return $this->meta['messages']; + } if (empty($this->raw_data)) { $this->meta['messages'] = 0; @@ -153,10 +154,14 @@ /** * Returns maximum message identifier in the result * - * @return int Maximum message identifier + * @return int|null Maximum message identifier */ public function max() { + if ($this->is_empty()) { + return null; + } + if (!isset($this->meta['max'])) { $this->meta['max'] = (int) @max($this->get()); } @@ -166,10 +171,14 @@ /** * Returns minimum message identifier in the result * - * @return int Minimum message identifier + * @return int|null Minimum message identifier */ public function min() { + if ($this->is_empty()) { + return null; + } + if (!isset($this->meta['min'])) { $this->meta['min'] = (int) @min($this->get()); } @@ -179,8 +188,8 @@ /** * Slices data set. * - * @param $offset Offset (as for PHP's array_slice()) - * @param $length Number of elements (as for PHP's array_slice()) + * @param int $offset Offset (as for PHP's array_slice()) + * @param int $length Number of elements (as for PHP's array_slice()) */ public function slice($offset, $length) { @@ -207,9 +216,9 @@ $this->meta = array(); $this->meta['count'] = 0; - while ($start < $datalen && - (($pos = @strpos($this->raw_data, self::SEPARATOR_ELEMENT, - $start)) != false|| ($pos = $datalen)) + while ($start < $datalen + && (($pos = strpos($this->raw_data, self::SEPARATOR_ELEMENT, $start)) !== false + || ($pos = $datalen)) ) { $len = $pos - $start; $elem = substr($this->raw_data, $start, $len); @@ -274,7 +283,7 @@ )); if (preg_match("/($begin)$msgid($end)/", $this->raw_data, $m, - $get_index ? PREG_OFFSET_CAPTURE : null) + $get_index ? PREG_OFFSET_CAPTURE : 0) ) { if ($get_index) { $idx = 0; @@ -361,8 +370,9 @@ $regexp = '(' . $element . '|' . $item . ')'; if (isset($this->meta['pos'][$index])) { - if (preg_match('/([0-9]+)/', $this->raw_data, $m, null, $this->meta['pos'][$index])) + if (preg_match('/([0-9]+)/', $this->raw_data, $m, 0, $this->meta['pos'][$index])) { $result = $m[1]; + } } else if (isset($this->meta['pos'][$index-1])) { // get chunk of data after previous element @@ -391,7 +401,7 @@ // Finally use less effective method $data = $this->get(); - return $data[$index]; + return $data[$index] ?? null; } /** @@ -421,7 +431,7 @@ */ public function sort($index) { - $this->sort_order = $index->get_parameters('ORDER'); + $this->order = $index->get_parameters('ORDER'); if (empty($this->raw_data)) { return; @@ -440,9 +450,9 @@ // in memory at a time // Assign roots - while ($start < $datalen && - (($pos = @strpos($this->raw_data, self::SEPARATOR_ELEMENT, - $start)) != false || ($pos = $datalen)) + while ( + ($start < $datalen && ($pos = strpos($this->raw_data, self::SEPARATOR_ELEMENT, $start))) + || ($start < $datalen && ($pos = $datalen)) ) { $len = $pos - $start; $elem = substr($this->raw_data, $start, $len); @@ -468,9 +478,9 @@ $result = array_fill_keys($result, null); $start = 0; - while ($start < $datalen && - (($pos = @strpos($this->raw_data, self::SEPARATOR_ELEMENT, - $start)) != false || ($pos = $datalen)) + while ( + ($start < $datalen && ($pos = strpos($this->raw_data, self::SEPARATOR_ELEMENT, $start))) + || ($start < $datalen && ($pos = $datalen)) ) { $len = $pos - $start; $elem = substr($this->raw_data, $start, $len); @@ -496,9 +506,9 @@ $result = array(); $start = 0; - while ($start < $datalen && - (($pos = @strpos($this->raw_data, self::SEPARATOR_ELEMENT, $start)) != false - || ($pos = $datalen)) + while ($start < $datalen + && (($pos = strpos($this->raw_data, self::SEPARATOR_ELEMENT, $start)) !== false + || ($pos = $datalen)) ) { $len = $pos - $start; $elem = substr($this->raw_data, $start, $len); @@ -569,16 +579,16 @@ protected function parse_thread($str, $begin = 0, $end = 0, $depth = 0) { // Don't be tempted to change $str to pass by reference to speed this up - it will slow it down by about - // 7 times instead :-) See comments on http://uk2.php.net/references and this article: - // http://derickrethans.nl/files/phparch-php-variables-article.pdf + // 7 times instead :-) See comments on https://www.php.net/references and this article: + // https://derickrethans.nl/files/phparch-php-variables-article.pdf $node = ''; if (!$end) { $end = strlen($str); } - // Let's try to store data in max. compacted stracture as a string, + // Let's try to store data in max. compacted structure as a string, // arrays handling is much more expensive - // For the following structure: THREAD (2)(3 6 (4 23)(44 7 96)) + // For the following structure: THREAD (2)(3 6 (4 23)(44 7 96))((11)(12)) // -- 2 // -- 3 // \-- 6 @@ -588,8 +598,11 @@ // \-- 44 // \-- 7 // \-- 96 + // -- 11 + // \-- 12 // - // The output will be: 2,3^1:6^2:4^3:23^2:44^3:7^4:96 + // The output will be: 2 3~1:6~2:4~3:23~2:44~3:7~4:96 11~1:12 + // Note: The "11" thread has no root, we use the first message as root if ($str[$begin] != '(') { // find next bracket @@ -641,7 +654,26 @@ } } - $thread = $this->parse_thread($str, $start + 1, $off - 1, $depth); + // Handle threads with missing parent by using first message as root + if (substr_compare($str, '((', $start, 2) === 0) { + // Extract the current thread, e.g. "((1)(2))" + $thread = substr($str, $start, $off - $start); + // Length of the first token, e.g. "(1)" + $len = strspn($thread, '(0123456789', 1) + 1; + // Extract the token and modify it to look like a thread root + $token = substr($thread, 1, $len); + // Warning: The order is important + $token = str_replace('(', '', $token); + $token = str_replace(' ', ' (', $token); + $token = str_replace(')', ' ', $token); + $thread = substr_replace($thread, $token, 1, $len); + // Parse the thread + $thread = $this->parse_thread($thread, 0, 0, $depth); + } + else { + $thread = $this->parse_thread($str, $start + 1, $off - 1, $depth); + } + if ($thread) { if (!$depth) { if ($node) {
