Solved

PHP form processing,  MIME types, email attachments for  Entourage (for Mac)

Posted on 2011-02-26
3
649 Views
Last Modified: 2012-05-11
I have created the below code which processes the attached HTML web form, and then sends the data to a recipient. I have tested it using Yahoo Mail, Gmail, Outlook Express (PC) and on Android, and the attachements show up as attachments.  

My problem is that the attachments involved, do not display correctly in the email program, Entourage for Macintosh. Instead, they show up as text inside the message, like this below:

"This is a multi-part message in MIME format.

--==frontier
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

The following person has applied online:

Name: tr
Phone: r
Email: tr
Address: t
Educational Level: r
Additional Info:
How they heard of us:


--==frontier
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document;
name="testhey.docx"
Content-Disposition: attachment;
Content-Transfer-Encoding: base64

UEsDBBQABgAIAAAAIQDd/JU3ZgEAACAFAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAI ooAAC
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAC0
VMtuwjAQvFfqP0S+Vomhh6qqCBz6OLZIpR9g7A1Y9Uv28vr7bg JEVQtBKuUSKVnvzOzsxIPR2pps
CTFp70rWL3osAye90m5Wso/JS37PsoTCKWG8g5JtILHR8PpqMNkESBl1u1SyOWJ44DzJOViRC h/
..."

PHP process code is below, and the apply-now.html (web form) is attached.

Thanks in advance!
<?php


   $to="obsurf@seniorssharing.org";
   $subject="Online Application Received";
   $from = stripslashes($_POST['fullname'])."<".stripslashes($_POST['email']).">";

   // generate a random string to be used as the boundary marker
   //$mime_boundary="==Multipart_Boundary_x".md5(mt_rand())."x";
       $mime_boundary="==frontier";

   // now we'll build the message headers
   $headers = "From: $from\r\n" .
   "MIME-Version: 1.0\r\n" .
      "Content-Type: multipart/mixed;\r\n" .
      " boundary=\"{$mime_boundary}\"";


   $fullname= stripslashes( $_POST['fullname']);
   $phone= stripslashes( $_POST['phone']);
   $address= stripslashes( $_POST['address']);
   $email= stripslashes( $_POST['email']);
   $education= stripslashes( $_POST['education']);
   $additional= stripslashes( $_POST['additional']);
   $reference= stripslashes( $_POST['reference']);
 $message="The following person has applied online: \n\n ";
 $message.="Name: $fullname \n";
 $message.="Phone: $phone \n";
 $message.="Email: $email \n";
 $message.="Address: $address \n";
 $message.="Educational Level: $education \n";
 $message.="Additional Info: $additional \n";
 $message.="How they heard of us: $reference \n";




   $message = "This is a multi-part message in MIME format.\n\n" .
      "--{$mime_boundary}\n" .
      "Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
      "Content-Transfer-Encoding: 7bit\n\n" .
   $message . "\n\n";

  
   foreach($_FILES as $userfile){
      // store the file information to variables for easier access
      $tmp_name = $userfile['tmp_name'];
      $type = $userfile['type'];
      $name = $userfile['name'];
      $size = $userfile['size'];

      
      if (file_exists($tmp_name)){

         if(is_uploaded_file($tmp_name)){
 	
      
            $file = fopen($tmp_name,'rb');
 	
            // read the file content into a variable
            $data = fread($file,filesize($tmp_name));

          
            fclose($file);
 	
           
            $data = chunk_split(base64_encode($data));
         }
 	
        
         $message .= "--{$mime_boundary}\n" .
            "Content-Type: {$type};\n" .
            " name=\"{$name}\"\n" .
            "Content-Disposition: attachment;\n" .
          //  " filename=\"{$fileatt_name}\"\n" .
            "Content-Transfer-Encoding: base64\n\n" .
         $data . "\n\n";
      }
   }
 
   $message.="--{$mime_boundary}--\n";
   // now we just send the message
   if (@mail($to, $subject, $message, $headers))
         echo '<meta http-equiv="Refresh" content="0; URL=thanks.html">';    
    else
         echo "Failed to send. Please contact us at: 510.658.7003";

?>

Open in new window

apply-now.html
0
Comment
Question by:trman
  • 2
3 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34991888
The code snippet contains the apply-now form, stripped of all of the non-moving parts.  It has the potential to upload as many as three files.  The action script, process.php, reads the form input controls and the uploaded files, and emails them to obsurf@seniorssharing.org.

I am going to suggest a small change in the application design.  Rather than sending the file attachments via email, save the file attachments on the server and simply send a URL link to the saved file attachments.  Not only will this cut down on the bloat of email traffic (and solve the Entourage issue), but it will enable you to keep the client information even if obsurf@seniorssharing.org loses an email message.

HTH, ~Ray
<form enctype="multipart/form-data" method="post" action="process.php" >
<input type="text" name="fullname" />
<input type="text" name="phone" />
<input type="text" name="education" />
<input type="text" name="email" />
<input type="text" name="address" />
<textarea name="additional"></textarea>
<textarea name="reference"></textarea>
<input type="file" name="file1">
<input type="file" name="file2">
<input type="file" name="file3">
<input type=button value="Apply Now!"
</form>

Open in new window

0
 

Author Comment

by:trman
ID: 34991963
I like youir comment, Ray.  Sometimes you down a certain rode for so long you forget there are other paths...I will check with  my associates and see if this solution is acceptable.  Meanwhile, do you have specific code in mind?
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 34992046
Not really any specific code, but here is what I might do...

Since email addresses are unique, we can use that part of the input to make a key.  Validate the input email address to be sure it is well-formed and routable.  Use strtoupper() to make it all upper case, and use md5() to make a 32-byte key from the email address.  You would use this key as part of the file name when you store the files.  If you wanted to allow versioning of the uploaded files, you might include the datetime string in the file names.  So your three uploaded files would assume names that looked something like this:

79f90c1ff4ab9677852975219db09a26_20110227114800.ext

The value you would use for .ext would be the same as the client used - DOC(X) or PDF, etc.

You can use http://php.net/manual/en/function.move-uploaded-file.php to store the files in a permanent directory on your server.  This could be a directory in the web root structure so you can use direct links into it to access these files.  With the md5() strings and the date/time in the file name there is little chance someone could "guess" a file name.  So if you have a simple index.php in this directory to avoid a directory listing your data is fairly safe from accidental disclosure.

The code snippet shows how to validate an email address.  You can test it on my web site here:
http://www.laprbass.com/RAY_email_validation.php
<?php // RAY_email_validation.php
error_reporting(E_ALL);


// A FUNCTION TO TEST FOR A VALID EMAIL ADDRESS, RETURN TRUE OR FALSE
function check_valid_email($email)
{
    // IF PHP 5.2 OR ABOVE, WE CAN USE THE FILTER
    // MAN PAGE: http://us3.php.net/manual/en/intro.filter.php
    if (strnatcmp(phpversion(),'5.2') >= 0)
    {
        if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) return FALSE;
    }
    // IF LOWER-LEVEL PHP, WE CAN CONSTRUCT A REGULAR EXPRESSION
    else
    {
        $regex
        = '/'                       // START REGEX DELIMITER
        . '^'                       // START STRING
        . '[A-Z0-9_-]'              // AN EMAIL - SOME CHARACTER(S)
        . '[A-Z0-9._-]*'            // AN EMAIL - SOME CHARACTER(S) PERMITS DOT
        . '@'                       // A SINGLE AT-SIGN
        . '([A-Z0-9][A-Z0-9-]*\.)+' // A DOMAIN NAME PERMITS DOT, ENDS DOT
        . '[A-Z\.]'                 // A TOP-LEVEL DOMAIN PERMITS DOT
        . '{2,6}'                   // TLD LENGTH >= 2 AND =< 6
        . '$'                       // ENDOF STRING
        . '/'                       // ENDOF REGEX DELIMITER
        . 'i'                       // CASE INSENSITIVE
        ;
        if (!preg_match($regex, $email)) return FALSE;
    }

    // FILTER_VAR OR PREG_MATCH DOES NOT TEST IF THE DOMAIN IS ROUTABLE
    $domain = explode('@', $email);

    // MAN PAGE: http://us3.php.net/manual/en/function.checkdnsrr.php
    if ( checkdnsrr($domain[1],"MX") || checkdnsrr($domain[1],"A") ) return TRUE;

    // EMAIL IS NOT ROUTABLE
    return FALSE;
}


// DEMONSTRATE THE FUNCTION IN ACTION
$e = '';
if (!empty($_GET["e"]))
{
    $e = $_GET["e"];
    if (check_valid_email($e))
    {
        echo "<br/>VALID: $e \n";
    } else
    {
        echo "<br/>BOGUS: $e \n";
    }
}

// END OF PROCESSING - PUT UP THE FORM
$form = <<<ENDFORM
<form method="get">
TEST A STRING FOR A VALID EMAIL ADDRESS:
<input name="e" value="$e" />
<input type="submit" />
</form>
ENDFORM;

echo $form;

Open in new window

0

Featured Post

Do email signature updates give you a headache?

Do you feel like all of your time is spent managing email signatures? Too busy to visit every user’s desk to make updates? Want high-quality HTML signatures on all devices, including on mobiles and Macs? Then, let Exclaimer solve all your email signature problems today!

Join & Write a Comment

Marketers need statistics and metrics like everybody else needs oxygen. In this article we explain how to enable marketing campaign statistics for Microsoft Exchange mail.
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
In this video we show how to create a mailbox database in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: First we need to log into the Exchange Admin Center. Navigate to the Servers >> Data…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now