Overview

Packages

  • IMP
  • None

Classes

  • IMP
  • IMP_Ajax_Application
  • IMP_Ajax_Imple_ContactAutoCompleter
  • IMP_Ajax_Imple_PassphraseDialog
  • IMP_Ajax_Queue
  • IMP_Api
  • IMP_Auth
  • IMP_Block_Newmail
  • IMP_Block_Summary
  • IMP_Compose
  • IMP_Compose_Exception
  • IMP_Compose_Stationery
  • IMP_Contents
  • IMP_Crypt_Pgp
  • IMP_Crypt_Smime
  • IMP_Dimp
  • IMP_Exception
  • IMP_Factory_AuthImap
  • IMP_Factory_Compose
  • IMP_Factory_Contents
  • IMP_Factory_Flags
  • IMP_Factory_Identity
  • IMP_Factory_Imap
  • IMP_Factory_Imaptree
  • IMP_Factory_Mail
  • IMP_Factory_Mailbox
  • IMP_Factory_MailboxList
  • IMP_Factory_MimeViewer
  • IMP_Factory_Pgp
  • IMP_Factory_Quota
  • IMP_Factory_Search
  • IMP_Factory_Sentmail
  • IMP_Factory_Smime
  • IMP_Filter
  • IMP_Flag_Base
  • IMP_Flag_Imap
  • IMP_Flag_Imap_Answered
  • IMP_Flag_Imap_Deleted
  • IMP_Flag_Imap_Draft
  • IMP_Flag_Imap_Flagged
  • IMP_Flag_Imap_Forwarded
  • IMP_Flag_Imap_Junk
  • IMP_Flag_Imap_NotJunk
  • IMP_Flag_Imap_Seen
  • IMP_Flag_System_Attachment
  • IMP_Flag_System_Encrypted
  • IMP_Flag_System_HighPriority
  • IMP_Flag_System_List
  • IMP_Flag_System_LowPriority
  • IMP_Flag_System_Match_Address
  • IMP_Flag_System_Match_Flag
  • IMP_Flag_System_Match_Header
  • IMP_Flag_System_Personal
  • IMP_Flag_System_Signed
  • IMP_Flag_System_Unseen
  • IMP_Flag_User
  • IMP_Flags
  • IMP_Imap
  • IMP_Imap_Acl
  • IMP_Imap_Exception
  • IMP_Imap_PermanentFlags
  • IMP_Imap_Thread
  • IMP_Imap_Tree
  • IMP_Indices
  • IMP_Indices_Form
  • IMP_LoginTasks_SystemTask_GarbageCollection
  • IMP_LoginTasks_SystemTask_Upgrade
  • IMP_LoginTasks_SystemTask_UpgradeAuth
  • IMP_LoginTasks_Task_Autocreate
  • IMP_LoginTasks_Task_DeleteAttachmentsMonthly
  • IMP_LoginTasks_Task_DeleteSentmailMonthly
  • IMP_LoginTasks_Task_FilterOnLogin
  • IMP_LoginTasks_Task_PurgeSentmail
  • IMP_LoginTasks_Task_PurgeSpam
  • IMP_LoginTasks_Task_PurgeTrash
  • IMP_LoginTasks_Task_RecoverDraft
  • IMP_LoginTasks_Task_RenameSentmailMonthly
  • IMP_Mailbox
  • IMP_Mailbox_List
  • IMP_Mailbox_List_Track
  • IMP_Maillog
  • IMP_Menu_Dimp
  • IMP_Message
  • IMP_Mime_Status
  • IMP_Mime_Viewer_Alternative
  • IMP_Mime_Viewer_Appledouble
  • IMP_Mime_Viewer_Audio
  • IMP_Mime_Viewer_Enriched
  • IMP_Mime_Viewer_Externalbody
  • IMP_Mime_Viewer_Html
  • IMP_Mime_Viewer_Images
  • IMP_Mime_Viewer_Itip
  • IMP_Mime_Viewer_Mdn
  • IMP_Mime_Viewer_Partial
  • IMP_Mime_Viewer_Pdf
  • IMP_Mime_Viewer_Pgp
  • IMP_Mime_Viewer_Plain
  • IMP_Mime_Viewer_Related
  • IMP_Mime_Viewer_Rfc822
  • IMP_Mime_Viewer_Smil
  • IMP_Mime_Viewer_Smime
  • IMP_Mime_Viewer_Status
  • IMP_Mime_Viewer_Vcard
  • IMP_Mime_Viewer_Video
  • IMP_Mime_Viewer_Zip
  • IMP_Notification_Event_Status
  • IMP_Notification_Handler_Decorator_ImapAlerts
  • IMP_Notification_Handler_Decorator_NewmailNotify
  • IMP_Notification_Listener_AjaxStatus
  • Imp_Prefs_Identity
  • IMP_Prefs_Ui
  • IMP_Quota
  • IMP_Quota_Base
  • IMP_Quota_Command
  • IMP_Quota_Hook
  • IMP_Quota_Imap
  • IMP_Quota_Maildir
  • IMP_Quota_Mdaemon
  • IMP_Quota_Mercury32
  • IMP_Quota_Null
  • IMP_Quota_Sql
  • IMP_Search
  • IMP_Search_Element
  • IMP_Search_Element_Attachment
  • IMP_Search_Element_Autogenerated
  • IMP_Search_Element_Bulk
  • IMP_Search_Element_Contacts
  • IMP_Search_Element_Date
  • IMP_Search_Element_Flag
  • IMP_Search_Element_Header
  • IMP_Search_Element_Mailinglist
  • IMP_Search_Element_Or
  • IMP_Search_Element_Personal
  • IMP_Search_Element_Recipient
  • IMP_Search_Element_Size
  • IMP_Search_Element_Text
  • IMP_Search_Element_Within
  • IMP_Search_Filter
  • IMP_Search_Filter_Attachment
  • IMP_Search_Filter_Autogenerated
  • IMP_Search_Filter_Builtin
  • IMP_Search_Filter_Bulk
  • IMP_Search_Filter_Contacts
  • IMP_Search_Filter_Mailinglist
  • IMP_Search_Filter_Personal
  • IMP_Search_Query
  • IMP_Search_Vfolder
  • IMP_Search_Vfolder_Builtin
  • IMP_Search_Vfolder_Vinbox
  • IMP_Search_Vfolder_Vtrash
  • IMP_Sentmail
  • IMP_Sentmail_Base
  • IMP_Sentmail_Null
  • IMP_Sentmail_Sql
  • IMP_Spam
  • IMP_Test
  • IMP_Tree_Flist
  • IMP_Tree_Jquerymobile
  • IMP_Tree_Simplehtml
  • IMP_Ui_Compose
  • IMP_Ui_Editor
  • IMP_Ui_Folder
  • IMP_Ui_Headers
  • IMP_Ui_Imageview
  • IMP_Ui_Mailbox
  • IMP_Ui_Message
  • IMP_Ui_Mimp
  • IMP_Ui_Search
  • IMP_Views_Compose
  • IMP_Views_ListMessages
  • IMP_Views_ShowMessage
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Dynamic (dimp) message list logic.
  4:  *
  5:  * Copyright 2005-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file COPYING for license information (GPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/gpl.
  9:  *
 10:  * @author   Michael Slusarz <slusarz@horde.org>
 11:  * @category Horde
 12:  * @license  http://www.horde.org/licenses/gpl GPL
 13:  * @package  IMP
 14:  */
 15: class IMP_Views_ListMessages
 16: {
 17:     /* String used to separate mailboxes/indexes in search mailboxes. */
 18:     const IDX_SEP = "\0";
 19: 
 20:     /**
 21:      * Does the flags hook exist?
 22:      *
 23:      * @var boolean
 24:      */
 25:     protected $_flaghook = true;
 26: 
 27:     /**
 28:      * Returns a list of messages for use with ViewPort.
 29:      *
 30:      * @var array $args  TODO
 31:      *   - applyfilter: (boolean) If true, apply filters to mailbox.
 32:      *   - change: (boolean)
 33:      *   - initial: (boolean) Is this the initial load of the view?
 34:      *   - mbox: (string) The mailbox of the view.
 35:      *   - qsearch: (boolean) Is this a quicksearch?
 36:      *   - qsearchfield: (string) The quicksearch search criteria.
 37:      *   - qsearchmbox: (string) The mailbox to do the quicksearch in
 38:      *                  (base64url encoded).
 39:      *   - qsearchfilter: TODO
 40:      *
 41:      * @return array  TODO
 42:      */
 43:     public function listMessages($args)
 44:     {
 45:         global $injector;
 46: 
 47:         $initial = $args['initial'];
 48:         $is_search = false;
 49:         $mbox = IMP_Mailbox::get($args['mbox']);
 50:         $sortpref = $mbox->getSort();
 51: 
 52:         /* Check for quicksearch request. */
 53:         if (strlen($args['qsearchmbox'])) {
 54:             $qsearch_mbox = IMP_Mailbox::formFrom($args['qsearchmbox']);
 55: 
 56:             if (strlen($args['qsearchfilter'])) {
 57:                 $injector->getInstance('IMP_Search')->applyFilter($args['qsearchfilter'], array($qsearch_mbox), $mbox);
 58:                 $is_search = true;
 59:             } else {
 60:                 /* Create the search query. */
 61:                 $c_list = array();
 62: 
 63:                 if (strlen($args['qsearchflag'])) {
 64:                     $c_list[] = new IMP_Search_Element_Flag(
 65:                         $args['qsearchflag'],
 66:                         empty($args['qsearchflagnot'])
 67:                     );
 68: 
 69:                     $is_search = true;
 70:                 } elseif (strlen($args['qsearch'])) {
 71:                     $GLOBALS['prefs']->setValue('dimp_qsearch_field', $args['qsearchfield']);
 72:                     $is_search = true;
 73: 
 74:                     switch ($args['qsearchfield']) {
 75:                     case 'all':
 76:                     case 'body':
 77:                         $c_list[] = new IMP_Search_Element_Text(
 78:                             $args['qsearch'],
 79:                             ($args['qsearchfield'] == 'body')
 80:                         );
 81:                         break;
 82: 
 83:                     case 'from':
 84:                     case 'subject':
 85:                         $c_list[] = new IMP_Search_Element_Header(
 86:                             $args['qsearch'],
 87:                             $args['qsearchfield']
 88:                         );
 89:                     break;
 90: 
 91:                     case 'recip':
 92:                         $c_list[] = new IMP_Search_Element_Recipient(
 93:                             $args['qsearch']
 94:                         );
 95:                         break;
 96: 
 97:                     default:
 98:                         $is_search = false;
 99:                         break;
100:                     }
101:                 }
102: 
103:                 /* Store the search in the session. */
104:                 if ($is_search) {
105:                     $injector->getInstance('IMP_Search')->createQuery($c_list, array(
106:                         'id' => $mbox,
107:                         'mboxes' => array($qsearch_mbox),
108:                         'type' => IMP_Search::CREATE_QUERY
109:                     ));
110:                 }
111:             }
112:         } else {
113:             $is_search = $mbox->search;
114:         }
115: 
116:         /* Set the current time zone. */
117:         $GLOBALS['registry']->setTimeZone();
118: 
119:         /* Run filters now. */
120:         if (!empty($args['applyfilter'])) {
121:             $mbox->filter();
122:         } elseif ($mbox->inbox) {
123:             $mbox->filterOnDisplay();
124:         }
125: 
126:         /* Generate the sorted mailbox list now. */
127:         $mailbox_list = $mbox->getListOb();
128:         $msgcount = count($mailbox_list);
129: 
130:         /* Create the base object. */
131:         $result = $this->getBaseOb($mbox);
132:         $result->cacheid = $mbox->cacheid_date;
133:         if (!empty($args['requestid'])) {
134:             $result->requestid = intval($args['requestid']);
135:         }
136:         $result->totalrows = $msgcount;
137:         if (!$args['initial']) {
138:             unset($result->label);
139:         }
140: 
141:         $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create();
142: 
143:         /* Check for UIDVALIDITY expiration. It is the first element in the
144:          * cacheid returned from the browser. If it has changed, we need to
145:          * purge the cached items on the browser. */
146:         $parsed = null;
147:         if ($args['cacheid'] && $args['cache']) {
148:             $uid_expire = false;
149:             $parsed = $imp_imap->parseCacheId($args['cacheid']);
150: 
151:             if ($parsed['date'] != date('mdy')) {
152:                 $uid_expire = true;
153:             } elseif (!$is_search) {
154:                 try {
155:                     $status = $imp_imap->status($mbox, Horde_Imap_Client::STATUS_UIDVALIDITY);
156:                     $uid_expire = ($parsed['uidvalidity'] != $status['uidvalidity']);
157:                 } catch (Horde_Imap_Cache_Exception $e) {
158:                     $uid_expire = true;
159:                 }
160:             }
161: 
162:             if ($uid_expire) {
163:                 $args['cache'] = array();
164:                 $args['initial'] = true;
165:                 $result->data_reset = $result->metadata_reset = 1;
166:             }
167:         }
168: 
169:         /* Mail-specific viewport information. */
170:         $md = &$result->metadata;
171:         if (($args['initial'] ||
172:              $args['delhide'] ||
173:              !is_null($args['sortby'])) &&
174:             $mbox->hideDeletedMsgs(true)) {
175:             $md->delhide = 1;
176:         }
177:         if ($args['initial'] || !is_null($args['sortby'])) {
178:             $md->sortby = intval($sortpref['by']);
179:         }
180:         if ($args['initial'] || !is_null($args['sortdir'])) {
181:             $md->sortdir = intval($sortpref['dir']);
182:         }
183:         if ($args['initial'] && $sortpref['locked']) {
184:             $md->sortlock = 1;
185:         }
186: 
187:         /* Actions only done on 'initial' request. */
188:         if ($args['initial']) {
189:             if (!$mbox->access_sortthread) {
190:                 $md->nothread = 1;
191:             }
192:             if ($mbox->special_outgoing) {
193:                 $md->special = 1;
194:                 if ($mbox == IMP_Mailbox::getPref('drafts_folder')) {
195:                     $md->drafts = 1;
196:                 }
197:             } elseif ($mbox == IMP_Mailbox::getPref('spam_folder')) {
198:                 $md->spam = 1;
199:             }
200: 
201:             if ($is_search) {
202:                 $md->search = 1;
203:             }
204: 
205:             /* Generate flag array. */
206:             $flaglist = $injector->getInstance('IMP_Flags')->getList(array(
207:                 'imap' => true,
208:                 'mailbox' => $is_search ? null : $mbox
209:             ));
210: 
211:             $md->flags = array();
212:             foreach ($flaglist as $val) {
213:                 $md->flags[] = $val->imapflag;
214:             }
215:         }
216: 
217:         /* The search query may have changed. */
218:         if ($is_search &&
219:             ($args['initial'] || strlen($args['qsearchmbox']))) {
220:             $imp_search = $injector->getInstance('IMP_Search');
221: 
222:             if ($mbox->vfolder) {
223:                 $md->slabel = $imp_search[$mbox]->label;
224:                 $md->vfolder = 1;
225:                 if (!$imp_search->isVFolder($mbox, true)) {
226:                     $md->noedit = 1;
227:                 }
228:             } else {
229:                 $md->slabel = $imp_search[$mbox]->querytext;
230:             }
231:         }
232: 
233:         /* These entries may change during a session, so always need to
234:          * update them. */
235:         $md->readonly = intval($mbox->readonly);
236:         if (!$md->readonly) {
237:             if (!$mbox->access_deletemsgs) {
238:                 $md->nodelete = 1;
239:             }
240:             if (!$mbox->access_expunge) {
241:                 $md->noexpunge = 1;
242:             }
243:         }
244: 
245:         /* Check for mailbox existence now. If there are no messages, there
246:          * is a chance that the mailbox doesn't exist. If there is at least
247:          * 1 message, we don't need this check. */
248:         if (empty($msgcount) && !$is_search) {
249:             if (!$mbox->exists) {
250:                 $GLOBALS['notification']->push(sprintf(_("Mailbox %s does not exist."), $mbox->label), 'horde.error');
251:             }
252: 
253:             if (!empty($args['change'])) {
254:                 unset($result->data, $result->rowlist, $result->totalrows);
255:                 $result->data_reset = $result->rowlist_reset = 1;
256:             }
257: 
258:             return $result;
259:         }
260: 
261:         /* TODO: This can potentially be optimized for arrival time sort - if
262:          * the cache ID changes, we know the changes must occur at end of
263:          * mailbox. */
264:         if (!isset($result->data_reset) && !empty($args['change'])) {
265:             $result->rowlist_reset = 1;
266:         }
267: 
268:         /* Get the cached list. */
269:         $cached = array();
270:         if (!empty($args['cache'])) {
271:             foreach ($imp_imap->getUtils()->fromSequenceString($args['cache']) as $key => $uids) {
272:                 $key = IMP_Mailbox::formFrom($key);
273: 
274:                 foreach ($uids as $val) {
275:                     $cached[] = $is_search
276:                         ? $this->searchUid($key, $val)
277:                         : $val;
278:                 }
279:             }
280:             $cached = array_flip($cached);
281:         }
282: 
283:         if (!empty($args['search_unseen'])) {
284:             /* Do an unseen search.  We know what messages the browser
285:              * doesn't have based on $cached. Thus, search for the first
286:              * unseen message not located in $cached. */
287:             $unseen_search = $mailbox_list->unseenMessages(Horde_Imap_Client::SORT_RESULTS_MATCH, true);
288:             if (!($uid_search = array_diff($unseen_search['match']->ids, array_keys($cached)))) {
289:                 return $result;
290:             }
291:             $rownum = $mailbox_list->getArrayIndex(reset($uid_search));
292:         } elseif (!empty($args['search_uid'])) {
293:             $rownum = $mailbox_list->getArrayIndex($args['search_uid'], $mbox);
294:         }
295: 
296:         /* If this is the initial request for a mailbox, figure out the
297:          * starting location based on user's preferences. */
298:         $rownum = ($initial || (isset($rownum) && is_null($rownum)))
299:                 ? intval($mailbox_list->mailboxStart($msgcount))
300:                 : null;
301: 
302:         /* Determine the row slice to process. */
303:         if (is_null($rownum)) {
304:             $slice_start = $args['slice_start'];
305:             $slice_end = $args['slice_end'];
306:         } else {
307:             $slice_start = $rownum - $args['before'];
308:             $slice_end = $rownum + $args['after'];
309:             if ($slice_start < 1) {
310:                 $slice_end += abs($slice_start) + 1;
311:             } elseif ($slice_end > $msgcount) {
312:                 $slice_start -= $slice_end - $msgcount;
313:             }
314: 
315:             $result->rownum = $rownum;
316:         }
317: 
318:         $slice_start = max(1, $slice_start);
319:         $slice_end = min($msgcount, $slice_end);
320: 
321:         /* Generate UID list. */
322:         $changed = $data = $msglist = $rowlist = $uidlist = array();
323:         foreach ($mailbox_list as $key => $val) {
324:             $uidlist[] = $is_search
325:                 ? $this->searchUid($val['m'], $val['u'])
326:                 : $val['u'];
327:         }
328: 
329:         /* If we are updating the rowlist on the browser, and we have cached
330:          * browser data information, we need to send a list of messages that
331:          * have 'disappeared'. */
332:         if (!empty($cached) && isset($result->rowlist_reset)) {
333:             $disappear = array();
334:             foreach (array_diff(array_keys($cached), $uidlist) as $uid) {
335:                 $disappear[] = $uid;
336:                 unset($cached[$uid]);
337:             }
338:             if (!empty($disappear)) {
339:                 $result->disappear = $disappear;
340:             }
341:         }
342: 
343:         /* Check for cached entries marked as changed via CONDSTORE IMAP
344:          * extension. If changed, resend the entire entry to update the
345:          * browser cache (done below). */
346:         if (!empty($cached) &&
347:             !$is_search &&
348:             !is_null($parsed) &&
349:             !empty($parsed['highestmodseq'])) {
350:             $status = $imp_imap->status($mbox, Horde_Imap_Client::STATUS_LASTMODSEQ | Horde_Imap_Client::STATUS_LASTMODSEQUIDS);
351:             if ($status['lastmodseq'] == $parsed['highestmodseq']) {
352:                 /* QRESYNC already provided the updated list of flags - we can
353:                  * grab the updated UIDS through this STATUS call and save a
354:                  * FETCH. */
355:                 $changed = array_flip($status['lastmodsequids']);
356:             } else {
357:                 $query = new Horde_Imap_Client_Fetch_Query();
358:                 $query->uid();
359: 
360:                 try {
361:                     $changed = $imp_imap->fetch($mbox, $query, array(
362:                         'changedsince' => $parsed['highestmodseq'],
363:                         'ids' => $imp_imap->getIdsOb(array_keys($cached))
364:                     ));
365:                 } catch (IMP_Imap_Exception $e) {}
366:             }
367:         }
368: 
369:         foreach (array_slice($uidlist, $slice_start - 1, $slice_end - $slice_start + 1, true) as $key => $uid) {
370:             $seq = ++$key;
371:             $msglist[$seq] = $mailbox_list[$seq]['u'];
372:             $rowlist[$uid] = $seq;
373:             /* Send browser message data if not already cached or if CONDSTORE
374:              * has indicated that data has changed. */
375:             if (!isset($cached[$uid]) || isset($changed[$uid])) {
376:                 $data[$seq] = 1;
377:             }
378:         }
379:         $result->rowlist = $rowlist;
380: 
381:         /* Build the list for rangeslice information. */
382:         if ($args['rangeslice']) {
383:             $slice = new stdClass;
384:             $slice->rangelist = array_keys($rowlist);
385:             $slice->view = $mbox->form_to;
386: 
387:             return $slice;
388:         }
389: 
390:         /* Build the overview list. */
391:         $result->data = $this->_getOverviewData($mbox, array_keys($data));
392: 
393:         /* Get thread information. */
394:         if (!$is_search &&
395:             ($sortpref['by'] == Horde_Imap_Client::SORT_THREAD)) {
396:             $imp_thread = new IMP_Imap_Thread($mailbox_list->getThreadOb());
397:             $md->thread = (object)$imp_thread->getThreadTreeOb($msglist, $sortpref['dir']);
398:         }
399: 
400:         return $result;
401:     }
402: 
403:     /**
404:      * Obtains IMAP overview data for a given set of message UIDs.
405:      *
406:      * @param IMP_Mailbox $mbox  The current mailbox.
407:      * @param array $msglist     The list of message sequence numbers to
408:      *                           process.
409:      *
410:      * @return array  TODO
411:      * @throws Horde_Exception
412:      */
413:     private function _getOverviewData($mbox, $msglist)
414:     {
415:         $msgs = array();
416: 
417:         if (empty($msglist)) {
418:             return $msgs;
419:         }
420: 
421:         /* Get mailbox information. */
422:         $overview = $mbox->getListOb()->getMailboxArray($msglist, array(
423:             'headers' => true,
424:             'type' => $GLOBALS['prefs']->getValue('atc_flag')
425:         ));
426:         $imp_imap = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create();
427:         $imp_ui = new IMP_Ui_Mailbox($mbox);
428: 
429:         $flags = $imp_imap->access(IMP_Imap::ACCESS_FLAGS);
430:         $pop3 = $imp_imap->pop3;
431:         $search = $mbox->search;
432: 
433:         /* Display message information. */
434:         reset($overview['overview']);
435:         while (list(,$ob) = each($overview['overview'])) {
436:             /* Initialize the header fields. */
437:             $msg = array(
438:                 'flag' => array(),
439:                 'mbox' => IMP_Mailbox::formTo($ob['mailbox']),
440:                 'uid' => ($pop3 ? $ob['uid'] : intval($ob['uid']))
441:             );
442: 
443:             /* Get all the flag information. */
444:             if ($flags) {
445:                 if ($this->_flaghook) {
446:                     try {
447:                         $ob['flags'] = array_merge($ob['flags'], Horde::callHook('msglist_flags', array($ob, 'dimp'), 'imp'));
448:                     } catch (Horde_Exception_HookNotSet $e) {
449:                         $this->_flaghook = false;
450:                     }
451:                 }
452: 
453:                 $flag_parse = $GLOBALS['injector']->getInstance('IMP_Flags')->parse(array(
454:                     'flags' => $ob['flags'],
455:                     'headers' => $ob['headers'],
456:                     'personal' => Horde_Mime_Address::getAddressesFromObject($ob['envelope']->to, array('charset' => 'UTF-8'))
457:                 ));
458: 
459:                 foreach ($flag_parse as $val) {
460:                     $msg['flag'][] = $val->id;
461:                 }
462:             }
463: 
464:             /* Format size information. */
465:             $msg['size'] = htmlspecialchars($imp_ui->getSize($ob['size']), ENT_QUOTES, 'UTF-8');
466: 
467:             /* Format the Date: Header. */
468:             $msg['date'] = htmlspecialchars($imp_ui->getDate($ob['envelope']->date), ENT_QUOTES, 'UTF-8');
469: 
470:             /* Format the From: Header. */
471:             $getfrom = $imp_ui->getFrom($ob['envelope'], array('specialchars' => 'UTF-8'));
472:             $msg['from'] = $getfrom['from'];
473: 
474:             /* Format the Subject: Header. */
475:             $msg['subject'] = $imp_ui->getSubject($ob['envelope']->subject, true);
476: 
477:             /* Check to see if this is a list message. Namely, we want to
478:              * check for 'List-Post' information because that is the header
479:              * that gives the e-mail address to reply to, which is all we
480:              * care about. */
481:             if ($ob['headers']->getValue('list-post')) {
482:                 $msg['listmsg'] = 1;
483:             }
484: 
485:             /* Need both mailbox and UID to create a unique ID string if
486:              * using a search mailbox.  Otherwise, use only the UID. */
487:             if ($search) {
488:                 $msgs[$this->searchUid($ob['mailbox'], $ob['uid'])] = $msg;
489:             } else {
490:                 $msgs[$ob['uid']] = $msg;
491:             }
492:         }
493: 
494:         /* Allow user to alter template array. */
495:         try {
496:             $msgs = Horde::callHook('mailboxarray', array($msgs, 'dimp'), 'imp');
497:         } catch (Horde_Exception_HookNotSet $e) {}
498: 
499:         return $msgs;
500:     }
501: 
502:     /**
503:      * Prepare the base object used by the ViewPort javascript class.
504:      *
505:      * @param IMP_Mailbox $mbox  The mailbox object.
506:      *
507:      * @return object  The base ViewPort object.
508:      */
509:     public function getBaseOb(IMP_Mailbox $mbox)
510:     {
511:         $ob = new stdClass;
512:         $ob->cacheid = 0;
513:         $ob->data = array();
514:         $ob->label = htmlspecialchars($mbox->label);
515:         $ob->metadata = new stdClass;
516:         $ob->rowlist = array();
517:         $ob->totalrows = 0;
518:         $ob->view = $mbox->form_to;
519: 
520:         return $ob;
521:     }
522: 
523:     /**
524:      * Generate the ViewPort UID to use for search mailboxes.
525:      *
526:      * @param string $mbox  Message mailbox.
527:      * @param string $uid   Message UID.
528:      *
529:      * @return string  ViewPort UID.
530:      */
531:     static public function searchUid($mbox, $uid)
532:     {
533:         return IMP::base64urlEncode(strval($mbox) . self::IDX_SEP . $uid);
534:     }
535: 
536: }
537: 
API documentation generated by ApiGen