|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-09-27 15:01 UTC] jochem dot blok at fasterforward dot nl
Description:
------------
imap_status should return an object with properties. This is not the case with Office365 servers. Requesting the flags command line results in, what seems to be, valid flags.
Below the responses. Requesting this with imap_status results in an empty object.
a3 SELECT "INBOX"
* 1 EXISTS
* 1 RECENT
* FLAGS (\Seen \Answered \Flagged \Deleted \Draft $MDNSent)
* OK [PERMANENTFLAGS (\Seen \Answered \Flagged \Deleted \Draft $MDNSent)] Permanent flags
* OK [UNSEEN 1] Is the first unseen message
* OK [UIDVALIDITY 14] UIDVALIDITY value
* OK [UIDNEXT 155668] The next unique identifier value
a3 OK [READ-WRITE] SELECT completed.
a4 EXAMINE "INBOX"
* 1 EXISTS
* 0 RECENT
* FLAGS (\Seen \Answered \Flagged \Deleted \Draft $MDNSent)
* OK [PERMANENTFLAGS ()] Permanent flags
* OK [UNSEEN 1] Is the first unseen message
* OK [UIDVALIDITY 14] UIDVALIDITY value
* OK [UIDNEXT 155668] The next unique identifier value
a4 OK [READ-ONLY] EXAMINE completed.
The following responses (from a different server) results in the correct response (an object with properties):
a3 SELECT "INBOX"
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded \*)] Flags permitted.
* 382 EXISTS
* 0 RECENT
* OK [UNSEEN 3] First unseen.
* OK [UIDVALIDITY 1286370445] UIDs valid
* OK [UIDNEXT 49620] Predicted next UID
* OK [HIGHESTMODSEQ 3557] Highest
a3 OK [READ-WRITE] Select completed.
a4 EXAMINE "INBOX"
* OK [CLOSED] Previous mailbox closed.
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* 382 EXISTS
* 0 RECENT
* OK [UNSEEN 3] First unseen.
* OK [UIDVALIDITY 1286370445] UIDs valid
* OK [UIDNEXT 49620] Predicted next UID
* OK [HIGHESTMODSEQ 3557] Highest
a4 OK [READ-ONLY] Select completed.
Test script:
---------------
$connection = '{outlook.office365.com:993/imap/ssl}';
$mbox = imap_open($connection, "user", "password", OP_HALFOPEN)
or die("can't connect: " . imap_last_error());
$status = imap_status($mbox, $connection, SA_ALL);
print_r($status);
Expected result:
----------------
stdClass Object
(
[flags] => 31
[messages] => 388
[recent] => 0
[unseen] => 208
[uidnext] => 49631
[uidvalidity] => 1286370445
)
Actual result:
--------------
stdClass Object
(
[flags] => 0
)
Patcheslibc-client-fix (last revision 2019-02-05 12:39 UTC by rino-s2 at outlook dot it)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 07 03:00:01 2025 UTC |
I have a bit of a workaround. It unfortunately is quite a bit slower, but is tested OK on an office 365 server. Retrieve a list of the mailboxes first using imap_getmailboxes, then for each of those items in the array of mailboxes, use imap_reopen to switch your imap stream to the new mailbox. imap_num_msg will return the number of messages in your imap stream, which you can save to a variable, then switch back to the original mailbox using imap_reopen again. The below function is similar to imap_status, but will return only the number of messages rather than the full mailbox information. function my_imap_status($stream, $mailbox='', $info=SA_ALL) { // get current mailbox name (and info) $curr_obj=imap_check($stream); if(!$curr_obj) return false; // if request if for current mailbox then just return it if( (empty($mailbox)) || ($mailbox==$curr_obj->Mailbox) ) return $curr_obj; // get current mailbox $current_mailbox=$curr_obj->Mailbox; // switch to new mailbox if(!imap_reopen($stream, $mailbox)) return false; // get number of messages $numMessages = imap_num_msg($stream); // switch back to original mailbox imap_reopen($stream, $current_mailbox); // return info return $numMessages; } $list = imap_getmailboxes($mailbox, $serverString, "*"); if (is_array($list)) { foreach ($list as $key => $val) { $mapname = str_replace($serverString, "", $val->name); $sstring = rtrim($serverString, "*"); $foldername = str_replace($sstring, "", $val->name); //$mbox_info = imap_status($mailbox, $val->name, SA_ALL); //$numMessages = $mbox_info->messages; $numMessages = my_imap_status($mailbox, $val->name, SA_ALL); if ($mapname != ".") { $list_folders[$key]['serverstring'] = $sstring; $list_folders[$key]['folder'] = $val->name; $list_folders[$key]['name'] = $mapname; $list_folders[$key]['delimit'] = $val->delimiter; $list_folders[$key]['attributes'] = $val->attributes; $list_folders[$key]['number'] = $numMessages; } } } else { echo "imap_getmailboxes failed: " . imap_last_error() . "\n"; }Exchange adds extra space in the "STATUS" response, which IMAP library fails to parse. It can be fixed with a small patch in the libc-client library: --- src/c-client/imap4r1.c.ORIG 2018-12-22 13:24:15.899707119 +0100 +++ src/c-client/imap4r1.c 2018-12-22 13:24:18.551731625 +0100 @@ -4092,7 +4092,7 @@ unsigned char *txt = reply->text; if ((t = imap_parse_astring (stream,&txt,reply,&j)) && txt && (*txt++ == ' ') && (*txt++ == '(') && (s = strchr (txt,')')) && - (s - txt) && !s[1]) { + (s - txt) && !s[1] || s[1] == ' ') { *s = '\0'; /* tie off status data */ /* initialize data block */ status.flags = status.messages = status.recent = status.unseen =