PHP类ImapMailbox不下载附件

Running Apache 2.2 with PHP 5.3 on Windows 8. Trying to get the PHP class ImapMailbox to download attachments, but each time I getMail(), the attachments value is empty on every email that has attachments.

All the rest of the email info is downloaded correctly.

I've looked through the class code but can't identify where the problem might be.

Here is my current code:

$mailbox = new ImapMailbox('{testsite.com:110/pop3/novalidate-cert}INBOX', 'testemail@testsite.com', 'MyPaSs', ATTACH_DIR, 'utf-8');

$mails = array();

foreach($mailbox->searchMailbox('SUBJECT "test attach" SINCE "' . date('m/d/Y', strtotime('-1 week')) . '"') as $mailId) {
        $mail = $mailbox->getMail($mailId);
       $mails[] = $mail;
}

After dumping the $data var in getMail(), it appears there are attachments in winmail.dat format. The code cannot get to these because no attachmentId value is being assigned due to an empty 'ifid' value. Decoding the winmail.dat attachments can be done, but only if they are detected and written to file.

Any ideas how create a workaround in the ImapMailbox code for this?

Here is what I wrote that fixes this problem.

At the beginning of initMailPart() method, add the following:

static $altAttachmentId = 0;

At the end of the IF block for if($this->attachmentsDir) { add the following where the closing } bracket is:

} elseif (!empty($params['fileName']) || !empty($params['filename']) || !empty($params['name'])) { // Process attachments that are not inline.
                            // Check if need to decode TNEF (Winmail.dat) file.
                            if ($partStructure->ifsubtype && $partStructure->subtype == 'MS-TNEF') {
                                require_once 'path_to_your/tnef_decoder.php';

                                $Tnef = new tnef_decoder;

                                $un_tnef = $Tnef->decompress($data);


                                $attached_files = array();

                                foreach ($un_tnef as $f) {
                                    if (!empty($f['name']) && !empty($f['stream'])) {
                                        $attachment = new IncomingMailAttachment();

                                        $attachment->id = $altAttachmentId;
                                        $attachment->name = $f['name'];
                                        $attachment->filePath = $this->attachmentsDir . DIRECTORY_SEPARATOR . preg_replace('~[\\\\/]~', '', $f['name']);

                                        $mail->addAttachment($attachment);

                                        if (file_exists($attachment->filePath) && md5($f['stream']) != md5_file($attachment->filePath)) {
                                            $attachment->filePath = $this->attachmentsDir . DIRECTORY_SEPARATOR . preg_replace('~[\\\\/]~', '', $mail->id . '_' . $altAttachmentId . '_' . $f['name']);
                                        }

                                        file_put_contents($attachment->filePath, $f['stream']);

                                        $altAttachmentId++;
                                    }
                                }
                            } else {
                                if (!empty($params['filename'])) {
                                    $fileName = $params['filename']; // Account for random camel-case mistake on element.
                                } elseif (!empty($params['fileName'])) {
                                    $fileName = $params['fileName'];
                                } else {
                                    $fileName = $params['name'];
                                }

                                $attachment = new IncomingMailAttachment();
                                $attachment->id = $altAttachmentId;
                                $attachment->name = $fileName;
                                $attachment->filePath = $this->attachmentsDir . DIRECTORY_SEPARATOR . preg_replace('~[\\\\/]~', '', $mail->id . '_' . $altAttachmentId . '_' . $fileName);

                                $mail->addAttachment($attachment);

                                file_put_contents($attachment->filePath, $data);

                                $altAttachmentId++;
                            }
                        }

Note that you must include the tnef_decoder.php file found in the Roundcube Webmail package for the TNEF decoding to work. I got inspiration for the TNEF solution here.

This modification will process all TNEF encoded files in a Winmail.dat file and any other attachment that is not attached inline. Watch your memory usage on large files.

It also won't overwrite existing files that are the same name if they are not exactly the same.