[ Index ] |
|
Code source de IMP H3 (4.1.5) |
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 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 12:30:07 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |