function fetchMessageHeaders($imapConnection, &$aMailbox) { /** * Retrieve the UIDSET. * Setindex is used to be able to store multiple uid sets. That will make it * possible to display the mailbox multiple times in different sort order * or to store serach results separate from normal mailbox view. */ $iSetIndx = isset($aMailbox['SETINDEX']) ? $aMailbox['SETINDEX'] : 0; $iLimit = $aMailbox['SHOWALL'][$iSetIndx] ? $aMailbox['EXISTS'] : $aMailbox['LIMIT']; /** * Adjust the start_msg */ $start_msg = $aMailbox['PAGEOFFSET']; if ($aMailbox['PAGEOFFSET'] > $aMailbox['EXISTS']) { $start_msg -= $aMailbox['LIMIT']; if ($start_msg < 1) { $start_msg = 1; } } if (is_array($aMailbox['UIDSET'])) { $aUid =& $aMailbox['UIDSET'][$iSetIndx]; } else { $aUid = false; } // initialize the fields we want to retrieve: $aHeaderFields = array('Date', 'To', 'Cc', 'From', 'Subject', 'X-Priority', 'Content-Type'); $aFetchItems = array('FLAGS', 'RFC822.SIZE'); // Are we sorting on internaldate then retrieve the internaldate value as well if ($aMailbox['INTERNALDATE']) { $aFetchItems[] = 'INTERNALDATE'; } /** * A uidset with sorted uid's is available. We can use the cache */ if (($aMailbox['SORT'] != SQSORT_NONE || $aMailbox['SEARCH'][$iSetIndx] != 'ALL') && isset($aUid) && $aUid) { // limit the cache to SQM_MAX_PAGES_IN_CACHE if (!$aMailbox['SHOWALL'][$iSetIndx]) { $iMaxMsgs = $iLimit * SQM_MAX_PAGES_IN_CACHE; $iCacheSize = count($aMailbox['MSG_HEADERS']); if ($iCacheSize > $iMaxMsgs) { $iReduce = $iCacheSize - $iMaxMsgs; foreach ($aMailbox['MSG_HEADERS'] as $iUid => $value) { if ($iReduce) { unset($aMailbox['MSG_HEADERS'][$iUid]); } else { break; } --$iReduce; } } } $id_slice = array_slice($aUid, $start_msg - 1, $iLimit); /* do some funky cache checks */ $aUidCached = array_keys($aMailbox['MSG_HEADERS']); $aUidNotCached = array_values(array_diff($id_slice, $aUidCached)); /** * $aUidNotCached contains an array with UID's which need to be fetched to * complete the needed message headers. */ if (count($aUidNotCached)) { $aMsgs = sqimap_get_small_header_list($imapConnection, $aUidNotCached, $aHeaderFields, $aFetchItems); // append the msgs to the existend headers $aMailbox['MSG_HEADERS'] += $aMsgs; } } else { /** * Initialize the sorted UID list and fetch the visible message headers */ if ($aMailbox['SORT'] != SQSORT_NONE || $aMailbox['SEARCH'][$iSetIndx] != 'ALL') { // || $aMailbox['SORT_METHOD'] & SQSORT_THREAD 'THREAD') { $error = false; if ($aMailbox['SEARCH'][$iSetIndx] && $aMailbox['SORT'] == 0) { $aUid = sqimap_run_search($imapConnection, $aMailbox['SEARCH'][$iSetIndx], $aMailbox['CHARSET'][$iSetIndx]); } else { $error = get_sorted_msgs_list($imapConnection, $aMailbox, $error); $aUid = $aMailbox['UIDSET'][$iSetIndx]; } if ($error === false) { $id_slice = array_slice($aUid, $aMailbox['OFFSET'], $iLimit); if (count($id_slice)) { $aMailbox['MSG_HEADERS'] = sqimap_get_small_header_list($imapConnection, $id_slice, $aHeaderFields, $aFetchItems); } else { return false; } } else { // FIX ME, format message and fallback to squirrel sort if ($error) { echo $error; } } } else { // limit the cache to SQM_MAX_PAGES_IN_CACHE if (!$aMailbox['SHOWALL'][$iSetIndx] && isset($aMailbox['MSG_HEADERS']) && is_array($aMailbox['MSG_HEADERS'])) { $iMaxMsgs = $iLimit * SQM_MAX_PAGES_IN_CACHE; $iCacheSize = count($aMailbox['MSG_HEADERS']); if ($iCacheSize > $iMaxMsgs) { $iReduce = $iCacheSize - $iMaxMsgs; foreach ($aMailbox['MSG_HEADERS'] as $iUid => $value) { if ($iReduce) { $iId = $aMailbox['MSG_HEADERS'][$iUid]['ID']; unset($aMailbox['MSG_HEADERS'][$iUid]); unset($aMailbox['ID'][$iId]); } else { break; } --$iReduce; } } } /** * retrieve messages by sequence id's and fetch the UID to retrieve * the UID. for sorted lists this is not needed because a UID FETCH * automaticly add the UID value in fetch results **/ $aFetchItems[] = 'UID'; //create id range $iRangeStart = $aMailbox['EXISTS'] - $aMailbox['OFFSET']; $iRangeEnd = $iRangeStart > $iLimit ? $iRangeStart - $iLimit + 1 : 1; $id_slice = range($iRangeStart, $iRangeEnd); /** * Non sorted mailbox with cached message headers */ if (isset($aMailbox['ID']) && is_array($aMailbox['ID'])) { // the fetched id => uid relation $aId = $aMailbox['ID']; $aIdCached = array(); foreach ($aId as $iId => $iUid) { if (isset($aMailbox['MSG_HEADERS'][$iUid])) { if ($iId <= $iRangeStart && $iId >= $iRangeEnd) { $aIdCached[] = $iId; } } } $aIdNotCached = array_diff($id_slice, $aIdCached); } else { $aIdNotCached = $id_slice; } if (count($aIdNotCached)) { $aMsgs = sqimap_get_small_header_list($imapConnection, $aIdNotCached, $aHeaderFields, $aFetchItems); // append the msgs to the existend headers if (isset($aMailbox['MSG_HEADERS']) && is_array($aMailbox['MSG_HEADERS'])) { $aMailbox['MSG_HEADERS'] += $aMsgs; } else { $aMailbox['MSG_HEADERS'] = $aMsgs; } // update the ID array foreach ($aMsgs as $iUid => $aMsg) { if (isset($aMsg['ID'])) { $aMailbox['ID'][$aMsg['ID']] = $iUid; } } } /** * In unsorted state we show newest messages first which means * that the UIDSET which represents the order of the messages * should contain a high to low ordered UID list */ $aSortedUidList = array(); foreach ($id_slice as $iId) { if (isset($aMailbox['ID'][$iId])) { $aSortedUidList[] = $aMailbox['ID'][$iId]; } } $aMailbox['UIDSET'][$iSetIndx] = $aSortedUidList; $aMailbox['OFFSET'] = 0; } } return true; }
/** * Execute the sorting for a mailbox * * @param resource $imapConnection Imap connection * @param array $aMailbox (reference) Mailbox retrieved with sqm_api_mailbox_select * @return int $error (reference) Error number * @private * @since 1.5.1 * @author Marc Groot Koerkamp */ function _get_sorted_msgs_list($imapConnection, &$aMailbox) { $iSetIndx = isset($aMailbox['SETINDEX']) ? $aMailbox['SETINDEX'] : 0; $bDirection = !($aMailbox['SORT'] % 2); $error = 0; if (!$aMailbox['SEARCH'][$iSetIndx]) { $aMailbox['SEARCH'][$iSetIndx] = 'ALL'; } if ($aMailbox['SORT'] & SQSORT_THREAD && sqimap_capability($imapConnection, 'THREAD')) { $aRes = get_thread_sort($imapConnection, $aMailbox['SEARCH'][$iSetIndx]); if ($aRes === false) { $aMailbox['SORT'] -= SQSORT_THREAD; $error = 1; // fix me, define an error code; } else { $aMailbox['UIDSET'][$iSetIndx] = $aRes[0]; $aMailbox['THREAD_INDENT'][$iSetIndx] = $aRes[1]; } } else { if ($aMailbox['SORT'] === SQSORT_NONE) { $id = sqimap_run_search($imapConnection, 'ALL', ''); if ($id === false) { $error = 1; // fix me, define an error code } else { $aMailbox['UIDSET'][$iSetIndx] = array_reverse($id); $aMailbox['TOTAL'][$iSetIndx] = $aMailbox['EXISTS']; } } else { if (sqimap_capability($imapConnection, 'SORT')) { $sSortField = _getSortField($aMailbox['SORT'], true); $id = sqimap_get_sort_order($imapConnection, $sSortField, $bDirection, $aMailbox['SEARCH'][$iSetIndx]); if ($id === false) { $error = 1; // fix me, define an error code } else { $aMailbox['UIDSET'][$iSetIndx] = $id; } } else { $id = NULL; if ($aMailbox['SEARCH'][$iSetIndx] != 'ALL') { $id = sqimap_run_search($imapConnection, $aMailbox['SEARCH'][$iSetIndx], $aMailbox['CHARSET'][$iSetIndx]); } $sSortField = _getSortField($aMailbox['SORT'], false); $aMailbox['UIDSET'][$iSetIndx] = get_squirrel_sort($imapConnection, $sSortField, $bDirection, $id); } } } return $error; }