2012-11-08 8 views
5

Ich verwende diese PHP IMAP-Klasse: http://code.google.com/p/php-imap/source/browse/trunk/ImapMailbox.php für ein aktuelles Projekt. Nach einigen Änderungen arbeitet der Kurs. Wenn die Klasse DOCX-Dateien jedoch herunterlädt, sind sie immer beschädigt und müssen vom Büro wiederhergestellt werden.Beschädigte DOCX-Dateien bei Verwendung einer PHP-IMAP-Klasse

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; 
} 
+0

Überprüfen Sie das Format des Anhangs. Werden diese Dokumente immer von einem bestimmten E-Mail-Client (z. B. Microsoft Outlook?) Angehängt? – hakre

+0

Sie sind definitiv .docx von Office 2007 gespeichert und es ist das gleiche, wenn E-Mails von Gmail, Outlook 2007 und Hotmail gesendet werden – Chardard

+0

Gut zu wissen! Können Sie eine MD5-Prüfsumme vor dem Anhängen und danach erstellen? Ändert sich auch die Dateigröße? Außerdem würde ich mehrere Versionen der Datei mit verschiedenen Kodierungen nur für Testzwecke speichern. Ich würde etwas riechen, aber natürlich ist es schwer zu sagen, nur weil ich den Code schnell scanne. Du hast einige Entscheidungen über leere Zeichensets und so, wahrscheinlich gibt es da einige Zuckungen. – hakre

Antwort

1

Versuchen in die binären Dateien mit einem guten Editor waten, sowohl vor als auch nach dem Round-Trip von IMAP, um zu sehen, ob es etwas offensichtlich. Ich hatte ähnliche Probleme, bei denen Leerzeichen in das PHP-Skript eintraten (z. B. am Ende einer Datei nach dem close?> -Tag); Die meisten Formate blinken nicht, aber .docx kann in eine Wiederherstellung versetzt werden, wenn am Ende noch Leerzeichen übrig sind.