PHP mail with attachment not working as a Shortcode - php

So I've been asked to create a form that once filled in sends an email to my client with the form entry, this must include a .csv file attachment with the included data.
Initially I tested this by hardcoding it to a plain page.
<form class="main-form" method="post">
<ul>
<li><div>Email: </div><input type="email" name="email" size="20" /></li>
<br />
<input type="submit">
</ul>
</form>
<?php
$email=$_REQUEST['email'];
if ($email =="") {
//Do nothing
} else {
$to = "mail#test.co.uk";
$from = "test";
$subject = "test";
//Message Body
$text = "test";
//The Attachment
$cr = "\n";
$data = "Email"
$data .= "$email". $cr;
$fp = fopen('test.csv','a');
fwrite($fp,$data);
fclose($fp);
$attachments[] = Array(
'data' => $data,
'name' => 'diploma_apprenticeship_form_sub.csv',
'type' => 'application/vnd.ms-excel'
);
//Generate a boundary string
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
//Add the headers for a file attachment
$headers = "MIME-Version: 1.0\n" .
"From: BRS\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
//Add a multipart boundary above the plain message
$message = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type: text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$text . "\n\n";
//Add attachments
foreach($attachments as $attachment){
$data = chunk_split(base64_encode($attachment['data']));
$name = $attachment['name'];
$type = $attachment['type'];
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$type};\n" .
" name=\"{$name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" ;
}
$message .= "--{$mime_boundary}--\n";
mail($to, $subject, $message, $headers);
}
?>
This works fine and emails the attachment exactly as I want. However they now want it as a shortcode so they can post it wherever in their wordpress build. So I've added the shortcode and posted the code into a php function which is called when wordpress detects [form]. But now it doesn't work.
function main_form() {
return <<<HTML
<form class="main-form" method="post">
<ul>
<li><div>Email: </div><input type="email" name="email" size="20" /></li>
<br />
<input type="submit">
</ul>
</form>
HTML;
// Then rest of php as it was above
}
The form outputs fine, but I no longer get an email. Initially I thought that the $_REQUEST[]; wasn't getting the data but I set $email to a fixed string and it still doesn't work.
Anyone have any ideas?

Change your HTML to something like this:
<form class="main-form" method="post" action="file.php">
You'll be redirected to "file.php" after your form will be submitted.
You can find a working example here: http://www.w3schools.com/php/php_forms.asp

Turns out I was using a return statement before the rest of the PHP hence it was printing the HTML and exiting the function. By putting the return at the end of the function it now works!

Related

Uploading multiple files in single form

I have a form on my site which requires users to enter data in a few basic fields, and then upload multiple image files to submit with their form.
The 'form' side of the equation seems easy enough, by simply adding multiple="multiple" to the input field.
However... after many attempts at different variations of code, I am still not understanding (or able) to get the php 'formHandler' side of the equation to actually send multiple image files.
Toying with the code got really confusing, and I made an awful mess of it.
So....
For this example, I left the 'multiple' aspect in the form input, however... to clean up my mess... I stripped back the php 'formHandler' code to where I had it before, which works fine for sending just a single image file.
Any advice as to modify the php 'formHandler' to properly send multiple images would be a life-saver and much appreciated.
Thanks in advance!
The Form:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
</head>
<body>
<h1>The Form</h1>
<form action="/formHandler.php" method="post" enctype="multipart/form-data">
<input type="text" id="userName" name="userName" class="inputField" placeholder=" Enter Your
Name" required><br><br>
<input type="email" id="userEmail" name="userEmail" class="inputField" placeholder=" Enter
Your Email Address" required><br><br><br>
<!-- Start Image Upload Section -->
<a>Select Multiple Images:</a><br><br>
<input type="file" id="file" name="userImages[]" multiple="multiple" required/><br><br><br><br>
<!-- End Image Upload Section -->
<input type="submit" id="submitButton" name="submitButton" value="Submit Form">
</body>
</html>
The php 'formHandler':
<?php
////////////////////////////////////////////////////////////////////////////
$filenameee = $_FILES['userImages']['name'];
$fileName = $_FILES['userImages']['tmp_name'];
$name = $_POST['userName'];
$email = $_POST['userEmail'];
////////////////////////////////////////////////////////////////////////////
$composition =
"\r\n\n\nName: " . $name .
"\r\nEmail Address: " . $email;
////////////////////////////////////////////////////////////////////////////
//Whatever you want to subject of the email to be when you receive the form.
$subject ="Form Submission";
////////////////////////////////////////////////////////////////////////////
//User name and email will be displayed in header when form is received.
$fromname ="$name";
$fromemail = "$email";
////////////////////////////////////////////////////////////////////////////
//The email address at which you want to receive the form.
$mailto = 'receiving#email.com';
////////////////////////////////////////////////////////////////////////////
//The Content Action
$content = file_get_contents($fileName);
$content = chunk_split(base64_encode($content));
//A random hash will be necessary to send mixed content.
$separator = md5(time());
//Carriage return type (RFC)
$eol = "\r\n";
//Main header (multipart mandatory)
$headers = "From: ".$fromname." <".$fromemail.">" . $eol;
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol;
$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
$headers .= "This is a MIME encoded message." . $eol;
$body = "--" . $separator . $eol;
$body .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol;
$body .= "Content-Transfer-Encoding: 8bit" . $eol;
$body .= $composition . $eol;
$body .= "--" . $separator . $eol;
$body .= "Content-Type: application/octet-stream; name=\"" . $filenameee . "\"" . $eol;
$body .= "Content-Transfer-Encoding: base64" . $eol;
$body .= "Content-Disposition: attachment" . $eol;
$body .= $content . $eol;
$body .= "--" . $separator . "--";
////////////////////////////////////////////////////////////////////////////
//Mail send action
#mail($mailto, $subject, $body, $headers);
////////////////////////////////////////////////////////////////////////////
//Page Re-direct after form submission
header('location: /formSent_confirmationPage.php');
?>
Change input file name to userImages[] that allows to populate an array and iterate through $_files element ($filename is now an array).
https://www.php.net/manual/en/features.file-upload.multiple.php
$filenameee = $_FILES['userImages']['name'];
$sizes = $_FILES['userImages']['size'];
$fileName = $_FILES['userImages']['tmp_name'];
foreach ($fileName as $tmpname) {
echo "<br> Tmp name: " . $tmpname;
}
foreach ($filenameee as $name) {
echo "<br> Chosen user name : " . $name;
}
foreach ($sizes as $size) {
echo "<br> File size : " . $size/1024 . " Ko";
}

Email attachment using php, file can't open in email

This is my code, in this case, the code works perfectly and I got the attachment in the mail but the attached file can't be opened. Then I downloaded the file and tried to open it, it shows an error "either not a supported file type or file has been damaged(For example, it was send as an email attachment and wasn't correctly decoded)"
<form action="#" method="POST" enctype="multipart/form-data" >
<input type="file" name="csv_file[]" />
<br/>
<input type="file" name="csv_file[]" />
<br/>
<input type="file" name="csv_file[]" />
<br/>
<input type="submit" name="upload" value="Upload" />
<br/>
</form>
<?php
if($_POST) {
for($i=0; $i < count($_FILES['csv_file']['name']); $i++){
$ftype[] = $_FILES['csv_file']['type'][$i];
$fname[] = $_FILES['csv_file']['name'][$i];
}
// array with filenames to be sent as attachment
$files = $fname;
// email fields: to, from, subject, and so on
$to = "example#gmail.com";
$from = "example#gmail.com";
$subject ="My subject";
$message = "My message1";
$headers = "From: $from";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$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";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n $data \n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>mail sent to $to!</p>";
} else {
echo "<p>mail could not be sent!</p>";
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>E-mail with Attachment</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<?php
if ($_SERVER['REQUEST_METHOD']=="POST"){
// we'll begin by assigning the To address and message subject
$to="example#gmail.com";
$subject="E-mail with attachment";
// get the sender's name and email address
// we'll just plug them a variable to be used later
$from = stripslashes($_POST['fromname'])."<".stripslashes($_POST['fromemail']).">";
// generate a random string to be used as the boundary marker
$mime_boundary="==Multipart_Boundary_x".md5(mt_rand())."x";
// 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}\"";
$message="This is an example";
$message .= "Name:".$_POST["fromname"]."Message Posted:".$_POST["modlist"];
$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";
// now we'll process our uploaded files
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 the upload succeded, the file will exist
if (file_exists($tmp_name)){
// check to make sure that it is an uploaded file and not a system file
if(is_uploaded_file($tmp_name)){
// open the file for a binary read
$file = fopen($tmp_name,'rb');
// read the file content into a variable
$data = fread($file,filesize($tmp_name));
// close the file
fclose($file);
// now we encode it and split it into acceptable length lines
$data = chunk_split(base64_encode($data));
}
// now we'll insert a boundary to indicate we're starting the attachment
// we have to specify the content type, file name, and disposition as
// an attachment, then add the file content.
// NOTE: we don't set another boundary to indicate that the end of the
// file has been reached here. we only want one boundary between each file
// we'll add the final one after the loop finishes.
$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";
}
}
// here's our closing mime boundary that indicates the last of the message
$message.="--{$mime_boundary}--\n";
// now we just send the message
if (#mail($to, $subject, $message, $headers))
echo "Message Sent";
else
echo "Failed to send";
} else {
?>
<p>Send an e-mail with an attachment:</p>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data" name="form1">
<p>Your name: <input type="text" name="fromname"></p>
<p>Your e-mail: <input type="text" name="fromemail"></p>
<p>Mod List: <textarea name="question" maxlength="1000" cols="25" rows="6" name="modlist"></textarea>
<p>File: <input type="file" name="file1"></p>
<p>File: <input type="file" name="file2"></p>
<p>File: <input type="file" name="file3"></p>
<p>File: <input type="file" name="file4"></p>
<p>File: <input type="file" name="file5"></p>
<p>File: <input type="file" name="file6"></p>
<p>File: <input type="file" name="file7"></p>
<p><input type="submit" name="Submit" value="Submit"></p>
</form>
<?php } ?>
</body>
</html>

Submit form with attachment to email

My code here is:
<form action="#" method="POST" enctype="multipart/form-data" >
<input type="file" name="csv_file[]" />
<br/>
<input type="file" name="csv_file[]" />
<br/>
<input type="file" name="csv_file[]" />
<br/>
<input type="submit" name="upload" value="Upload" />
<br/>
</form>
<?php
if($_POST) {
for($i=0; $i < count($_FILES['csv_file']['name']); $i++){
$ftype[] = $_FILES['csv_file']['type'][$i];
$fname[] = $_FILES['csv_file']['name'][$i];
}
// array with filenames to be sent as attachment
$files = $fname;
// email fields: to, from, subject, and so on
$to = "example#gmail.com";
$from = "example#gmail.com";
$subject ="My subject";
$message = "My message";
$headers = "From: $from";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$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";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>mail sent to $to!</p>";
} else {
echo "<p>mail could not be sent!</p>";
}
}
?>
I got the code from here: https://stackoverflow.com/a/27565430/4357238
the form successfully sends the email and when i get the email, the name of the file(s) show up but the file is an empty file (0 bytes).
For example, i send a file called car.jpg and when it gets to my email, it shows up on my email as car.jpg but when i download the file and open the file, it says the file is broken and it cannot be opened because the file is empty.
what is wrong and how can i fix it?

php mail() function to send mail with an attachment

I have created two scripts for this HTML and a corresponding PHP.
HTML markup:
<html>
<body>
<form action="http://senindiaonline.in/admar/non-series-numbers-db.php" method="post" target="_blank" name="non_series_numbers_db" enctype="multipart/form-data">
<label for="emp-id">Employee ID: </label>
<input type="text" name="emp-id" id="emp-id" maxlength="15" style='text-transform:uppercase'/>
<br/>
<label for="no-csv">If you have a mobile number database in CSV file format upload that here: </label>
<input name="no-csv" id="no-csv" type="file" accept=".csv"/>
<br/>
<label for="no-xls">If you have a mobile number database in XLS (excel) file format upload that here: </label>
<input name="no-xls" id="no-xls" type="file" accept=".xls"/>
<br/>
<label for="no-xlsx">If you have a mobile number database in XLSX (excel) file format upload that here: </label>
<input name="no-xlsx" id="no-xlsx" type="file" accept=".xlsx"/>
<br/>
<input name="send" value="Send" type="submit" id="send"/>
</form>
</body>
</html>
PHP script:
<?php
error_reporting(0);
$email_to = 'senindiagroup#gmail.com';
$email_subject = "Non-Seriesed Mobile Number Database from Ad&Marketing Employee Panel of Sen India Online inc.";
$emp_id = $_POST['emp-id'];
$sub="Employee ID: $emp_id";
$bound_text = "jimmyPI23";
$bound = "--" .$bound_text. "\r\n";
$bound_last = "--" .$bound_text. "--\r\n";
$email_message .= "If you can see this MIME than your client doesn't accept MIME types! \r\n" .$bound;
$email_message .= "Content-Type: text/html; Charset=\"iso-8859-1\"\r\n" ."Content-Transfer-Encoding: 7bit\r\n\r\n" ."$sub\r\n" .$bound;
//getting temporary file location with name
$a=file_get_contents($_FILES['no-csv']['tmp_name']);
$b=file_get_contents($_FILES['no-xls']['tmp_name']);
$c=file_get_contents($_FILES['no-xlsx']['tmp_name']);
//getting original name of the file you uploaded
$name=$_FILES["no-csv"]["name"];
$name1=$_FILES["no-xls"]["name"];
$name2=$_FILES["no-xlsx"]["name"];
$email_message .= "Content-Type: {\"application/octet-stream\"}; \n" . "name=\"$name\ "\n" . "Content-Transfer-Encoding: base64\r\n" ."Content-Disposition: attachment; \n" . " filename=\"$name\ "\n"."\r\n" .chunk_split(base64_encode($a)).$bound;
mail($email_to, $email_subject, $email_message, $headers);
?>
The error is:
syntax error showing on line 31, attach file with mail command.
And the mail is not send. I solve this error with DreamWeaver suggestion. Then the mail is send, but the attachment is not included in the mail.
This is the example of sending multiple attachments in mail
<?php
for($i=0; $i < count($_FILES['csv_file']['name']); $i++){
$ftype[] = $_FILES['csv_file']['type'][$i];
$fname[] = $_FILES['csv_file']['name'][$i];
}
// array with filenames to be sent as attachment
$files = $fname;
// email fields: to, from, subject, and so on
$to = "example#gmail.com";
$from = "example#gmail.com";
$subject ="My subject";
$message = "My message";
$headers = "From: $from";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$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";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>mail sent to $to!</p>";
} else {
echo "<p>mail could not be sent!</p>";
}
?>
if you want simple solution use phpmailer library, that would be easy to use,easy to configure.

Email HTML form submissions with csv file attachment - receiving multiple emails

I've been asked to create a form that on submission sends the admin an email with a .csv attachment of the collated data.
I've scoured the internet and found this solution, and it works! However on submission I get about 3-4 emails (it seems to vary). Is this the code, or am I already receiving spam?
HTML Form:
<form method="post">
<p>Enter your email address
<input type="text" name="email" size="50" />
</p>
<p>Please add your first name
<input type="text" name="firstName" size="20" />
</p>
<p>Please add your last name
<input rows="2" name="lastName" size="20"></input>
</p>
<p> </p>
<p> </p>
<p>
<input type="submit" value="Submit" name="B1" />
<input type="reset" value="Reset" name="B2" />
</p>
</form>
PHP Code:
<?php
$email=$_REQUEST['email'];
$firstName=$_REQUEST['firstName'];
$lastName=$_REQUEST['lastName'];
$to = "test#testmail.co.uk";
$subject = "Test subject";
$message = "".
"Email: $email" . "\n" .
"First Name: $firstName" . "\n" .
"Last Name: $lastName";
//The Attachment
$cr = "\n";
$data = "Email" . ',' . "First Name" . ',' . "Last Name" . $cr;
$data .= "$email" . ',' . "$firstName" . ',' . "$lastName" . $cr;
$fp = fopen('diploma_apprenticeship_form_sub.csv','a');
fwrite($fp,$data);
fclose($fp);
$attachments[] = Array(
'data' => $data,
'name' => 'diploma_apprenticeship_form_sub.csv',
'type' => 'application/vnd.ms-excel'
);
//Generate a boundary string
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
//Add the headers for a file attachment
$headers = "MIME-Version: 1.0\n" .
"From: {$from}\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
//Add a multipart boundary above the plain message
$message = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type: text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$text . "\n\n";
//Add sttachments
foreach($attachments as $attachment){
$data = chunk_split(base64_encode($attachment['data']));
$name = $attachment['name'];
$type = $attachment['type'];
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$type};\n" .
" name=\"{$name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" ;
}
$message .= "--{$mime_boundary}--\n";
mail($to, $subject, $message, $headers);
?>
Thanks in advance,
Matt
In the end I just added an if statement that says if the email field equals nothing don't send any emails. This stops the email being triggered when the page is loaded, and an email when the page resets after submission - hence why I was getting 3 emails!

Categories