[ Index ]
 

Code source de IMP H3 (4.1.5)

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/lib/ -> Mailbox.php (source)

   1  <?php
   2  
   3  define('IMP_MAILBOX_MOVE', 1);
   4  define('IMP_MAILBOX_COPY', 2);
   5  define('IMP_MAILBOX_DELETE', 3);
   6  define('IMP_MAILBOX_UNDELETE', 4);
   7  define('IMP_MAILBOX_EXPUNGE', 5);
   8  define('IMP_MAILBOX_EMPTY', 6);
   9  define('IMP_MAILBOX_UPDATE', 7);
  10  
  11  /**
  12   * The IMP_Mailbox:: class contains all code related to handling mailbox
  13   * access.
  14   *
  15   * $Horde: imp/lib/Mailbox.php,v 1.76.10.61 2007/01/02 13:54:56 jan Exp $
  16   *
  17   * Copyright 2002-2007 Michael Slusarz <slusarz@bigworm.colorado.edu>
  18   *
  19   * See the enclosed file COPYING for license information (GPL). If you
  20   * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
  21   *
  22   * @author  Michael Slusarz <slusarz@bigworm.colorado.edu>
  23   * @since   IMP 4.0
  24   * @package IMP
  25   */
  26  class IMP_Mailbox {
  27  
  28      /**
  29       * The location in the sorted array we are at.
  30       *
  31       * @var integer
  32       */
  33      var $_arrayIndex = null;
  34  
  35      /**
  36       * The location of the last message we were at.
  37       *
  38       * @var integer
  39       */
  40      var $_lastArrayIndex = null;
  41  
  42      /**
  43       * The array of sorted indices.
  44       *
  45       * @var array
  46       */
  47      var $_sorted = array();
  48  
  49      /**
  50       * The array of sorted mailboxes.
  51       *
  52       * @var array
  53       */
  54      var $_sortedMbox = array();
  55  
  56      /**
  57       * The threading information for the current mailbox.
  58       *
  59       * @var IMP_Thread
  60       */
  61      var $_thread = null;
  62  
  63      /**
  64       * Should we show Hide/purge deleted message links?
  65       *
  66       * @var boolean
  67       */
  68      var $_showdelete = false;
  69  
  70      /**
  71       * The number of new messages in the mailbox.
  72       *
  73       * @var integer
  74       */
  75      var $_newmsgs = 0;
  76  
  77      /**
  78       * Using POP to access mailboxes?
  79       *
  80       * @var boolean
  81       */
  82      var $_usepop = false;
  83  
  84      /**
  85       * The sort method for this mailbox.
  86       *
  87       * @var integer
  88       */
  89      var $_sortby;
  90  
  91      /**
  92       * Are we hiding deleted messages?
  93       *
  94       * @var boolean
  95       */
  96      var $_delhide;
  97  
  98      /**
  99       * Special folder flag.
 100       *
 101       * @var boolean
 102       */
 103      var $_specialFolder = null;
 104  
 105      /**
 106       * Has the sorting limit been reached?
 107       *
 108       * @var boolean
 109       */
 110      var $_sortLimit = false;
 111  
 112      /**
 113       * Variables relating to showing message previews.
 114       *
 115       * @var array
 116       */
 117      var $_previews = array();
 118  
 119      /**
 120       * The 'no_newmail_popup' flag.
 121       *
 122       * @var boolean
 123       */
 124      var $_no_newmail_popup = false;
 125  
 126      /**
 127       * Attempts to return a reference to a concrete IMP_Mailbox instance.
 128       * It will only create a new instance if no IMP_Mailbox instance with
 129       * the same parameters currently exists.
 130       *
 131       * This method must be invoked as: $var = &IMP_Mailbox::singleton();
 132       *
 133       * @param integer $index  See IMP_Mailbox constructor.
 134       * @param boolean $force  Force the creation of a new instance.
 135       *
 136       * @return mixed  The created concrete IMP_Mailbox instance, or false
 137       *                on error.
 138       */
 139      function &singleton($index = null, $force = false)
 140      {
 141          static $instances = array();
 142  
 143          $signature = serialize($index);
 144          if ($force || !isset($instances[$signature])) {
 145              $instances[$signature] = new IMP_Mailbox($index);
 146          }
 147  
 148          return $instances[$signature];
 149      }
 150  
 151      /**
 152       * Constructor.
 153       *
 154       * @param integer $index  The index of the current message. This will cause
 155       *                        IMP_Message to update the various message arrays
 156       *                        after each action.
 157       */
 158      function IMP_Mailbox($index = null)
 159      {
 160          if (!is_null($index)) {
 161              $this->setNewIndex($index);
 162          }
 163  
 164          if ($GLOBALS['imp']['base_protocol'] == 'pop3') {
 165              $this->_usepop = true;
 166          }
 167  
 168          /* Determine whether we're hiding deleted messages; let the
 169             trash folder take precedence. */
 170          if ($GLOBALS['prefs']->getValue('use_vtrash')) {
 171              $this->_delhide = !$GLOBALS['imp_search']->isVTrashFolder();
 172          } else {
 173              $this->_delhide = ($GLOBALS['prefs']->getValue('delhide') &&
 174                                 !$GLOBALS['prefs']->getValue('use_trash') &&
 175                                 ($GLOBALS['imp_search']->isSearchMbox() ||
 176                                 ($GLOBALS['prefs']->getValue('sortby') != SORTTHREAD)));
 177          }
 178      }
 179  
 180      /**
 181       * Sets the value of the 'no_newmail_popup' flag.
 182       *
 183       * @param boolean $nopopup  The value to set the flag.
 184       */
 185      function setNoNewmailPopup($nopopup)
 186      {
 187          $this->_no_newmail_popup = (bool) $nopopup;
 188      }
 189  
 190      /**
 191       * Sets a new index.
 192       *
 193       * @param integer $index  The index of the new current message.
 194       */
 195      function setNewIndex($index)
 196      {
 197          $this->_setSorted();
 198          $this->_setArrayIndex($index, 'uid');
 199      }
 200  
 201      /**
 202       * Determines if mail previews should be generated.
 203       *
 204       * @return boolean  True if mail previews should be generated.
 205       */
 206      function showPreviews()
 207      {
 208          if (!empty($this->_previews)) {
 209              return true;
 210          }
 211  
 212          if (!$GLOBALS['conf']['mailbox']['show_preview'] ||
 213              !$GLOBALS['prefs']->getValue('preview_enabled')) {
 214              return false;
 215          }
 216  
 217          $this->_previews['unread'] = $GLOBALS['prefs']->getValue('preview_show_unread');
 218          $this->_previews['maxlen'] = $GLOBALS['prefs']->getValue('preview_maxlen');
 219          if ($this->_previews['maxlen'] != -1) {
 220              $this->_previews['maxlen'] = max(5, $this->_previews['maxlen'] - 3);
 221          }
 222          $this->_previews['strip'] = $GLOBALS['prefs']->getValue('preview_strip_nl');
 223          $this->_previews['tooltip'] = $GLOBALS['prefs']->getValue('preview_show_tooltip');
 224  
 225          return true;
 226      }
 227  
 228      /**
 229       * Build the array of message information.
 230       *
 231       * @param integer $begin  The beginning message number.
 232       * @param integer $end    The ending message number.
 233       *
 234       * @return array  An array with information on the requested messages.
 235       * <pre>
 236       * Key: array index in current sorted mailbox array
 237       * 'header'     --  Header information from imap_fetch_overview().
 238       * 'mbox'       --  Name of the mailbox.
 239       * 'preview'    --  The message preview (if the 'show_preview' preference
 240       *                  is active).
 241       * 'structure'  --  Structure of the message (if the 'show_attachments'
 242       *                  configuration option is active).
 243       * </pre>
 244       */
 245      function buildMailboxArray($begin, $end)
 246      {
 247          $this->_showdelete = false;
 248  
 249          $mboxes = array();
 250          $overview = array();
 251          $show_preview = $this->showPreviews();
 252  
 253          /* Build the list of mailboxes and messages. */
 254          for ($i = $begin - 1; $i < $end; $i++) {
 255              /* Make sure that the index is actually in the slice of messages
 256                 we're looking at. If we're hiding deleted messages, for
 257                 example, there may be gaps here. */
 258              if (isset($this->_sorted[$i])) {
 259                  if (isset($this->_sortedMbox[$i])) {
 260                      $mboxname = $this->_sortedMbox[$i];
 261                  } else {
 262                      $mboxname = $GLOBALS['imp']['mailbox'];
 263                  }
 264  
 265                  if (!isset($mboxes[$mboxname])) {
 266                      $mboxes[$mboxname] = array();
 267                  }
 268                  $mboxes[$mboxname][$this->_sorted[$i]] = $i;
 269              }
 270          }
 271  
 272          require_once  IMP_BASE . '/lib/IMAP.php';
 273          $imp_imap = &IMP_IMAP::singleton();
 274  
 275          /* Retrieve information from each mailbox. */
 276          foreach ($mboxes as $mbox => $ids) {
 277              $imp_imap->changeMbox($mbox, OP_READONLY);
 278              $imapOverview = @imap_fetch_overview($GLOBALS['imp']['stream'], implode(',', array_keys($ids)), FT_UID);
 279              foreach ($imapOverview as $header) {
 280                  $key = $ids[$header->uid];
 281                  $overview[$key] = array();
 282                  $overview[$key]['header'] = $header;
 283                  if ($header->deleted) {
 284                      $this->_showdelete = true;
 285                  }
 286  
 287                  if ($GLOBALS['conf']['fetchmail']['show_account_colors']) {
 288                      $hdr = @imap_fetchheader($GLOBALS['imp']['stream'], $header->uid, FT_UID);
 289                      if (preg_match("/X-color:(.*)\n/", $hdr, $color)) {
 290                          $overview[$key]['color'] = trim($color[1]);
 291                      }
 292                  }
 293  
 294                  $overview[$key]['mbox'] = $mbox;
 295  
 296                  /* Add preview information. */
 297                  if ($show_preview &&
 298                      (!$this->_previews['unread'] ||
 299                       !$header->seen ||
 300                       $header->recent)) {
 301                      require_once  IMP_BASE . '/lib/MIME/Contents.php';
 302                      $imp_contents = &IMP_Contents::singleton($header->uid . IMP_IDX_SEP . $mbox);
 303                      if (($mimeid = $imp_contents->findBody(false)) !== null) {
 304                          $pmime = &$imp_contents->getDecodedMIMEPart($mimeid);
 305                          $ptext = $pmime->getContents();
 306                          $ptext = String::convertCharset($ptext, $pmime->getCharset());
 307                          if ($pmime->getType() == 'text/html') {
 308                              require_once 'Horde/Text/Filter.php';
 309                              $ptext = Text_Filter::filter($ptext, 'html2text');
 310                          }
 311                          if ($this->_previews['maxlen'] != -1) {
 312                              if (String::length($ptext) > $this->_previews['maxlen']) {
 313                                  $ptext = String::substr($ptext, 0, $this->_previews['maxlen']) . ' ...';
 314                              } else {
 315                                  $ptext .= '[[' . _("END") . ']]';
 316                              }
 317                          }
 318  
 319                          if ($this->_previews['strip'] &&
 320                              !$this->_previews['tooltip']) {
 321                              $ptext = str_replace("\r", "\n", $ptext);
 322                              $ptext = preg_replace('/\n/', ' ', $ptext);
 323                              $ptext = preg_replace('/(\s)+/', '$1', $ptext);
 324                          } else {
 325                              $ptext = str_replace("\r", '', $ptext);
 326                          }
 327                          if (!$this->_previews['tooltip']) {
 328                              require_once 'Horde/Text/Filter.php';
 329                              $ptext = Text_Filter::filter($ptext, 'text2html', array('parselevel' => TEXT_HTML_NOHTML, 'charset' => '', 'class' => ''));
 330                          }
 331                      } else {
 332                          $ptext = '[[' . _("No Preview Text") . ']]';
 333                      }
 334  
 335                      $overview[$key]['structure'] = $imp_contents->getMIMEMessage();
 336                      $overview[$key]['preview'] = $ptext;
 337                  } else {
 338                      require_once 'Horde/MIME/Structure.php';
 339                      $overview[$key]['structure'] = ($GLOBALS['conf']['mailbox']['show_attachments']) ? MIME_Structure::parse(@imap_fetchstructure($GLOBALS['imp']['stream'], $header->uid, FT_UID)) : null;
 340                      $overview[$key]['preview'] = null;
 341                  }
 342              }
 343          }
 344  
 345          /* Sort via the sorted array index. */
 346          ksort($overview);
 347  
 348          return $overview;
 349      }
 350  
 351      /**
 352       * Builds the list of messages in the mailbox.
 353       *
 354       * @access private
 355       *
 356       * @return array  The sorted index.
 357       */
 358      function _buildMailbox()
 359      {
 360          $this->_newmsgs = 0;
 361  
 362          if ($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 363              $query = null;
 364              if ($this->_delhide) {
 365                  require_once  IMP_BASE . '/lib/IMAP/Search.php';
 366                  $query = &new IMP_IMAP_Search_Query();
 367                  $query->deleted(false);
 368              }
 369              $sorted = $GLOBALS['imp_search']->runSearch($query, $GLOBALS['imp']['mailbox']);
 370  
 371              /* Return to the search page if this is not a virtual folder. */
 372              if (empty($sorted) &&
 373                  !$GLOBALS['imp_search']->isVFolder($GLOBALS['imp']['mailbox'])) {
 374                  $GLOBALS['notification']->push(_("No messages matched your search."), 'horde.warning');
 375                  header('Location: ' . Util::addParameter(Horde::applicationUrl('search.php', true), 'no_match', 1));
 376                  exit;
 377              }
 378          } else {
 379              $this->_getSortedIndex();
 380              if (!empty($this->_sorted) &&
 381                  (($GLOBALS['prefs']->getValue('nav_popup') ||
 382                    $GLOBALS['prefs']->getValue('nav_audio')) &&
 383                   !$this->_no_newmail_popup)) {
 384                  $newQuery = 'RECENT';
 385                  if ($this->_delhide) {
 386                      $newQuery .= ' UNDELETED';
 387                  }
 388                  if (($new = @imap_search($GLOBALS['imp']['stream'], $newQuery))) {
 389                      $this->_newmsgs = count($new);
 390                  }
 391              }
 392              $sorted = $this->_sorted;
 393          }
 394  
 395          /* Store the sorted range in IMP_Message. */
 396          $this->_setRange($sorted);
 397  
 398          return $sorted;
 399      }
 400  
 401      /**
 402       * The number of new messages in the mailbox (IMAP RECENT flag,
 403       * with UNDELETED if we're hiding deleted messages).
 404       *
 405       * @return integer The number of new messages in the mailbox.
 406       */
 407      function newMessageCount()
 408      {
 409          return $this->_newmsgs;
 410      }
 411  
 412      /**
 413       * Get the list of unseen messages in the mailbox (IMAP UNSEEN flag).
 414       *
 415       * @return array  The list of unseen messages.
 416       */
 417      function unseenMessages()
 418      {
 419          $newQuery = 'UNSEEN';
 420          if ($this->_delhide) {
 421              $newQuery .= ' UNDELETED';
 422          }
 423          $ret = @imap_search($GLOBALS['imp']['stream'], 'ALL ' . $newQuery, SE_UID);
 424          return (empty($ret)) ? array() : $ret;
 425      }
 426  
 427      /**
 428       * Returns the current array index.
 429       *
 430       * @return integer  The array index.
 431       */
 432      function getArrayIndex()
 433      {
 434          return $this->_arrayIndex;
 435      }
 436  
 437      /**
 438       * Returns the current message array index. If the array index has
 439       * run off the end of the message array, will return the last index.
 440       *
 441       * @return integer  The message array index.
 442       */
 443      function getMessageIndex()
 444      {
 445          if (is_null($this->_arrayIndex)) {
 446              if (is_null($this->_lastArrayIndex)) {
 447                  $index = 0;
 448              } else {
 449                  $index = $this->_lastArrayIndex;
 450              }
 451          } else {
 452              $index = $this->_arrayIndex;
 453          }
 454  
 455          return $index + 1;
 456      }
 457  
 458      /**
 459       * Returns the current message count of the mailbox.
 460       *
 461       * @return integer  The mailbox message count.
 462       */
 463      function getMessageCount()
 464      {
 465          return count($this->_sorted);
 466      }
 467  
 468      /**
 469       * Checks to see if the current index is valid.
 470       * This function is only useful if an index was passed to the constructor.
 471       *
 472       * @return boolean  True if index is valid, false if not.
 473       */
 474      function isValidIndex()
 475      {
 476          $this->_sortIfNeeded();
 477          return !is_null($this->_arrayIndex);
 478      }
 479  
 480      /**
 481       * Returns IMAP mbox/UID information on a message.
 482       *
 483       * @param integer $offset  The offset from the current message.
 484       *
 485       * @return array  'index'   -- The message index.
 486       *                'mailbox' -- The mailbox.
 487       */
 488      function getIMAPIndex($offset = 0)
 489      {
 490          $return_array = array();
 491          $index = $this->_arrayIndex + $offset;
 492  
 493          /* If the offset would put us out of array index, return now. */
 494          if (!isset($this->_sorted[$index])) {
 495              return $return_array;
 496          }
 497  
 498          $return_array['index'] = $this->_sorted[$index];
 499          if ($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 500              $return_array['mailbox'] = $this->_sortedMbox[$index];
 501          } else {
 502              $return_array['mailbox'] = $GLOBALS['imp']['mailbox'];
 503          }
 504  
 505          return $return_array;
 506      }
 507  
 508      /**
 509       * Update the current mailbox if an action has been performed on the
 510       * current message index.
 511       *
 512       * @param integer $action   The action to perform.
 513       * @param boolean $success  Was the action successful?
 514       */
 515      function updateMailbox($action, $success = true)
 516      {
 517          switch ($action) {
 518          case IMP_MAILBOX_COPY:
 519              /* Just move to the next message. */
 520              $this->moveNext();
 521  
 522              /* Determine if we need to resort. */
 523              $this->_sortIfNeeded();
 524              break;
 525  
 526          case IMP_MAILBOX_MOVE:
 527          case IMP_MAILBOX_DELETE:
 528              /* If we are using POP, we need to resort every time. */
 529              if ($success && $this->_usepop) {
 530                  $this->_getSortedIndex();
 531              } elseif ($success &&
 532                        ($this->_delhide ||
 533                         $GLOBALS['prefs']->getValue('use_trash'))) {
 534                  /* Nuke message from sorted list if sent to trash or
 535                     hidden. */
 536                  $this->_removeCurrent();
 537              } else {
 538                  /* Either we failed, or the message is still in the
 539                     mailbox and has been marked as deleted - just move
 540                     to the next message. */
 541                  $this->moveNext();
 542  
 543                  /* Determine if we need to resort. */
 544                  $this->_sortIfNeeded();
 545              }
 546              break;
 547  
 548          case IMP_MAILBOX_UNDELETE:
 549              $this->moveNext();
 550              break;
 551  
 552          case IMP_MAILBOX_EXPUNGE:
 553          case IMP_MAILBOX_EMPTY:
 554          case IMP_MAILBOX_UPDATE:
 555              if (!$GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 556                  $this->_getSortedIndex();
 557              }
 558              break;
 559          }
 560      }
 561  
 562      /**
 563       * Using the preferences and the current mailbox, determines the messages
 564       * to view on the current page.
 565       *
 566       * @param integer $page   The page number currently being displayed.
 567       * @param integer $start  The starting message number.
 568       *
 569       * @return stdClass  An object with the following fields:
 570       * <pre>
 571       * 'anymsg'     -  Are there any messages at all in mailbox? E.g. If
 572       *                 'msgcount' is 0, there may still be hidden deleted
 573       *                 messages.
 574       * 'begin'      -  The beginning message number of the page.
 575       * 'end'        -  The ending message number of the page.
 576       * 'index'      -  The index of the starting message.
 577       * 'msgcount'   -  The number of viewable messages in the current mailbox.
 578       * 'page'       -  The current page number.
 579       * 'pagecount'  -  The number of pages in this mailbox.
 580       * </pre>
 581       */
 582      function buildMailboxPage($page = 0, $start = 0)
 583      {
 584          $sorted = $this->_buildMailbox();
 585          $msgcount = $this->getMessageCount();
 586  
 587          $maxmsgs = $GLOBALS['prefs']->getValue('max_msgs');
 588          $sortdir = $GLOBALS['prefs']->getValue('sortdir');
 589  
 590          $this->_determineSort();
 591  
 592          if ($msgcount > $maxmsgs) {
 593              $pageCount = ceil($msgcount / (($maxmsgs > 0) ? $maxmsgs : 20));
 594  
 595              /* Determine which page to display. */
 596              if (empty($page) || strcspn($page, '0123456789')) {
 597                  if (!empty($start)) {
 598                      /* Messages set this when returning to a mailbox. */
 599                      $page = ceil($start / $maxmsgs);
 600                  } else {
 601                      $startpage = $GLOBALS['prefs']->getValue('mailbox_start');
 602                      switch ($startpage) {
 603                      case IMP_MAILBOXSTART_FIRSTPAGE:
 604                          $page = 1;
 605                          break;
 606  
 607                      case IMP_MAILBOXSTART_LASTPAGE:
 608                          $page = $pageCount;
 609                          break;
 610  
 611                      case IMP_MAILBOXSTART_FIRSTUNSEEN:
 612                      case IMP_MAILBOXSTART_LASTUNSEEN:
 613                          if (!$this->aboveSortLimit() &&
 614                              !$GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox']) &&
 615                              ($query = $this->unseenMessages())) {
 616                              $sortednew = array_keys(array_intersect($sorted, $query));
 617                              $first_new = ($startpage == IMP_MAILBOXSTART_FIRSTUNSEEN) ?
 618                                  array_shift($sortednew) :
 619                                  array_pop($sortednew);
 620                              $page = ceil(($first_new + 1) / $maxmsgs);
 621                          }
 622                          break;
 623                      }
 624                  }
 625  
 626                  if (empty($page)) {
 627                      $page = $sortdir ? 1 : $pageCount;
 628                  }
 629              }
 630  
 631              /* Make sure we're not past the end or before the beginning, and
 632                 that we have an integer value. */
 633              $page = intval($page);
 634              if ($page > $pageCount) {
 635                  $page = $pageCount;
 636              } elseif ($page < 1) {
 637                  $page = 1;
 638              }
 639  
 640              $begin = (($page - 1) * $maxmsgs) + 1;
 641              $end = $begin + $maxmsgs - 1;
 642              if ($end > $msgcount) {
 643                  $end = $msgcount;
 644              }
 645          } else {
 646              $begin = 1;
 647              $end = $msgcount;
 648              $page = 1;
 649              $pageCount = 1;
 650          }
 651  
 652          if ($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 653              $beginIndex = $begin - 1;
 654          } else {
 655              $beginIndex = $this->getArrayIndex();
 656          }
 657  
 658          /* If there are no viewable messages, check for deleted messages in
 659             the mailbox. */
 660          $anymsg = true;
 661          if (($msgcount == 0) &&
 662              !$GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 663              $status = @imap_status($GLOBALS['imp']['stream'], IMP::serverString($GLOBALS['imp']['mailbox']), SA_MESSAGES);
 664              if (is_object($status) && ($status->messages == 0)) {
 665                  $anymsg = false;
 666              }
 667          }
 668  
 669          $ob = new stdClass;
 670          $ob->anymsg    = $anymsg;
 671          $ob->begin     = $begin;
 672          $ob->end       = $end;
 673          $ob->index     = $beginIndex;
 674          $ob->msgcount  = $msgcount;
 675          $ob->page      = $page;
 676          $ob->pagecount = $pageCount;
 677  
 678          return $ob;
 679      }
 680  
 681      /**
 682       * Return the current sort method used.
 683       *
 684       * @return integer  The sort method.
 685       */
 686      function sortby()
 687      {
 688          static $orig_sort;
 689  
 690          $sortpref = $GLOBALS['prefs']->getValue('sortby');
 691          if (!isset($this->_sortby) || ($orig_sort != $sortpref)) {
 692              $this->_sortby = $orig_sort = $sortpref;
 693  
 694              /* The search mailbox doesn't support thread sort. */
 695              if ($GLOBALS['imp_search']->isSearchMbox($_SESSION['imp']['mailbox']) &&
 696                  ($this->_sortby == SORTTHREAD)) {
 697                  $this->_sortby = SORTDATE;
 698              }
 699          }
 700  
 701          return $this->_sortby;
 702      }
 703  
 704      /**
 705       * Determine whether the sort limit has been reached.
 706       *
 707       * @return boolean  Has the sort limit been reached?
 708       */
 709      function aboveSortLimit()
 710      {
 711          return $this->_sortLimit;
 712      }
 713  
 714      /**
 715       * Is this a 'special' folder (e.g. 'drafts' or 'sent-mail' folder)?
 716       *
 717       * @return boolean  Is this a 'special' folder?
 718       */
 719      function isSpecialFolder()
 720      {
 721          if (is_null($this->_specialFolder)) {
 722              /* Get the identities. */
 723              require_once 'Horde/Identity.php';
 724              $identity = &Identity::singleton(array('imp', 'imp'));
 725  
 726              $this->_specialFolder = (($GLOBALS['imp']['mailbox'] == IMP::folderPref($GLOBALS['prefs']->getValue('drafts_folder'), true)) || (in_array($GLOBALS['imp']['mailbox'], $identity->getAllSentmailFolders())));
 727          }
 728  
 729          return $this->_specialFolder;
 730      }
 731  
 732      /**
 733       * Updates the sorted messages array.
 734       *
 735       * @access private
 736       */
 737      function _setSorted()
 738      {
 739          $this->_sorted = array();
 740          $this->_sortedMbox = array();
 741  
 742          if (empty($GLOBALS['imp']['msgl'])) {
 743              $this->_sorted = array();
 744          } else {
 745              $msglist = explode(IMP_MSG_SEP, $GLOBALS['imp']['msgl']);
 746              if ($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 747                  foreach ($msglist as $val) {
 748                      list($idx, $mbox) = explode(IMP_IDX_SEP, $val);
 749                      $this->_sorted[] = $idx;
 750                      $this->_sortedMbox[] = $mbox;
 751                  }
 752              } else {
 753                  $this->_sorted = $msglist;
 754              }
 755          }
 756      }
 757  
 758      /**
 759       * Updates the message array index.
 760       *
 761       * @access private
 762       *
 763       * @param integer $data  If $type is 'offset', the number of messages to
 764       *                       increase array index by.  If type is 'uid',
 765       *                       sets array index to the value of the current
 766       *                       current message index.
 767       * @param string $type   Either 'offset' or 'uid'.
 768       */
 769      function _setArrayIndex($data, $type)
 770      {
 771          if ($type == 'offset') {
 772              $this->_lastArrayIndex = $this->_arrayIndex;
 773              $this->_arrayIndex += $data;
 774              if (empty($this->_sorted[$this->_arrayIndex])) {
 775                  $this->_arrayIndex = null;
 776              }
 777          } elseif ($type == 'uid') {
 778              if ($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 779                  /* Need to compare both mbox name and message UID to
 780                     obtain the correct array index since there may be
 781                     duplicate UIDs. */
 782                  $this->_arrayIndex = null;
 783                  foreach (array_keys($this->_sorted, $data) as $key) {
 784                      if ($this->_sortedMbox[$key] == $_SESSION['imp']['thismailbox']) {
 785                          $this->_arrayIndex = $key;
 786                          break;
 787                      }
 788                  }
 789              } else {
 790                  /* array_search() returns false on no result. We will
 791                     set an unsuccessful result to NULL. */
 792                  if (($this->_arrayIndex = array_search($data, $this->_sorted)) === false) {
 793                      $this->_arrayIndex = null;
 794                  }
 795              }
 796              $this->_lastArrayIndex = $this->_arrayIndex;
 797          }
 798  
 799          if (is_null($this->_arrayIndex) && !empty($this->_lastArrayIndex)) {
 800              $this->_lastArrayIndex--;
 801          }
 802      }
 803  
 804      /**
 805       * Get the sorted list of messages for a mailbox. This function
 806       * correctly handles sort preferences, deletion preferences
 807       * (e.g. hide deleted messages), and protocol (e.g. 'pop3'
 808       * vs. 'imap').
 809       *
 810       * The following variables are updated by this method:
 811       *   msgl
 812       *
 813       * @access private
 814       */
 815      function _getSortedIndex()
 816      {
 817          $sortdir = $GLOBALS['prefs']->getValue('sortdir');
 818          $sorted = array();
 819  
 820          $this->_determineSort(true);
 821  
 822          if ($this->sortby() == SORTTHREAD) {
 823              $sorted = $this->_threadSort((bool)$sortdir);
 824          } else {
 825              $delhidecmd = (!$this->_usepop && $this->_delhide) ? 'UNDELETED' : '';
 826              if ($this->sortby() == SORTARRIVAL) {
 827                  $sorted = imap_search($GLOBALS['imp']['stream'], ($delhidecmd) ? $delhidecmd : 'ALL', SE_UID);
 828                  if ($sorted === false) {
 829                      return;
 830                  }
 831                  if ($sortdir) {
 832                      $sorted = array_reverse($sorted);
 833                  }
 834              } else {
 835                  require_once  IMP_BASE . '/lib/IMAP/Search.php';
 836                  $imap_search = &IMP_IMAP_Search::singleton(array('pop3' => $this->_usepop));
 837                  $query = &new IMP_IMAP_Search_Query();
 838                  if ($delhidecmd) {
 839                      $query->deleted(false);
 840                  }
 841                  $sorted = $imap_search->searchSortMailbox($query, $_SESSION['imp']['stream'], $_SESSION['imp']['mailbox'], $this->sortby(), $sortdir);
 842                  if (is_a($sorted, 'PEAR_Error')) {
 843                      $sorted = array();
 844                  }
 845              }
 846          }
 847  
 848          $this->_setRange($sorted);
 849      }
 850  
 851      /**
 852       * Sets the current page of messages based on the current index.
 853       * The following session variables are updated by this method:
 854       *   'msgl'
 855       *
 856       * @access private
 857       *
 858       * @param array $arr  The array of message indices.
 859       */
 860      function _setRange($arr)
 861      {
 862          $GLOBALS['imp']['msgl'] = implode(IMP_MSG_SEP, $arr);
 863  
 864          /* Set the new sorted message list. */
 865          $this->_setSorted();
 866  
 867          /* Update the current array index to its new position in the message
 868           * array. */
 869          $this->_setArrayIndex(0, 'offset');
 870      }
 871  
 872      /**
 873       * Perform re-threading sort.
 874       *
 875       * @access private
 876       *
 877       * @param boolean $new   True for newest messages first, false for oldest
 878       *                       messages first.
 879       *
 880       * @return array  The sorted list of messages.
 881       */
 882      function _threadSort($new)
 883      {
 884          $ref_array = @imap_thread($GLOBALS['imp']['stream'], SE_UID);
 885          if (!is_array($ref_array)) {
 886              return array();
 887          }
 888  
 889          require_once  IMP_BASE . '/lib/IMAP/Thread.php';
 890          $this->_thread = &new IMP_Thread($ref_array);
 891          return $this->_thread->messageList($new);
 892      }
 893  
 894      /**
 895       * Get the IMP_Thread object for the current mailbox.
 896       *
 897       * @return IMP_Thread  The IMP_Thread object for the current mailbox.
 898       */
 899      function getThreadOb()
 900      {
 901          if (is_null($this->_thread)) {
 902              $this->_threadSort(false);
 903          }
 904          return $this->_thread;
 905      }
 906  
 907      /**
 908       * Determines if a resort is needed, and, if necessary, performs
 909       * the resort.
 910       *
 911       * The sorted range needs to be updated in the following cases:
 912       *   + Indexes are being tracked
 913       *   + There is a valid array index
 914       *   + This is not a search mailbox
 915       *   + The UIDs may no longer be valid (Optional)
 916       *   + This is the last message in the mailbox
 917       *   + A sort has not already occurred by some method in this class
 918       *
 919       * @access private
 920       */
 921      function _sortIfNeeded()
 922      {
 923          /* If array index is null, we have reached the beginning/end
 924             of the mailbox so we shouldn't sort anything. There is also
 925             no need to sort the search results. */
 926          if (!is_null($this->_arrayIndex) &&
 927              ($this->_arrayIndex != $this->_lastArrayIndex) &&
 928              !$GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox']) &&
 929              !$this->getIMAPIndex(1)) {
 930              $this->_getSortedIndex();
 931          }
 932      }
 933  
 934      /**
 935       * Returns the current sorted array without the current index message.
 936       *
 937       * @access private
 938       *
 939       * @return array  The sorted array without the current index in it.
 940       */
 941      function _removeCurrent()
 942      {
 943          /* Remove the current entry and recalculate the range. */
 944          unset($this->_sorted[$this->_arrayIndex]);
 945          if ($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp']['mailbox'])) {
 946              unset($this->_sortedMbox[$this->_arrayIndex]);
 947              $arr = array_map(create_function('$a, $b', 'return $a . IMP_IDX_SEP . $b;'), array_values($this->_sorted), array_values($this->_sortedMbox));
 948          } else {
 949              $arr = array_values($this->_sorted);
 950          }
 951  
 952          $this->_setRange($arr);
 953      }
 954  
 955      /**
 956       * Determine the correct sort method for this mailbox.
 957       *
 958       * @access private
 959       *
 960       * @param boolean  Run the sort_limit check?
 961       */
 962      function _determineSort($check = false)
 963      {
 964          $sortby = $this->sortby();
 965          if ($check &&
 966              ($sortby != SORTARRIVAL) &&
 967              !empty($GLOBALS['conf']['server']['sort_limit']) &&
 968              (@imap_num_msg($GLOBALS['imp']['stream']) > $GLOBALS['conf']['server']['sort_limit'])) {
 969              $this->_sortLimit = true;
 970              $this->_sortby = SORTARRIVAL;
 971          } else {
 972              if ($check) {
 973                  $this->_sortLimit = false;
 974              }
 975              if ($this->isSpecialFolder()) {
 976                  /* If the preference is to sort by From Address, when we are
 977                     in the Drafts or Sent folders, sort by To Address. */
 978                  if ($sortby == SORTFROM) {
 979                      $this->_sortby = SORTTO;
 980                  }
 981              } elseif ($sortby == SORTTO) {
 982                  $this->_sortby = SORTFROM;
 983              }
 984          }
 985      }
 986  
 987      /**
 988       * Move current pointer to the next index.
 989       */
 990      function moveNext()
 991      {
 992          $this->_setArrayIndex(1, 'offset');
 993      }
 994  
 995  }


Généré le : Thu Nov 29 12:30:07 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics