Bug #73186 [Com]: imap_status returns empty object

From: Date: Sat, 22 Dec 2018 12:33:42 +0000
Subject: Bug #73186 [Com]: imap_status returns empty object
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-218567@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73186&edit=1 ID: 73186 Comment by: jachirica at gmail dot com Reported by: jochem dot blok at fasterforward dot nl Summary: imap_status returns empty object Status: Open Type: Bug Package: IMAP related Operating System: Ubuntu 14.04 PHP Version: 5.6.26 Block user comment: N Private report: N New Comment: 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 = Previous Comments: ------------------------------------------------------------------------ [2017-05-30 23:24:26] brendan at carrmail dot ca 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"; } ------------------------------------------------------------------------ [2016-09-27 15:01:03] 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 ) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=73186&edit=1

« previous php.bugs (#218567) next »