4

I have a custom PHP form that was coded about 3 yeas ago. It was built to email all atttachments including docx files and worked like a charm. Just starting this year, client is noticing that users are complaining of errors sending form which allows them to upload their resume. Troubleshooting found that it only happens with SOME .docx files. We have a ton of .docx files that were uploaded and emailed fine. So it is either: 1. a change in the .docx encoding or something im not familiar with 2. Users must be corrupting their .docx files somehow.

I searched for any evidence of the way to code .docx files changed and found nothing. My code appears to be the best practice for uploading multiple files, even .docx files. To make sure I am posting my send-mail.php file and asking if anyone sees something that would allow all listed file formats, and some .docx to send FINE, but some .docx files are choking the script and failing at the "If (OK) {" line, meaning error sending mail. Thanks ahead of time for any help.

UPDATE: Seems like it is not working on docs saved in "Word 2016" format. So what would I have to do to my code below to make it work,also, with Word 2016 files?

 if(isset($_FILES) ) {

  // define allowed extensions
  $allowedExtensions = array("pdf","doc","docx","gif","jpeg","jpg","png","rtf","txt","");
  $files = array();

  // loop through all the files
  foreach($_FILES as $name=>$file) {

     // define some variables
     $file_name = $file['name']; 
     $temp_name = $file['tmp_name'];
     $file_type = $file['type'];

     // check if this file type is allowed
     $path_parts = pathinfo($file_name);
     $ext = $path_parts['extension'];
     if(!in_array($ext,$allowedExtensions)) {
        die("Your file type is not allowed. Must be only pdf, txt, doc, docx, gif , jpeg, jpg, png, or rtf. Use backspace to go back.");
     }

     // move this file to the server YOU HAVE TO DO THIS
     $server_file = "/home/content/25/9264325/html/wp-content/uploads/files/$path_parts[basename]";
     move_uploaded_file($temp_name,$server_file);

     // add this file to the array of files
     array_push($files,$server_file);
  }  

  // define some mail variables

  $to = "xxxx@gmail.com";
  $from = $email;
  $subject ="NEW EMPLOYMENT APPLICATION"; 
  $headers = "From: Cxxxxxxs \r\nReply-To: ".$from;

  // define our boundary
  $semi_rand = md5(time()); 
  $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

  // tell the header about the boundary
  $headers .= "\r\nMIME-Version: 1.0\r\n";
  $headers .= "Content-Type: multipart/mixed;\r\n";
  $headers .= " boundary=\"{$mime_boundary}\"\r\n\r\n"; 

  // part 1: define the plain HTML email
  $message ="\r\n\r\n--{$mime_boundary}\r\n";
  $message .="Content-Type: text/html; charset=\"iso-8859-1\"\r\n";
  $message .="Content-Transfer-Encoding: base64\r\n\r\n" . $msg . "\r\n\r\n";


  // part 2: loop and define mail attachments if thee is a file


          foreach($files as $file) {
             $aFile = fopen($file,"rb");
             $data = fread($aFile,filesize($file));
             fclose($aFile);
             $data = chunk_split(base64_encode($data));
             $message .= "\r\n--{$mime_boundary}\r\n";
             $message .= "Content-Type: {$file_type};\r\n";
             $message .= " name=\"{$file_name}\"\r\n";
             $message .= "Content-Transfer-Encoding: base64\r\n";
             $message .= "Content-Disposition: attachment;\r\n";
             $message .= "filename=\"{$file_name}\"\r\n";
             $message .= $data . "\r\n";
             $message .= "--{$mime_boundary}--\r\n";
          }

  // send the email
  $ok = mail($to, $subject, $message, $headers); 
  if ($ok) { 
     header('Location: http://www.xxxxx.com/thank-you/');
            } else { 
                echo "<p>mail could not be sent!</p>"; 
            }
            die();
}// if isset files
Norman Bird
  • 642
  • 3
  • 10
  • 29
  • 2
    Use [`PHPMailer`](https://github.com/PHPMailer/PHPMailer) or equivalent library to do this heavy lifting. If you insist on rolling your own, then what is the value of `$file_type` on a corrupted file? – bishop Dec 31 '16 at 01:47

2 Answers2

4

Hard to say without any test file/case, but my guess is wrong Content-Type, as you rely only on $file['type'].

The hard-coded lists in the browsers are pretty limited. Often, the MIME type sent by the browser will be the one reported by the OS. And this is exactly why, as stated in the question, the MIME type reported by the browser is unreliable How is mime type of an uploaded file determined by browser?

Try changing it to "universal"

application/octet-stream

Community
  • 1
  • 1
Adam Fischer
  • 1,075
  • 11
  • 23
1

Your code seems to be perfect but would recommend to do certain things to ensure that your script is running correctly.

Kindly change the reading file conents as it will not change any thing but change the memory usage only as from :

$aFile = fopen($file,"rb");
$data = fread($aFile,filesize($file));
fclose($aFile);
$data = chunk_split(base64_encode($data));

to

$attachments = chunk_split(base64_encode(file_get_contents('filename.ext')));

so it will decrease the memory usage and handling files

Second Change from:

$ok = mail($to, $subject, $message, $headers); 

to

$ok = @mail($to, $subject, $message, $headers); 

and

if ( $ok ) {
}else{
   echo $ok;    //It will give you the exact error reason here
}

Third thing you have to confirm the setting of your email sending attachment size. As it is important that some systems don't allow sending PHP email more than 100 KB or 500 KB.

If above thing doesn't resolve the issue then kindly let me know to suggest other things.

Vineet1982
  • 7,730
  • 4
  • 32
  • 67
  • I am considering doing your changes, but I do not understand why ALL Word docs would be fine UNTILL 2016 version of MS Word comes out and THEY only is hickupping? Seems like that 2016 format is what changed...no? So would it not be better to investigate and see how the code needs to be updated in order to allow the new format? Are there anyone with upload code that works on 2016 Word Doc? I think I will just try PHPMailer code since they seem to be working good with it. – Norman Bird Jan 04 '17 at 20:34
  • Just as another note it could be included image in the said CV as most email servers have a maximum attachment size around 5 MB so if the file is bigger than that the reciving server might reject it – Barkermn01 Jan 06 '17 at 17:22