Split IMP_Mailbox into two separate classes.
authorMichael M Slusarz <slusarz@curecanti.org>
Mon, 27 Sep 2010 21:31:22 +0000 (15:31 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 30 Sep 2010 17:47:23 +0000 (11:47 -0600)
One holds the sorted list information, one extends to include array
index tracking (since this part of the class is only used in the message
views of IMP/MIMP).
Improve serialization of this data.

20 files changed:
imp/config/hooks.php.dist
imp/lib/Ajax/Application.php
imp/lib/Application.php
imp/lib/Indices.php
imp/lib/Injector/Binder/Mailbox.php [deleted file]
imp/lib/Injector/Binder/MailboxList.php [new file with mode: 0644]
imp/lib/Injector/Factory/Mailbox.php [deleted file]
imp/lib/Injector/Factory/MailboxList.php [new file with mode: 0644]
imp/lib/Mailbox.php [deleted file]
imp/lib/Mailbox/List.php [new file with mode: 0644]
imp/lib/Mailbox/List/Track.php [new file with mode: 0644]
imp/lib/Message.php
imp/lib/Spam.php
imp/lib/Views/ListMessages.php
imp/mailbox-mimp.php
imp/mailbox.php
imp/message-mimp.php
imp/message.php
imp/rss.php
imp/thread.php

index 7728c47..3c46f31 100644 (file)
@@ -272,9 +272,9 @@ class IMP_Hooks
      * mailbox.
      *
      * @param array $data   The overview information for a message as returned
-     *                      from the IMP_Mailbox::getMailboxArray() call (see
-     *                      lib/Mailbox.php for documentation on the structure
-     *                      of the array).
+     *                      from the IMP_Mailbox_List::getMailboxArray() call
+     *                      (see lib/Mailbox/List.php for documentation on the
+     *                      structure of the array).
      * @param string $mode  Either 'imp' or 'dimp'.
      *
      * @return array  An array of additional flags to add. These flags must be
index bb6c810..b3f005a 100644 (file)
@@ -731,7 +731,7 @@ class IMP_Ajax_Application extends Horde_Core_Ajax_Application
                 $result->ViewPort = $this->_viewPortData(true);
             } else {
                 $result->ViewPort = new stdClass;
-                $result->ViewPort->updatecacheid = $GLOBALS['injector']->getInstance('IMP_Mailbox')->getOb($this->_vars->view)->getCacheID($this->_vars->view);
+                $result->ViewPort->updatecacheid = $GLOBALS['injector']->getInstance('IMP_Mailbox_List')->getList($this->_vars->view)->getCacheID($this->_vars->view);
                 $result->ViewPort->view = $this->_vars->view;
             }
             return $result;
@@ -925,7 +925,7 @@ class IMP_Ajax_Application extends Horde_Core_Ajax_Application
                 $result = $this->_checkUidvalidity($result);
             } elseif (!$change) {
                 /* Only update cacheid info if it changed. */
-                $cacheid = $GLOBALS['injector']->getInstance('IMP_Mailbox')->getOb($this->_vars->view)->getCacheID($this->_vars->view);
+                $cacheid = $GLOBALS['injector']->getInstance('IMP_Mailbox_List')->getList($this->_vars->view)->getCacheID($this->_vars->view);
                 if ($cacheid != $this->_vars->cacheid) {
                     $result->ViewPort = new stdClass;
                     $result->ViewPort->updatecacheid = $cacheid;
@@ -1874,7 +1874,7 @@ class IMP_Ajax_Application extends Horde_Core_Ajax_Application
             $result->ViewPort = $this->_viewPortData(true);
         } else {
             $result->ViewPort = new stdClass;
-            $result->ViewPort->updatecacheid = $GLOBALS['injector']->getInstance('IMP_Mailbox')->getOb($this->_vars->view)->getCacheID($this->_vars->view);
+            $result->ViewPort->updatecacheid = $GLOBALS['injector']->getInstance('IMP_Mailbox_List')->getList($this->_vars->view)->getCacheID($this->_vars->view);
             $result->ViewPort->view = $this->_vars->view;
         }
 
@@ -1923,7 +1923,7 @@ class IMP_Ajax_Application extends Horde_Core_Ajax_Application
             }
         }
 
-        return ($GLOBALS['injector']->getInstance('IMP_Mailbox')->getOb($this->_vars->view)->getCacheID($this->_vars->view) != $this->_vars->cacheid);
+        return ($GLOBALS['injector']->getInstance('IMP_Mailbox_List')->getList($this->_vars->view)->getCacheID($this->_vars->view) != $this->_vars->cacheid);
     }
 
     /**
index 2708888..c5a013a 100644 (file)
@@ -99,7 +99,7 @@ class IMP_Application extends Horde_Registry_Application
             'IMP_Imap' => 'IMP_Injector_Binder_Imap',
             'IMP_Imap_Tree' => 'IMP_Injector_Binder_Imaptree',
             'IMP_Mail' => 'IMP_Injector_Binder_Mail',
-            'IMP_Mailbox' => 'IMP_Injector_Binder_Mailbox',
+            'IMP_Mailbox_List' => 'IMP_Injector_Binder_MailboxList',
             'IMP_Mime_Viewer' => 'IMP_Injector_Binder_MimeViewer',
             'IMP_Quota' => 'IMP_Injector_Binder_Quota',
             'IMP_Search' => 'IMP_Injector_Binder_Search',
index b70edaf..b588a97 100644 (file)
@@ -53,7 +53,7 @@ class IMP_Indices implements Countable, Iterator
      * + IMP_Compose object
      * + IMP_Contents object
      * + IMP_Indices object
-     * + IMP_Mailbox object
+     * + IMP_Mailbox_List_Track object
      * + String
      *   Format: IMAP sequence string
      *
@@ -92,7 +92,7 @@ class IMP_Indices implements Countable, Iterator
                 );
             } elseif ($data instanceof IMP_Indices) {
                 $indices = $data->indices();
-            } elseif ($data instanceof IMP_Mailbox) {
+            } elseif ($data instanceof IMP_Mailbox_List_Track) {
                 $idx = $data->getIMAPIndex();
                 $indices = array(
                     $idx['mailbox'] => array($idx['uid'])
diff --git a/imp/lib/Injector/Binder/Mailbox.php b/imp/lib/Injector/Binder/Mailbox.php
deleted file mode 100644 (file)
index 07bae9a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
- * Binder for IMP_Mailbox::.
- *
- * Copyright 2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- *
- * @author   Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license  http://www.fsf.org/copyleft/gpl.html GPL
- * @package  IMP
- */
-class IMP_Injector_Binder_Mailbox implements Horde_Injector_Binder
-{
-    /**
-     */
-    public function create(Horde_Injector $injector)
-    {
-        return new IMP_Injector_Factory_Mailbox($injector);
-    }
-
-    /**
-     */
-    public function equals(Horde_Injector_Binder $binder)
-    {
-        return false;
-    }
-
-}
diff --git a/imp/lib/Injector/Binder/MailboxList.php b/imp/lib/Injector/Binder/MailboxList.php
new file mode 100644 (file)
index 0000000..b8b329c
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Binder for IMP_Mailbox_List::.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  IMP
+ */
+class IMP_Injector_Binder_MailboxList implements Horde_Injector_Binder
+{
+    /**
+     */
+    public function create(Horde_Injector $injector)
+    {
+        return new IMP_Injector_Factory_MailboxList($injector);
+    }
+
+    /**
+     */
+    public function equals(Horde_Injector_Binder $binder)
+    {
+        return false;
+    }
+
+}
diff --git a/imp/lib/Injector/Factory/Mailbox.php b/imp/lib/Injector/Factory/Mailbox.php
deleted file mode 100644 (file)
index 624b284..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/**
- * A Horde_Injector:: based IMP_Mailbox:: factory.
- *
- * PHP version 5
- *
- * @author   Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license  http://www.fsf.org/copyleft/gpl.html GPL
- * @link     http://pear.horde.org/index.php?package=IMP
- * @package  IMP
- */
-
-/**
- * A Horde_Injector:: based IMP_Mailbox:: factory.
- *
- * Copyright 2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- *
- * @author   Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license  http://www.fsf.org/copyleft/gpl.html GPL
- * @link     http://pear.horde.org/index.php?package=IMP
- * @package  IMP
- */
-class IMP_Injector_Factory_Mailbox
-{
-    /**
-     * Instances.
-     *
-     * @var array
-     */
-    private $_instances = array();
-
-    /**
-     * The injector.
-     *
-     * @var Horde_Injector
-     */
-    private $_injector;
-
-    /**
-     * Constructor.
-     *
-     * @param Horde_Injector $injector  The injector to use.
-     */
-    public function __construct(Horde_Injector $injector)
-    {
-        $this->_injector = $injector;
-    }
-
-    /**
-     * Return the IMP_Mailbox:: instance.
-     *
-     * @param string $mailbox       The mailbox name.
-     * @param IMP_Indices $indices  An indices object.
-     *
-     * @return IMP_Mailbox  The singleton mailbox instance.
-     * @throws IMP_Exception
-     */
-    public function getOb($mailbox, $indices = null)
-    {
-        if (!isset($this->_instances[$mailbox])) {
-            $this->_instances[$mailbox] = new IMP_Mailbox($mailbox, $indices);
-        } elseif (!is_null($indices)) {
-            $this->_instances[$mailbox]->setIndex($indices);
-        }
-
-        return $this->_instances[$mailbox];
-    }
-
-}
diff --git a/imp/lib/Injector/Factory/MailboxList.php b/imp/lib/Injector/Factory/MailboxList.php
new file mode 100644 (file)
index 0000000..ff4d71d
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+/**
+ * A Horde_Injector:: based IMP_Mailbox_List:: factory.
+ *
+ * PHP version 5
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @link     http://pear.horde.org/index.php?package=IMP
+ * @package  IMP
+ */
+
+/**
+ * A Horde_Injector:: based IMP_Mailbox_List:: factory.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @link     http://pear.horde.org/index.php?package=IMP
+ * @package  IMP
+ */
+class IMP_Injector_Factory_MailboxList
+{
+    /**
+     * Instances.
+     *
+     * @var array
+     */
+    private $_instances = array(
+        'list' => array(),
+        'track' => array()
+    );
+
+    /**
+     * The injector.
+     *
+     * @var Horde_Injector
+     */
+    private $_injector;
+
+    /**
+     * Constructor.
+     *
+     * @param Horde_Injector $injector  The injector to use.
+     */
+    public function __construct(Horde_Injector $injector)
+    {
+        $this->_injector = $injector;
+
+        register_shutdown_function(array($this, 'shutdown'));
+    }
+
+    /**
+     * Return the IMP_Mailbox_List:: instance.
+     *
+     * @param string $mailbox  The mailbox name.
+     *
+     * @return IMP_Mailbox_List  The singleton mailbox instance.
+     * @throws IMP_Exception
+     */
+    public function getList($mailbox)
+    {
+        if (!isset($this->_instances['list'][$mailbox])) {
+            $this->_instances['list'][$mailbox] = new IMP_Mailbox_List($mailbox);
+        }
+
+        return $this->_instances['list'][$mailbox];
+    }
+
+    /**
+     * Return the IMP_Mailbox_List_Track:: instance.
+     *
+     * @param string $mailbox       The mailbox name.
+     * @param IMP_Indices $indices  An indices object.
+     *
+     *
+     * @return IMP_Mailbox_List_Track  The singleton mailbox instance.
+     * @throws IMP_Exception
+     */
+    public function getListTrack($mailbox, $indices = null)
+    {
+        if (!isset($this->_instances['track'][$mailbox])) {
+            $ob = null;
+            if (isset($_SESSION['imp']['cache']['imp_mailbox'][$mailbox])) {
+                try {
+                    $ob = @unserialize($_SESSION['imp']['cache']['imp_mailbox'][$mailbox]);
+                } catch (Exception $e) {}
+            }
+
+            if (!$ob) {
+                $ob = new IMP_Mailbox_List_Track($mailbox);
+            }
+
+            $this->_instances['track'][$mailbox] = $ob;
+        }
+
+        if (!is_null($indices)) {
+            $this->_instances['track'][$mailbox]->setIndex($indices);
+        }
+
+        return $this->_instances['track'][$mailbox];
+    }
+
+    /**
+     * Tasks to perform on shutdown.
+     */
+    public function shutdown()
+    {
+        /* Cache mailbox information if viewing in standard (IMP) message
+         * mode. Needed to keep navigation consistent when moving through the
+         * message list, and to ensure messages aren't marked as missing in
+         * search mailboxes (e.g. if search is dependent on unseen flag). */
+        foreach ($this->_instances['track'] as $key => $val) {
+            if ($val->changed) {
+                $_SESSION['imp']['cache']['imp_mailbox'][$key] = serialize($val);
+            }
+        }
+    }
+
+}
diff --git a/imp/lib/Mailbox.php b/imp/lib/Mailbox.php
deleted file mode 100644 (file)
index 7fd96ec..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-<?php
-/**
- * The IMP_Mailbox:: class contains all code related to handling a mailbox
- * message list.
- *
- * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- *
- * @author   Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license  http://www.fsf.org/copyleft/gpl.html GPL
- * @package  IMP
- */
-class IMP_Mailbox implements Countable
-{
-    /**
-     * The mailbox to work with.
-     *
-     * @var string
-     */
-    protected $_mailbox;
-
-    /**
-     * The location in the sorted array we are at.
-     *
-     * @var integer
-     */
-    protected $_arrayIndex = null;
-
-    /**
-     * The array of sorted indices.
-     *
-     * @var array
-     */
-    protected $_sorted = null;
-
-    /**
-     * The mailboxes corresponding to the sorted indices list.
-     * If empty, uses $_mailbox.
-     *
-     * @var array
-     */
-    protected $_sortedMbox = array();
-
-    /**
-     * Is this a search malbox?
-     *
-     * @var boolean
-     */
-    protected $_searchmbox;
-
-    /**
-     * The Horde_Imap_Client_Thread object for the mailbox.
-     *
-     * @var Horde_Imap_Client_Thread
-     */
-    protected $_threadob = null;
-
-    /**
-     * Has the internal message list changed?
-     *
-     * @var boolean
-     */
-    protected $_changed = false;
-
-    /**
-     * Constructor.
-     *
-     * @param string $mailbox       The mailbox to work with.
-     * @param IMP_Indices $indices  An indices object.
-     */
-    public function __construct($mailbox, $indices = null)
-    {
-        $this->_mailbox = $mailbox;
-        $this->_searchmbox = $GLOBALS['injector']->getInstance('IMP_Search')->isSearchMbox($mailbox);
-
-        if (is_null($indices)) {
-            unset($_SESSION['imp']['cache']['imp_mailbox'][$mailbox]);
-        } else {
-            /* Try to rebuild sorted information from the session cache. */
-            if (isset($_SESSION['imp']['cache']['imp_mailbox'][$mailbox])) {
-                $tmp = json_decode($_SESSION['imp']['cache']['imp_mailbox'][$mailbox]);
-                $this->_sorted = $this->_searchmbox ? $tmp->s : $tmp;
-                $this->_sortedMbox = $this->_searchmbox ? $tmp->m : array();
-            }
-            $this->setIndex($indices);
-        }
-
-        register_shutdown_function(array($this, 'shutdown'));
-    }
-
-    /**
-     * Cache mailbox information if viewing in standard (IMP) message mode.
-     * Needed to keep navigation consistent when moving through the message
-     * list, and to ensure messages aren't marked as missing in search
-     * mailboxes (e.g. if search is dependent on unseen flag).
-     */
-    public function shutdown()
-    {
-        if ($this->_changed &&
-            ($_SESSION['imp']['view'] == 'imp')) {
-            /* Casting $_sorted to integers saves a significant amount of
-             * space when json_encoding (no need to quote every value). Only
-             * can do for IMAP though (since POP3 UIDs are not limited to
-             * integers). */
-            $sorted = ($_SESSION['imp']['protocol'] == 'pop')
-                ? $this->_sorted
-                : array_map('intval', $this->_sorted);
-            $_SESSION['imp']['cache']['imp_mailbox'][$this->_mailbox] = $this->_searchmbox
-                ? json_encode(array('m' => $this->_sortedMbox, 's' => $sorted))
-                : json_encode($sorted);
-        }
-    }
-
-    /**
-     * Build the array of message information.
-     *
-     * @param array $msgnum   An array of message sequence numbers.
-     * @param array $options  Additional options:
-     * <pre>
-     * 'headers' - (boolean) Return info on the non-envelope headers
-     *             'Importance', 'List-Post', and 'X-Priority'.
-     *             DEFAULT: false (only envelope headers returned)
-     * 'preview' - (mixed) Include preview information?  If empty, add no
-     *                     preview information. If 1, uses value from prefs.
-     *                     If 2, forces addition of preview info.
-     *                     DEFAULT: No preview information.
-     * 'structure' - (boolean) Get structure information from server.
-     *               Contained in the 'strucutre' entry.
-     *               DEFAULT: false
-     * </pre>
-     *
-     * @return array  An array with the following keys:
-     * <pre>
-     * 'overview' - (array) The overview information. Contains the following:
-     *              'envelope' - (array) Envelope information returned from
-     *                           the IMAP server. See
-     *                           Horde_Imap_Client::fetch() for format.
-     *              'flags' - (array) The list of IMAP flags returned from
-     *                        the server. See Horde_Imap_Client::fetch() for
-     *                        the format.
-     *              'headers' - (array) Any headers requested in
-     *                          $options['headers']. Horde_Mime_Headers objects
-     *                          are returned.  See Horde_Imap_Client::fetch()
-     *                          for the format.
-     *              'mailbox' - (string) The mailbox containing the message.
-     *              'preview' - (string) If requested in $options['preview'],
-     *                          the preview text.
-     *              'previewcut'- (boolean) Has the preview text been cut?
-     *              'size' - (integer) The size of the message in bytes.
-     *              'structure'- (array) The structure of the message. Only
-     *                           set if $options['structure'] is true. See
-     *                           Horde_Imap_Client::fetch() for format.
-     *              'uid' - (string) The unique ID of the message.
-     *
-     * 'uids' - (IMP_Indices) An indices object.
-     * </pre>
-     */
-    public function getMailboxArray($msgnum, $options = array())
-    {
-        $this->_buildMailbox();
-
-        $overview = $to_process = $uids = array();
-
-        /* Build the list of mailboxes and messages. */
-        foreach ($msgnum as $i) {
-            /* Make sure that the index is actually in the slice of messages
-               we're looking at. If we're hiding deleted messages, for
-               example, there may be gaps here. */
-            if (isset($this->_sorted[$i - 1])) {
-                $mboxname = ($this->_searchmbox) ? $this->_sortedMbox[$i - 1] : $this->_mailbox;
-
-                // $uids - KEY: UID, VALUE: sequence number
-                $to_process[$mboxname][$this->_sorted[$i - 1]] = $i;
-            }
-        }
-
-        $fetch_criteria = array(
-            Horde_Imap_Client::FETCH_ENVELOPE => true,
-            Horde_Imap_Client::FETCH_FLAGS => true,
-            Horde_Imap_Client::FETCH_SIZE => true,
-            Horde_Imap_Client::FETCH_UID => true,
-        );
-
-        if (!empty($options['headers'])) {
-            $fetch_criteria[Horde_Imap_Client::FETCH_HEADERS] = array(array('cache' => true, 'headers' => array('importance', 'list-post', 'x-priority'), 'label' => 'imp', 'parse' => true, 'peek' => true));
-        }
-
-        if (!empty($options['structure'])) {
-            $fetch_criteria[Horde_Imap_Client::FETCH_STRUCTURE] = array('parse' => true);
-        }
-
-        $imp_imap = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb();
-
-        if (empty($options['preview'])) {
-            $cache = null;
-            $options['preview'] = 0;
-        } else {
-            $cache = $imp_imap->getCache();
-        }
-
-        /* Retrieve information from each mailbox. */
-        foreach ($to_process as $mbox => $ids) {
-            try {
-                $fetch_res = $imp_imap->fetch($mbox, $fetch_criteria, array('ids' => array_keys($ids)));
-
-                if ($options['preview']) {
-                    $preview_info = $tostore = array();
-                    if ($cache) {
-                        try {
-                            $preview_info = $cache->get($mbox, array_keys($ids), array('IMPpreview', 'IMPpreviewc'));
-                        } catch (Horde_Imap_Client_Exception $e) {}
-                    }
-                }
-
-                foreach (array_keys($ids) as $k) {
-                    $v = $fetch_res[$k];
-
-                    $v['mailbox'] = $mbox;
-                    if (isset($v['headers']['imp'])) {
-                        $v['headers'] = $v['headers']['imp'];
-                    }
-
-                    if (($options['preview'] === 2) ||
-                        (($options['preview'] === 1) &&
-                         (!$GLOBALS['prefs']->getValue('preview_show_unread') ||
-                          !in_array('\\seen', $v['flags'])))) {
-                        if (empty($preview_info[$k])) {
-                            try {
-                                $imp_contents = $GLOBALS['injector']->getInstance('IMP_Contents')->getOb(new IMP_Indices($mbox, $k));
-                                $prev = $imp_contents->generatePreview();
-                                $preview_info[$k] = array('IMPpreview' => $prev['text'], 'IMPpreviewc' => $prev['cut']);
-                                if (!is_null($cache)) {
-                                    $tostore[$k] = $preview_info[$k];
-                                }
-                            } catch (Exception $e) {
-                                $preview_info[$k] = array('IMPpreview' => '', 'IMPpreviewc' => false);
-                            }
-                        }
-
-                        $v['preview'] = $preview_info[$k]['IMPpreview'];
-                        $v['previewcut'] = $preview_info[$k]['IMPpreviewc'];
-                    }
-
-                    $overview[] = $v;
-                }
-
-                $uids[$mbox] = array_keys($fetch_res);
-
-                if (!is_null($cache) && !empty($tostore)) {
-                    $status = $imp_imap->status($mbox, Horde_Imap_Client::STATUS_UIDVALIDITY);
-                    $cache->set($mbox, $tostore, $status['uidvalidity']);
-                }
-            } catch (Horde_Imap_Client_Exception $e) {}
-        }
-
-        return array(
-            'overview' => $overview,
-            'uids' => new IMP_Indices($uids)
-        );
-    }
-
-    /**
-     * Returns true if the mailbox data has been built.
-     *
-     * @return boolean  True if the mailbox has been built.
-     */
-    public function isBuilt()
-    {
-        return !is_null($this->_sorted);
-    }
-
-    /**
-     * Builds the sorted list of messages in the mailbox.
-     */
-    protected function _buildMailbox()
-    {
-        if ($this->isBuilt()) {
-            return;
-        }
-
-        $this->_changed = true;
-        $this->_sorted = $this->_sortedMbox = array();
-        $query = null;
-
-        if ($this->_searchmbox) {
-            if (IMP::hideDeletedMsgs($this->_mailbox)) {
-                $query = new Horde_Imap_Client_Search_Query();
-                $query->flag('\\deleted', false);
-            }
-
-            try {
-                foreach ($GLOBALS['injector']->getInstance('IMP_Search')->runSearch($query, $this->_mailbox) as $mbox => $idx) {
-                    $this->_sorted[] = $idx;
-                    $this->_sortedMbox[] = $mbox;
-                }
-            } catch (Horde_Imap_Client_Exception $e) {
-                $GLOBALS['notification']->push(_("Mailbox listing failed") . ': ' . $e->getMessage(), 'horde.error');
-            }
-        } else {
-            $sortpref = IMP::getSort($this->_mailbox, true);
-            if ($sortpref['by'] == Horde_Imap_Client::SORT_THREAD) {
-                $this->_threadob = null;
-                $threadob = $this->getThreadOb();
-                $this->_sorted = $threadob->messageList((bool)$sortpref['dir']);
-            } else {
-                if (($_SESSION['imp']['protocol'] != 'pop') &&
-                    IMP::hideDeletedMsgs($this->_mailbox)) {
-                    $query = new Horde_Imap_Client_Search_Query();
-                    $query->flag('\\deleted', false);
-                }
-                try {
-                    $res = $GLOBALS['injector']->getInstance('IMP_Search')->imapSearch($this->_mailbox, $query, array('sort' => array($sortpref['by']), 'reverse' => (bool)$sortpref['dir']));
-                    $this->_sorted = $res['sort'];
-                } catch (Horde_Imap_Client_Exception $e) {
-                    $GLOBALS['notification']->push(_("Mailbox listing failed") . ': ' . $e->getMessage(), 'horde.error');
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the list of new messages in the mailbox (IMAP RECENT flag, with
-     * UNDELETED if we're hiding deleted messages).
-     *
-     * @param integer $results  A Horde_Imap_Client::SORT_* constant that
-     *                          indicates the desired return type.
-     * @param boolean $uid      Return UIDs instead of sequence numbers (for
-     *                          $results queries that return message lists).
-     *
-     * @return mixed  Whatever is requested in $results.
-     */
-    public function newMessages($results, $uid = false)
-    {
-        return $this->_msgFlagSearch('recent', $results, $uid);
-    }
-
-    /**
-     * Get the list of unseen messages in the mailbox (IMAP UNSEEN flag, with
-     * UNDELETED if we're hiding deleted messages).
-     *
-     * @param integer $results  A Horde_Imap_Client::SORT_RESULTS_* constant
-     *                          that indicates the desired return type.
-     * @param boolean $uid      Return UIDs instead of sequence numbers (for
-     *                          $results queries that return message lists).
-     *
-     * @return mixed  Whatever is requested in $results.
-     */
-    public function unseenMessages($results, $uid = false)
-    {
-        return $this->_msgFlagSearch('unseen', $results, $uid);
-    }
-
-    /**
-     * Do a search on a mailbox in the most efficient way available.
-     *
-     * @param string $type      The search type - either 'recent' or 'unseen'.
-     * @param integer $results  A Horde_Imap_Client::SORT_RESULTS_* constant
-     *                          that indicates the desired return type.
-     * @param boolean $uid      Return UIDs instead of sequence numbers (for
-     *                          $results queries that return message lists).
-     *
-     * @return mixed  Whatever is requested in $results.
-     */
-    protected function _msgFlagSearch($type, $results, $uid)
-    {
-        $count = ($results == Horde_Imap_Client::SORT_RESULTS_COUNT);
-
-        if ($this->_searchmbox || empty($this->_sorted)) {
-            if ($count &&
-                $this->_searchmbox &&
-                ($type == 'unseen') &&
-                $GLOBALS['injector']->getInstance('IMP_Search')->isVinbox($this->_mailbox)) {
-                return count($this);
-            }
-
-            return $count ? 0 : array();
-        }
-
-        $criteria = new Horde_Imap_Client_Search_Query();
-        $imp_imap = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb();
-
-        if (IMP::hideDeletedMsgs($this->_mailbox)) {
-            $criteria->flag('\\deleted', false);
-        } elseif ($count) {
-            try {
-                $status_res = $imp_imap->status($this->_mailbox, $type == 'recent' ? Horde_Imap_Client::STATUS_RECENT : Horde_Imap_Client::STATUS_UNSEEN);
-                return $status_res[$type];
-            } catch (Horde_Imap_Client_Exception $e) {
-                return 0;
-            }
-        }
-
-        if ($type == 'recent') {
-            $criteria->flag('\\recent', true);
-        } else {
-            $criteria->flag('\\seen', false);
-        }
-
-        try {
-            $res = $imp_imap->search($this->_mailbox, $criteria, array('results' => array($results), 'sequence' => !$uid));
-            return $count ? $res['count'] : $res;
-        } catch (Horde_Imap_Client_Exception $e) {
-            return $count ? 0 : array();
-        }
-    }
-
-    /**
-     * Returns the current message array index. If the array index has
-     * run off the end of the message array, will return the last index.
-     *
-     * @return integer  The message array index.
-     */
-    public function getMessageIndex()
-    {
-        return is_null($this->_arrayIndex) ? 1 : $this->_arrayIndex + 1;
-    }
-
-    /**
-     * Checks to see if the current index is valid.
-     * This function is only useful if an index was passed to the constructor.
-     *
-     * @return boolean  True if index is valid, false if not.
-     */
-    public function isValidIndex($rebuild = true)
-    {
-        return !is_null($this->_arrayIndex);
-    }
-
-    /**
-     * Returns IMAP mbox/UID information on a message.
-     *
-     * @param integer $offset  The offset from the current message.
-     *
-     * @return array  Array with the following entries:
-     * <pre>
-     * 'mailbox' - (string) The mailbox.
-     * 'uid' - (integer) The message UID.
-     * </pre>
-     */
-    public function getIMAPIndex($offset = 0)
-    {
-        $index = $this->_arrayIndex + $offset;
-
-        return isset($this->_sorted[$index])
-            ? array(
-                  'mailbox' => ($this->_searchmbox ? $this->_sortedMbox[$index] : $this->_mailbox),
-                  'uid' => $this->_sorted[$index]
-              )
-            : array();
-    }
-
-    /**
-     * Using the preferences and the current mailbox, determines the messages
-     * to view on the current page.
-     *
-     * @param integer $page   The page number currently being displayed.
-     * @param integer $start  The starting message number.
-     *
-     * @return array  An array with the following fields:
-     * <pre>
-     * 'anymsg' - (boolean) Are there any messages at all in mailbox? E.g. If
-     *            'msgcount' is 0, there may still be hidden deleted messages.
-     * 'begin' - (integer) The beginning message sequence number of the page.
-     * 'end' - (integer) The ending message sequence number of the page.
-     * 'index' - (integer) The index of the starting message.
-     * 'msgcount' - (integer) The number of viewable messages in the current
-     *              mailbox.
-     * 'page' - (integer) The current page number.
-     * 'pagecount' - (integer) The number of pages in this mailbox.
-     * </pre>
-     */
-    public function buildMailboxPage($page = 0, $start = 0, $opts = array())
-    {
-        $this->_buildMailbox();
-
-        $ret = array('msgcount' => count($this->_sorted));
-
-        $page_size = $GLOBALS['prefs']->getValue('max_msgs');
-
-        if ($ret['msgcount'] > $page_size) {
-            $ret['pagecount'] = ceil($ret['msgcount'] / $page_size);
-
-            /* Determine which page to display. */
-            if (empty($page) || strcspn($page, '0123456789')) {
-                if (!empty($start)) {
-                    /* Messages set this when returning to a mailbox. */
-                    $page = ceil($start / $page_size);
-                } else {
-                    /* Search for the last visited page first. */
-                    if (isset($_SESSION['imp']['cache']['mbox_page'][$this->_mailbox])) {
-                        $page = $_SESSION['imp']['cache']['mbox_page'][$this->_mailbox];
-                    } elseif ($this->_searchmbox) {
-                        $page = 1;
-                    } else {
-                        $page = ceil($this->mailboxStart($ret['msgcount']) / $page_size);
-                    }
-                }
-            }
-
-            /* Make sure we're not past the end or before the beginning, and
-               that we have an integer value. */
-            $ret['page'] = intval($page);
-            if ($ret['page'] > $ret['pagecount']) {
-                $ret['page'] = $ret['pagecount'];
-            } elseif ($ret['page'] < 1) {
-                $ret['page'] = 1;
-            }
-
-            $ret['begin'] = (($ret['page'] - 1) * $page_size) + 1;
-            $ret['end'] = $ret['begin'] + $page_size - 1;
-            if ($ret['end'] > $ret['msgcount']) {
-                $ret['end'] = $ret['msgcount'];
-            }
-        } else {
-            $ret['begin'] = 1;
-            $ret['end'] = $ret['msgcount'];
-            $ret['page'] = 1;
-            $ret['pagecount'] = 1;
-        }
-
-        $ret['index'] = ($this->_searchmbox) ? ($ret['begin'] - 1) : $this->_arrayIndex;
-
-        /* If there are no viewable messages, check for deleted messages in
-           the mailbox. */
-        $ret['anymsg'] = true;
-        if (!$ret['msgcount'] && !$this->_searchmbox) {
-            try {
-                $status = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->status($this->_mailbox, Horde_Imap_Client::STATUS_MESSAGES);
-                $ret['anymsg'] = (bool)$status['messages'];
-            } catch (Horde_Imap_Client_Exception $e) {
-                $ret['anymsg'] = false;
-            }
-        }
-
-        /* Store the page value now. */
-        $_SESSION['imp']['cache']['mbox_page'][$this->_mailbox] = $ret['page'];
-
-        return $ret;
-    }
-
-    /**
-     * Determines the sequence number of the first message to display, based
-     * on the user's preferences.
-     *
-     * @param integer $total  The total number of messages in the mailbox.
-     *
-     * @return integer  The sequence number in the sorted mailbox.
-     */
-    public function mailboxStart($total)
-    {
-        if ($this->_searchmbox) {
-            return 1;
-        }
-
-        switch ($GLOBALS['prefs']->getValue('mailbox_start')) {
-        case IMP::MAILBOX_START_FIRSTPAGE:
-            return 1;
-
-        case IMP::MAILBOX_START_LASTPAGE:
-            return $total;
-
-        case IMP::MAILBOX_START_FIRSTUNSEEN:
-            $sortpref = IMP::getSort($this->_mailbox);
-
-            /* Optimization: if sorting by sequence then first unseen
-             * information is returned via a SELECT/EXAMINE call. */
-            if ($sortpref['by'] == Horde_Imap_Client::SORT_SEQUENCE) {
-                try {
-                    $res = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->status($this->_mailbox, Horde_Imap_Client::STATUS_FIRSTUNSEEN);
-                    if (!is_null($res['firstunseen'])) {
-                        return $res['firstunseen'];
-                    }
-                } catch (Horde_Imap_Client_Exception $e) {}
-
-                return 1;
-            }
-
-            $unseen_msgs = $this->unseenMessages(Horde_Imap_Client::SORT_RESULTS_MIN, true);
-            return empty($unseen_msgs['min'])
-                ? 1
-                : ($this->getArrayIndex($unseen_msgs['min']) + 1);
-
-        case IMP::MAILBOX_START_LASTUNSEEN:
-            $unseen_msgs = $this->unseenMessages(Horde_Imap_Client::SORT_RESULTS_MAX, true);
-            return empty($unseen_msgs['max'])
-                ? 1
-                : ($this->getArrayIndex($unseen_msgs['max']) + 1);
-        }
-    }
-
-    /**
-     * Updates the message array index.
-     *
-     * @param mixed $data  If an integer, the number of messages to increase
-     *                     array index by. If an indices object, sets array
-     *                     index to the index value.
-     */
-    public function setIndex($data)
-    {
-        if ($data instanceof IMP_Indices) {
-            list($mailbox, $uid) = $data->getSingle();
-            $this->_arrayIndex = $this->getArrayIndex($uid, $mailbox);
-            if (empty($this->_arrayIndex)) {
-                $this->_rebuild(true);
-                $this->_arrayIndex = $this->getArrayIndex($uid, $mailbox);
-            }
-        } elseif (!is_null($this->_arrayIndex)) {
-            $index = $this->_arrayIndex += $data;
-            if (isset($this->_sorted[$this->_arrayIndex])) {
-                $this->_rebuild();
-            } else {
-                $this->_rebuild(true);
-                $this->_arrayIndex = isset($this->_sorted[$index])
-                    ? $index
-                    : null;
-            }
-        }
-    }
-
-    /**
-     * Get the Horde_Imap_Client_Thread object for the current mailbox.
-     *
-     * @return Horde_Imap_Client_Thread  The thread object for the current
-     *                                   mailbox.
-     */
-    public function getThreadOb()
-    {
-        if (is_null($this->_threadob)) {
-            try {
-                $this->_threadob = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->thread($this->_mailbox, array('criteria' => $_SESSION['imp']['imap']['thread']));
-            } catch (Horde_Imap_Client_Exception $e) {
-                $GLOBALS['notification']->push($e);
-                return new Horde_Imap_Client_Thread(array(), 'uid');
-            }
-        }
-
-        return $this->_threadob;
-    }
-
-    /**
-     * Determines if a rebuild is needed, and, if necessary, performs
-     * the rebuild.
-     *
-     * @param boolean $force  Force a rebuild?
-     */
-    protected function _rebuild($force = false)
-    {
-        if ($force ||
-            (!is_null($this->_arrayIndex) && !$this->getIMAPIndex(1))) {
-            $this->_sorted = null;
-            $this->_buildMailbox();
-        }
-    }
-
-    /**
-     * Returns the array index of the given message UID.
-     *
-     * @param integer $uid   The message UID.
-     * @param integer $mbox  The message mailbox (defaults to the current
-     *                       mailbox).
-     *
-     * @return mixed  The array index of the location of the message UID in
-     *                the current mailbox. Returns null if not found.
-     */
-    public function getArrayIndex($uid, $mbox = null)
-    {
-        $aindex = null;
-
-        $this->_buildMailbox();
-
-        if ($this->_searchmbox) {
-            if (is_null($mbox)) {
-                $mbox = IMP::$thismailbox;
-            }
-
-            /* Need to compare both mbox name and message UID to obtain the
-             * correct array index since there may be duplicate UIDs. */
-            foreach (array_keys($this->_sorted, $uid) as $key) {
-                if ($this->_sortedMbox[$key] == $mbox) {
-                    return $key;
-                }
-            }
-        } else {
-            /* array_search() returns false on no result. We will set an
-             * unsuccessful result to NULL. */
-            if (($aindex = array_search($uid, $this->_sorted)) === false) {
-                $aindex = null;
-            }
-        }
-
-        return $aindex;
-    }
-
-    /**
-     * Returns a raw sorted list of the mailbox.
-     *
-     * @return array  An array with two keys: 's' = sorted UIDS list, 'm' =
-     *                sorted mailboxes list.
-     */
-    public function getSortedList()
-    {
-        $this->_buildMailbox();
-
-        /* For exterior use, the array needs to begin numbering at 1. */
-        $s = $this->_sorted;
-        array_unshift($s, 0);
-        unset($s[0]);
-        $m = $this->_sortedMbox;
-        array_unshift($m, 0);
-        unset($m[0]);
-
-        return array('s' => $s, 'm' => $m);
-    }
-
-    /**
-     * Returns the current sorted array without the given messages.
-     *
-     * @param mixed $indices  An IMP_Indices object or true to remove all
-     *                        messages in the mailbox.
-     */
-    public function removeMsgs($indices)
-    {
-        if ($indices === true) {
-            $this->_rebuild(true);
-            return;
-        }
-
-        if (!count($indices)) {
-            return;
-        }
-
-        /* Remove the current entry and recalculate the range. */
-        foreach ($indices as $mbox => $uid) {
-            $val = $this->getArrayIndex($uid, $mbox);
-            unset($this->_sorted[$val]);
-            if ($this->_searchmbox) {
-                unset($this->_sortedMbox[$val]);
-            }
-        }
-
-        $this->_sorted = array_values($this->_sorted);
-        $this->_changed = true;
-        if ($this->_searchmbox) {
-            $this->_sortedMbox = array_values($this->_sortedMbox);
-        }
-
-        $this->_threadob = null;
-
-        /* Update the current array index to its new position in the message
-         * array. */
-        $this->setIndex(0);
-    }
-
-    /**
-     * Returns a unique identifier for the current mailbox status.
-     *
-     * This cache ID is guaranteed to change if messages are added/deleted from
-     * the mailbox. Additionally, if CONDSTORE is available on the remote
-     * IMAP server, this ID will change if flag information changes.
-     *
-     * @return string  The cache ID string, which will change when the
-     *                 composition of the mailbox changes.
-     */
-    public function getCacheID()
-    {
-        if (!$this->_searchmbox) {
-            $sortpref = IMP::getSort($this->_mailbox, true);
-            try {
-                return $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->getCacheId($this->_mailbox, array($sortpref['by'], $sortpref['dir']));
-            } catch (Horde_Imap_Client_Exception $e) {}
-        }
-
-        return strval(new Horde_Support_Randomid());
-    }
-
-    /* Countable methods. */
-
-    /**
-     * Returns the current message count of the mailbox.
-     *
-     * @return integer  The mailbox message count.
-     */
-    public function count()
-    {
-        $this->_buildMailbox();
-        return count($this->_sorted);
-    }
-
-}
diff --git a/imp/lib/Mailbox/List.php b/imp/lib/Mailbox/List.php
new file mode 100644 (file)
index 0000000..13b8a9d
--- /dev/null
@@ -0,0 +1,741 @@
+<?php
+/**
+ * This class contains code related to generating and handling a mailbox
+ * message list.
+ *
+ * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  IMP
+ */
+class IMP_Mailbox_List implements Countable, Serializable
+{
+    /* Serialized version. */
+    const VERSION = 1;
+
+    /**
+     * Has the internal message list changed?
+     *
+     * @var boolean
+     */
+    public $changed = false;
+
+    /**
+     * The mailbox to work with.
+     *
+     * @var string
+     */
+    protected $_mailbox;
+
+    /**
+     * Is this a search malbox?
+     *
+     * @var boolean
+     */
+    protected $_searchmbox;
+
+    /**
+     * The list of additional variables to serialize.
+     *
+     * @var array
+     */
+    protected $_slist = array();
+
+    /**
+     * The array of sorted indices.
+     *
+     * @var array
+     */
+    protected $_sorted = null;
+
+    /**
+     * The mailboxes corresponding to the sorted indices list.
+     * If empty, uses $_mailbox.
+     *
+     * @var array
+     */
+    protected $_sortedMbox = array();
+
+    /**
+     * The Horde_Imap_Client_Thread object for the mailbox.
+     *
+     * @var Horde_Imap_Client_Thread
+     */
+    protected $_threadob = null;
+
+    /**
+     * Constructor.
+     *
+     * @param string $mailbox  The mailbox to work with.
+     */
+    public function __construct($mailbox)
+    {
+        $this->_mailbox = $mailbox;
+        $this->_searchmbox = $GLOBALS['injector']->getInstance('IMP_Search')->isSearchMbox($mailbox);
+    }
+
+    /**
+     * Build the array of message information.
+     *
+     * @param array $msgnum   An array of message sequence numbers.
+     * @param array $options  Additional options:
+     * <pre>
+     * 'headers' - (boolean) Return info on the non-envelope headers
+     *             'Importance', 'List-Post', and 'X-Priority'.
+     *             DEFAULT: false (only envelope headers returned)
+     * 'preview' - (mixed) Include preview information?  If empty, add no
+     *                     preview information. If 1, uses value from prefs.
+     *                     If 2, forces addition of preview info.
+     *                     DEFAULT: No preview information.
+     * 'structure' - (boolean) Get structure information from server.
+     *               Contained in the 'strucutre' entry.
+     *               DEFAULT: false
+     * </pre>
+     *
+     * @return array  An array with the following keys:
+     * <pre>
+     * 'overview' - (array) The overview information. Contains the following:
+     *              'envelope' - (array) Envelope information returned from
+     *                           the IMAP server. See
+     *                           Horde_Imap_Client::fetch() for format.
+     *              'flags' - (array) The list of IMAP flags returned from
+     *                        the server. See Horde_Imap_Client::fetch() for
+     *                        the format.
+     *              'headers' - (array) Any headers requested in
+     *                          $options['headers']. Horde_Mime_Headers objects
+     *                          are returned.  See Horde_Imap_Client::fetch()
+     *                          for the format.
+     *              'mailbox' - (string) The mailbox containing the message.
+     *              'preview' - (string) If requested in $options['preview'],
+     *                          the preview text.
+     *              'previewcut'- (boolean) Has the preview text been cut?
+     *              'size' - (integer) The size of the message in bytes.
+     *              'structure'- (array) The structure of the message. Only
+     *                           set if $options['structure'] is true. See
+     *                           Horde_Imap_Client::fetch() for format.
+     *              'uid' - (string) The unique ID of the message.
+     *
+     * 'uids' - (IMP_Indices) An indices object.
+     * </pre>
+     */
+    public function getMailboxArray($msgnum, $options = array())
+    {
+        $this->_buildMailbox();
+
+        $overview = $to_process = $uids = array();
+
+        /* Build the list of mailboxes and messages. */
+        foreach ($msgnum as $i) {
+            /* Make sure that the index is actually in the slice of messages
+               we're looking at. If we're hiding deleted messages, for
+               example, there may be gaps here. */
+            if (isset($this->_sorted[$i - 1])) {
+                $mboxname = ($this->_searchmbox) ? $this->_sortedMbox[$i - 1] : $this->_mailbox;
+
+                // $uids - KEY: UID, VALUE: sequence number
+                $to_process[$mboxname][$this->_sorted[$i - 1]] = $i;
+            }
+        }
+
+        $fetch_criteria = array(
+            Horde_Imap_Client::FETCH_ENVELOPE => true,
+            Horde_Imap_Client::FETCH_FLAGS => true,
+            Horde_Imap_Client::FETCH_SIZE => true,
+            Horde_Imap_Client::FETCH_UID => true,
+        );
+
+        if (!empty($options['headers'])) {
+            $fetch_criteria[Horde_Imap_Client::FETCH_HEADERS] = array(array('cache' => true, 'headers' => array('importance', 'list-post', 'x-priority'), 'label' => 'imp', 'parse' => true, 'peek' => true));
+        }
+
+        if (!empty($options['structure'])) {
+            $fetch_criteria[Horde_Imap_Client::FETCH_STRUCTURE] = array('parse' => true);
+        }
+
+        $imp_imap = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb();
+
+        if (empty($options['preview'])) {
+            $cache = null;
+            $options['preview'] = 0;
+        } else {
+            $cache = $imp_imap->getCache();
+        }
+
+        /* Retrieve information from each mailbox. */
+        foreach ($to_process as $mbox => $ids) {
+            try {
+                $fetch_res = $imp_imap->fetch($mbox, $fetch_criteria, array('ids' => array_keys($ids)));
+
+                if ($options['preview']) {
+                    $preview_info = $tostore = array();
+                    if ($cache) {
+                        try {
+                            $preview_info = $cache->get($mbox, array_keys($ids), array('IMPpreview', 'IMPpreviewc'));
+                        } catch (Horde_Imap_Client_Exception $e) {}
+                    }
+                }
+
+                foreach (array_keys($ids) as $k) {
+                    $v = $fetch_res[$k];
+
+                    $v['mailbox'] = $mbox;
+                    if (isset($v['headers']['imp'])) {
+                        $v['headers'] = $v['headers']['imp'];
+                    }
+
+                    if (($options['preview'] === 2) ||
+                        (($options['preview'] === 1) &&
+                         (!$GLOBALS['prefs']->getValue('preview_show_unread') ||
+                          !in_array('\\seen', $v['flags'])))) {
+                        if (empty($preview_info[$k])) {
+                            try {
+                                $imp_contents = $GLOBALS['injector']->getInstance('IMP_Contents')->getOb(new IMP_Indices($mbox, $k));
+                                $prev = $imp_contents->generatePreview();
+                                $preview_info[$k] = array('IMPpreview' => $prev['text'], 'IMPpreviewc' => $prev['cut']);
+                                if (!is_null($cache)) {
+                                    $tostore[$k] = $preview_info[$k];
+                                }
+                            } catch (Exception $e) {
+                                $preview_info[$k] = array('IMPpreview' => '', 'IMPpreviewc' => false);
+                            }
+                        }
+
+                        $v['preview'] = $preview_info[$k]['IMPpreview'];
+                        $v['previewcut'] = $preview_info[$k]['IMPpreviewc'];
+                    }
+
+                    $overview[] = $v;
+                }
+
+                $uids[$mbox] = array_keys($fetch_res);
+
+                if (!is_null($cache) && !empty($tostore)) {
+                    $status = $imp_imap->status($mbox, Horde_Imap_Client::STATUS_UIDVALIDITY);
+                    $cache->set($mbox, $tostore, $status['uidvalidity']);
+                }
+            } catch (Horde_Imap_Client_Exception $e) {}
+        }
+
+        return array(
+            'overview' => $overview,
+            'uids' => new IMP_Indices($uids)
+        );
+    }
+
+    /**
+     * Returns true if the mailbox data has been built.
+     *
+     * @return boolean  True if the mailbox has been built.
+     */
+    public function isBuilt()
+    {
+        return !is_null($this->_sorted);
+    }
+
+    /**
+     * Builds the sorted list of messages in the mailbox.
+     */
+    protected function _buildMailbox()
+    {
+        if ($this->isBuilt()) {
+            return;
+        }
+
+        $this->changed = true;
+        $this->_sorted = $this->_sortedMbox = array();
+        $query = null;
+
+        if ($this->_searchmbox) {
+            if (IMP::hideDeletedMsgs($this->_mailbox)) {
+                $query = new Horde_Imap_Client_Search_Query();
+                $query->flag('\\deleted', false);
+            }
+
+            try {
+                foreach ($GLOBALS['injector']->getInstance('IMP_Search')->runSearch($query, $this->_mailbox) as $mbox => $idx) {
+                    $this->_sorted[] = $idx;
+                    $this->_sortedMbox[] = $mbox;
+                }
+            } catch (Horde_Imap_Client_Exception $e) {
+                $GLOBALS['notification']->push(_("Mailbox listing failed") . ': ' . $e->getMessage(), 'horde.error');
+            }
+        } else {
+            $sortpref = IMP::getSort($this->_mailbox, true);
+            if ($sortpref['by'] == Horde_Imap_Client::SORT_THREAD) {
+                $this->_threadob = null;
+                $threadob = $this->getThreadOb();
+                $this->_sorted = $threadob->messageList((bool)$sortpref['dir']);
+            } else {
+                if (($_SESSION['imp']['protocol'] != 'pop') &&
+                    IMP::hideDeletedMsgs($this->_mailbox)) {
+                    $query = new Horde_Imap_Client_Search_Query();
+                    $query->flag('\\deleted', false);
+                }
+                try {
+                    $res = $GLOBALS['injector']->getInstance('IMP_Search')->imapSearch($this->_mailbox, $query, array('sort' => array($sortpref['by']), 'reverse' => (bool)$sortpref['dir']));
+                    $this->_sorted = $res['sort'];
+                } catch (Horde_Imap_Client_Exception $e) {
+                    $GLOBALS['notification']->push(_("Mailbox listing failed") . ': ' . $e->getMessage(), 'horde.error');
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the list of new messages in the mailbox (IMAP RECENT flag, with
+     * UNDELETED if we're hiding deleted messages).
+     *
+     * @param integer $results  A Horde_Imap_Client::SORT_* constant that
+     *                          indicates the desired return type.
+     * @param boolean $uid      Return UIDs instead of sequence numbers (for
+     *                          $results queries that return message lists).
+     *
+     * @return mixed  Whatever is requested in $results.
+     */
+    public function newMessages($results, $uid = false)
+    {
+        return $this->_msgFlagSearch('recent', $results, $uid);
+    }
+
+    /**
+     * Get the list of unseen messages in the mailbox (IMAP UNSEEN flag, with
+     * UNDELETED if we're hiding deleted messages).
+     *
+     * @param integer $results  A Horde_Imap_Client::SORT_RESULTS_* constant
+     *                          that indicates the desired return type.
+     * @param boolean $uid      Return UIDs instead of sequence numbers (for
+     *                          $results queries that return message lists).
+     *
+     * @return mixed  Whatever is requested in $results.
+     */
+    public function unseenMessages($results, $uid = false)
+    {
+        return $this->_msgFlagSearch('unseen', $results, $uid);
+    }
+
+    /**
+     * Do a search on a mailbox in the most efficient way available.
+     *
+     * @param string $type      The search type - either 'recent' or 'unseen'.
+     * @param integer $results  A Horde_Imap_Client::SORT_RESULTS_* constant
+     *                          that indicates the desired return type.
+     * @param boolean $uid      Return UIDs instead of sequence numbers (for
+     *                          $results queries that return message lists).
+     *
+     * @return mixed  Whatever is requested in $results.
+     */
+    protected function _msgFlagSearch($type, $results, $uid)
+    {
+        $count = ($results == Horde_Imap_Client::SORT_RESULTS_COUNT);
+
+        if ($this->_searchmbox || empty($this->_sorted)) {
+            if ($count &&
+                $this->_searchmbox &&
+                ($type == 'unseen') &&
+                $GLOBALS['injector']->getInstance('IMP_Search')->isVinbox($this->_mailbox)) {
+                return count($this);
+            }
+
+            return $count ? 0 : array();
+        }
+
+        $criteria = new Horde_Imap_Client_Search_Query();
+        $imp_imap = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb();
+
+        if (IMP::hideDeletedMsgs($this->_mailbox)) {
+            $criteria->flag('\\deleted', false);
+        } elseif ($count) {
+            try {
+                $status_res = $imp_imap->status($this->_mailbox, $type == 'recent' ? Horde_Imap_Client::STATUS_RECENT : Horde_Imap_Client::STATUS_UNSEEN);
+                return $status_res[$type];
+            } catch (Horde_Imap_Client_Exception $e) {
+                return 0;
+            }
+        }
+
+        if ($type == 'recent') {
+            $criteria->flag('\\recent', true);
+        } else {
+            $criteria->flag('\\seen', false);
+        }
+
+        try {
+            $res = $imp_imap->search($this->_mailbox, $criteria, array('results' => array($results), 'sequence' => !$uid));
+            return $count ? $res['count'] : $res;
+        } catch (Horde_Imap_Client_Exception $e) {
+            return $count ? 0 : array();
+        }
+    }
+
+    /**
+     * Using the preferences and the current mailbox, determines the messages
+     * to view on the current page.
+     *
+     * @param integer $page   The page number currently being displayed.
+     * @param integer $start  The starting message number.
+     *
+     * @return array  An array with the following fields:
+     * <pre>
+     * 'anymsg' - (boolean) Are there any messages at all in mailbox? E.g. If
+     *            'msgcount' is 0, there may still be hidden deleted messages.
+     * 'begin' - (integer) The beginning message sequence number of the page.
+     * 'end' - (integer) The ending message sequence number of the page.
+     * 'index' - (integer) The index of the starting message.
+     * 'msgcount' - (integer) The number of viewable messages in the current
+     *              mailbox.
+     * 'page' - (integer) The current page number.
+     * 'pagecount' - (integer) The number of pages in this mailbox.
+     * </pre>
+     */
+    public function buildMailboxPage($page = 0, $start = 0, $opts = array())
+    {
+        $this->_buildMailbox();
+
+        $ret = array('msgcount' => count($this->_sorted));
+
+        $page_size = $GLOBALS['prefs']->getValue('max_msgs');
+
+        if ($ret['msgcount'] > $page_size) {
+            $ret['pagecount'] = ceil($ret['msgcount'] / $page_size);
+
+            /* Determine which page to display. */
+            if (empty($page) || strcspn($page, '0123456789')) {
+                if (!empty($start)) {
+                    /* Messages set this when returning to a mailbox. */
+                    $page = ceil($start / $page_size);
+                } else {
+                    /* Search for the last visited page first. */
+                    if (isset($_SESSION['imp']['cache']['mbox_page'][$this->_mailbox])) {
+                        $page = $_SESSION['imp']['cache']['mbox_page'][$this->_mailbox];
+                    } elseif ($this->_searchmbox) {
+                        $page = 1;
+                    } else {
+                        $page = ceil($this->mailboxStart($ret['msgcount']) / $page_size);
+                    }
+                }
+            }
+
+            /* Make sure we're not past the end or before the beginning, and
+               that we have an integer value. */
+            $ret['page'] = intval($page);
+            if ($ret['page'] > $ret['pagecount']) {
+                $ret['page'] = $ret['pagecount'];
+            } elseif ($ret['page'] < 1) {
+                $ret['page'] = 1;
+            }
+
+            $ret['begin'] = (($ret['page'] - 1) * $page_size) + 1;
+            $ret['end'] = $ret['begin'] + $page_size - 1;
+            if ($ret['end'] > $ret['msgcount']) {
+                $ret['end'] = $ret['msgcount'];
+            }
+        } else {
+            $ret['begin'] = 1;
+            $ret['end'] = $ret['msgcount'];
+            $ret['page'] = 1;
+            $ret['pagecount'] = 1;
+        }
+
+        $ret['index'] = $ret['begin'] - 1;
+
+        /* If there are no viewable messages, check for deleted messages in
+           the mailbox. */
+        $ret['anymsg'] = true;
+        if (!$ret['msgcount'] && !$this->_searchmbox) {
+            try {
+                $status = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->status($this->_mailbox, Horde_Imap_Client::STATUS_MESSAGES);
+                $ret['anymsg'] = (bool)$status['messages'];
+            } catch (Horde_Imap_Client_Exception $e) {
+                $ret['anymsg'] = false;
+            }
+        }
+
+        /* Store the page value now. */
+        $_SESSION['imp']['cache']['mbox_page'][$this->_mailbox] = $ret['page'];
+
+        return $ret;
+    }
+
+    /**
+     * Determines the sequence number of the first message to display, based
+     * on the user's preferences.
+     *
+     * @param integer $total  The total number of messages in the mailbox.
+     *
+     * @return integer  The sequence number in the sorted mailbox.
+     */
+    public function mailboxStart($total)
+    {
+        if ($this->_searchmbox) {
+            return 1;
+        }
+
+        switch ($GLOBALS['prefs']->getValue('mailbox_start')) {
+        case IMP::MAILBOX_START_FIRSTPAGE:
+            return 1;
+
+        case IMP::MAILBOX_START_LASTPAGE:
+            return $total;
+
+        case IMP::MAILBOX_START_FIRSTUNSEEN:
+            $sortpref = IMP::getSort($this->_mailbox);
+
+            /* Optimization: if sorting by sequence then first unseen
+             * information is returned via a SELECT/EXAMINE call. */
+            if ($sortpref['by'] == Horde_Imap_Client::SORT_SEQUENCE) {
+                try {
+                    $res = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->status($this->_mailbox, Horde_Imap_Client::STATUS_FIRSTUNSEEN);
+                    if (!is_null($res['firstunseen'])) {
+                        return $res['firstunseen'];
+                    }
+                } catch (Horde_Imap_Client_Exception $e) {}
+
+                return 1;
+            }
+
+            $unseen_msgs = $this->unseenMessages(Horde_Imap_Client::SORT_RESULTS_MIN, true);
+            return empty($unseen_msgs['min'])
+                ? 1
+                : ($this->getArrayIndex($unseen_msgs['min']) + 1);
+
+        case IMP::MAILBOX_START_LASTUNSEEN:
+            $unseen_msgs = $this->unseenMessages(Horde_Imap_Client::SORT_RESULTS_MAX, true);
+            return empty($unseen_msgs['max'])
+                ? 1
+                : ($this->getArrayIndex($unseen_msgs['max']) + 1);
+        }
+    }
+
+    /**
+     * Get the Horde_Imap_Client_Thread object for the current mailbox.
+     *
+     * @return Horde_Imap_Client_Thread  The thread object for the current
+     *                                   mailbox.
+     */
+    public function getThreadOb()
+    {
+        if (is_null($this->_threadob)) {
+            try {
+                $this->_threadob = $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->thread($this->_mailbox, array('criteria' => $_SESSION['imp']['imap']['thread']));
+            } catch (Horde_Imap_Client_Exception $e) {
+                $GLOBALS['notification']->push($e);
+                return new Horde_Imap_Client_Thread(array(), 'uid');
+            }
+        }
+
+        return $this->_threadob;
+    }
+
+    /**
+     * Determines if a rebuild is needed, and, if necessary, performs
+     * the rebuild.
+     *
+     * @param boolean $force  Force a rebuild?
+     */
+    protected function _rebuild($force = false)
+    {
+        if ($force) {
+            $this->_sorted = null;
+            $this->_buildMailbox();
+        }
+    }
+
+    /**
+     * Returns the array index of the given message UID.
+     *
+     * @param integer $uid   The message UID.
+     * @param integer $mbox  The message mailbox (defaults to the current
+     *                       mailbox).
+     *
+     * @return mixed  The array index of the location of the message UID in
+     *                the current mailbox. Returns null if not found.
+     */
+    public function getArrayIndex($uid, $mbox = null)
+    {
+        $aindex = null;
+
+        $this->_buildMailbox();
+
+        if ($this->_searchmbox) {
+            if (is_null($mbox)) {
+                $mbox = IMP::$thismailbox;
+            }
+
+            /* Need to compare both mbox name and message UID to obtain the
+             * correct array index since there may be duplicate UIDs. */
+            foreach (array_keys($this->_sorted, $uid) as $key) {
+                if ($this->_sortedMbox[$key] == $mbox) {
+                    return $key;
+                }
+            }
+        } else {
+            /* array_search() returns false on no result. We will set an
+             * unsuccessful result to NULL. */
+            if (($aindex = array_search($uid, $this->_sorted)) === false) {
+                $aindex = null;
+            }
+        }
+
+        return $aindex;
+    }
+
+    /**
+     * Returns a raw sorted list of the mailbox.
+     *
+     * @return array  An array with two keys: 's' = sorted UIDS list, 'm' =
+     *                sorted mailboxes list.
+     */
+    public function getSortedList()
+    {
+        $this->_buildMailbox();
+
+        /* For exterior use, the array needs to begin numbering at 1. */
+        $s = $this->_sorted;
+        array_unshift($s, 0);
+        unset($s[0]);
+        $m = $this->_sortedMbox;
+        array_unshift($m, 0);
+        unset($m[0]);
+
+        return array('s' => $s, 'm' => $m);
+    }
+
+    /**
+     * Returns the current sorted array without the given messages.
+     *
+     * @param mixed $indices  An IMP_Indices object or true to remove all
+     *                        messages in the mailbox.
+     *
+     * @return boolean  True if the message was removed from the mailbox.
+     */
+    public function removeMsgs($indices)
+    {
+        if ($indices === true) {
+            $this->_rebuild(true);
+            return false;
+        }
+
+        if (!count($indices)) {
+            return false;
+        }
+
+        /* Remove the current entry and recalculate the range. */
+        foreach ($indices as $mbox => $uid) {
+            $val = $this->getArrayIndex($uid, $mbox);
+            unset($this->_sorted[$val]);
+            if ($this->_searchmbox) {
+                unset($this->_sortedMbox[$val]);
+            }
+        }
+
+        $this->changed = true;
+        $this->_sorted = array_values($this->_sorted);
+        if ($this->_searchmbox) {
+            $this->_sortedMbox = array_values($this->_sortedMbox);
+        }
+        $this->_threadob = null;
+
+        return true;
+    }
+
+    /**
+     * Returns a unique identifier for the current mailbox status.
+     *
+     * This cache ID is guaranteed to change if messages are added/deleted from
+     * the mailbox. Additionally, if CONDSTORE is available on the remote
+     * IMAP server, this ID will change if flag information changes.
+     *
+     * @return string  The cache ID string, which will change when the
+     *                 composition of the mailbox changes.
+     */
+    public function getCacheID()
+    {
+        if (!$this->_searchmbox) {
+            $sortpref = IMP::getSort($this->_mailbox, true);
+            try {
+                return $GLOBALS['injector']->getInstance('IMP_Imap')->getOb()->getCacheId($this->_mailbox, array($sortpref['by'], $sortpref['dir']));
+            } catch (Horde_Imap_Client_Exception $e) {}
+        }
+
+        return strval(new Horde_Support_Randomid());
+    }
+
+    /* Countable methods. */
+
+    /**
+     * Returns the current message count of the mailbox.
+     *
+     * @return integer  The mailbox message count.
+     */
+    public function count()
+    {
+        $this->_buildMailbox();
+        return count($this->_sorted);
+    }
+
+    /* Serializable methods. */
+
+    /**
+     * Serialization.
+     *
+     * @return string  Serialized data.
+     */
+    public function serialize()
+    {
+        $data = array(
+            'm' => $this->_mailbox,
+            's' => $this->_searchmbox,
+            'v' => self::VERSION
+        );
+
+        if (!is_null($this->_sorted)) {
+            $data['so'] = $this->_sorted;
+            if (!empty($this->_sortedmbox)) {
+                $data['som'] = $this->_sortedmbox;
+            }
+        }
+
+        foreach ($this->_slist as $val) {
+            $data[$val] = $this->$val;
+        }
+
+        return json_encode($data);
+    }
+
+    /**
+     * Unserialization.
+     *
+     * @param string $data  Serialized data.
+     *
+     * @throws Exception
+     */
+    public function unserialize($data)
+    {
+        $data = json_decode($data, true);
+        if (!is_array($data) ||
+            !isset($data['v']) ||
+            ($data['v'] != self::VERSION)) {
+            throw new Exception('Cache version change');
+        }
+
+        $this->_mailbox = $data['m'];
+        $this->_searchmbox = $data['s'];
+
+        if (isset($data['so'])) {
+            $this->_sorted = $data['so'];
+            if (isset($data['som'])) {
+                $this->_sortedmbox = $data['som'];
+            }
+        }
+
+        foreach ($this->_slist as $val) {
+            $this->$val = $data[$val];
+        }
+    }
+
+}
diff --git a/imp/lib/Mailbox/List/Track.php b/imp/lib/Mailbox/List/Track.php
new file mode 100644 (file)
index 0000000..761c836
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+/**
+ * This class contains code related to generating and handling a mailbox
+ * message list.  This class will keep track of the current index within
+ * a mailbox.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  IMP
+ */
+class IMP_Mailbox_List_Track extends IMP_Mailbox_List
+{
+    /**
+     * The location in the sorted array we are at.
+     *
+     * @var integer
+     */
+    protected $_index = null;
+
+    /**
+     * The list of additional variables to serialize.
+     *
+     * @var array
+     */
+    protected $_slist = array('_index');
+
+    /**
+     * Returns the current message array index. If the array index has
+     * run off the end of the message array, will return the last index.
+     *
+     * @return integer  The message array index.
+     */
+    public function getMessageIndex()
+    {
+        return $this->isValidIndex()
+            ? ($this->_index + 1)
+            : 1;
+    }
+
+    /**
+     * Checks to see if the current index is valid.
+     *
+     * @return boolean  True if index is valid, false if not.
+     */
+    public function isValidIndex()
+    {
+        return !is_null($this->_index);
+    }
+
+    /**
+     * Returns IMAP mbox/UID information on a message.
+     *
+     * @param integer $offset  The offset from the current message.
+     *
+     * @return array  Array with the following entries:
+     * <pre>
+     * 'mailbox' - (string) The mailbox.
+     * 'uid' - (integer) The message UID.
+     * </pre>
+     */
+    public function getIMAPIndex($offset = 0)
+    {
+        $index = $this->_index + $offset;
+
+        return isset($this->_sorted[$index])
+            ? array(
+                  'mailbox' => ($this->_searchmbox ? $this->_sortedMbox[$index] : $this->_mailbox),
+                  'uid' => $this->_sorted[$index]
+              )
+            : array();
+    }
+
+    /**
+     * Using the preferences and the current mailbox, determines the messages
+     * to view on the current page.
+     *
+     * @see parent::buildMailboxPage()
+     */
+    public function buildMailboxPage($page = 0, $start = 0, $opts = array())
+    {
+        $ret = parent::buildMailboxPage($page, $start, $opts);
+
+        if (!$this->_searchmbox) {
+            $ret['index'] = $this->_index;
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Updates the message array index.
+     *
+     * @param mixed $data  If an integer, the number of messages to increase
+     *                     array index by. If an indices object, sets array
+     *                     index to the index value.
+     */
+    public function setIndex($data)
+    {
+        if ($data instanceof IMP_Indices) {
+            list($mailbox, $uid) = $data->getSingle();
+            $this->_index = $this->getArrayIndex($uid, $mailbox);
+            if (empty($this->_index)) {
+                $this->_rebuild(true);
+                $this->_index = $this->getArrayIndex($uid, $mailbox);
+            }
+        } elseif (!is_null($this->_index)) {
+            $index = $this->_index += $data;
+            if (isset($this->_sorted[$this->_index])) {
+                $this->_rebuild();
+            } else {
+                $this->_rebuild(true);
+                $this->_index = isset($this->_sorted[$index])
+                    ? $index
+                    : null;
+            }
+        }
+    }
+
+    /**
+     * Determines if a rebuild is needed, and, if necessary, performs
+     * the rebuild.
+     *
+     * @param boolean $force  Force a rebuild?
+     */
+    protected function _rebuild($force = false)
+    {
+        if ($force ||
+            (!is_null($this->_index) && !$this->getIMAPIndex(1))) {
+            $this->_sorted = null;
+            $this->_buildMailbox();
+        }
+    }
+
+    /**
+     * Returns the current sorted array without the given messages.
+     *
+     * @param mixed $indices  An IMP_Indices object or true to remove all
+     *                        messages in the mailbox.
+     */
+    public function removeMsgs($indices)
+    {
+        if (parent::removeMsgs($indices)) {
+            /* Update the current array index to its new position in the
+             * message array. */
+            $this->setIndex(0);
+        }
+    }
+
+}
index 7b4321e..4093d78 100644 (file)
@@ -50,7 +50,7 @@ class IMP_Message
      * <pre>
      * 'create' - (boolean) Should the target mailbox be created?
      *            DEFAULT: false
-     * 'mailboxob' - (IMP_Mailbox) Update this mailbox object.
+     * 'mailboxob' - (IMP_Mailbox_List) Update this mailbox object.
      *               DEFAULT: No update.
      * </pre>
      *
@@ -167,7 +167,7 @@ class IMP_Message
      * <pre>
      * 'keeplog' - (boolean) Should any history information of the message be
      *             kept?
-     * 'mailboxob' - (IMP_Mailbox) Update this mailbox object.
+     * 'mailboxob' - (IMP_Mailbox_List) Update this mailbox object.
      *               DEFAULT: No update.
      * 'nuke' - (boolean) Override user preferences and nuke (i.e. permanently
      *          delete) the messages instead?
@@ -472,7 +472,7 @@ class IMP_Message
      *                              parts are stripped if null.
      * @param array $opts           Additional options:
      * <pre>
-     * 'mailboxob' - (IMP_Mailbox) Update this mailbox object.
+     * 'mailboxob' - (IMP_Mailbox_List) Update this mailbox object.
      *               DEFAULT: No update.
      * </pre>
      *
@@ -704,7 +704,7 @@ class IMP_Message
      * <pre>
      * 'list' - (boolean) Return a list of messages expunged.
      *          DEFAULT: false
-     * 'mailboxob' - (IMP_Mailbox) Update this mailbox object.
+     * 'mailboxob' - (IMP_Mailbox_List) Update this mailbox object.
      *               DEFAULT: No update.
      * </pre>
      *
index 545ec1f..c9e3cb2 100644 (file)
@@ -23,7 +23,7 @@ class IMP_Spam
      * @param string $action        Either 'spam' or 'notspam'.
      * @param array $opts           Additional options:
      * <pre>
-     * 'mailboxob' - (IMP_Mailbox) Update this mailbox object.
+     * 'mailboxob' - (IMP_Mailbox_List) Update this mailbox list object.
      *               DEFAULT: No update.
      * 'noaction' - (boolean) Don't perform any action after reporting?
      *              DEFAULT: false
index 6ca9f8e..648b890 100644 (file)
@@ -108,7 +108,7 @@ class IMP_Views_ListMessages
         }
 
         /* Generate the sorted mailbox list now. */
-        $imp_mailbox = $GLOBALS['injector']->getInstance('IMP_Mailbox')->getOb($mbox);
+        $imp_mailbox = $GLOBALS['injector']->getInstance('IMP_Mailbox_List')->getList($mbox);
         $sorted_list = $imp_mailbox->getSortedList();
         $msgcount = count($sorted_list['s']);
 
@@ -379,11 +379,11 @@ class IMP_Views_ListMessages
     /**
      * Obtains IMAP overview data for a given set of message UIDs.
      *
-     * @param IMP_Mailbox $imp_mailbox  An IMP_Mailbox:: object.
-     * @param string $folder            The current folder.
-     * @param array $msglist            The list of message sequence numbers
-     *                                  to process.
-     * @param boolean $search           Is this a search mbox?
+     * @param IMP_Mailbox_List $imp_mailbox  The mailbox list  object.
+     * @param string $folder                 The current folder.
+     * @param array $msglist                 The list of message sequence
+     *                                       numbers to process.
+     * @param boolean $search                Is this a search mbox?
      *
      * @return array  TODO
      * @throws Horde_Exception
index 0a982d1..0163b5e 100644 (file)
@@ -127,7 +127,7 @@ case 'rs':
 }
 
 /* Build the list of messages in the mailbox. */
-$imp_mailbox = $injector->getInstance('IMP_Mailbox')->getOb(IMP::$mailbox);
+$imp_mailbox = $injector->getInstance('IMP_Mailbox_List')->getList(IMP::$mailbox);
 $pageOb = $imp_mailbox->buildMailboxPage($vars->p, $vars->s);
 
 /* Generate page title. */
index 4d57ac8..634b368 100644 (file)
@@ -225,7 +225,7 @@ if ($conf['user']['allow_folders']) {
 }
 
 /* Build the list of messages in the mailbox. */
-$imp_mailbox = $injector->getInstance('IMP_Mailbox')->getOb(IMP::$mailbox);
+$imp_mailbox = $injector->getInstance('IMP_Mailbox_List')->getList(IMP::$mailbox);
 $pageOb = $imp_mailbox->buildMailboxPage($vars->page, $start);
 $show_preview = $prefs->getValue('preview_enabled');
 
index 328857a..e82db7e 100644 (file)
@@ -29,7 +29,7 @@ Horde_Registry::appInit('imp', array(
 $vars = Horde_Variables::getDefaultVariables();
 
 /* Make sure we have a valid index. */
-$imp_mailbox = $injector->getInstance('IMP_Mailbox')->getOb(IMP::$mailbox, new IMP_Indices(IMP::$thismailbox, IMP::$uid));
+$imp_mailbox = $injector->getInstance('IMP_Mailbox_List')->getListTrack(IMP::$mailbox, new IMP_Indices(IMP::$thismailbox, IMP::$uid));
 if (!$imp_mailbox->isValidIndex()) {
     IMP::generateIMPUrl('mailbox-mimp.php', IMP::$mailbox)->add('a', 'm')->redirect();
 }
index 9afac40..78189ba 100644 (file)
@@ -34,7 +34,7 @@ if (!($search_mbox = $injector->getInstance('IMP_Search')->isSearchMbox(IMP::$ma
 }
 
 /* Make sure we have a valid index. */
-$imp_mailbox = $injector->getInstance('IMP_Mailbox')->getOb(IMP::$mailbox, new IMP_Indices(IMP::$thismailbox, IMP::$uid));
+$imp_mailbox = $injector->getInstance('IMP_Mailbox_List')->getListTrack(IMP::$mailbox, new IMP_Indices(IMP::$thismailbox, IMP::$uid));
 if (!$imp_mailbox->isValidIndex()) {
     _returnToMailbox(null, 'message_missing');
     require IMP_BASE . '/mailbox.php';
index f81cd80..6107ce2 100644 (file)
@@ -46,7 +46,7 @@ if (!empty($request)) {
     $new_mail = (isset($request_parts[1]) && ($request_parts[1] === 'new'));
 }
 
-$imp_mailbox = $injector->getInstance('IMP_Mailbox')->getOb($mailbox);
+$imp_mailbox = $injector->getInstance('IMP_Mailbox_List')->getList($mailbox);
 $imp_search = $injector->getInstance('IMP_Search');
 
 /* Obtain some information describing the mailbox state. */
index 1f5ccf5..ea4e541 100644 (file)
@@ -28,7 +28,7 @@ $mode = $vars->mode
     : 'thread';
 
 $imp_imap = $injector->getInstance('IMP_Imap')->getOb();
-$imp_mailbox = $injector->getInstance('IMP_Mailbox')->getOb(IMP::$mailbox, new IMP_Indices(IMP::$thismailbox, IMP::$uid));
+$imp_mailbox = $injector->getInstance('IMP_Mailbox_List')->getListTrack(IMP::$mailbox, new IMP_Indices(IMP::$thismailbox, IMP::$uid));
 
 $error = false;
 if ($mode == 'thread') {