How to send multiple attachments to email - php

I have the following simple form that is ment to send multiple files to email:
<form method="post" enctype="multipart/form-data">
<input id="upload-file" class="upload-file" type="file" name="my_file[]" multiple>
<input type="submit" value="Send">
</form>
I am using the following php code to do the actual sending:
if (isset($_FILES['my_file'])) {
$to = 'my-email#maybe-gmail.com';
$subject = 'Files moar files';
$message = 'Message Body';
$headers = 'Some random email header';
$attachments = array();
$myFile = $_FILES['my_file'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i < $fileCount; $i++) {
$attachments[$i] = $_FILES['my_file']['tmp_name'][$i];
}
wp_mail($to, $subject, $message, $headers, $attachments);
}
I am using wp_mail() method, because this is in a Wordpress website(it is the same as the php mail() function).
My problem is, that I receive an email with the attachments, but the name of the file is messed up, and there is no extension, so it's hard to open it. What am I doing wrong here, and how can I fix it?

When you upload files in PHP, they are uploaded to a temporary directory and given a random name. This is what is stored in the 'tmp_name' key for each of the files. It also explains why each file does not have an extension when sent via email, as they are simply stored as files in the temporary directory. The original file name is stored in the 'name' key.
The easiest way to deal with this issue is to rename the files to their appropriate file names and then send them, because it doesn't seem that WordPress supports a second field to provide the file name for each file.
$uploaddir = '/var/www/uploads/'; //Or some other temporary location
$myFile = $_FILES['my_file'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i < $fileCount; $i++) {
$uploadfile = $uploaddir . basename($_FILES['my_file']['name'][$i]);
if (!move_uploaded_file($_FILES['my_file']['tmp_name'][$i], $uploadfile)) {
//If there is a potential file attack, stop processing files.
break;
}
$attachments[$i] = $uploadfile;
}
wp_mail($to, $subject, $message, $headers, $attachments);
//clean up your temp files after sending
foreach($attachments as $att) {
#unlink($att);
}
When dealing with files it's also a good practice to validate MIME types and restrict the types of files that you support.
WordPress wp_mail: https://developer.wordpress.org/reference/functions/wp_mail/
PHP POST Uploads: http://php.net/manual/en/features.file-upload.post-method.php

$attachments = array();
array_push($attachments, WP_CONTENT_DIR .
'/uploads/my-document.pdf' ); array_push($attachments,
WP_CONTENT_DIR . '/uploads/my-file.zip' );
It's work good for me for multiple files !
Good luck

Related

Check file exist on UploadiFive

I downloaded this upload example: https://github.com/xmissra/UploadiFive
When sending an apernas file, it works perfectly but when sending more than one file the function that checks if the file already exists presents a problem. Apparently the loop does not ignore that the file has just been sent and presents the message asking to replace the file. Is there any way to solve this?
This is the function that checks if the file already exists.
$targetFolder = 'uploads'; // Relative to the root and should match the upload folder in the uploader
script
if (file_exists($targetFolder . '/' . $_POST['filename'])) {
echo 1;
} else {
echo 0;
}
You can test the upload working at: http://inside.epizy.com/index.php
*Submit a file and then send more than one to test.
I tried it this way but it didn't work:
$targetFolder = 'uploads';
$files = array($_POST['filename']);
foreach($files as $file){
if (file_exists($targetFolder . '/' . $file)) {
echo 1;
} else {
echo 0;
}
When you have multiple files to be uploaded keep these things in mind;
HTML
Input name must be array name="file[]"
Include multiple keyword inside input tag.
eg; <input name="files[]" type="file" multiple="multiple" />
PHP
Use syntax $_FILES['inputName']['parameter'][index]
Look for empty files using array_filter()
$filesCount = count($_FILES['upload']['name']);
// Loop through each file
for ($i = 0; $i < $filesCount; $i++) {
// $files = array_filter($_FILES['upload']['name']); use if required
if (file_exists($targetFolder . '/' . $_FILES['upload']['name'][$i])) {
echo 1;
} else {
echo 0;
}
}

How can I get the URL of each uploaded file and send through email?

OVERVIEW:
I have a form that includes 5 file upload fields. A php script processes the data and sends out 2 emails (one to the admin and a confirmation receipt to the user) AND appends the data to a .csv file on the server.
QUESTION:
How do I get the URL of the uploaded files in to a variable that I can use to populate the email and .csv file.
Everything is working great except I need a link to each of the the uploaded files included in the emails and in the .csv file. I cannot seem to figure that part out after a couple days of trying.
SIMPLIFIED HTML FORM:
<HTML><head><title>MultiFile Upload and Send Email</title></head><body>
<form method='post' action='php/multiUploadTestProcess.php' multipart='' enctype='multipart/form-data'>
<label for ='exhName'>Exhibitor Name:</label>
<input type='text' name='exhName' multiple class='form-control'><br><br>
Select File 1: <input type='file' name='img[]' multiple class='form-control' size='10'><br><br>
Select File 2: <input type='file' name='img[]' multiple class='form-control' size='10'><br><br>
Select File 3: <input type='file' name='img[]' multiple class='form-control' size='10'><br><br>
Select File 4: <input type='file' name='img[]' multiple class='form-control' size='10'><br><br>
Select File 5: <input type='file' name='img[]' multiple class='form-control' size='10'><br><br>
<input type='submit' value='upload'>
</form>
THE PHP: NOTE: I've removed all the validation/sanitizing, removed .csv appending, and the second email submission. I'm assuming once we can get the links in to one email the rest will be pretty much the same.
<?php
$exhName = $_POST['exhName'];
$exhNameNoSpace = str_replace(" ","-", $exhName);
$img = $_FILES['img'];
$to = 'DESTINATION-EMAIL#DOMAIN.com';
$subject = 'New File Uploads';
$email = 'ReplyYToEMAIL#DOMAIN.com';
if(!empty($img))
{
/* reArrayFiles changes the array pattern for PHP's $_FILES (see function at end) */
$img_desc = reArrayFiles($img);
print_r($img_desc);
/* RENAME EACH FILE to current date, exhibitor name w/o spaces, and random integer string (ensuring no file overwrites). Then MOVE FILE to uploads */
foreach($img_desc as $val)
{
$newname = date('m-d-Y',time()).'-'.$exhNameNoSpace.'-'.mt_rand().'.jpg';
move_uploaded_file($val['tmp_name'],'../uploads/'.$newname);
/* THIS FOLLOWING LINE WAS MY ATTEMPT AT GETTING A LINK TO EACH UPLOADED FILE BUT IS NOT WORKING. AND THE VARIABLE $newname HERE IS ADDING A NEW RANDOM INT TO THE FILENAME - NOT THE ONE THE FILE WAS SAVED WITH. */
$filePath = '**Full Path To Directory**'.$newname;
}
/* SEND EMAIL TO ADMIN */
$emailText = "=============================================\nYou have a new Market Place Application\n".
"Here are the details:\n=============================================\n\n Exhibitor Name: $exhName \n\n Upload File 1: $filePath \n\n Upload File 2: $filePath \n\n ###";
// All the neccessary headers for the email.
$headers = array('Content-Type: text/plain; charset="UTF-8";',
'From: ' . $email,
'Reply-To: ' . $email,
'Return-Path: ' . $email,
);
$emailText = wordwrap($emailText, 70);
// Send email
mail($to, $subject, $emailText, implode("\n", $headers));
/* END SEND EMAIL TO ADMIN */
}
function reArrayFiles($file)
{
$file_ary = array();
$file_count = count($file['name']);
$file_key = array_keys($file);
for($i=0;$i<$file_count;$i++)
{
foreach($file_key as $val)
{
$file_ary[$i][$val] = $file[$val][$i];
}
}
return $file_ary;
}
?>
Help is greatly appreciated!
If you want to attach the file to your emails, you may need the fullpath on the server rather than external URL. Have a look at realpath PHP function and try to wrap the path you saved the file into this function call, so making it something like:
$newname = date('m-d-Y',time()).'-'.$exhNameNoSpace.'-'.mt_rand().'.jpg';
move_uploaded_file($val['tmp_name'],'../uploads/'.$newname);
/* THIS FOLLOWING LINE WAS MY ATTEMPT AT GETTING A LINK TO EACH UPLOADED FILE BUT IS NOT WORKING. AND THE VARIABLE $newname HERE IS ADDING A NEW RANDOM INT TO THE FILENAME - NOT THE ONE THE FILE WAS SAVED WITH. */
$filePath = realpath('../uploads/'.$newname);
after this $filepath should contain the full path to the uploaded file on the server.
If you wish to add a link with an external URL into your mails, you really need the full URL, but it depends on the domain name and the location of uploads folder relatively to the root (/) of your domain. It should be something like http://example.com/uploads/11-16-2018-name-6534.jpg and you can figure it out by testing the access to the generated filenames via your browser, assuming your uploads folder is accessible through the webserver. Once you figure out the URL you may either save the domain and path into your config file or you may check if $_SERVER['SERVER_NAME'] contains the domain name and append it with the path then.
In order to use the URLs in the email text you need to modify your code like:
$emailText = "=============================================\nYou have a new Market Place Application\nHere are the details:\n=============================================\n\n Exhibitor Name: $exhName \n\n ";
$i = 1;
foreach($img_desc as $val)
{
$newname = date('m-d-Y',time()).'-'.$exhNameNoSpace.'-'.mt_rand().'.jpg';
move_uploaded_file($val['tmp_name'],'../uploads/'.$newname);
/* THIS FOLLOWING LINE WAS MY ATTEMPT AT GETTING A LINK TO EACH UPLOADED FILE BUT IS NOT WORKING. AND THE VARIABLE $newname HERE IS ADDING A NEW RANDOM INT TO THE FILENAME - NOT THE ONE THE FILE WAS SAVED WITH. */
$filePath = '**Full Path To Directory**'.$newname;
$emailText .= "Upload File " . $i . ": " . $filePath . "\n\n";
$i++;
}
// All the neccessary headers for the email.
$headers = array('Content-Type: text/plain; charset="UTF-8";',
'From: ' . $email,
'Reply-To: ' . $email,
'Return-Path: ' . $email,
);
$emailText = wordwrap($emailText, 70);
// Send email
mail($to, $subject, $emailText, implode("\n", $headers));

Moving Attachments To Folder And Attaching Them With Email

I have a simple page, which is sending an Email message and multiple attachments, through phpmailer.
I have to attach the multiple attachments to the Email message to send, and also upload these files o server at same time, For which i m using the following loop:
$MyUploads = array();
foreach(array_keys($_FILES['attach']['name']) as $key)
{ $Location="uploads/";
$name=$_FILES['attach']['name'][$key];
$filePath = $Location . $name;
$source = $_FILES['attach']['tmp_name'][$key]; // location of PHP's temporary file for
$tmp=$_FILES['attach']['tmp_name'][$key];
if($mail->AddAttachment($source, $name))
{if(move_uploaded_file($tmp, $filePath)){
$MyUploads[] = $filePath;}
else
{$MyUploads[]='';
echo "not uploaded";}
}
}
The problem is, when i use the function move_uploaded_file(), the files are uploaded to the server folder, but are not sent with the attachments. As i comment out this function the attachments are sended.
Can;t find out, why these two dnt work together. Please any body help
Here is the loop that sends Attachments, And move them to a target path, for further use. I hope any one else can be helped by this:
$MyUploads = array();
$numFiles = count(array_filter($_FILES['attach']['name']));
for ($i = 0; $i < $numFiles; ++$i) {
$target_path = 'uploads/' . basename($_FILES['attach']['name'][$i]);
if(move_uploaded_file($_FILES['attach']['tmp_name'][$i], $target_path)) {
echo "the file ".basename($_FILES['attach']['name'][$i])." has been uploaded<br />";
$MyUploads[] = $target_path;
echo $MyUploads;
$mail->AddAttachment($target_path);
}
}

PHP storing file name from HTML for and saving to variable

I am uploading a file to a server through an HTML form and then emailing the HTML form content to myself. I can store all the form values into PHP variables like this...
$name = strip_tags($_POST["name"]);
$email = strip_tags($_POST["email"]);
$phone = strip_tags($_POST["phone"]);
but can not store the file name of the uploaded file in the same way. ex..
$uploadFile0 = strip_tags($_POST["uploadFile0"]);
I'm storing the file(s) to my server using a loop.
$i = 0;
while(isset($_FILES['uploadFile'. $i])){
echo 'item' . $i . 'present';
$file_name = $_FILES['uploadFile'. $i]['name'];
$file_name = stripslashes($file_name);
$file_name = str_replace("'","",$file_name);
$copy = copy($_FILES['uploadFile'. $i]['tmp_name'], $folderPath . $file_name);
if($copy){
echo "$file_name | uploaded sucessfully!<br>";
}else{
echo "$file_name | could not be uploaded!<br>";
}
$i++;
};
Basically I want to capture the name of the file to a variable and echo it out in an email. I have a feeling I'm staring at the answer but I just can't put it together. Thanks in advance for the help!
Will $_FILES['uploadFile'. $i]['name'] not give you the name of the file?
Or just to grab the first one $_FILES['uploadFile0']['name']

How do I combine 2 .php file into one single function

I want to thank everyone for helping me get my sendmail.php and fileupload.php file working properly as individual function. Now I am trying to combine them into a single file so the form that will use them will perform both functions on SUBMIT.
This is what I have currently:
<?php
$project = $_REQUEST['project'] ;
$project_other = $_REQUEST['project_other'] ;
$quantity = $_REQUEST['quantity'] ;
$pages = $_REQUEST['pages'] ;
$color = $_REQUEST['color'] ;
$color_other = $_REQUEST['color_other'] ;
$size = $_REQUEST['size'] ;
$page_layout = $_REQUEST['page_layout'] ;
$stock = $_REQUEST['stock'] ;
$stock_other = $_REQUEST['stock_other'] ;
$paper_finish = $_REQUEST['paper_finish'] ;
$paper_finish_other = $_REQUEST['paper_finish_other'] ;
$typeset = $_REQUEST['typeset'] ;
$timeframe = $_REQUEST['timeframe'] ;
$budget = $_REQUEST['budget'] ;
$add_info = $_REQUEST['add_info'] ;
$name = $_REQUEST['name'] ;
$phone = $_REQUEST['phone'] ;
$email = $_REQUEST['email'] ;
$company = $_REQUEST['company'] ;
$proj_name = $_REQUEST['proj_name'] ;
$zip = $_REQUEST['zip'] ;
$upload = $_REQUEST['upload'] ;
if (!isset($_REQUEST['email'])) {
header( "Location: ../pages/quote/quote.html" );
}
if ( ereg( "[\r\n]", $name ) || ereg( "[\r\n]", $email ) ) {
header( "Location: ../pages/quote/quote_injection_error.html" );
}
elseif (empty($name) || empty($phone) || empty($email) || empty($company) || empty($proj_name) || empty($zip) || empty($project) || empty($quantity) || empty($color) || empty($size) || empty($timeframe) || empty($budget)) {
header( "Location: ../pages/quote/quote_content_error.html" );
}
else {
mail( "QUOTES#DOMAIN.com", "Request for Quote: $project",
"$add_info\n
What kind of project is this? $project\n
Name: $name\n
Name of Project: $proj_name\n
Company: $company\n
Telephone: $phone\n
E-mail Address: $email\n
ZIP code: $zip\n
Is there a file attachment/upload? $upload\n
What do you need a quote on? $project : $project_other\n
What quantity do you require? $quantity\n
If applicable, how many pages is each document? $pages\n
Full color or black and white? $color : $color_other\n
What size do you want your print project to be? $size\n
What type of page layout do you need for your project? $page_layout\n
What paper stock do you require? $stock : $stock_other\n
What paper finish do you require? $paper_finish : $paper_finish_other\n
Are your documents typeset? $typeset\n
When do you need this project completed by? $timeframe\n
What is your budget for this project? $budget\n
Additional information to help COMPANY prepare our quote for you? $add_info",
"From: $name <$email>" );
header( "Location: ../pages/quote/quote_thanks.html" );
}
if (isset($_POST['submit'])) {
// Configuration - Script Options
$filename = $_FILES['userfile']['name']; // Get the name of the file (including file extension
$file_basename = substr($filename, 0, strripos($filename, '.')); // Get file name minus extension
$file_ext = substr($filename, strripos($filename, '.')); // Get file extension
$filesize = $_FILES['file']['size']; // Get file size
$allowed_file_types = array('.jpg','.jpeg','.gif','.bmp','.png','.pdf','.doc','.docx','.psd'); // These will be the types of files that are allowed to pass the upload validation
$file_counter = 1; // used to increment filename if name already exists
$company = $_REQUEST['company'];
$project = $_REQUEST['proj_name'];
// File renaming and upload functionality
if (in_array($file_ext,$allowed_file_types) && ($filesize < 10000001)) { // Checks to make sure uploaded file(s) is an allowed file type AND within the allowable file size (currently 10MB)
// Rename File
$newfilename = $company . '_' . $proj_name . '_' . $file_basename; // Rename file as (CompanyName_FileName_DateStamp)
// Loop until an available file name is found
while (file_exists( "file_uploads/" . $newfilename ))
$finalfilename = $newfilename . '_' . $file_counter++ . $file_ext; // This will be the File Name shown in the upload destination directory (currently the "file_uploads" directory)
if (file_exists("file_uploads/" . $finalfilename)) {
// file already exists error
echo "This file already exists. Please rename this file and upload again if necessary.";
} else {
move_uploaded_file($_FILES["file"]["tmp_name"], "file_uploads/" . $finalfilename);
echo "File uploaded successfully.";
}
} elseif (empty($file_basename)) {
// file selection error
echo "Please select a file to upload.";
} elseif ($filesize > 10000000) {
//file size error
echo "The file you are trying to upload is too large. Files must be no larger than 10MB.";
} else {
// file type error
echo "The file you attempted to upload is not allowed. You can only upload the following types of files: .jpg, .jpeg, .gif, .bmp, .png, .pdf, .doc, .docx, and .psd.";
unlink($_FILES["file"]["tmp_name"]);
}
}
/*
must add page links for error and success messages:
// redirect to upload success url
header( "Location: http://www.example.com/thankyou.html" );
die();
*/
?>
The "sendmail" portion works and I get the answers to my form inputs emailed to me clearly and concisely. However, since I added the "file_upload" file into bottom of the sendmail.php with no changes to either (just cut and pasted in above the final closing php tag ?>), the file_upload and renaming functions do not work.
Can anyone point me in the right direction as to how to get this to work in a single file? I am less than new to php but any thoughts/assistance would be appreciated.
Your form obviously posts a submit value right? If not it will skip the file upload function.
<input type="hidden" name="submit" value="TRUE" />
Because you put this at the top of the file_upload portion of the script.
if (isset($_POST['submit']))
The other thing could be you moved the file_upload.php file from one directory to another and now when you call
file_exists( "file_uploads/" . $newfilename)
The directory can not be found and skips the function.
Last, are you missing a {} for the while loop? You said you copied 100% from another file. So im assuming it worked like this when it was on it's own?
while (file_exists( "file_uploads/" . $newfilename ))

Categories