1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17: 18: 19: 20: 21: 22:
23: class IMP_Ajax_Application_ListMessages
24: {
25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
41: public function listMessages($args)
42: {
43: global $injector, $notification;
44:
45: $is_search = false;
46: $mbox = IMP_Mailbox::get($args['mbox']);
47: $sortpref = $mbox->getSort(true);
48:
49:
50: if (strlen($args['qsearchmbox'])) {
51: $qsearch_mbox = IMP_Mailbox::formFrom($args['qsearchmbox']);
52:
53: if (strlen($args['qsearchfilter'])) {
54: $injector->getInstance('IMP_Search')->applyFilter($args['qsearchfilter'], array($qsearch_mbox), $mbox);
55: $is_search = true;
56: } else {
57:
58: $c_list = array();
59:
60: if (strlen($args['qsearchflag'])) {
61: $c_list[] = new IMP_Search_Element_Flag(
62: $args['qsearchflag'],
63: empty($args['qsearchflagnot'])
64: );
65:
66: $is_search = true;
67: } elseif (strlen($args['qsearch'])) {
68: $is_search = true;
69:
70: switch ($args['qsearchfield']) {
71: case 'all':
72: case 'body':
73: $c_list[] = new IMP_Search_Element_Text(
74: $args['qsearch'],
75: ($args['qsearchfield'] == 'body')
76: );
77: break;
78:
79: case 'from':
80: case 'subject':
81: $c_list[] = new IMP_Search_Element_Header(
82: $args['qsearch'],
83: $args['qsearchfield']
84: );
85: break;
86:
87: case 'recip':
88: $c_list[] = new IMP_Search_Element_Recipient(
89: $args['qsearch']
90: );
91: break;
92:
93: default:
94: $is_search = false;
95: break;
96: }
97: }
98:
99:
100: if ($is_search) {
101: $injector->getInstance('IMP_Search')->createQuery($c_list, array(
102: 'id' => $mbox,
103: 'mboxes' => array($qsearch_mbox),
104: 'type' => IMP_Search::CREATE_QUERY
105: ));
106: }
107: }
108: } else {
109: $is_search = $mbox->search;
110: }
111:
112:
113: if (!empty($args['applyfilter'])) {
114: $mbox->filter();
115: } elseif ($mbox->inbox) {
116: $mbox->filterOnDisplay();
117: }
118:
119: 120:
121: $imp_imap = $mbox->imp_imap;
122: $imp_imap->openMailbox($mbox, Horde_Imap_Client::OPEN_READWRITE);
123:
124:
125: $result = new IMP_Ajax_Application_Viewport($mbox);
126: $result->label = $mbox->label;
127:
128: if ($is_search) {
129: 130: 131:
132: if (!empty($args['change'])) {
133: $args['cache'] = array();
134: $args['change'] = true;
135: $result->data_reset = $result->rowlist_reset = true;
136: }
137: } elseif (!$args['initial'] && $args['cacheid'] && $args['cache']) {
138: 139:
140: $parsed = $imp_imap->parseCacheId($args['cacheid']);
141: $uid_expire = true;
142:
143: if ($parsed['date'] == date('z')) {
144: try {
145: $imp_imap->sync($mbox, $parsed['token'], array(
146: 'criteria' => Horde_Imap_Client::SYNC_UIDVALIDITY
147: ));
148: $uid_expire = false;
149: } catch (Horde_Imap_Client_Exception_Sync $e) {}
150: }
151:
152: if ($uid_expire) {
153: $args['cache'] = array();
154: $args['initial'] = true;
155: $result->data_reset = $result->metadata_reset = true;
156: }
157: } else {
158: $parsed = null;
159: }
160:
161:
162: if (($args['initial'] ||
163: $args['delhide'] ||
164: !is_null($args['sortby'])) &&
165: $mbox->hideDeletedMsgs(true)) {
166: $result->setMetadata('delhide', 1);
167: }
168: if ($args['initial'] ||
169: !is_null($args['sortby']) ||
170: !is_null($args['sortdir'])) {
171: $result->setMetadata('sortby', $sortpref->sortby);
172: $result->setMetadata('sortdir', $sortpref->sortdir);
173: }
174:
175:
176: if ($args['initial']) {
177:
178: $injector->getInstance('IMP_Ajax_Queue')->quota($mbox, true);
179:
180: if (!$mbox->is_imap) {
181: $result->setMetadata('pop3', 1);
182: }
183: if ($sortpref->sortby_locked) {
184: $result->setMetadata('sortbylock', 1);
185: }
186: if ($sortpref->sortdir_locked) {
187: $result->setMetadata('sortdirlock', 1);
188: }
189: if (!$mbox->access_sortthread) {
190: $result->setMetadata('nothread', 1);
191: }
192: if ($mbox->special_outgoing) {
193: $result->setMetadata('special', 1);
194: if ($mbox->drafts) {
195: $result->setMetadata('drafts', 1);
196: } elseif ($mbox->templates) {
197: $result->setMetadata('templates', 1);
198: }
199: } elseif ($mbox->spam) {
200: $result->setMetadata('innocent_show', 1);
201: if ($mbox->spam_show) {
202: $result->setMetadata('spam_show', 1);
203: }
204: } else {
205: if ($mbox->innocent_show) {
206: $result->setMetadata('innocent_show', 1);
207: }
208: $result->setMetadata('spam_show', 1);
209: }
210:
211: if ($is_search) {
212: $result->setMetadata('innocent_show', 1);
213: $result->setMetadata('search', 1);
214: $result->setMetadata('spam_show', 1);
215: }
216:
217: $result->addFlagMetadata();
218: }
219:
220:
221: if ($is_search &&
222: ($args['initial'] || strlen($args['qsearchmbox']))) {
223: $imp_search = $injector->getInstance('IMP_Search');
224:
225: if ($mbox->vfolder) {
226: $result->setMetadata('slabel', $imp_search[$mbox]->label);
227: $result->setMetadata('vfolder', 1);
228: if (!$imp_search->isVFolder($mbox, true)) {
229: $result->setMetadata('noedit', 1);
230: }
231: } else {
232: $result->setMetadata('slabel', $imp_search[$mbox]->querytext);
233: }
234: }
235:
236: 237:
238: if ($mbox->readonly) {
239: $result->setMetadata('readonly', 1);
240: $result->setMetadata('nodelete', 1);
241: $result->setMetadata('expunge', 1);
242: } else {
243: if (!$mbox->access_deletemsgs) {
244: $result->setMetadata('nodelete', 1);
245: }
246: if (!$mbox->access_expunge) {
247: $result->setMetadata('noexpunge', 1);
248: }
249: }
250:
251:
252: $mailbox_list = $mbox->list_ob;
253: if ($is_search && (!empty($args['change']) || $args['initial'])) {
254: $mailbox_list->rebuild(true);
255: }
256:
257: $msgcount = count($mailbox_list);
258:
259: 260: 261:
262: if (empty($msgcount) && !$is_search) {
263: if (!$mbox->exists) {
264: $notification->push(sprintf(_("Mailbox %s does not exist."), $mbox->label), 'horde.error');
265: }
266:
267: if (!empty($args['change'])) {
268: $result->data_reset = true;
269: $result->rowlist_reset = true;
270: }
271:
272: return $result;
273: }
274:
275: $result->totalrows = $msgcount;
276:
277: 278: 279:
280: if (!$result->data_reset && !empty($args['change'])) {
281: $result->rowlist_reset = true;
282: }
283:
284:
285: if (empty($args['cache'])) {
286: $cached = array();
287: } else {
288: $cache_indices = new IMP_Indices($mbox, $args['cache']);
289: $cache_uids = $cache_indices->getSingle(true);
290: $cached = array_flip($cache_uids[1]);
291: }
292:
293: if (!$is_search && !empty($args['search_unseen'])) {
294: 295: 296:
297: $unseen_search = $mailbox_list->unseenMessages(Horde_Imap_Client::SEARCH_RESULTS_MATCH, array('uids' => true));
298: if (!($uid_search = array_diff($unseen_search['match']->ids, array_keys($cached)))) {
299: return $result;
300: }
301: $rownum = $mailbox_list->getArrayIndex(reset($uid_search));
302: } elseif (!empty($args['search_buid'])) {
303: $search_buid = $mailbox_list->resolveBuid($args['search_buid']);
304: $rownum = $mailbox_list->getArrayIndex($search_buid['u'], $search_buid['m']);
305: }
306:
307: 308:
309: $rownum = (($args['initial'] && !isset($rownum)) || (isset($rownum) && is_null($rownum)))
310: ? intval($mailbox_list->mailboxStart($msgcount))
311: : (isset($rownum) ? ($rownum + 1) : null);
312:
313:
314: if (is_null($rownum) || isset($args['slice_start'])) {
315: $slice_start = $args['slice_start'];
316: $slice_end = $args['slice_end'];
317: } else {
318: $slice_start = $rownum - $args['before'];
319: $slice_end = $rownum + $args['after'];
320: if ($slice_start < 1) {
321: $slice_end += abs($slice_start) + 1;
322: } elseif ($slice_end > $msgcount) {
323: $slice_start -= $slice_end - $msgcount;
324: }
325: }
326:
327: if (!is_null($rownum)) {
328: $result->rownum = $rownum;
329: }
330:
331: $slice_start = max(1, $slice_start);
332: $slice_end = min($msgcount, $slice_end);
333:
334:
335: $buidlist = $changed = $data = $msglist = $rowlist = array();
336: foreach ($mailbox_list as $val) {
337: $buidlist[] = $mailbox_list->getBuid($val['m'], $val['u']);
338: }
339:
340: 341: 342:
343: if (!empty($cached) && $result->rowlist_reset) {
344: $disappear = array();
345: foreach (array_diff(array_keys($cached), $buidlist) as $uid) {
346: $disappear[] = $uid;
347: unset($cached[$uid]);
348: }
349: if (!empty($disappear)) {
350: $result->disappear = $disappear;
351: }
352: }
353:
354: 355:
356: if (!empty($cached) && !$is_search && !is_null($parsed)) {
357: $sync_ob = $imp_imap->sync($mbox, $parsed['token'], array(
358: 'criteria' => Horde_Imap_Client::SYNC_FLAGSUIDS,
359: 'ids' => $imp_imap->getIdsOb(array_keys($cached))
360: ));
361: $changed = array_flip($sync_ob->flagsuids->ids);
362: }
363:
364: foreach (array_slice($buidlist, $slice_start - 1, $slice_end - $slice_start + 1, true) as $key => $uid) {
365: $seq = ++$key;
366: $msglist[$seq] = $mailbox_list[$seq]['u'];
367: $rowlist[$uid] = $seq;
368: 369:
370: if (!isset($cached[$uid]) || isset($changed[$uid])) {
371: $data[$seq] = 1;
372: }
373: }
374:
375:
376: if ($args['rangeslice']) {
377: $slice = new IMP_Ajax_Application_Viewport($mbox);
378: $slice->rangelist = array_keys($rowlist);
379: return $slice;
380: }
381:
382: $result->rowlist = $rowlist;
383:
384:
385: $result->data = $this->_getOverviewData($mbox, array_keys($data));
386:
387:
388: if ($sortpref->sortby == Horde_Imap_Client::SORT_THREAD) {
389: $thread = new stdClass;
390: foreach ($msglist as $key => $val) {
391: $tmp = $mailbox_list->getThreadOb($key);
392: $thread->$val = $sortpref->sortdir
393: ? $tmp->reverse_raw
394: : $tmp->raw;
395: }
396:
397: $result->setMetadata('thread', $thread);
398: }
399:
400: return $result;
401: }
402:
403: 404: 405: 406: 407: 408: 409: 410: 411: 412:
413: private function _getOverviewData($mbox, $msglist)
414: {
415: global $injector, $prefs;
416:
417: $msgs = array();
418:
419: if (empty($msglist)) {
420: return $msgs;
421: }
422:
423:
424: $flags = $mbox->access_flags;
425: $imp_flags = $injector->getInstance('IMP_Flags');
426: $imp_ui = new IMP_Mailbox_Ui($mbox);
427: $list_ob = $mbox->list_ob;
428: $overview = $list_ob->getMailboxArray($msglist, array(
429: 'headers' => true,
430: 'type' => $prefs->getValue('atc_flag')
431: ));
432:
433:
434: reset($overview['overview']);
435: while (list(,$ob) = each($overview['overview'])) {
436:
437: $msg = array(
438: 'flag' => $flags
439: ? array_map('strval', $imp_flags->parse(array(
440: 'flags' => $ob['flags'],
441: 'headers' => $ob['headers'],
442: 'runhook' => $ob,
443: 'personal' => $ob['envelope']->to
444: )))
445: : array()
446: );
447:
448:
449: $msg['size'] = IMP::sizeFormat($ob['size']);
450:
451:
452: $msg['date'] = strval(new IMP_Message_Date(
453: isset($ob['envelope']->date) ? $ob['envelope']->date : null
454: ));
455:
456:
457: $getfrom = $imp_ui->getFrom($ob['envelope']);
458: $msg['from'] = $getfrom['from'];
459: if ($getfrom['from'] !== $getfrom['from_addr']) {
460: $msg['fromaddr'] = $getfrom['from_addr'];
461: }
462:
463:
464: $msg['subject'] = $imp_ui->getSubject($ob['envelope']->subject);
465:
466: 467: 468: 469:
470: if ($ob['headers']->getValue('list-post')) {
471: $msg['listmsg'] = 1;
472: }
473:
474: $msgs[$list_ob->getBuid($ob['mailbox'], $ob['uid'])] = $msg;
475: }
476:
477:
478: try {
479: $msgs = $injector->getInstance('Horde_Core_Hooks')->callHook(
480: 'mailboxarray',
481: 'imp',
482: array($msgs)
483: );
484: } catch (Horde_Exception_HookNotSet $e) {}
485:
486: return $msgs;
487: }
488:
489: }
490: