Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Corrupt .docx files when using a PHP IMAP class

Tags:

php

imap

I'm Using this PHP IMAP Class: http://code.google.com/p/php-imap/source/browse/trunk/ImapMailbox.php on a current project. After a few modifications the class is working. However whenever the class downloads .docx files they are always corrupt and have to be recovered by office.

    protected function initMailPart(IncomingMail $mail, $partStruct, $partNum) {
    $data = $partNum ? $this->imap_fetchbody($this->mbox, $mail->mId, $partNum, FT_UID) : $this->imap_body($this->mbox, $mail->mId, FT_UID);

    if($partStruct->encoding == 1) {
        $data = $this->imap_utf8($data);
    }
    elseif($partStruct->encoding == 2) {
        $data = $this->imap_binary($data);
    }
    elseif($partStruct->encoding == 3) {
        $data = $this->imap_base64($data);
    }
    elseif($partStruct->encoding == 4) {
        $data = $this->imap_qprint($data);
    }
    $data = trim($data);

    $params = array();
    if(!empty($partStruct->parameters)) {
        foreach($partStruct->parameters as $param) {
            $params[strtolower($param->attribute)] = $param->value;
        }
    }
    if(!empty($partStruct->dparameters)) {
        foreach($partStruct->dparameters as $param) {
            $params[strtolower($param->attribute)] = $param->value;
        }
    }
    if(!empty($params['charset'])) {
        $data = iconv($params['charset'], $this->serverEncoding, $data);
    }

    // attachments
    if($this->attachmentsDir) {
        $filename = false;
        $attachmentId = $partStruct->ifid ? trim($partStruct->id, " <>") : null;
        if(empty($params['filename']) && empty($params['name']) && $attachmentId) {
            $filename = $attachmentId . '.' . strtolower($partStruct->subtype);
        }
        elseif(!empty($params['filename']) || !empty($params['name'])) {
            $filename = !empty($params['filename']) ? $params['filename'] : $params['name'];
            $filename = $this->decodeMimeStr($filename);
            $filename = $this->quoteAttachmentFilename($filename);
        }
        if($filename) {
            if($this->attachmentsDir) {
                $filepath = rtrim($this->attachmentsDir, '/\\') . DIRECTORY_SEPARATOR . $filename;
                file_put_contents($filepath, $data);
                $mail->attachments[$filename] = $filepath;
            }
            else {
                $mail->attachments[$filename] = $filename;
            }
            if($attachmentId) {
                $mail->attachmentsIds[$filename] = $attachmentId;
            }
        }
    }
    if($partStruct->type == 0 && $data) {
        if(strtolower($partStruct->subtype) == 'plain') {
            $mail->textPlain .= $data;
        }
        else {
            $mail->textHtml .= $data;
        }
    }
    elseif($partStruct->type == 2 && $data) {
        $mail->textPlain .= trim($data);
    }
    if(!empty($partStruct->parts)) {
        foreach($partStruct->parts as $subpartNum => $subpartStruct) {
            $this->initMailPart($mail, $subpartStruct, $partNum . '.' . ($subpartNum + 1));
        }
    }
}

protected function decodeMimeStr($string, $charset = 'UTF-8') {
    $newString = '';
    $elements = $this->imap_mime_header_decode($string);
    for($i = 0; $i < count($elements); $i++) {
        if($elements[$i]->charset == 'default') {
            $elements[$i]->charset = 'iso-8859-1';
        }
        $newString .= iconv($elements[$i]->charset, $charset, $elements[$i]->text);
    }
    return $newString;
}
like image 895
Chardard Avatar asked Nov 13 '22 18:11

Chardard


1 Answers

Try wading into the binary files with a good editor, both before and after the round-trip from IMAP, to see if there's something obvious. I've had similar problems where whitespace made its way into the PHP script (e.g. at the end of a file after the close ?> tag); most formats won't blink but .docx may get kicked into a recovery if there's whitespace left over at the end.

like image 64
asmecher Avatar answered Nov 15 '22 07:11

asmecher