comparison program/lib/Roundcube/rcube_result_multifolder.php @ 0:4681f974d28b

vanilla 1.3.3 distro, I hope
author Charlie Root
date Thu, 04 Jan 2018 15:52:31 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4681f974d28b
1 <?php
2
3 /**
4 +-----------------------------------------------------------------------+
5 | This file is part of the Roundcube Webmail client |
6 | Copyright (C) 2005-2011, The Roundcube Dev Team |
7 | Copyright (C) 2011, Kolab Systems AG |
8 | |
9 | Licensed under the GNU General Public License version 3 or |
10 | any later version with exceptions for skins & plugins. |
11 | See the README file for a full license statement. |
12 | |
13 | PURPOSE: |
14 | SORT/SEARCH/ESEARCH response handler |
15 +-----------------------------------------------------------------------+
16 | Author: Thomas Bruederli <roundcube@gmail.com> |
17 +-----------------------------------------------------------------------+
18 */
19
20 /**
21 * Class holding a set of rcube_result_index instances that together form a
22 * result set of a multi-folder search
23 *
24 * @package Framework
25 * @subpackage Storage
26 */
27 class rcube_result_multifolder
28 {
29 public $multi = true;
30 public $sets = array();
31 public $incomplete = false;
32 public $folder;
33
34 protected $meta = array();
35 protected $index = array();
36 protected $folders = array();
37 protected $sdata = array();
38 protected $order = 'ASC';
39 protected $sorting;
40
41
42 /**
43 * Object constructor.
44 */
45 public function __construct($folders = array())
46 {
47 $this->folders = $folders;
48 $this->meta = array('count' => 0);
49 }
50
51 /**
52 * Initializes object with SORT command response
53 *
54 * @param string $data IMAP response string
55 */
56 public function add($result)
57 {
58 $this->sets[] = $result;
59
60 if ($result->count()) {
61 $this->append_result($result);
62 }
63 else if ($result->incomplete) {
64 $this->incomplete = true;
65 }
66 }
67
68 /**
69 * Append message UIDs from the given result to our index
70 */
71 protected function append_result($result)
72 {
73 $this->meta['count'] += $result->count();
74
75 // append UIDs to global index
76 $folder = $result->get_parameters('MAILBOX');
77 $index = array_map(function($uid) use ($folder) { return $uid . '-' . $folder; }, $result->get());
78
79 $this->index = array_merge($this->index, $index);
80 }
81
82 /**
83 * Store a global index of (sorted) message UIDs
84 */
85 public function set_message_index($headers, $sort_field, $sort_order)
86 {
87 $this->index = array();
88 foreach ($headers as $header) {
89 $this->index[] = $header->uid . '-' . $header->folder;
90 }
91
92 $this->sorting = $sort_field;
93 $this->order = $sort_order;
94 }
95
96 /**
97 * Checks the result from IMAP command
98 *
99 * @return bool True if the result is an error, False otherwise
100 */
101 public function is_error()
102 {
103 return false;
104 }
105
106 /**
107 * Checks if the result is empty
108 *
109 * @return bool True if the result is empty, False otherwise
110 */
111 public function is_empty()
112 {
113 return empty($this->sets) || $this->meta['count'] == 0;
114 }
115
116 /**
117 * Returns number of elements in the result
118 *
119 * @return int Number of elements
120 */
121 public function count()
122 {
123 return $this->meta['count'];
124 }
125
126 /**
127 * Returns number of elements in the result.
128 * Alias for count() for compatibility with rcube_result_thread
129 *
130 * @return int Number of elements
131 */
132 public function count_messages()
133 {
134 return $this->count();
135 }
136
137 /**
138 * Reverts order of elements in the result
139 */
140 public function revert()
141 {
142 $this->order = $this->order == 'ASC' ? 'DESC' : 'ASC';
143 $this->index = array_reverse($this->index);
144
145 // revert order in all sub-sets
146 foreach ($this->sets as $set) {
147 if ($this->order != $set->get_parameters('ORDER')) {
148 $set->revert();
149 }
150 }
151 }
152
153 /**
154 * Check if the given message ID exists in the object
155 *
156 * @param int $msgid Message ID
157 * @param bool $get_index When enabled element's index will be returned.
158 * Elements are indexed starting with 0
159 * @return mixed False if message ID doesn't exist, True if exists or
160 * index of the element if $get_index=true
161 */
162 public function exists($msgid, $get_index = false)
163 {
164 if (!empty($this->folder)) {
165 $msgid .= '-' . $this->folder;
166 }
167
168 return array_search($msgid, $this->index);
169 }
170
171 /**
172 * Filters data set. Removes elements listed in $ids list.
173 *
174 * @param array $ids List of IDs to remove.
175 * @param string $folder IMAP folder
176 */
177 public function filter($ids = array(), $folder = null)
178 {
179 $this->meta['count'] = 0;
180 foreach ($this->sets as $set) {
181 if ($set->get_parameters('MAILBOX') == $folder) {
182 $set->filter($ids);
183 }
184
185 $this->meta['count'] += $set->count();
186 }
187 }
188
189 /**
190 * Slices data set.
191 *
192 * @param int $offset Offset (as for PHP's array_slice())
193 * @param int $length Number of elements (as for PHP's array_slice())
194 */
195 public function slice($offset, $length)
196 {
197 $data = array_slice($this->get(), $offset, $length);
198
199 $this->index = $data;
200 $this->meta['count'] = count($data);
201 }
202
203 /**
204 * Filters data set. Removes elements not listed in $ids list.
205 *
206 * @param array $ids List of IDs to keep.
207 */
208 public function intersect($ids = array())
209 {
210 // not implemented
211 }
212
213 /**
214 * Return all messages in the result.
215 *
216 * @return array List of message IDs
217 */
218 public function get()
219 {
220 return $this->index;
221 }
222
223 /**
224 * Return all messages in the result in compressed form
225 *
226 * @return string List of message IDs in compressed form
227 */
228 public function get_compressed()
229 {
230 return '';
231 }
232
233 /**
234 * Return result element at specified index
235 *
236 * @param int|string $index Element's index or "FIRST" or "LAST"
237 *
238 * @return int Element value
239 */
240 public function get_element($idx)
241 {
242 switch ($idx) {
243 case 'FIRST': return $this->index[0];
244 case 'LAST': return end($this->index);
245 default: return $this->index[$idx];
246 }
247 }
248
249 /**
250 * Returns response parameters, e.g. ESEARCH's MIN/MAX/COUNT/ALL/MODSEQ
251 * or internal data e.g. MAILBOX, ORDER
252 *
253 * @param string $param Parameter name
254 *
255 * @return array|string Response parameters or parameter value
256 */
257 public function get_parameters($param=null)
258 {
259 $params = array(
260 'SORT' => $this->sorting,
261 'ORDER' => $this->order,
262 'MAILBOX' => $this->folders,
263 );
264
265 if ($param !== null) {
266 return $params[$param];
267 }
268
269 return $params;
270 }
271
272 /**
273 * Returns the stored result object for a particular folder
274 *
275 * @param string $folder Folder name
276 *
277 * @return false|object rcube_result_* instance of false if none found
278 */
279 public function get_set($folder)
280 {
281 foreach ($this->sets as $set) {
282 if ($set->get_parameters('MAILBOX') == $folder) {
283 return $set;
284 }
285 }
286
287 return false;
288 }
289
290 /**
291 * Returns length of internal data representation
292 *
293 * @return int Data length
294 */
295 protected function length()
296 {
297 return $this->count();
298 }
299
300
301 /* Serialize magic methods */
302
303 public function __sleep()
304 {
305 $this->sdata = array('incomplete' => array(), 'error' => array());
306
307 foreach ($this->sets as $set) {
308 if ($set->incomplete) {
309 $this->sdata['incomplete'][] = $set->get_parameters('MAILBOX');
310 }
311 else if ($set->is_error()) {
312 $this->sdata['error'][] = $set->get_parameters('MAILBOX');
313 }
314 }
315
316 return array('sdata', 'index', 'folders', 'sorting', 'order');
317 }
318
319 public function __wakeup()
320 {
321 $this->meta = array('count' => count($this->index));
322 $this->incomplete = count($this->sdata['incomplete']) > 0;
323
324 // restore result sets from saved index
325 $data = array();
326 foreach ($this->index as $item) {
327 list($uid, $folder) = explode('-', $item, 2);
328 $data[$folder] .= ' ' . $uid;
329 }
330
331 foreach ($this->folders as $folder) {
332 if (in_array($folder, $this->sdata['error'])) {
333 $data_str = null;
334 }
335 else {
336 $data_str = '* SORT' . $data[$folder];
337 }
338
339 $set = new rcube_result_index($folder, $data_str, strtoupper($this->order));
340
341 if (in_array($folder, $this->sdata['incomplete'])) {
342 $set->incomplete = true;
343 }
344
345 $this->sets[] = $set;
346 }
347 }
348 }