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;
}
Exemplo n.º 2
0
/**
 * 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;
}