Save email attachment from piped email - php

I am using pipe to program to send emails to a script. Using this script, I can sucessfully save the entire email as a .txt file on my server. The only thing left to do, is figure out how to save any attachment that the email comes in with. (This email address is only given to one trusted source, so security is not an issue)
Working code that saves entire email as .txt file:
$fd = fopen("php://stdin", "r");
$email = ""; // This will be the variable holding the data.
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
/* Saves the data into a file */
$fdw = fopen("/home/lmshost22/public_html/pipemail.txt", "w+");
fwrite($fdw, $email);
fclose($fdw);
Can anyone help me with code that simply extracts the attachment (will ALWAYS be a .csv file) and saves it on my server?
Here is the code that the .txt file shows for the attachment:
------=_NextPart_000_0133_01CE0E98.061E7400
Content-Type: application/vnd.ms-excel;
name="leads.csv"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="leads.csv"
ApplicationDetailId,DateCreated,VehicleInfoId,FirstName,MiddleName,LastNa=
me,Suffix,Street,City,State,ZipCode,Email,HomePhoneArea,HomePhonePrefix,H=
omePhoneSuffix,CellArea,CellPrefix,CellSuffix,WorkPhoneArea,WorkPhonePreF=
ix,WorkPhoneSuffix,AmountBorrow,IsVehiclePaidOff,IsVehicleSalvaged,OweAmo=
unt,TitleOwnership,IsInBankruptcy,IsInCreditCounseling,HearOfUs,VehicleIn=
foId,Year,Make,Model,Trim,Miles,Engine,DriveTrain,Transmission,Options,Bo=
ok,ClassCode,Door,FuelType,BodyStyle
4523,2/18/2013 2:56:33 PM,4524,James,,Pruitt,,7900 =
Carmelita,Atascadero,CA,93422,,702,=3D"353",=3D"9760",=3D"",=3D"",=3D"",=3D=
"",=3D"",=3D"",=3D"2500.0000",True,False,0.0000,No =
one,False,False,Google,4524,2001,=3D"Toyota",Tacoma =
Xtracab,PreRunner,200000,V6 3.4 =
Liter,2WD,Automatic,199443~199448~199471~199480~199508~4234190~,0.0000,1,=
0,Gas,Pickup
------=_NextPart_000_0133_01CE0E98.061E7400--

Attachments imply that the message is MIME/Multipart and has a boundary header set which will delimit the various message parts. eg:
Content-Type: multipart/mixed;
boundary="b1_bb1b331cd6dafa1dc6a19e3b2e090b07"
So you want to find that first via something like:
preg_match('/boundary="(.*)"/', $message, $matches);
The message is divided by -- concatenated with the boundary, followed by headers specific to that part, a blank line, and then the data. eg:
--b1_bb1b331cd6dafa1dc6a19e3b2e090b07
Content-Type: application/pdf; name="Invoice-37272.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Invoice-37272.pdf"
// base64 data here //
And the message is terminated with '--' . $boundary . '--', eg: --b1_bb1b331cd6dafa1dc6a19e3b2e090b07--
So you can use those two bits of info to break up your messages into their constituent parts and find/save the attachment.

here is my entire PHP file to extract a csv file(email with .csv attachment is piped to this script). The key is you have to decode the text that makes up the file, it is between the boundaries mentioned above.
<?
$home_path = '/home/USERNAME/public_html/DIRECTORY/';
$filename = "FILENAME.TXT"; // TO SAVE THE CONTENTS OF CSV FILE AS TEXT
$sock = fopen ("php://stdin", 'r');
$email = '';
while (!feof($sock)) {
$email .= fread($sock, 10240);
}
fclose($sock);
$encoding1 = explode ("------=_", $email);
$encoding2 = explode ("------=_", $encoding1[2]);
$encoding3 = $encoding2[0];
$encoding4 = explode (".csv", $encoding3);
$encoding5 = explode ("\n\n", $encoding4[2]);
$encoding = base64_decode($encoding5[1]);
$encoding = $encoding . "---" . strlen($encoding);
$fdw = fopen($home_path . $filename . ".txt", "w+");
fwrite($fdw, $encoding);
fclose($fdw);
?>

Related

How do I seperate CSV headers and columns in PHP

I am trying to create a csv with PHP, that separate the the headers and columns.
Currently I am able to create the csv and dump the data, but each row in dumped into one cell.
The result is:
I expected this:
Here is my code
<?php
// Load the database configuration file
require_once('db/connect_db.php');
//$time = date('Y-m-d:').preg_replace("/^.*\./i","", microtime(true));
$time = date('Y-m-d');
$dteTimetamp = date('Y-m-d');
// Fetch records from database
$find = $conn->prepare("SELECT School, SchoolAddress, School_Email, Principle_Name, Reception_Number, QuantityFingerPrintScanner, InvoiceNumber from School");
$find->execute();
$udonr = "$dteTimetamp" . "Request";
//$filename = "$udonr.csv";
// Create a file pointer
$f = fopen(dirname(__FILE__).'/testfolder/'.$udonr.'.csv', 'w');
// Set column headers
$header = array('School Name', 'Contact Person', 'Contact Number', 'School Address', 'Number of scanners to deliver', 'Invoice Nuber');
fputcsv($f, $header);
// Output each row of the data, format line as csv and write to file pointer
while($row = $find->fetch(PDO::FETCH_ASSOC)){
$lineData = array($row['School'], $row['Principle_Name'], $row['Reception_Number'], $row['SchoolAddress'], $row['QuantityFingerPrintScanner'], $row['InvoiceNumber']);
fputcsv($f, $lineData);
// Set headers to download file rather than displayed
//header('Content-Type: text/csv');
// header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
}
//exit;
#FROSIT is right. Excel is kinda dumb about opening CSV files, especially ones with comma separator (ironically).
Your file looks good but if you need to have it automatically open in Excel (e.i. someone else will need to open it), you might want to find which one is the default separator for Excel and set that in your script.

Printing or Echo form data to csv file

I have listened to a youtube tutorial severally in order to write a php code for online form data and print to CSV file on my website. The code the teacher used on the tutorial works perfectly on my local computer but doesn’t print anything on the CSV file as I have now uploaded the page on my website.
when site users fill the form online and click on submit button on my site – no information from form is printed on the same CSV file. Why?
This is the code I got from the tutorial and wrote the same:
<?php
if(isset($_POST['submit'])){
$names = $_POST['names'];
$telephone = $_POST['telephone'];
$email = $_POST['email'];
$job = $_POST['job'];
$city = $_POST['city'];
$data = $names . "," . $telephone . "," . $email . "," . $job . "," . $city;
$file = "cardealer.csv";
file_put_contents ($file, $data . PHP_EOL, FILE_APPEND);
echo "Thank you for completing this form, we will reply soon";
}
?>
How can I fix this problem sir, I used the exact offline code you gave in the tutorial.
I appreciate your kind gestures here to help starters like us.
Thank you,
this to export excel file based on CSV data and download the file
if you want to write a file you should consider using chmod
like this
chmod($folder_path. $file_name. ".".$ext, '775');
also in this part
fopen("php://output",w);
you can change it to
fopen($path_to_file,w);
you can change the MIME-TYPE and the file extension to what ever you want.
/**
*the $array the data to be converted to CSV
*
*/
function array_to_csv_download($array, $filename = "export.xls", $delimiter=";") {
header('Content-Type: application/xls');
header('Content-Disposition: attachment; filename="'.$filename.'";');
header("Pragma: no-cache");
header("Expires: 0");
// open the "output" stream
$f = fopen('php://output', 'w');
foreach ($array as $line) {
fputcsv($f, $line, $delimiter);
}
}

convert $_POST values to CSV

Updated Situation:
I have managed to create a registration form that outputs the data to a new CSV file for use into a separate database. However the code that sends the attachment doesn't work, but the system stores the file into a separate folder (I must stress this is while I am testing).
My question is, can I both create the CSV file and send it via email? If so, what do I need to do?
I am also aware that there are security risks: One suggestion has been to store the CSV files outside to root directory. is this foolproof and if not, could anyone make any recommendations?
My code is:
<?php
$_POST['password'] = md5($_POST['password']);
$headers=array_keys($_POST);
$file = "csv/" . $_POST['username'].date('Ymdhis').".csv"; //filename
$file = fopen($file, 'a');
fputcsv($file, $headers);
fputcsv($file, $_POST);
fclose($file);
require_once('email/PHPMailerAutoload.php');
$m = new PHPMailer;
$m->isSMTP();
$m->SMTPAuth = true;
$m->SMTPDebug = 0;
$m->Host = 'mymail.com';
$m->Username = 'me#mymail.com';
$m->Password = 'mypass';
$m->SMTPSecure = 'SSL';
$m->Port = 26;
$m->From = 'me#mymail.com';
$m->FromName = 'My name';
$m->addReplyTo('me#mymail.com', 'Reply Address');
$m->AddAddress('me#mymail.com', 'My name');
$m->isHTML(true);
$m->addAttachment('csv/data.csv', 'data.csv');
$m->Subject = 'New feed ';
$m->Body = '<p>This is an email just sent from our website</p><p><strong>Please import into your database.</strong></p>';
$m->AltBody = 'This is the body. Please import into the database';
if($m->send()) {
echo '<h1>Thank you</h1> <p>We have received your Registration and will send you confirmation details shortly.</p>';
} else {
echo $m->ErrorInfo;
}
I also have a checkbox field that needs to be written with the commas separating the values, for example 1,2,3. How can I write this?
Any assistance/advice will as always be gratefully received.
Many thanks in advance.
$_POST['id']="101"; //example data
$_POST['username']="kraysak"; //example data
$_POST['password']="grumpycat"; //example data
$_POST['usergroup']="admin"; //example data
$_POST['lastaccess']="14-10-2014 00:01"; //example data,
$_POST['password'] = md5($_POST['password']);
$headers=array_keys($_POST);
$file = $_POST['username'].date('Ymdhis').".csv"; //filename
$file = fopen($file, 'a');
fputcsv($file, $headers ); //write headers (key of the $_POST array (id,username,password,etc)
fputcsv($file, $_POST );
fclose($file);
this create a file named kraysak20141014010253.csv with the next information:
id,username,password,usergroup,lastaccess
101,kraysak,5557981401e83c1963412f19c7487965,amdin,"14-10-2014 00:01"
is hard for me to explain, (my english isn't good enought) but fputcsv funtion write the content of an array in the file, and $_POST is an array... so, you dont need to create new variables, you only need to use md5() function in one variable.
fputcsv consists of two parameters; location and content. So;
fputcsv(location, content);
or
$fileNameVariable = 'blah';
$fileName = $fileNameVariable . date('Ymdhis') . '.csv';
$fp = fopen('/exampleDirectoryName/' . $fileName, 'w');
$headers = array ('info1', 'info2', 'info3');
fputcsv($fp, $headers);
You can adapt this exmaple for your situation pretty easily.
Try:
$csvname=md5(rand());
$fp = fopen("csv/$csvname.csv", "w");
$savearray = [ $name, $email, $password, $usergroup, $lastsid, $fname, $lname, $lastaccess, $company, $phone, $addone, $addtwo, $city, $stateprov, $country, $postalcode, $rescom, $addbook, $subscriptions, $affilid, $affilcommpct, $affilsalestodate, $affilcommearned, $affilcommowed, $affilcommpaid, $whlsalepct, $show_currency, $loyaltypoints ];
fputcsv($fp, $savearray);
fclose($fp);
Use array() on $savearray instead of [] for older php versions.

Read email attachment

I have emails piped to a PHP script, which looks like this:
#!/usr/local/bin/php -q
<?php
// read from stdin
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd))
{
$email .= fread($fd, 1024);
}
fclose($fd);
mail('test#test.com','From TEST','"' . $email . '"');
?>
This essentially sends me the entirety of the email.
I can't seem to find anything that doesn't rely on existing frameworks to read attachments.
Can anyone point me in the right direction for getting just the attachment data? The attachment will always be a CSV file.

CSV file_get_contents sending PHP

I'm trying to send a .CSV file with PHP. The file is written to disk before it's sent but when I try to attach the file with file_get_contents(); the structure of the .CSV isn't preseved yet when try and send the file that's created before it's sent I get a resource id (#183) so how can i attach a file which the user can open as a .CSV file? I've made sure the mime type and headers are correct
EDIT
if(!file_exists(_PS_ORDERS_DIR_.$orderDate.'/'.$file_name.'.csv'))
{
if($file = fopen (_PS_ORDERS_DIR_.$orderDate.'/'.$file_name.'.csv', 'x+'))
{
foreach ($list as $fields)
{
fputcsv($file, $fields);
}
$attachment['mime'] = 'application/vnd.ms-excel';
$attachment['content'] = file_get_contents(_PS_ORDERS_DIR_.$orderDate.'/'.$file_name.'.csv');
$attachment['name'] = $order.'order';
Mail::Send(1, 'order_conf', 'Order CSV Attachment', $success, 'dan.farr#gmail.com', CakeToppers, NULL, NULL, $attachment);
return true;
}
If you are using Swift Mailer, there is no need for file_get_contents(), you can just attach the file directly.
From the Swift Mailer documentation:
//Create the attachment
// * Note that you can technically leave the content-type parameter out
$attachment = Swift_Attachment::fromPath('/path/to/image.jpg', 'image/jpeg');
//Attach it to the message
$message->attach($attachment);
So for you that would be:
$attachment = Swift_Attachment::fromPath(_PS_ORDERS_DIR_.$orderDate.'/'.$file_name.'.csv', 'application/vnd.ms-excel');
//Attach it to the message
$message->attach($attachment);

Categories