Zend_Mail: moveMessage() exception
According to the documentation, you should use the getNumberByUniqueId() method to retrieve the message ID when moving/deleting emails. However, I still seem to get an exception appearing part way through processing a folder: "the single id was not found in response".
The code that is used goes along the lines of:
try {
$emailAddresses = array ();
$invalidAddresses = array ();
$errors = array();
$emailValidator = new Zend_Val开发者_C百科idate_EmailAddress ();
$trimFilter = new Zend_Filter_StringTrim ();
$mail = new Zend_Mail_Storage_Imap (...);
$mail->selectFolder ( '/Unsubscribe' );
echo 'There are ' . $mail->countMessages () . " messages to process\n";
foreach ( $mail as $messageId => $message ) {
try {
$mail->noop ();
$recipientMatch = $trimFilter->filter ( str_ireplace ( 'REMOVE ', '', $message->subject ) );
if (! substr_count ( $recipientMatch, '@' )) {
// Try the sender if the subject line doesn't have an address in
$matches = array ();
$from = $message->getHeader ( 'from' );
preg_match ( '/<(.+@.+)>/', $from, $matches );
if (sizeof ( $matches ) == 2) {
$recipientMatch = $matches [1];
} else {
$recipientMatch = $from;
}
}
if (! $emailValidator->isValid ( $recipientMatch )) {
$invalidAddresses [] = $recipientMatch;
continue;
}
$emailAddresses [] = $recipientMatch;
$messageUniqueId = $mail->getUniqueId ( $messageId );
$mail->moveMessage ( $mail->getNumberByUniqueId ( $messageUniqueId ), '/Unsubscribe/done' );
} catch ( Exception $e ) {
$errors[] = array($recipientMatch , $e);
}
}
} catch ( Zend_Mail_Storage_Exception $e ) {
echo "There was a problem processing the mail account\n", $e->getMessage ();
} catch ( Exception $e ) {
echo "There was an unmatched exception\n", $e->getMessage ();
}
Any ideas why the exception is being thrown (Zend Framework v1.10.8)?
The stack trace for the exception is:#0 /usr/share/php/libzend-framework-php/Zend/Mail/Storage/Imap.php(163): Zend_Mail_Protocol_Imap->fetch(Array, 4)
#1 /usr/share/php/libzend-framework-php/Zend/Mail/Storage/Abstract.php(307): Zend_Mail_Storage_Imap->getMessage(4)
#2 /tmp/unsubscribe.php(29): Zend_Mail_Storage_Abstract->current()
#3 /tmp/dummy.php(1): include('/tmp/unsubscribe.php')
#4 {main}
The content of the Array used in Zend_Mail_Protocol_Imap->fetch()
is:
Array(
0 => 'FLAGS',
1 => 'RFC822.HEADER'
)
You sholud not use this kind of loop. With this loop $messageId is outdated as soon as you delete a single message. With the next cycle the $messageId would 'point' to the wrong message or even no message (like Index-Out-Of-Bounce). That's why you've got the error message.
Solution: collect all relevant unique ids first into an array, then loop through this array and call moveMessage - with the up-to-date id that you get from getNumberByUniqueId!
I hope I'm not wrong, but I think moveMessage($id, $folder) should be moveMessage($index, $folder). This is more accurate. But correct me if this is wrong.
as it mentioned before... in case if you've got an error: "the single id was not found in response" means that the message sequence changed in expunge process, so when you save all IDs of all messages and try to iterate you have this error, because some messages was deleted in previous, please check: http://framework.zend.com/issues/browse/ZF-5655
You can use "while" for get ACTUAL collection of ids on every iteration, like this:
while($next_id = $gmail->getUniqueId()) {
// move message to label folder "My_archive_folder"
$gmail->moveMessage($next_id, 'My_archive_folder');
}
精彩评论