PHP imap_search UNSEEN SINCE date with time
Asked Answered
G

3

11

I am using PHP imap_search to fetch list of unseen messages since a given date like this:

imap_search($stream, 'UNSEEN SINCE 20-Sep-2015');

This is working fine. However, I am periodically every few minutes checking for new emails and then storing the last check time in a session. I want to be able to run the imap_search with the UNSEEN SINCE date including time. But it just does not seem to work. I've tried:

imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03 +0000 (UTC)');
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03 +0000');
imap_search($stream, 'UNSEEN SINCE 20-Sep-2015 12:35:03');

Nothing seems to work. Any ideas if this can be done?

Groningen answered 21/9, 2015 at 14:56 Comment(0)
C
25

Looking at the definition of SINCE in RFC 3501:

  SINCE <date>
     Messages whose internal date (disregarding time and timezone)
     is within or later than the specified date.

And a date is defined as just a date, without a time:

date            = date-text / DQUOTE date-text DQUOTE

date-day        = 1*2DIGIT
                    ; Day of month

date-month      = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
                  "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"

date-text       = date-day "-" date-month "-" date-year

date-year       = 4DIGIT

So you can't use SINCE to search for messages based on a time more specific than a day.


Another way to do this is to remember the UID of the latest message you've seen, and then search for messages above that:

imap_search($stream, 'UID ' . $latest_uid . ':*', SE_UID);

The SE_UID option is required to make imap_search return UIDs instead of message sequence numbers.

To get the UID of the latest message in the first place, search for *, which represents the highest-numbered message in the mailbox:

imap_search($stream, 'UID *', SE_UID);
Castano answered 21/9, 2015 at 15:30 Comment(6)
Just a quick question @legoscia. What happens if the $latest_uid message is deleted? Will this method still work?Interoceptor
It will still work. The IMAP server will skip over the missing UIDs and return the existing ones, up to and including the newest message in the mailbox. Note that * always represents the highest-numbered message, so if $latest_uid is deleted and no messages are added, this will return the newest still existing message.Castano
Just another quick question: how can I retrieve this $latest_uid from the last e-mail received?Station
@GabrielAugusto I updated the answer to include that.Castano
Thanks. But the imap_search using the UID is returning false all the time. Any sugestions? Even if I replace the $lastest_uid with some ID like 1, it doesn't work. Just returns false.Station
That's strange, not sure why that would fail (unless the mailbox is empty). Check if imap_errors returns something.Castano
S
4

You cannot achieve that with "SINCE"

Another way to do this is to remember the UID of the latest message you've seen, and then search for messages above that: (thanks to @legoscia)

According to http://php.net/manual/en/function.imap-search.php

$emails = imap_search($inbox, "UID 1:*", SE_UID); 

is not valid, it is not working. Use

$emails = imap_fetch_overview($inbox, "$latest_uid:*", FT_UID); 

Here * refers to the latest mail UID. This will return an array of objects from which you can extract the UIDs of emails. You can use a loop to make an array of the UIDs separately. As answered at PHP imap_search UID SEARCH returns false

Spessartite answered 19/11, 2018 at 8:7 Comment(0)
V
2

I don't think it's possible using php and the IMAP protocol. It seems that IMAP has a WITHIN Search Extension defined in rfc 5032, but it looks like php doesn't have this criteria yet. Also the SINCE criteria (and basically all the datetime criteria in the IMAP protocol) just ignores the time and timezone when you do a search operation. A workaround could be to get the emails with your current query, and then get the internal date and implementing the filter function with php datetime functions. Hope this helps. More info about IMAP: rfc 3501

Vacancy answered 21/9, 2015 at 15:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.