I have a script that currently takes some data from a wordpress DB and then loops over the returned rows and uses fputcsv(). The file handle was setup with:
$fh = fopen('php://output', 'w');
The script is linked to a link of a webpage and when you click the link it downloads the CSV (using the content-disposition header).
Is it possible to write to php://output this CSV file and then use PHP's mail() function to send it in an attachment?
I have a mail function I've written that will set the MIME type to multipart/mixed, I'm just not sure how to create the actual attachment to be emailed.
Use tmpfile() instead. Write your CSV data to that temp file, then attach it to your email.
Plus, don't write your own mime handling/generating functions. Use a library like PHPMailer or Swiftmailer to do it for you. Far easier and far more reliable. Part of their attachment handling code allows you specify the filename the user sees, so even though it might be "/tmp/abc123def", it'll show up as "data.csv" (or whatever you specify) in the actual email.
Related
I recently had a asked a question very similar to this one, however after evaluating that I did not explain it in the best way I have come back once again explaining it in a greater manner.
So, I am creating a system that will gather data from a MySQL database and use a unique id to download a file, however depending on the value of a column within that database called type, this file could be anything from a png file to an xml file. What I am currently doing is trying to download these files WITHOUT any extension.
As an example to maybe make this easier to understand, a file named image.png would be converted to just image and then downloaded.
With this you could rename the file to image.png again on the local machine and view the image.
This may seem very inefficient to most reading this but for my current situation it's all that will work.
How could I remove a files extension and then download it? (in php)
Thank you in advance.
Just use headers to specify response type.
$filepath = '/wherever/the/file/is.png';
$filename = 'new-cool-name';
header('Content-Type: whatever/content-type-is');
header("Content-disposition: attachment;filename=$filename");
readfile($filepath);
This basically sends a response with specified content-type as an attachment and the body of the attachment contains the file contents. If you never sure what's the content type is, then just use application/octet-stream
Usually when you set out to push a file for downloading from a serverside script, you do so by utilizing http headers like https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
The filename of the downloadable file is specified in that header
Okay so to remove an extention from a file you could do is
$withoutExtion = preg_replace('/\\.[^.\\s]{3,4}$/', '', $youfilename);
...followed by your file download code
I have successfully implemented a form where I receive a JSON base64 encoded string from an external URL using curl. After which I decode the string and save the file as a pdf using php and then email the pdf to the user's email using swiftmailer.
The main section of the code after retrieving the JSON value stream
$jsonvalue = $json['value'];
$dcode = (base64_decode($jsonvalue));
file_put_contents($file, $dcode);
//Swift mailer email attachment code
After this I use php swiftmailer to email this file as an attachment.
Is this correct and the most efficient way of doing this?
Thanks for your time
1). Not sure you can directly save the content as a .pdf file. As far I know, you need to use a thirdparty library called tcpdf http://www.tcpdf.org/ for saving the file as PDF file.
2). You can use swift mailer to send the attachment with email.
I've come across a bit of a problem and was wondering if anyone could point me in the right direction, I'm writing a email parser that parses emails and extracts particular info.
It parses plain text emails(the emails are in a set format) using regex, this works fine.
If an email has an attachment which is of type 3 && encoding = 3 && disposition = attachment then save the attachment to local disk.
My problem is step 2:
I foreach through each email structure if it has more than 2 parts I attempt to decode the attachment and save it to disk, but this is failing.
If I try to simply use file_put_contents I get a 0 KB File, I have given full permissions to the wamp server user, So I do not think it's file permissions and I have verified I can write by using mkdir.
file_put_contents(APPPATH . "attachments/". $partofpart->dparameters[0]->value, $partofpart); //$partofpart is part[2] of the full email structure
So I attempted to decode the part and save the decoded part instead using file_put_contents
$attachment = base64_decode($partofpart);
var_dump($attachment);
//then save the attachment with attachment name
file_put_contents(APPPATH . "attachments/". $partofpart->dparameters[0]->value, $attachment);
but this returns an error saying base64_decode requires an string not an object, how do I then convert my email-part-attachment to a string for use by base64_decode?
Even just writing that out I feel I'm missing something obvious and shouldn't require the extra steps.
Am I right in thinking the part IS the attachment? All the parameters lead me to believe so, Type, Subtype, size etc are all correct for the attachment.
Link to the entire scraper model
Thanks for reading and any help.
Below is a vardump of parts that meet the type/encoding/disposition checks
I have worked out the problem, I was not fetching the actual pdf back just its structure
So I wrote a function to retrieve the body of the particular email then used imap_base64 to encode then finally file_put_contents.
function getAttachment($msg_index, $part)
{
$mailbody = imap_fetchbody($this->conn,$msg_index,$part);
return $mailbody;
}
$attachment = imap_base64($this->email_model->getAttachment($email['index'], "2"));
//mkdir(APPPATH . "attachmentzs/");
//then save the attachment with attachment name
file_put_contents(APPPATH . "attachments/". $partofpart->dparameters[0]->value, $attachment);
I am having some issues with trying to get SwiftMailer to attach a file I have created with FPDF. Basically I have a page called createPDF.php that is dynamically generated based on the ID number in the URL. This page is set to output the PDF inline using $pdf->Output("filename.pdf",I);. What I want to do is to be able to attach this file to an email using SwiftMailer from another page simply by calling my createPDF.php?id=xxx link.
From the PHP page where I want to send the email from, everything works, except the attachment. It attaches something, but not what I want and it is not viewable in a PDF viewer on my local machine. The line specific to the attaching the file is:
->attach(Swift_Attachment::fromPath('createPDF.php?id=xxxx'))
This does not work, but surely, it must be possible without saving the file on my web server by FPDF.
Is this possible? If so, how?
Thanks!
The problem here is Swiftmailer gets the file contents, it does not execute your php file. So the contents of your PDF will the code that is in createPDF.php.
why cant you safe the file first? You should be able to safe it and delete it when your email is sent.
<?php
$id = "xxx";
$fileName = "tmp/".sha1(time()+mt_rand(0,99999999));
include "createPDF.php"; //saves it to $fileName
->attach(Swift_Attachment::fromFile( $fileName )->setFilename('blaha.pdf'));
unlink($fileName);
Ok, so I just figured this out.
Basically I made a new PHP file with the bulk of my createPDF.php file as a function and simply passed in two variables into the function as my $id and an $output variable. $output is simply the way that FPDF outputs the file — inline, etc... I then set the function to return the output of the FPDF. In my createPDF.php file I simply call my function passing in $id and 'I' as the variables so it displays the correct PDF inline in the browser.
In my sendEmail function I simply pass in $id and 'S' and set it to a variable $content, which I pass into SwiftMailer as an attachment.
Works great.
Thanks for your help!
I'm generating a pdf file with html2fpdf.
$pdf = new HTML2FPDF();
$pdf->HTML2FPDF("P","mm","A4");
$pdf->AddPage();
$pdf->WriteHTML($html);
$pdf->output('sample.pdf');
This sample works great. But:
How do I delete the pdf after the output? I just want to have links in my tool, the users can download the pdf and after that it shoud be deleted on the server.
How can I 'clean up' after generating the pdf?
You can use PHP's file deletion function called unlink()
Call this function with the full path to the generated PDF file (or any file for that matter) and PHP will delete that file.
http://php.net/manual/en/function.unlink.php
You don't necessarily have to delete the file immediately after the user has downloaded it. You can just as easily place all the generated files in one central folder and have a cron job execute a more general clean up script simply removing the older files.
One method could be -
Scan the contents of the folder using scandir().
Iterate over its files in a foreach loop..
Inspect the creation time of each file using filemtime().
If the creation time was over hour ago, delete the file using unlink().
Because you are generating the PDF file yourself within your PHP code, I didn't mention the permissions consideration. Here would be a good place to mention that your PHP must have the correct file system permissions in order to perform any action on the file system. You are creating a PDF file so it's safe to assume that you have the correct permissions to make changes to the file system but if you plan on using this unlink() function in other scripts make sure that the files you are dealing with have the correct permissions set.
If you don't add the 'F' flag to the output function there will be no pdf files stored on the server at all:
$pdf->output('sample.pdf', 'F'); //stores PDF on server
In your case the script itself behaves like an actual pdf file. So, creating a link to the script is just like a link to the pdf, except that the PDF is created every time the script is requested. To tell the browser it's a PDF the content-type response header must be set to application/pdf:
content-type: application/pdf
This way the broser knows that it's a pdf even if the URL is ending in a .php. You can use rewrite engine to make it end in pdf or whatever else.
Sending the headers is done by the fpdf/tcpdf. In short: you don't have to do any cleanup, because no pdf file is stored on the server.
If you wonder what the name is for than, try saving the pdf file. The recommanded name when saving will be sample.pdf.
Reference:
PHP header() function, at the examples there is one for sending pdf
FPDF::Output()
TCPDF::Output()