Can PHP convert form data into an email with attachments?

Frequently Asked Questions about WYSIWYG Web Builder
Locked
User avatar
Pablo
 
Posts: 21699
Joined: Sun Mar 28, 2004 12:00 pm
Location: Europe
Contact:

Can PHP convert form data into an email with attachments?

Post by Pablo »

This article describes how to make a form that produces an email with attachments. Using WebBuilder you can make any form you like, but your webhost/server must support PHP for the following method.

You have to create two pages in WebBuilder: the form page and the processing page. The latter holds the PHP script AND should report that the form was sent successfully.

I - The form page
1. Draw a Form Area and change the Form Properties to:
- Action: feedback_plus.php
- Method: POST
- Encoding type: multipart/form-data
2. Make up your form. Remarks:
- include an Editbox named email (lower case). Your visitor must enter a valid email address;
- include one or more File Upload objects and name all of them userfile[]
- the form page has no added php, so the File Extension should be html.

II - The processing page
1. Make up a nice page according the style of your site. Remarks:
- tell your visitors that the form is sent succesfully;
- include a link or menu to other pages of your site.
2. Rename the page to feedback_plus using the Site Manager;
3. Bring up the Page Properties dialogue and change it to:
- File Extension: php
4. Bring up the Page HTML dialogue. Select 'Start of Page' and insert this code:

Code: Select all

<?php
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  header('Refresh: 0; URL=/index.html');
  exit;
}
$mailto   = 'name@yourdomain.com';
$subject  = 'Feedback form';
$message  = 'Values submitted from web site form:';
$max_size = 1024*1024;
$eol      = "\n";

# No edits beyond this line
$pattern  = '/^([0-9a-z]([-.\w]*[0-9a-z])*@(([0-9a-z])+([-\w]*[0-9a-z])*\.)+[a-z]{2,6})$/i';
$boundary = md5(uniqid(time()));
foreach ($_POST as $key => $value) {
  if (!is_array($value)) {
    $message .= $eol.$key.' : '.$value;
  }
  else {
    foreach ($_POST[$key] as $itemvalue) {
      $message .= $eol.$key.' : '.$itemvalue;
    }
  }
}
$email = isset($_POST['email']) ? $_POST['email'] : $mailto;
$email = preg_match($pattern,$email) ? $email : $mailto;
$headers  = 'From: '.$email.$eol;
$headers .= 'Reply-To: '.$email.$eol;
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= 'Content-Type: multipart/mixed; boundary="'.$boundary.'"'.$eol;
$body  = 'This is a multi-part message in MIME format.'.$eol.$eol;
$body .= '--'.$boundary.$eol;
$body .= 'Content-Type: text/plain; charset=iso-8859-1'.$eol;
$body .= 'Content-Transfer-Encoding: 8bit'.$eol;
$body .= $eol.stripslashes($message).$eol;
foreach ($_FILES['userfile']['error'] as $i => $error) {
  if ($error == 0 && $_FILES['userfile']['size'][$i] <= $max_size) {
    $body .= '--'.$boundary.$eol;
    $body .= 'Content-Type: '.$_FILES['userfile']['type'][$i].'; name='.$_FILES['userfile']['name'][$i].$eol;
    $body .= 'Content-Transfer-Encoding: base64'.$eol;
    $body .= 'Content-Disposition: attachment; filename='.$_FILES['userfile']['name'][$i].$eol;
    $body .= $eol.chunk_split(base64_encode(file_get_contents($_FILES['userfile']['tmp_name'][$i]))).$eol;
    $attached[] = $_FILES['userfile']['name'][$i];
  }
}
$body .= '--'.$boundary.'--'.$eol;
mail($mailto,$subject,$body,$headers) or exit('Fatal Mail Error!');
?>
Notes
1. If the script was not activated by a form-POST it will be redirected to an URL of your choice. Replace /index.html with your own landing page.
2. The variable $mailto should hold the receiver's email address.
3. The variable $subject holds the email subject.
4. The variable $message holds the first line of the email message.
5. The variable $max_size holds the max. size of an attachment. 1024*1024 means 1 MB. The max. upload size is also limited by server settings.
6. The variable $eol holds the code for 'new line'. On most servers "\n" works well. You can also try "\r\n" or "\r".
7. The php-code can handle multiple selections. That is true for grouped Checkboxes, the Combobox and the Listbox. If you use PHP to process your form, the items must have names like 'list[]' or 'options[]' (names ending with []).
8. As the email address is validated the script is protected against abuse (no 'injected' headers like 'CC:', 'BCC:', etc.).
9. If the sender's email address is found invalid, it is replaced with the receiver's email address. This way the email sending should not fail.
10. Be aware that email can be marked as spam by spam filters. Check your spam box now and then.
11. If you want to show a list of successfully attached files, follow these steps:
a. Draw an HTML Object on the Processing Page;
b. Bring up its HTML Properties dialogue box and insert this code:

Code: Select all

<?php
if (isset($attached)) {
  foreach ($attached as $filename) {
    echo $filename.'<br>'."\n";
  }
}
?>
12. The script was tested with Outlook Express. I hope it will work with other email clients as well.

Related topics:
How do I create a form in Web Builder?
viewtopic.php?t=133

How do I use PHP to collect form data?
viewtopic.php?t=134

How to prevent form hijacked/spam injection?
viewtopic.php?t=2067

How can PHP upload files to my server?
viewtopic.php?t=635

Article submitted by Kees Versluis
Edited: 17-05-2007 (optimized text and code)
Updated: 20-06-2007 (added: Option to show a list of successfully attached files)
Locked