Overview

Packages

  • IMP

Classes

  • IMP
  • IMP_Ajax_Addresses
  • IMP_Ajax_Application
  • IMP_Ajax_Application_Compose
  • IMP_Ajax_Application_Handler_Common
  • IMP_Ajax_Application_Handler_ComposeAttach
  • IMP_Ajax_Application_Handler_Draft
  • IMP_Ajax_Application_Handler_Dynamic
  • IMP_Ajax_Application_Handler_ImageUnblock
  • IMP_Ajax_Application_Handler_Mboxtoggle
  • IMP_Ajax_Application_Handler_Passphrase
  • IMP_Ajax_Application_Handler_Remote
  • IMP_Ajax_Application_Handler_RemotePrefs
  • IMP_Ajax_Application_Handler_Search
  • IMP_Ajax_Application_Handler_Smartmobile
  • IMP_Ajax_Application_ListMessages
  • IMP_Ajax_Application_ShowMessage
  • IMP_Ajax_Application_Viewport
  • IMP_Ajax_Application_Viewport_Error
  • IMP_Ajax_Imple_ImportEncryptKey
  • IMP_Ajax_Imple_ItipRequest
  • IMP_Ajax_Imple_PassphraseDialog
  • IMP_Ajax_Imple_VcardImport
  • IMP_Ajax_Queue
  • IMP_Api
  • IMP_Application
  • IMP_Auth
  • IMP_Basic_Base
  • IMP_Basic_Compose
  • IMP_Basic_Contacts
  • IMP_Basic_Error
  • IMP_Basic_Folders
  • IMP_Basic_Listinfo
  • IMP_Basic_Mailbox
  • IMP_Basic_Message
  • IMP_Basic_Pgp
  • IMP_Basic_Saveimage
  • IMP_Basic_Search
  • IMP_Basic_Searchbasic
  • IMP_Basic_Smime
  • IMP_Basic_Thread
  • IMP_Block_Newmail
  • IMP_Block_Summary
  • IMP_Compose
  • IMP_Compose_Attachment
  • IMP_Compose_Attachment_Linked_Metadata
  • IMP_Compose_Attachment_Metadata
  • IMP_Compose_Attachment_Storage
  • IMP_Compose_Attachment_Storage_AutoDetermine
  • IMP_Compose_Attachment_Storage_Temp
  • IMP_Compose_Attachment_Storage_VfsLinked
  • IMP_Compose_Exception
  • IMP_Compose_Exception_Address
  • IMP_Compose_HtmlSignature
  • IMP_Compose_Link
  • IMP_Compose_LinkedAttachment
  • IMP_Compose_Ui
  • IMP_Compose_View
  • IMP_Contacts
  • IMP_Contacts_Avatar_Addressbook
  • IMP_Contacts_Avatar_Gravatar
  • IMP_Contacts_Avatar_Unknown
  • IMP_Contacts_Flag_Host
  • IMP_Contacts_Image
  • IMP_Contents
  • IMP_Contents_InlineOutput
  • IMP_Contents_View
  • IMP_Crypt_Pgp
  • IMP_Crypt_Smime
  • IMP_Dynamic_AddressList
  • IMP_Dynamic_Base
  • IMP_Dynamic_Compose
  • IMP_Dynamic_Compose_Common
  • IMP_Dynamic_Helper_Base
  • IMP_Dynamic_Mailbox
  • IMP_Dynamic_Message
  • IMP_Exception
  • IMP_Factory_AuthImap
  • IMP_Factory_Compose
  • IMP_Factory_ComposeAtc
  • IMP_Factory_Contacts
  • IMP_Factory_Contents
  • IMP_Factory_Flags
  • IMP_Factory_Ftree
  • IMP_Factory_Identity
  • IMP_Factory_Imap
  • IMP_Factory_Mail
  • IMP_Factory_MailAutoconfig
  • IMP_Factory_Mailbox
  • IMP_Factory_MailboxCache
  • IMP_Factory_MailboxList
  • IMP_Factory_Maillog
  • IMP_Factory_MimeViewer
  • IMP_Factory_Pgp
  • IMP_Factory_PrefsSort
  • IMP_Factory_Quota
  • IMP_Factory_Search
  • IMP_Factory_Sentmail
  • IMP_Factory_Smime
  • IMP_Factory_Spam
  • 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_Ftree
  • IMP_Ftree_Account
  • IMP_Ftree_Account_Imap
  • IMP_Ftree_Account_Inboxonly
  • IMP_Ftree_Account_Remote
  • IMP_Ftree_Account_Vfolder
  • IMP_Ftree_Element
  • IMP_Ftree_Eltdiff
  • IMP_Ftree_Iterator
  • IMP_Ftree_Iterator_Ancestors
  • IMP_Ftree_IteratorFilter
  • IMP_Ftree_IteratorFilter_Children
  • IMP_Ftree_IteratorFilter_Containers
  • IMP_Ftree_IteratorFilter_Expanded
  • IMP_Ftree_IteratorFilter_Invisible
  • IMP_Ftree_IteratorFilter_Mailboxes
  • IMP_Ftree_IteratorFilter_Nonimap
  • IMP_Ftree_IteratorFilter_Polled
  • IMP_Ftree_IteratorFilter_Remote
  • IMP_Ftree_IteratorFilter_Special
  • IMP_Ftree_IteratorFilter_Subscribed
  • IMP_Ftree_IteratorFilter_Vfolder
  • IMP_Ftree_Prefs
  • IMP_Ftree_Prefs_Expanded
  • IMP_Ftree_Prefs_Poll
  • IMP_Ftree_Select
  • IMP_Images
  • IMP_Imap
  • IMP_Imap_Acl
  • IMP_Imap_Cache_Wrapper
  • IMP_Imap_Config
  • IMP_Imap_Exception
  • IMP_Imap_Password
  • IMP_Imap_PermanentFlags
  • IMP_Imap_Remote
  • IMP_Indices
  • IMP_Indices_Mailbox
  • 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_Pop3
  • IMP_Mailbox_List_Thread
  • IMP_Mailbox_List_Virtual
  • IMP_Mailbox_SessionCache
  • IMP_Mailbox_Ui
  • IMP_Maillog
  • IMP_Maillog_Log_Base
  • IMP_Maillog_Log_Forward
  • IMP_Maillog_Log_Mdn
  • IMP_Maillog_Log_Redirect
  • IMP_Maillog_Log_Reply
  • IMP_Maillog_Log_Replyall
  • IMP_Maillog_Log_Replylist
  • IMP_Maillog_Message
  • IMP_Maillog_Storage_Base
  • IMP_Maillog_Storage_Composite
  • IMP_Maillog_Storage_History
  • IMP_Maillog_Storage_Mdnsent
  • IMP_Maillog_Storage_Null
  • IMP_Mbox_Generate
  • IMP_Mbox_Import
  • IMP_Mbox_Size
  • IMP_Message
  • IMP_Message_Date
  • IMP_Message_Ui
  • IMP_Mime_Headers
  • IMP_Mime_Status
  • IMP_Mime_Status_RenderIssue
  • IMP_Mime_Status_RenderIssue_Display
  • 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_Minimal_Base
  • IMP_Minimal_Compose
  • IMP_Minimal_Error
  • IMP_Minimal_Folders
  • IMP_Minimal_Mailbox
  • IMP_Minimal_Message
  • IMP_Minimal_Messagepart
  • IMP_Minimal_Search
  • IMP_Notification_Event_Status
  • IMP_Notification_Handler_Decorator_ImapAlerts
  • IMP_Notification_Handler_Decorator_NewmailNotify
  • IMP_Perms
  • IMP_Prefs_AttribText
  • IMP_Prefs_Identity
  • IMP_Prefs_Sort
  • IMP_Prefs_Sort_FixedDate
  • IMP_Prefs_Sort_None
  • IMP_Prefs_Sort_Sortpref
  • IMP_Prefs_Sort_Sortpref_Locked
  • IMP_Prefs_Special_Acl
  • IMP_Prefs_Special_ComposeTemplates
  • IMP_Prefs_Special_Drafts
  • IMP_Prefs_Special_Encrypt
  • IMP_Prefs_Special_Flag
  • IMP_Prefs_Special_HtmlSignature
  • IMP_Prefs_Special_ImageReplacement
  • IMP_Prefs_Special_InitialPage
  • IMP_Prefs_Special_Mailto
  • IMP_Prefs_Special_NewmailSound
  • IMP_Prefs_Special_PgpPrivateKey
  • IMP_Prefs_Special_PgpPublicKey
  • IMP_Prefs_Special_Remote
  • IMP_Prefs_Special_Searches
  • IMP_Prefs_Special_Sentmail
  • IMP_Prefs_Special_SmimePrivateKey
  • IMP_Prefs_Special_SmimePublicKey
  • IMP_Prefs_Special_Sourceselect
  • IMP_Prefs_Special_Spam
  • IMP_Prefs_Special_SpecialMboxes
  • IMP_Prefs_Special_Trash
  • IMP_Quota
  • IMP_Quota_Hook
  • IMP_Quota_Imap
  • IMP_Quota_Null
  • IMP_Quota_Ui
  • IMP_Remote
  • IMP_Remote_Account
  • IMP_Script_Package_Autocomplete
  • IMP_Script_Package_ComposeBase
  • IMP_Script_Package_DynamicBase
  • IMP_Script_Package_Editor
  • IMP_Script_Package_Imp
  • IMP_Search
  • IMP_Search_Element
  • IMP_Search_Element_Attachment
  • IMP_Search_Element_Autogenerated
  • IMP_Search_Element_Bulk
  • IMP_Search_Element_Contacts
  • IMP_Search_Element_Daterange
  • 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_IteratorFilter
  • IMP_Search_Query
  • IMP_Search_Ui
  • IMP_Search_Vfolder
  • IMP_Search_Vfolder_Builtin
  • IMP_Search_Vfolder_Vinbox
  • IMP_Search_Vfolder_Vtrash
  • IMP_Sentmail
  • IMP_Sentmail_Mongo
  • IMP_Sentmail_Null
  • IMP_Sentmail_Sql
  • IMP_Smartmobile
  • IMP_Spam
  • IMP_Spam_Email
  • IMP_Spam_Null
  • IMP_Spam_Program
  • IMP_Test
  • IMP_Tree_Flist
  • IMP_Tree_Jquerymobile
  • IMP_Tree_Simplehtml
  • IMP_View_Subinfo

Interfaces

  • IMP_Compose_Attachment_Linked
  • IMP_Contacts_Avatar_Backend
  • IMP_Contacts_Flag_Backend
  • IMP_Spam_Base
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Copyright 2005-2014 Horde LLC (http://www.horde.org/)
  4:  *
  5:  * See the enclosed file COPYING for license information (GPL). If you
  6:  * did not receive this file, see http://www.horde.org/licenses/gpl.
  7:  *
  8:  * @category  Horde
  9:  * @copyright 2005-2014 Horde LLC
 10:  * @license   http://www.horde.org/licenses/gpl GPL
 11:  * @package   IMP
 12:  */
 13: 
 14: /**
 15:  * Message listing action for AJAX application handler.
 16:  *
 17:  * @author    Michael Slusarz <slusarz@horde.org>
 18:  * @category  Horde
 19:  * @copyright 2005-2014 Horde LLC
 20:  * @license   http://www.horde.org/licenses/gpl GPL
 21:  * @package   IMP
 22:  */
 23: class IMP_Ajax_Application_ListMessages
 24: {
 25:     /**
 26:      * Returns a list of messages for use with ViewPort.
 27:      *
 28:      * @var array $args  TODO
 29:      *   - applyfilter: (boolean) If true, apply filters to mailbox.
 30:      *   - change: (boolean) True if the cache value has changed.
 31:      *   - initial: (boolean) Is this the initial load of the view?
 32:      *   - mbox: (string) The mailbox of the view.
 33:      *   - qsearch: (string) The quicksearch search string.
 34:      *   - qsearchfield: (string) The quicksearch search criteria.
 35:      *   - qsearchmbox: (string) The mailbox to do the quicksearch in
 36:      *                  (base64url encoded).
 37:      *   - qsearchfilter: TODO
 38:      *
 39:      * @return IMP_Ajax_Application_Viewport  Viewport data object.
 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:         /* Check for quicksearch request. */
 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:                 /* Create the search query. */
 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:                 /* Store the search in the session. */
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:         /* Run filters now. */
113:         if (!empty($args['applyfilter'])) {
114:             $mbox->filter();
115:         } elseif ($mbox->inbox) {
116:             $mbox->filterOnDisplay();
117:         }
118: 
119:         /* Optimization: saves at least a STATUS and an EXAMINE call since
120:          * we will eventually open mailbox READ-WRITE. */
121:         $imp_imap = $mbox->imp_imap;
122:         $imp_imap->openMailbox($mbox, Horde_Imap_Client::OPEN_READWRITE);
123: 
124:         /* Create the base object. */
125:         $result = new IMP_Ajax_Application_Viewport($mbox);
126:         $result->label = $mbox->label;
127: 
128:         if ($is_search) {
129:             /* For search mailboxes, we need to invalidate all browser data
130:              * and repopulate on force update, since BUIDs may have
131:              * changed (TODO: only do this if search mailbox has changed?). */
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:             /* Check for UIDVALIDITY expiration. If it has changed, we need to
139:              * purge the cached items on the browser. */
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:         /* Mail-specific viewport information. */
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:         /* Actions only done on 'initial' request. */
176:         if ($args['initial']) {
177:             /* Load quota information on original request. */
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:         /* The search query may have changed. */
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:         /* These entries may change during a session, so always need to
237:          * update them. */
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:         /* Generate the sorted mailbox list now. */
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:         /* Check for mailbox existence now. If there are no messages, there
260:          * is a chance that the mailbox doesn't exist. If there is at least
261:          * 1 message, we don't need this check. */
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:         /* TODO: This can potentially be optimized for arrival time sort - if
278:          * the cache ID changes, we know the changes must occur at end of
279:          * mailbox. */
280:         if (!$result->data_reset && !empty($args['change'])) {
281:             $result->rowlist_reset = true;
282:         }
283: 
284:         /* Get the cached list. */
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:             /* Do an unseen search.  We know what messages the browser
295:              * doesn't have based on $cached. Thus, search for the first
296:              * unseen message not located in $cached. */
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:         /* If this is the initial request for a mailbox, figure out the
308:          * starting location based on user's preferences. */
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:         /* Determine the row slice to process. */
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:         /* Generate BUID list. */
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:         /* If we are updating the rowlist on the browser, and we have cached
341:          * browser data information, we need to send a list of messages that
342:          * have 'disappeared'. */
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:         /* Check for cached entries marked as changed. If changed, resend the
355:          * entire entry to update the browser cache (done below). */
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:             /* Send browser message data if not already cached or if CONDSTORE
369:              * has indicated that data has changed. */
370:             if (!isset($cached[$uid]) || isset($changed[$uid])) {
371:                 $data[$seq] = 1;
372:             }
373:         }
374: 
375:         /* Build the list for rangeslice information. */
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:         /* Build the overview list. */
385:         $result->data = $this->_getOverviewData($mbox, array_keys($data));
386: 
387:         /* Get thread information. */
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:      * 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:         global $injector, $prefs;
416: 
417:         $msgs = array();
418: 
419:         if (empty($msglist)) {
420:             return $msgs;
421:         }
422: 
423:         /* Get mailbox information. */
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:         /* Display message information. */
434:         reset($overview['overview']);
435:         while (list(,$ob) = each($overview['overview'])) {
436:             /* Get all the flag information. */
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:             /* Format size information. */
449:             $msg['size'] = IMP::sizeFormat($ob['size']);
450: 
451:             /* Format the Date: Header. */
452:             $msg['date'] = strval(new IMP_Message_Date(
453:                 isset($ob['envelope']->date) ? $ob['envelope']->date : null
454:             ));
455: 
456:             /* Format the From: Header. */
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:             /* Format the Subject: Header. */
464:             $msg['subject'] = $imp_ui->getSubject($ob['envelope']->subject);
465: 
466:             /* Check to see if this is a list message. Namely, we want to
467:              * check for 'List-Post' information because that is the header
468:              * that gives the e-mail address to reply to, which is all we
469:              * care about. */
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:         /* Allow user to alter template array. */
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: 
API documentation generated by ApiGen