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 2002-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 2002-2014 Horde LLC
  10:  * @license   http://www.horde.org/licenses/gpl GPL
  11:  * @package   IMP
  12:  */
  13: 
  14: /**
  15:  * This class contains code related to generating and handling a mailbox
  16:  * message list.
  17:  *
  18:  * @author    Michael Slusarz <slusarz@horde.org>
  19:  * @category  Horde
  20:  * @copyright 2002-2014 Horde LLC
  21:  * @license   http://www.horde.org/licenses/gpl GPL
  22:  * @package   IMP
  23:  */
  24: class IMP_Mailbox_List
  25: implements ArrayAccess, Countable, Iterator, Serializable
  26: {
  27:     /* The UID count at which the sorted list will undergo UID compression
  28:      * when being serialized. */
  29:     const SERIALIZE_LIMIT = 500;
  30: 
  31:     /**
  32:      * Has the internal message list changed?
  33:      *
  34:      * @var boolean
  35:      */
  36:     public $changed = false;
  37: 
  38:     /**
  39:      * Max assigned browser-UID.
  40:      *
  41:      * @var integer
  42:      */
  43:     protected $_buidmax = 0;
  44: 
  45:     /**
  46:      * Mapping of browser-UIDs to UIDs.
  47:      *
  48:      * @var array
  49:      */
  50:     protected $_buids = array();
  51: 
  52:     /**
  53:      * The IMAP cache ID of the mailbox.
  54:      *
  55:      * @var string
  56:      */
  57:     protected $_cacheid = null;
  58: 
  59:     /**
  60:      * The location in the sorted array we are at.
  61:      *
  62:      * @var integer
  63:      */
  64:     protected $_index = null;
  65: 
  66:     /**
  67:      * The mailbox to work with.
  68:      *
  69:      * @var IMP_Mailbox
  70:      */
  71:     protected $_mailbox;
  72: 
  73:     /**
  74:      * The array of sorted indices.
  75:      *
  76:      * @var array
  77:      */
  78:     protected $_sorted = null;
  79: 
  80:     /**
  81:      * The thread object representation(s) for the mailbox.
  82:      *
  83:      * @var array
  84:      */
  85:     protected $_thread = array();
  86: 
  87:     /**
  88:      * The thread tree UI cached data.
  89:      *
  90:      * @var array
  91:      */
  92:     protected $_threadui = array();
  93: 
  94:     /**
  95:      * Constructor.
  96:      *
  97:      * @param string $mbox  The mailbox to work with.
  98:      */
  99:     public function __construct($mbox)
 100:     {
 101:         $this->_mailbox = IMP_Mailbox::get($mbox);
 102:     }
 103: 
 104:     /**
 105:      * Build the array of message information.
 106:      *
 107:      * @param array $msgnum   An array of index numbers.
 108:      * @param array $options  Additional options:
 109:      *   - headers: (boolean) Return info on the non-envelope headers
 110:      *              'Importance', 'List-Post', and 'X-Priority'.
 111:      *              DEFAULT: false (only envelope headers returned)
 112:      *   - preview: (mixed) Include preview information?  If empty, add no
 113:      *              preview information. If 1, uses value from prefs.
 114:      *              If 2, forces addition of preview info.
 115:      *              DEFAULT: No preview information.
 116:      *   - type: (boolean) Return info on the MIME Content-Type of the base
 117:      *           message part ('Content-Type' header).
 118:      *           DEFAULT: false
 119:      *
 120:      * @return array  An array with the following keys:
 121:      *   - overview: (array) The overview information. Contains the following:
 122:      *   - envelope: (Horde_Imap_Client_Data_Envelope) Envelope information
 123:      *               returned from the IMAP server.
 124:      *   - flags: (array) The list of IMAP flags returned from the server.
 125:      *   - headers: (array) Horde_Mime_Headers objects containing header data
 126:      *              if either $options['headers'] or $options['type'] are
 127:      *              true.
 128:      *   - idx: (integer) Array index of this message.
 129:      *   - mailbox: (string) The mailbox containing the message.
 130:      *   - preview: (string) If requested in $options['preview'], the preview
 131:      *              text.
 132:      *   - previewcut: (boolean) Has the preview text been cut?
 133:      *   - size: (integer) The size of the message in bytes.
 134:      *   - uid: (string) The unique ID of the message.
 135:      *   - uids: (IMP_Indices) An indices object.
 136:      */
 137:     public function getMailboxArray($msgnum, $options = array())
 138:     {
 139:         $this->_buildMailbox();
 140: 
 141:         $headers = $overview = $to_process = $uids = array();
 142: 
 143:         /* Build the list of mailboxes and messages. */
 144:         foreach ($msgnum as $i) {
 145:             /* Make sure that the index is actually in the slice of messages
 146:                we're looking at. If we're hiding deleted messages, for
 147:                example, there may be gaps here. */
 148:             if (isset($this->_sorted[$i - 1])) {
 149:                 $to_process[strval($this->_getMbox($i - 1))][$i] = $this->_sorted[$i - 1];
 150:             }
 151:         }
 152: 
 153:         $fetch_query = new Horde_Imap_Client_Fetch_Query();
 154:         $fetch_query->envelope();
 155:         $fetch_query->flags();
 156:         $fetch_query->size();
 157:         $fetch_query->uid();
 158: 
 159:         if (!empty($options['headers'])) {
 160:             $headers = array_merge($headers, array(
 161:                 'importance',
 162:                 'list-post',
 163:                 'x-priority'
 164:             ));
 165:         }
 166: 
 167:         if (!empty($options['type'])) {
 168:             $headers[] = 'content-type';
 169:         }
 170: 
 171:         if (!empty($headers)) {
 172:             $fetch_query->headers('imp', $headers, array(
 173:                 'cache' => true,
 174:                 'peek' => true
 175:             ));
 176:         }
 177: 
 178:         if (empty($options['preview'])) {
 179:             $cache = null;
 180:             $options['preview'] = 0;
 181:         } else {
 182:             $cache = $this->_mailbox->imp_imap->getCache();
 183:         }
 184: 
 185:         /* Retrieve information from each mailbox. */
 186:         foreach ($to_process as $mbox => $ids) {
 187:             try {
 188:                 $imp_imap = IMP_Mailbox::get($mbox)->imp_imap;
 189:                 $fetch_res = $imp_imap->fetch($mbox, $fetch_query, array(
 190:                     'ids' => $imp_imap->getIdsOb($ids)
 191:                 ));
 192: 
 193:                 if ($options['preview']) {
 194:                     $preview_info = $tostore = array();
 195:                     if ($cache) {
 196:                         try {
 197:                             $preview_info = $cache->get($mbox, $ids, array('IMPpreview', 'IMPpreviewc'));
 198:                         } catch (IMP_Imap_Exception $e) {}
 199:                     }
 200:                 }
 201: 
 202:                 $mbox_ids = array();
 203: 
 204:                 foreach ($ids as $k => $v) {
 205:                     if (!isset($fetch_res[$v])) {
 206:                         continue;
 207:                     }
 208: 
 209:                     $f = $fetch_res[$v];
 210:                     $uid = $f->getUid();
 211:                     $v = array(
 212:                         'envelope' => $f->getEnvelope(),
 213:                         'flags' => $f->getFlags(),
 214:                         'headers' => $f->getHeaders('imp', Horde_Imap_Client_Data_Fetch::HEADER_PARSE),
 215:                         'idx' => $k,
 216:                         'mailbox' => $mbox,
 217:                         'size' => $f->getSize(),
 218:                         'uid' => $uid
 219:                     );
 220: 
 221:                     if (($options['preview'] === 2) ||
 222:                         (($options['preview'] === 1) &&
 223:                          (!$GLOBALS['prefs']->getValue('preview_show_unread') ||
 224:                           !in_array(Horde_Imap_Client::FLAG_SEEN, $v['flags'])))) {
 225:                         if (empty($preview_info[$uid])) {
 226:                             try {
 227:                                 $imp_contents = $GLOBALS['injector']->getInstance('IMP_Factory_Contents')->create(new IMP_Indices($mbox, $uid));
 228:                                 $prev = $imp_contents->generatePreview();
 229:                                 $preview_info[$uid] = array(
 230:                                     'IMPpreview' => $prev['text'],
 231:                                     'IMPpreviewc' => $prev['cut']
 232:                                 );
 233:                                 if (!is_null($cache)) {
 234:                                     $tostore[$uid] = $preview_info[$uid];
 235:                                 }
 236:                             } catch (Exception $e) {
 237:                                 $preview_info[$uid] = array(
 238:                                     'IMPpreview' => '',
 239:                                     'IMPpreviewc' => false
 240:                                 );
 241:                             }
 242:                         }
 243: 
 244:                         $v['preview'] = $preview_info[$uid]['IMPpreview'];
 245:                         $v['previewcut'] = $preview_info[$uid]['IMPpreviewc'];
 246:                     }
 247: 
 248:                     $overview[] = $v;
 249:                     $mbox_ids[] = $uid;
 250:                 }
 251: 
 252:                 $uids[$mbox] = $mbox_ids;
 253: 
 254:                 if (!is_null($cache) && !empty($tostore)) {
 255:                     $status = $imp_imap->status($mbox, Horde_Imap_Client::STATUS_UIDVALIDITY);
 256:                     $cache->set($mbox, $tostore, $status['uidvalidity']);
 257:                 }
 258:             } catch (IMP_Imap_Exception $e) {}
 259:         }
 260: 
 261:         return array(
 262:             'overview' => $overview,
 263:             'uids' => new IMP_Indices($uids)
 264:         );
 265:     }
 266: 
 267:     /**
 268:      * Using the preferences and the current mailbox, determines the messages
 269:      * to view on the current page (if using a paged view).
 270:      *
 271:      * @param integer $page   The page number currently being displayed.
 272:      * @param integer $start  The starting message number.
 273:      *
 274:      * @return array  An array with the following fields:
 275:      *   - anymsg: (boolean) Are there any messages at all in mailbox? E.g. If
 276:      *             'msgcount' is 0, there may still be hidden deleted messages.
 277:      *   - begin: (integer) The beginning message sequence number of the page.
 278:      *   - end: (integer) The ending message sequence number of the page.
 279:      *   - msgcount: (integer) The number of viewable messages in the current
 280:      *               mailbox.
 281:      *   - page: (integer) The current page number.
 282:      *   - pagecount: (integer) The number of pages in this mailbox.
 283:      */
 284:     public function buildMailboxPage($page = 0, $start = 0)
 285:     {
 286:         global $prefs, $session;
 287: 
 288:         $this->_buildMailbox();
 289: 
 290:         $ret = array('msgcount' => count($this->_sorted));
 291: 
 292:         $page_size = max($prefs->getValue('max_msgs'), 1);
 293: 
 294:         if ($ret['msgcount'] > $page_size) {
 295:             $ret['pagecount'] = ceil($ret['msgcount'] / $page_size);
 296: 
 297:             /* Determine which page to display. */
 298:             if (empty($page) || strcspn($page, '0123456789')) {
 299:                 if (!empty($start)) {
 300:                     /* Messages set this when returning to a mailbox. */
 301:                     $page = ceil($start / $page_size);
 302:                 } else {
 303:                     /* Search for the last visited page first. */
 304:                     $page = $session->exists('imp', 'mbox_page/' . $this->_mailbox)
 305:                         ? $session->get('imp', 'mbox_page/' . $this->_mailbox)
 306:                         : ceil($this->mailboxStart($ret['msgcount']) / $page_size);
 307:                 }
 308:             }
 309: 
 310:             /* Make sure we're not past the end or before the beginning, and
 311:                that we have an integer value. */
 312:             $ret['page'] = intval($page);
 313:             if ($ret['page'] > $ret['pagecount']) {
 314:                 $ret['page'] = $ret['pagecount'];
 315:             } elseif ($ret['page'] < 1) {
 316:                 $ret['page'] = 1;
 317:             }
 318: 
 319:             $ret['begin'] = (($ret['page'] - 1) * $page_size) + 1;
 320:             $ret['end'] = $ret['begin'] + $page_size - 1;
 321:             if ($ret['end'] > $ret['msgcount']) {
 322:                 $ret['end'] = $ret['msgcount'];
 323:             }
 324:         } else {
 325:             $ret['begin'] = 1;
 326:             $ret['end'] = $ret['msgcount'];
 327:             $ret['page'] = 1;
 328:             $ret['pagecount'] = 1;
 329:         }
 330: 
 331:         /* If there are no viewable messages, check for deleted messages in
 332:            the mailbox. */
 333:         $ret['anymsg'] = true;
 334:         if (!$ret['msgcount'] && !$this->_mailbox->search) {
 335:             try {
 336:                 $status = $this->_mailbox->imp_imap->status($this->_mailbox, Horde_Imap_Client::STATUS_MESSAGES);
 337:                 $ret['anymsg'] = (bool)$status['messages'];
 338:             } catch (IMP_Imap_Exception $e) {
 339:                 $ret['anymsg'] = false;
 340:             }
 341:         }
 342: 
 343:         /* Store the page value now. */
 344:         $session->set('imp', 'mbox_page/' . $this->_mailbox, $ret['page']);
 345: 
 346:         return $ret;
 347:     }
 348: 
 349:     /**
 350:      * Returns true if the mailbox data has been built.
 351:      *
 352:      * @return boolean  True if the mailbox has been built.
 353:      */
 354:     public function isBuilt()
 355:     {
 356:         return !is_null($this->_sorted);
 357:     }
 358: 
 359:     /**
 360:      * Builds the sorted list of messages in the mailbox.
 361:      */
 362:     protected function _buildMailbox()
 363:     {
 364:         $cacheid = $this->_mailbox->cacheid;
 365: 
 366:         if ($this->isBuilt() && ($this->_cacheid == $cacheid)) {
 367:             return;
 368:         }
 369: 
 370:         $this->changed = true;
 371:         $this->_cacheid = $cacheid;
 372:         $this->_sorted = array();
 373: 
 374:         $query_ob = $this->_buildMailboxQuery();
 375:         $sortpref = $this->_mailbox->getSort(true);
 376:         $thread_sort = ($sortpref->sortby == Horde_Imap_Client::SORT_THREAD);
 377: 
 378:         if ($this->_mailbox->access_search &&
 379:             $this->_mailbox->hideDeletedMsgs()) {
 380:             $delete_query = new Horde_Imap_Client_Search_Query();
 381:             $delete_query->flag(Horde_Imap_Client::FLAG_DELETED, false);
 382: 
 383:             if (is_null($query_ob)) {
 384:                 $query_ob = array(strval($this->_mailbox) => $delete_query);
 385:             } else {
 386:                 foreach ($query_ob as $val) {
 387:                     $val->andSearch($delete_query);
 388:                 }
 389:             }
 390:         }
 391: 
 392:         if (is_null($query_ob)) {
 393:             $query_ob = array(strval($this->_mailbox) => null);
 394:         }
 395: 
 396:         if ($thread_sort) {
 397:             $this->_thread = $this->_threadui = array();
 398:         }
 399: 
 400:         foreach ($query_ob as $mbox => $val) {
 401:             if ($thread_sort) {
 402:                 $this->_getThread($mbox, $val ? array('search' => $val) : array());
 403:                 $sorted = $this->_thread[$mbox]->messageList()->ids;
 404:                 if ($sortpref->sortdir) {
 405:                     $sorted = array_reverse($sorted);
 406:                 }
 407:             } else {
 408:                 $res = IMP_Mailbox::get($mbox)->imp_imap->search($mbox, $val, array(
 409:                     'sort' => array($sortpref->sortby)
 410:                 ));
 411:                 if ($sortpref->sortdir) {
 412:                     $res['match']->reverse();
 413:                 }
 414:                 $sorted = $res['match']->ids;
 415:             }
 416: 
 417:             $this->_sorted = array_merge($this->_sorted, $sorted);
 418:             $this->_buildMailboxProcess($mbox, $sorted);
 419:         }
 420:     }
 421: 
 422:     /**
 423:      */
 424:     protected function _buildMailboxQuery()
 425:     {
 426:         return null;
 427:     }
 428: 
 429:     /**
 430:      */
 431:     protected function _buildMailboxProcess($mbox, $sorted)
 432:     {
 433:     }
 434: 
 435:     /**
 436:      * Get the list of unseen messages in the mailbox (IMAP UNSEEN flag, with
 437:      * UNDELETED if we're hiding deleted messages).
 438:      *
 439:      * @param integer $results  A Horde_Imap_Client::SEARCH_RESULTS_* constant
 440:      *                          that indicates the desired return type.
 441:      * @param array $opts       Additional options:
 442:      *   - sort: (array) List of sort criteria to use.
 443:      *   - uids: (boolean) Return UIDs instead of sequence numbers (for
 444:      *           $results queries that return message lists).
 445:      *           DEFAULT: false
 446:      *
 447:      * @return mixed  Whatever is requested in $results.
 448:      */
 449:     public function unseenMessages($results, array $opts = array())
 450:     {
 451:         $count = ($results == Horde_Imap_Client::SEARCH_RESULTS_COUNT);
 452: 
 453:         if (empty($this->_sorted)) {
 454:             return $count ? 0 : array();
 455:         }
 456: 
 457:         $criteria = new Horde_Imap_Client_Search_Query();
 458:         $imp_imap = $this->_mailbox->imp_imap;
 459: 
 460:         if ($this->_mailbox->hideDeletedMsgs()) {
 461:             $criteria->flag(Horde_Imap_Client::FLAG_DELETED, false);
 462:         } elseif ($count) {
 463:             try {
 464:                 $status_res = $imp_imap->status($this->_mailbox, Horde_Imap_Client::STATUS_UNSEEN);
 465:                 return $status_res['unseen'];
 466:             } catch (IMP_Imap_Exception $e) {
 467:                 return 0;
 468:             }
 469:         }
 470: 
 471:         $criteria->flag(Horde_Imap_Client::FLAG_SEEN, false);
 472: 
 473:         try {
 474:             $res = $imp_imap->search($this->_mailbox, $criteria, array(
 475:                 'results' => array($results),
 476:                 'sequence' => empty($opts['uids']),
 477:                 'sort' => empty($opts['sort']) ? null : $opts['sort']
 478:             ));
 479:             return $count ? $res['count'] : $res;
 480:         } catch (IMP_Imap_Exception $e) {
 481:             return $count ? 0 : array();
 482:         }
 483:     }
 484: 
 485:     /**
 486:      * Determines the sequence number of the first message to display, based
 487:      * on the user's preferences.
 488:      *
 489:      * @param integer $total  The total number of messages in the mailbox.
 490:      *
 491:      * @return integer  The sequence number in the sorted mailbox.
 492:      */
 493:     public function mailboxStart($total)
 494:     {
 495:         switch ($GLOBALS['prefs']->getValue('mailbox_start')) {
 496:         case IMP::MAILBOX_START_FIRSTPAGE:
 497:             return 1;
 498: 
 499:         case IMP::MAILBOX_START_LASTPAGE:
 500:             return $total;
 501: 
 502:         case IMP::MAILBOX_START_FIRSTUNSEEN:
 503:             if (!$this->_mailbox->access_sort) {
 504:                 return 1;
 505:             }
 506: 
 507:             $sortpref = $this->_mailbox->getSort();
 508: 
 509:             /* Optimization: if sorting by sequence then first unseen
 510:              * information is returned via a SELECT/EXAMINE call. */
 511:             if ($sortpref->sortby == Horde_Imap_Client::SORT_SEQUENCE) {
 512:                 try {
 513:                     $res = $this->_mailbox->imp_imap->status($this->_mailbox, Horde_Imap_Client::STATUS_FIRSTUNSEEN | Horde_Imap_Client::STATUS_MESSAGES);
 514:                     if (!is_null($res['firstunseen'])) {
 515:                         return $sortpref->sortdir
 516:                             ? ($res['messages'] - $res['firstunseen'] + 1)
 517:                             : $res['firstunseen'];
 518:                     }
 519:                 } catch (IMP_Imap_Exception $e) {}
 520: 
 521:                 return 1;
 522:             }
 523: 
 524:             $unseen_msgs = $this->unseenMessages(Horde_Imap_Client::SEARCH_RESULTS_MIN, array(
 525:                 'sort' => array(Horde_Imap_Client::SORT_DATE),
 526:                 'uids' => true
 527:             ));
 528:             return empty($unseen_msgs['min'])
 529:                 ? 1
 530:                 : ($this->getArrayIndex($unseen_msgs['min']) + 1);
 531: 
 532:         case IMP::MAILBOX_START_LASTUNSEEN:
 533:             if (!$this->_mailbox->access_sort) {
 534:                 return 1;
 535:             }
 536: 
 537:             $unseen_msgs = $this->unseenMessages(Horde_Imap_Client::SEARCH_RESULTS_MAX, array(
 538:                 'sort' => array(Horde_Imap_Client::SORT_DATE),
 539:                 'uids' => true
 540:             ));
 541:             return empty($unseen_msgs['max'])
 542:                 ? 1
 543:                 : ($this->getArrayIndex($unseen_msgs['max']) + 1);
 544:         }
 545:     }
 546: 
 547:     /**
 548:      * Rebuilds/resets the mailbox list.
 549:      *
 550:      * @param boolean $reset  If true, resets the list instead of rebuilding.
 551:      */
 552:     public function rebuild($reset = false)
 553:     {
 554:         $this->_cacheid = $this->_sorted = null;
 555: 
 556:         if ($reset) {
 557:             $this->_buidmax = 0;
 558:             $this->_buids = array();
 559:             $this->changed = true;
 560:         } else {
 561:             $this->_buildMailbox();
 562:         }
 563:     }
 564: 
 565:     /**
 566:      * Returns the array index of the given message UID.
 567:      *
 568:      * @param integer $uid  The message UID.
 569:      * @param string $mbox  The message mailbox (defaults to the current
 570:      *                      mailbox).
 571:      *
 572:      * @return mixed  The array index of the location of the message UID in
 573:      *                the current mailbox. Returns null if not found.
 574:      */
 575:     public function getArrayIndex($uid, $mbox = null)
 576:     {
 577:         $this->_buildMailbox();
 578: 
 579:         /* array_search() returns false on no result. We will set an
 580:          * unsuccessful result to NULL. */
 581:         return (($aindex = array_search($uid, $this->_sorted)) === false)
 582:             ? null
 583:             : $aindex;
 584:     }
 585: 
 586:     /**
 587:      * Generate an IMP_Indices object out of the contents of this mailbox.
 588:      *
 589:      * @return IMP_Indices  An indices object.
 590:      */
 591:     public function getIndicesOb()
 592:     {
 593:         $this->_buildMailbox();
 594: 
 595:         return new IMP_Indices($this->_mailbox, $this->_sorted);
 596:     }
 597: 
 598:     /**
 599:      * Removes messages from the mailbox.
 600:      *
 601:      * @param mixed $indices  An IMP_Indices object or true to remove all
 602:      *                        messages in the mailbox.
 603:      *
 604:      * @return boolean  True if the message was removed from the mailbox.
 605:      */
 606:     public function removeMsgs($indices)
 607:     {
 608:         if ($indices === true) {
 609:             $this->rebuild();
 610:             return false;
 611:         }
 612: 
 613:         if (!count($indices)) {
 614:             return false;
 615:         }
 616: 
 617:         /* Remove the current entry and recalculate the range. */
 618:         foreach ($indices as $ob) {
 619:             foreach ($ob->uids as $uid) {
 620:                 unset($this->_sorted[$this->getArrayIndex($uid, $ob->mbox)]);
 621:             }
 622:         }
 623: 
 624:         $this->changed = true;
 625:         $this->_sorted = array_values($this->_sorted);
 626: 
 627:         if (isset($this->_thread[strval($ob->mbox)])) {
 628:             unset($this->_thread[strval($ob->mbox)], $this->_threadui[strval($ob->mbox)]);
 629:         }
 630: 
 631:         if (!is_null($this->_index)) {
 632:             $this->setIndex(0);
 633:         }
 634: 
 635:         return true;
 636:     }
 637: 
 638:     /**
 639:      * Returns the list of UIDs for an entire thread given one message in
 640:      * that thread.
 641:      *
 642:      * @param integer $uid  The message UID.
 643:      * @param string $mbox  The message mailbox (defaults to the current
 644:      *                      mailbox).
 645:      *
 646:      * @return IMP_Indices  An indices object.
 647:      */
 648:     public function getFullThread($uid, $mbox = null)
 649:     {
 650:         if (is_null($mbox)) {
 651:             $mbox = $this->_mailbox;
 652:         }
 653: 
 654:         return new IMP_Indices($mbox, array_keys($this->_getThread($mbox)->getThread($uid)));
 655:     }
 656: 
 657:     /**
 658:      * Returns a thread object for a message.
 659:      *
 660:      * @param integer $offset  Sequence number of message.
 661:      *
 662:      * @return IMP_Mailbox_List_Thread  The thread object.
 663:      */
 664:     public function getThreadOb($offset)
 665:     {
 666:         $entry = $this[$offset];
 667:         $mbox = strval($entry['m']);
 668:         $uid = $entry['u'];
 669: 
 670:         if (!isset($this->_threadui[$mbox][$uid])) {
 671:             $thread_level = array();
 672:             $t_ob = $this->_getThread($mbox);
 673: 
 674:             foreach ($t_ob->getThread($uid) as $key => $val) {
 675:                 if (is_null($val->base) ||
 676:                     ($val->last && ($val->base == $key))) {
 677:                     $this->_threadui[$mbox][$key] = '';
 678:                     continue;
 679:                 }
 680: 
 681:                 if ($val->last) {
 682:                     $join = IMP_Mailbox_List_Thread::JOINBOTTOM;
 683:                 } else {
 684:                     $join = (!$val->level && ($val->base == $key))
 685:                         ? IMP_Mailbox_List_Thread::JOINBOTTOM_DOWN
 686:                         : IMP_Mailbox_List_Thread::JOIN;
 687:                 }
 688: 
 689:                 $thread_level[$val->level] = $val->last;
 690:                 $line = '';
 691: 
 692:                 for ($i = 0; $i < $val->level; ++$i) {
 693:                     if (isset($thread_level[$i])) {
 694:                         $line .= (isset($thread_level[$i]) && !$thread_level[$i])
 695:                             ? IMP_Mailbox_List_Thread::LINE
 696:                             : IMP_Mailbox_List_Thread::BLANK;
 697:                     }
 698:                 }
 699: 
 700:                 $this->_threadui[$mbox][$key] = $line . $join;
 701:             }
 702:         }
 703: 
 704:         return new IMP_Mailbox_List_Thread($this->_threadui[$mbox][$uid]);
 705:     }
 706: 
 707:     /**
 708:      * Returns the thread object for a mailbox.
 709:      *
 710:      * @param string $mbox  The mailbox.
 711:      * @param array $extra  Extra options to pass to IMAP thread() command.
 712:      *
 713:      * @return Horde_Imap_Client_Data_Thread  Thread object.
 714:      */
 715:     protected function _getThread($mbox, array $extra = array())
 716:     {
 717:         if (!isset($this->_thread[strval($mbox)])) {
 718:             $imp_imap = IMP_Mailbox::get($mbox)->imp_imap;
 719: 
 720:             try {
 721:                 $thread = $imp_imap->thread($mbox, array_merge($extra, array(
 722:                     'criteria' => $imp_imap->thread_algo
 723:                 )));
 724:             } catch (Horde_Imap_Client_Exception $e) {
 725:                 $thread = new Horde_Imap_Client_Data_Thread(array(), 'uid');
 726:             }
 727: 
 728:             $this->_thread[strval($mbox)] = $thread;
 729:         }
 730: 
 731:         return $this->_thread[strval($mbox)];
 732:     }
 733: 
 734:     /**
 735:      * Get the mailbox for a sequence ID.
 736:      *
 737:      * @param integer $id  Sequence ID.
 738:      *
 739:      * @return IMP_Mailbox  The mailbox.
 740:      */
 741:     protected function _getMbox($id)
 742:     {
 743:         return $this->_mailbox;
 744:     }
 745: 
 746:     /* Pseudo-UID related methods. */
 747: 
 748:     /**
 749:      * Create a browser-UID from a mail UID.
 750:      *
 751:      * @param string $mbox  The mailbox.
 752:      * @param integer $uid  UID.
 753:      *
 754:      * @return integer  Browser-UID.
 755:      */
 756:     public function getBuid($mbox, $uid)
 757:     {
 758:         return $uid;
 759:     }
 760: 
 761:     /**
 762:      * Resolve a mail UID from a browser-UID.
 763:      *
 764:      * @param integer $buid  Browser-UID.
 765:      *
 766:      * @return array  Two-element array:
 767:      *   - m: (IMP_Mailbox) Mailbox of message.
 768:      *   - u: (string) UID of message.
 769:      */
 770:     public function resolveBuid($buid)
 771:     {
 772:         return array(
 773:             'm' => $this->_mailbox,
 774:             'u' => intval($buid)
 775:         );
 776:     }
 777: 
 778:     /* Tracking related methods. */
 779: 
 780:     /**
 781:      * Returns the current message array index. If the array index has
 782:      * run off the end of the message array, will return the first index.
 783:      *
 784:      * @return integer  The message array index.
 785:      */
 786:     public function getIndex()
 787:     {
 788:         return $this->isValidIndex()
 789:             ? ($this->_index + 1)
 790:             : 1;
 791:     }
 792: 
 793:     /**
 794:      * Checks to see if the current index is valid.
 795:      *
 796:      * @return boolean  True if index is valid, false if not.
 797:      */
 798:     public function isValidIndex()
 799:     {
 800:         return !is_null($this->_index);
 801:     }
 802: 
 803:     /**
 804:      * Updates the message array index.
 805:      *
 806:      * @param mixed $data  If an integer, the number of messages to increase
 807:      *                     the array index by. If an indices object, sets
 808:      *                     array index to the index value.
 809:      */
 810:     public function setIndex($data)
 811:     {
 812:         if ($data instanceof IMP_Indices) {
 813:             list($mailbox, $uid) = $data->getSingle();
 814:             $this->_index = $this->getArrayIndex($uid, $mailbox);
 815:             if (is_null($this->_index)) {
 816:                 $this->rebuild();
 817:                 $this->_index = $this->getArrayIndex($uid, $mailbox);
 818:             }
 819:         } else {
 820:             $index = $this->_index += $data;
 821:             if (isset($this->_sorted[$this->_index])) {
 822:                 if (!isset($this->_sorted[$this->_index + 1])) {
 823:                     $this->rebuild();
 824:                 }
 825:             } else {
 826:                 $this->rebuild();
 827:                 $this->_index = isset($this->_sorted[$index])
 828:                     ? $index
 829:                     : null;
 830:             }
 831:         }
 832:     }
 833: 
 834:     /* ArrayAccess methods. */
 835: 
 836:     /**
 837:      * @param integer $offset  Sequence number of message.
 838:      */
 839:     public function offsetExists($offset)
 840:     {
 841:         return isset($this->_sorted[$offset - 1]);
 842:     }
 843: 
 844:     /**
 845:      * @param integer $offset  Sequence number of message.
 846:      *
 847:      * @return array  Two-element array:
 848:      *   - m: (IMP_Mailbox) Mailbox of message.
 849:      *   - u: (string) UID of message.
 850:      */
 851:     public function offsetGet($offset)
 852:     {
 853:         if (!isset($this->_sorted[$offset - 1])) {
 854:             return null;
 855:         }
 856: 
 857:         $ret = array(
 858:             'm' => $this->_getMbox($offset - 1),
 859:             'u' => $this->_sorted[$offset - 1]
 860:         );
 861: 
 862:         return $ret;
 863:     }
 864: 
 865:     /**
 866:      * @throws BadMethodCallException
 867:      */
 868:     public function offsetSet($offset, $value)
 869:     {
 870:         throw new BadMethodCallException('Not supported');
 871:     }
 872: 
 873:     /**
 874:      * @throws BadMethodCallException
 875:      */
 876:     public function offsetUnset($offset)
 877:     {
 878:         throw new BadMethodCallException('Not supported');
 879:     }
 880: 
 881:     /* Countable methods. */
 882: 
 883:     /**
 884:      * Returns the current message count of the mailbox.
 885:      *
 886:      * @return integer  The mailbox message count.
 887:      */
 888:     public function count()
 889:     {
 890:         $this->_buildMailbox();
 891:         return count($this->_sorted);
 892:     }
 893: 
 894:     /* Iterator methods. */
 895: 
 896:     /**
 897:      * @return array  Two-element array:
 898:      *   - m: (IMP_Mailbox) Mailbox of message.
 899:      *   - u: (string) UID of message.
 900:      */
 901:     public function current()
 902:     {
 903:         return $this[key($this->_sorted) + 1];
 904:     }
 905: 
 906:     /**
 907:      * @return integer  Sequence number of message.
 908:      */
 909:     public function key()
 910:     {
 911:         return (key($this->_sorted) + 1);
 912:     }
 913: 
 914:     /**
 915:      */
 916:     public function next()
 917:     {
 918:         next($this->_sorted);
 919:     }
 920: 
 921:     /**
 922:      */
 923:     public function rewind()
 924:     {
 925:         reset($this->_sorted);
 926:     }
 927: 
 928:     /**
 929:      */
 930:     public function valid()
 931:     {
 932:         return (key($this->_sorted) !== null);
 933:     }
 934: 
 935:     /* Serializable methods. */
 936: 
 937:     /**
 938:      * Serialization.
 939:      *
 940:      * @return string  Serialized data.
 941:      */
 942:     public function serialize()
 943:     {
 944:         return $GLOBALS['injector']->getInstance('Horde_Pack')->pack(
 945:             $this->_serialize(),
 946:             array(
 947:                 'compression' => false,
 948:                 'phpob' => true
 949:             )
 950:         );
 951:     }
 952: 
 953:     /**
 954:      */
 955:     protected function _serialize()
 956:     {
 957:         $data = array(
 958:             'm' => $this->_mailbox
 959:         );
 960: 
 961:         if ($this->_buidmax) {
 962:             $data['bm'] = $this->_buidmax;
 963:             if (!empty($this->_buids)) {
 964:                 $data['b'] = $this->_buids;
 965:             }
 966:         }
 967: 
 968:         if (!is_null($this->_cacheid)) {
 969:             $data['c'] = $this->_cacheid;
 970:         }
 971: 
 972:         if (!is_null($this->_sorted)) {
 973:             /* Store UIDs in sequence string to save on storage space. */
 974:             if (count($this->_sorted) > self::SERIALIZE_LIMIT) {
 975:                 $ids = $this->_mailbox->imp_imap->getIdsOb();
 976:                 /* Optimization: we know there are no duplicates in sorted. */
 977:                 $ids->duplicates = true;
 978:                 $ids->add($this->_sorted);
 979:                 $data['so'] = $ids;
 980:             } else {
 981:                 $data['so'] = $this->_sorted;
 982:             }
 983:         }
 984: 
 985:         return $data;
 986:     }
 987: 
 988:     /**
 989:      * Unserialization.
 990:      *
 991:      * @param string $data  Serialized data.
 992:      *
 993:      * @throws Exception
 994:      */
 995:     public function unserialize($data)
 996:     {
 997:         $this->_unserialize(
 998:             $GLOBALS['injector']->getInstance('Horde_Pack')->unpack($data)
 999:         );
1000:     }
1001: 
1002:     /**
1003:      */
1004:     protected function _unserialize($data)
1005:     {
1006:         $this->_mailbox = $data['m'];
1007: 
1008:         if (isset($data['bm'])) {
1009:             $this->_buidmax = $data['bm'];
1010:             if (isset($data['b'])) {
1011:                 $this->_buids = $data['b'];
1012:             }
1013:         }
1014: 
1015:         if (isset($data['c'])) {
1016:             $this->_cacheid = $data['c'];
1017:         }
1018: 
1019:         if (isset($data['so'])) {
1020:             $this->_sorted = is_object($data['so'])
1021:                 ? $data['so']->ids
1022:                 : $data['so'];
1023:         }
1024:     }
1025: 
1026: }
1027: 
API documentation generated by ApiGen