In the following code, I'm searching for IMAP items with a particular email address. If the item has an attachment, they are expected to have one, the attachment is saved and the filename is added to an array.
I'm having problems when this code is saving Excel attachments. Seems the files are getting corrupted, The file size differs from the file I save when vieing the attachment.
I have no problems with text based files, such as CSV, tab-delimited, or even ZIP and DBF files. It is XLS and XLSX files that are exhibiting this problem.
Any ideas as to what may be the problem?
// $node is XML node with email and user_id
while(list( , $node) = each($result)) {
$email = $node->LI_email;
$user_id = $node->LI_user_id;
$search = "UNSEEN FROM \"$email\"";
$result2 = imap_search($mailbox, $search);
if($result2) {
$index = $result2[0];
$structure = imap_fetchstructure($mailbox, $index);
$ov = imap_fetch_overview($mailbox, $index);
foreach ($ov as $overview) {
// this variable is used later to rename the files with the filedate as well.
$md = date_parse($overview->date);
$md = $md['month'].'_'.$md['day'].'_'.$md['year'];
}
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => '');
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($mailbox, $index, $i+1, FT_PEEK);
// All my Excel files have encoding set to 3.
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
} // for($i = 0; $i < count($structure->parts); $i++)
} // if(isset($structure->parts) && count($structure->parts))
And here is where I'm handling the $attachments array:
for($i = 0; $i < count($attachments); $i++) {
if (strlen(trim($attachments[$i]['filename'])) > 0) {
$filename = 'file_uploads/'.$user_id.'_'.$path_parts['filename'].'_'.$md.'.'.$path_parts['extension'];
$fp = fopen($filename, "w");
$attachments[$i]['attachment'] = preg_replace('`[\r\n]+`',"\n",$attachments[$i]['attachment']);
fwrite($fp, $attachments[$i]['attachment']);
fclose($fp);
// remove the directory from the filename to be inserted into database table for import
$extracted['file_uploads/'.$user_id.'_'.$path_parts['filename'].'_'.$md.'.'.$path_parts['extension']] = $user_id;
} // if (strlen(trim($attachments['name'])) > 0
} // for($i = 0; $i < count($attachments); $i++)