开发者

imap_search limit the number of messages returned

I have PHP script that fetch messages from a mailbox. I use the imap_search function: $emails = imap_search($mbox, 'UNSEEN');

Is there a way to limit the number of returned messages. Right now on huge mailboxes i get like 5000 messages. I want only the top 20 ordered by date.

开发者_如何学GoIs there a way to do that?

Thanks.


The imap_search function has a CRITERIA attribute you can use to limit the messages in a number of ways:

ALL - return all messages matching the rest of the criteria
ANSWERED - match messages with the \ANSWERED flag set
BCC "string" - match messages with "string" in the Bcc: field
BEFORE "date" - match messages with Date: before "date"
BODY "string" - match messages with "string" in the body of the message
CC "string" - match messages with "string" in the Cc: field
DELETED - match deleted messages
FLAGGED - match messages with the \FLAGGED (sometimes referred to as Important or Urgent) flag set
FROM "string" - match messages with "string" in the From: field
KEYWORD "string" - match messages with "string" as a keyword
NEW - match new messages
OLD - match old messages
ON "date" - match messages with Date: matching "date"
RECENT - match messages with the \RECENT flag set
SEEN - match messages that have been read (the \SEEN flag is set)
SINCE "date" - match messages with Date: after "date"
SUBJECT "string" - match messages with "string" in the Subject:
TEXT "string" - match messages with text "string"
TO "string" - match messages with "string" in the To : UNANSWERED - match messages that have not been answered
UNDELETED - match messages that are not deleted
UNFLAGGED - match messages that are not flagged
UNKEYWORD "string" - match messages that do not have the keyword "string"
UNSEEN - match messages which have not been read yet


imap_sort will allow you to both sort and filter at the same time

But still, it won't allow to limit to the 'top 20' right at the function call.


imap_search docs indicate this function:

Returns an array of message numbers or UIDs.

imap_fetch_overview docs indicate this function also returns:

message_id - Message-ID, uid - UID the message has in the mailbox

So we can use the imap_fetch_overview and sort a certain number and order with the same return as the imap_search function.

// get information about the current mailbox
$mboxCheck = imap_check($mbox);

// get the total amount of messages
$totalMessages = $mboxCheck->Nmsgs;

// select how many messages you want to see
$showMessages = 20;

// get those messages    
$result = imap_fetch_overview($mbox($totalMessages-$showMessages+1).":".$totalMessages);

$n = 0;
$emails = array();
// loop through returned messages, collect message numbers in same format as output of imap_search
foreach ($result as $mail) {
    $emails[$n] = $mail->msgno;
    $n++;
}  

if($emails) {
// put the newest emails on top 
rsort($emails);
}

This is built with the concept from this answer


To solve this problem by so:

1.You could limit the no of result returned by reducing the no of data using the since criteria 2. Retreive few last returned messages e.g 15

$this->msgCounts = imap_search($imap_resource, 'SUBJECT "hello dolly" SINCE "8 April 2003"', SE_UID);

And then here is an example to retreive the last 15 returned and then toggle forward and backward to view more results or older.Note this assumes you have a button forward and older that set $_GET variables.

$this->msgCounts = $messageCounts;
        $multiarray=[];
        \Session::put('totalmsg',$this->msgCounts);             //Sav etotal no of message in folder to session to determine if to allow next or previous

        if($this->msgCounts > 15)                               //MESSAGES IS MORE THAN WE NEED GET 20
        {
            $offcut = 15;                                       //default offcut

            /**
            * Viewing previous or next messages
            **/
                if(isset($_GET['msgs']) && $_GET['msgs'] == 'older')
                {
                 $this->msgCounts =  \Cache::has('msgpointer') ? \Cache::get('msgpointer') : $this->msgCounts;
                    $msgOffset = $this->msgCounts - $offcut;    //get +15 messages

                    if($offcut > $msgOffset) {
                        $msgOffset = $msgOffset + 5;            //if less than 15 get 10
                        $offcut = 10;
                    }
                    if($offcut > $msgOffset) {
                        $msgOffset = $msgOffset + 5;            //if less than 10 get 5
                        $offcut = 5;
                    }
                    if($offcut > $msgOffset) {
                        $msgOffset = $msgOffset + 3;            //if less than 3 get 2
                        $offcut = 2;
                    }
                    if($offcut > $msgOffset) {
                        $msgOffset = $msgOffset + 2;            //if less than 2 get 1
                        $offcut = 1;
                    }


                    \Cache::put('msgpointer',$msgOffset,60 * 60 * 24);
                }

                if(isset($_GET['msgs']) && $_GET['msgs'] == 'newest')
                {
                    $this->msgCounts =  \Cache::has('msgpointer') ? \Cache::get('msgpointer') : $this->msgCounts;
                    $msgOffset = $this->msgCounts + $offcut;    //get +15 messages

                    if($msgOffset > $messageCounts) {
                        $msgOffset = $msgOffset - 5;            //if not up to 15 get 10
                        $offcut = 10;
                    }
                    if($msgOffset > $messageCounts) {
                        $msgOffset = $msgOffset - 5;            //if not up to 10 get 5
                        $offcut = 5;
                    }
                    if($msgOffset > $messageCounts) {
                        $msgOffset = $msgOffset - 3;            //if not up to 5 get 2
                        $offcut = 2;
                    }
                    if($msgOffset > $messageCounts) {
                        $msgOffset = $msgOffset - 2;            //if not up to 2 get 1
                        $offcut = 1;
                    }


                    \Cache::put('msgpointer',$msgOffset,60 * 60 * 24);
                }


            // LOOP THROUGH LAST 20 MESSAGES IF THERE MORE THAN 10 MESSAGES
            for ($i = $this->msgCounts; $i > $this->msgCounts - $offcut; $i--) 
            { 

                 $header = imap_header($this->conn,$i);                             //GET HEADER INFO USING IMAP FUNCTION
                 $uid    = imap_uid($this->conn,$i);                                //GET UNIQUE MESSAGE ID FOR READING MESSAGE LATER


                 //SAVE ALL MESSAGE INFO IN ARRAY
                 $tobox    = $header->reply_to[0]->mailbox ? $header->reply_to[0]->mailbox : 'noreply';
                 $tohost   = $header->reply_to[0]->mailbox ? $header->reply_to[0]->host : 'email.com';
                 $toaddress = $tobox.'@'.$tohost;


                 $mailbox = isset($header->from[0]->mailbox) ? $header->from[0]->mailbox : 'no-reply';
                 $host    = isset($header->from[0]->host) ? $header->from[0]->host : 'email.com';
                 $fromaddress = $mailbox.'@'.$host;

                 $array = ['toaddress' => isset($header->toaddress) ? $header->toaddress : isset($header->to) ? $header->to[0]->mailbox.'@'.$header->to[0]->host : $toaddress,'date' => isset($header->date) ? $header->date : date('Y-m-d'),'subject' => isset($header->subject) ? $header->subject : "no subject" ,'from' => isset($header->from[0]->personal) ? $header->from[0]->personal :$fromaddress,'unseen' => isset($header->Unseen) ? $header->Unseen : 'S', 'uid' => isset($uid) ? $uid : $i,'fromemail' => $fromaddress];
                //PASS A MESSAGE INFO INTO A MULTI ARRAY
                $multiarray[] = $array;

            }

You could set the date it get from to be 90 days before then if its a lot.return it chunk by chunk like above.My apologies for using some laravel helper classes there,all is well commented out. Hope this helps someone!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜