I've recently created an online template for creating job postings for our website. Everything is all done, it formats correctly in a browser, automatically posts to our website, bla bla bla.
The last piece I'm creating is to give the administrator a few options for distributing the posting to various places (via email) in a consistent, convenient way. I've created a PHP page that creates a PDF doc on the fly, using the TCPDF library. When loading pdf.php?id=X, the page displays a PDF with the content of job posting X. This means I'm never saving the PDF file to the server, just creating it on the fly each time it's called.
But I want to attach this PDF to an email, and send it to various colleges, and internal mailing lists, etc. If I attach the pdf.php?id=x to the email, it doesn't attach the PDF, it attaches what appears to be a blank file, with the above name.
Is it possible to attach this to the email without saving it to the server?
Below added based on JM4's response for further trouble shooting. I have put the PDF file creation into a function, and put it into an include file, just to keep things easier to manage.
// random hash necessary to send mixed content
$separator = md5(time());
$eol = PHP_EOL;
// attachment name
$filename = "_Desiredfilename.pdf";
include_once('pdf.php');
// encode data (puts attachment in proper format)
$pdfdoc = job_posting_to_pdf($posting_id);
$attachment = chunk_split(base64_encode($pdfdoc));
///////////HEADERS INFORMATION////////////
// main header (multipart mandatory) message
$headers = "From: Sender_Name<valid_email#mydomain.com>".$eol;
//$headers .= "Bcc: email#domain.com".$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;
$headers .= "Content-Transfer-Encoding: 7bit".$eol;
$headers .= "This is a MIME encoded message.".$eol.$eol;
// message
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$headers .= $message.$eol.$eol;
// attachment
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= "Content-Disposition: attachment".$eol.$eol;
$headers .= $attachment.$eol.$eol;
$headers .= "--".$separator."--";
//Email message
if(mail('valid_email#mydomain.com', 'test job posting', 'message body goes here', $headers)) {
echo 'mail sent';
} else {
echo 'error in email';
}
Here is a stripped down version of pdf.php:
function job_posting_to_pdf($job_id) {
require_once(ROOT . 'assets/libs/tcpdf/config/lang/eng.php');
require_once(ROOT . 'assets/libs/tcpdf/tcpdf.php');
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('');
$pdf->SetTitle('OPL Job Posting');
$pdf->SetSubject('Job Posting');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// remove default header/footer
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
//set margins
$pdf->SetMargins(11, PDF_MARGIN_TOP, 11);
//set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
//set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
//set some language-dependent strings
$pdf->setLanguageArray($l);
// ---------------------------------------------------------
$pdf->SetFont('times', 'I', 9);
$pdf->AddPage();
$left_cell_width = 60;
$row_height = 6;
$pdf->Image(ROOT . 'assets/gfx/logos/OPL-Logo.jpg', 0, 5, null, 16, null, null, 'N', false, null,'R');
$pdf->Ln('3');
if(!$row['internal']) {
$pdf->Cell(0,0,'This position will be posted internally and externally, concurrently.',0,2,'C');
} else {
$pdf->Cell(0,0,'Internal posting only.',0,2,'C');
}
//Remainder of actual PDF creation removed to keep things simple
return $pdf->Output("", "S");
}
If I completely understand what you are asking this is quite simple. I am assuming you already have the PDF generated using something like fdpf or tcpdf. In that case - simply use the following code:
<?php
// random hash necessary to send mixed content
$separator = md5(time());
$eol = PHP_EOL;
// attachment name
$filename = "_Desiredfilename.pdf";
// encode data (puts attachment in proper format)
$pdfdoc = $pdf->Output("", "S");
$attachment = chunk_split(base64_encode($pdfdoc));
///////////HEADERS INFORMATION////////////
// main header (multipart mandatory) message
$headers = "From: Sender_Name<sender#domain.com>".$eol;
$headers .= "Bcc: email#domain.com".$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;
$headers .= "Content-Transfer-Encoding: 7bit".$eol;
$headers .= "This is a MIME encoded message.".$eol.$eol;
// message
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$headers .= $message.$eol.$eol;
// attachment
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= "Content-Disposition: attachment".$eol.$eol;
$headers .= $attachment.$eol.$eol;
$headers .= "--".$separator."--";
//Email message
mail($emailto, $emailsubject, $emailbody, $headers);
?>
I just had to figure this out and my eyeballs were definitely sore by the end...
1) You need to install PHPMailer to the php server.
2) Include the PHPmailer class in your TCPDF script, like so (your path may vary):
require_once('../PHPMailer_v5.1/class.phpmailer.php');
3) Now after your pdf code simply talk to PHPMailer like so:
$filename = "custompdf_$name_$time.pdf";
$pdf->Output($filename, 'F'); // save the pdf under filename
$mail = new PHPMailer(); $mail->IsSMTP();
$mail->Host = "mail.yourhost.com";
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Port = 26; // set the SMTP port for the GMAIL server
$mail->Username = "user+yourhost.com"; // SMTP account username
$mail->Password = "topsecret"; // SMTP account password
$mail->From = "noreply#yourhost.com";
$mail->FromName = "Stack Overflower";
$mail->AddAddress( $email, $name ); // in this case the variable has been passed
$mail->AddCC( "person#somehost.net", "Johnny Person"); // in this case we just hard code it
$mail->SMTPDebug = 0; // use 2 for debugging the email send
$pdf_content = file_get_contents($filename);
$mail->WordWrap = 50;
$mail->AddStringAttachment($pdf_content, "custompdf_for_$name_$time.pdf", "base64", "application/pdf"); // note second item is name of emailed pdf
$mail->IsHTML(true);
$mail->Subject = "Your pdf is here";
$mail->Body = "Dear $name,<br>
Here is your custom generated pdf generated at $t.<br><br>
Thank you";
if(!$mail->Send()) {
echo "Sorry ... EMAIL FAILED";
} else { echo "Done. . . Email sent to $email at $t."; }
unlink($filename); // this will delete the file off of server
Of course you have many options for the email sent, like not using html, or sending both html and text, adding many recipients and/or cc's, etc.
EDIT: This does save the file temporarily on the server, but it cleans up after itself with the unlink command.
Take a look at this page which discusses advanced email in PHP.
http://articles.sitepoint.com/article/advanced-email-php/5
They take an uploaded file and load the binary data into $data, but you can just start from there.
You may also want to look at sending it as an attachment via PEAR Mail_Mime. It can accept an attachment as a string of data.
The RMail package also looks as if it will do the same via the stringAttachment class. You'll have to google for it, because I'm a new user and so I can post only one link at a time.
I agree about using a mail library in place of building mime messages by hand with the default mail() function. SwiftMailer is another good open source PHP mail library. Here's the sample code for using dynamic content as an attachment without having to save it to the file system first.
Your headers seem to be a little out:
application/octet-stream should become application/octetstream
Content-Disposition: attachment .. should become Content-Disposition: attachment; filename="' . basename($filename) . '"
heres what the attachement headers should look like:
// attachment
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octetstream;".$eol; //Fixed
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= 'Content-Disposition: attachment; filename="' . basename(filename).'"'.$eol;
$headers .= 'Content-ID: <' . basename($filename) . '>' . $eol . $eol //EOL X2 Before
$headers .= $attachment;
//Run the above in a loop for multiple attachments, after add the final line
$headers .= '--' . $separator . '--' . $eol;
This was taken from one of my working applications, heres the loop if you wish to see it:
foreach ($this->attachments as $attachment) {
if (file_exists($attachment['file'])) {
$handle = fopen($attachment['file'], 'r');
$content = fread($handle, filesize($attachment['file']));
fclose($handle);
$message .= '--' . $boundary . $this->newline;
$message .= 'Content-Type: application/octetstream' . $this->newline;
$message .= 'Content-Transfer-Encoding: base64' . $this->newline;
$message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline;
$message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline;
$message .= chunk_split(base64_encode($content));
}
}
$message .= '--' . $boundary . '--' . $this->newline;
Related
i handcraft a php file and it works. it sends a fpdf as attachment. but now, how to use umlauts in sender, subject and text and how use html-content instead of only unformatted text in mail body?
here is my code:
<?php
require('fpdf/fpdf.php');
$pdf = new FPDF('P','mm','A4');
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10, "this is a pdf example");
$to = "to#blah.com";
$from = "blah <blah#blah.de>";
$subject = "Test";
// a random hash will be necessary to send mixed content
$separator = md5(time());
// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;
// attachment name
$filename = "Test.pdf";
// encode data (puts attachment in proper format)
$pdfdoc = $pdf->Output("", "S");
$attachment = chunk_split(base64_encode($pdfdoc));
// main header
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; charset=utf-8; boundary=\"".$separator."\"";
// no more headers after this, we start the body! //
$body = "--".$separator.$eol;
$body .= "Content-Transfer-Encoding: 7bit".$eol.$eol;
$body .= "hallo, test".$eol;
// attachment
$body .= "--".$separator.$eol;
$body .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$body .= "Content-Transfer-Encoding: base64".$eol;
$body .= "Content-Disposition: attachment".$eol.$eol;
$body .= $attachment.$eol;
$body .= "--".$separator."--";
// send message
mail($to, $subject, $body, $headers);
//name of pdf file
$pdf_file = "test.pdf";
// additional output pdf
$pdf->Output('I', $pdf_file);
?>
can you help me? im simply to stupid.... i have tried many things with utf etc. but it doesnt work...
you should use PHPMailer - Mailing library
https://github.com/PHPMailer/PHPMailer
it is easy to handle & it never fails to send an email
I have a strange problem in chrome, I am using window.open to open a new tab and create a pdf using tcpdf and then send it as attachment to a specific address, now in chrome what happens is that it sends 2 mails. If popup is enabled then I get 2 window actions 1. Popup and 2. New Tab, firstly I don't understand how is that possible, I have never seen this.
Then If is disable the popup, it only opens in new tab, but still 2 mails.
Code used to call the popup page and email code is mentioned below. Please help.
window.open('/loancal/rhexportemail.php' + qstring,"_blank");
//Code used to open popup
//------------- EMAIL CODE ----------------//
$to = "someone#gamil.com";
$from = "info#mydomain.com";
$subject = "Loan Enquiry Calculation Cashback - " . $client;
$message = "Please find attached Loan Enquiry Calculation Cashback statement for ".$client."." ;
//a random hash will be necessary to send mixed content
$separator = md5(time());
// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;
// attachment name
$filename = $subject.".pdf";
// encode data (puts attachment in proper format)
$pdfdoc = $pdf->Output('LECC'.$separator.'.pdf', 'S');
$attachment = chunk_split(base64_encode($pdfdoc));
// encode data (multipart mandatory)
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;
$headers .= "Content-Transfer-Enconding: 7bit".$eol;
$headers .= "This is a MIME encoded message.".$eol.$eol;
// message
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: text/html; charsrt=\"iso-8859-1\"".$eol;
$headers .= $message.$eol.$eol;
// attachment
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= "Content-Disposition: attachment".$eol.$eol;
$headers .= $attachment.$eol.$eol;
$headers .= "--".$separator."--";
// send message
if(#mail($to, $subject, $message, $headers))
{
echo "<script type='text/javascript'> alert('mail sent');window.close();</script>";
}
else{
echo "<script type='text/javascript'>alert('mail not sent');window.close(); </script>";
}
I strongly believe that you somehow call this twice.
i have function to send mail with attachment to microsoft exchange server. My problem is that when I wanna to add attachment the whole message part is adding my text to attachment source. When I save attachment to body section of mail, my attachment source is wrote down in email body instead of creating an attachment. Belowe is my source.
$eol = "\r\n";
$boundary = md5(time());
$mail = "explame#explame.com";
$headers = "From: no-replay#explame.com".$eol;
$headers .= "MIME-Version: 1.0".$eol; //utworzenie headera wiadomosci
$headers .= "Content-type: multipart/alternative; charset=utf-8".$eol;
$headers .= "Message-ID:< TheSystem#".$_SERVER['SERVER_NAME'].">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol;
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/related; boundary=\"".$boundary."\"".$eol;
$headers .= "--$boundary".$eol;
$headers .= "Content-Type: text/plain; charset=utf-8".$eol;
$headers .= "Content-Transfer-Encoding: 8bit".$eol;
$headers .= "--$boundary--".$eol.$eol;
if ($file != ''){
$handle = fopen($file['tmp_name'], 'rb');
$f_content = fread($handle, $file['size']);
$attachment = chunk_split(base64_encode($f_content));
fclose($handle);
$content .= "--$boundary".$eol;
$content .= "Content-type: ".$file['type'].'; '.'name="'.$file['name'].'"'.$eol;
$content .= 'Content-Disposition: attachment; filename="'.$file['name'].'"'.$eol.$eol;
$content .= "Content-Transfer-Encoding: base64".$eol;
$content .= $attachment.$eol.$eol;
$content .= "--$boundary--".$eol.$eol;
}
mail($mail, 'title', $content, $headers)
i think I tried everything but nothing works for me. :(
a really good PHP lib for sending mail (especially for dealing with attachments) is the phpmailer class.
You can find it here: http://code.google.com/a/apache-extras.org/p/phpmailer/
EDIT - the above link is to the old project, it's now hosted on Github and more regularly maintained: https://github.com/PHPMailer/PHPMailer
And an example of how to use it to send an attachment:
include("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsHTML(true);
$mail->SetFrom('from#mydomain.com');
$mail->AddReplyTo('from#mydomain.com'); //set from & reply-to headers
$mail->AddAddress('to#exchangeserver.com'); //set destination address
$mail->Subject="some subject"; //set subject
$mail->Body="some body HTML <br/><br/>"; //set body content
$mail->AddAttachment('filepath', 'filename'); //attach file
$mail->AltBody = "Can't see this message? Please view in HTML\n\n";
$mail->Send();
I have been using FPDF for the last two years to generate a PDF file. After this file has been generated it is e-mailed to me. I recently installed the exact same script on a new server. For one or other reason the generation of the PDF works since I don't get a error message. The message that I receive on the email is straight text and looks like:
--4aca5942d8bd7e7d523d8b2d71c6b1ea--
or
--d7582bf6769dd1fa2ee8f05cb04cf445--
every message is different.
The stripped code is:
require('class.phpmailer.php');
require('fpdf.php');
define('FPDF_FONTPATH','font/');
//Create new PDF
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->company = $business;
$pdf->SetFont('Arial','',12);
$pdf->SetAutoPageBreak(false);
$pdf->AddPage('P');
// email stuff
$tijd = time();
$datum = date('j-m-Y', $tijd);
$bestandsnaam = $usernameinlog."-".$datum;
$from = "magazijnbeheer#".$website;
$subject = "Voorraad mutatie door ".$usernameinlog;
$message = "<p>Zie bijlage voor een mutatieoverzicht.</p>";
// a random hash will be necessary to send mixed content
$separator = md5(time());
// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;
// attachment name
$filename = $bestandsnaam.".pdf";
// encode data (puts attachment in proper format)
$pdfdoc = $pdf->Output("", "S");
$attachment = chunk_split(base64_encode($pdfdoc));
// main header (multipart mandatory)
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;
$headers .= "Content-Transfer-Encoding: 7bit".$eol;
$headers .= "This is a MIME encoded message.".$eol.$eol;
// The actual message
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$headers .= $message.$eol.$eol;
// Bijlage
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= "Content-Disposition: attachment".$eol.$eol;
$headers .= $attachment.$eol.$eol;
$headers .= "--".$separator."--";
mail($emailemployee, $subject, "", $headers);
Does anyone know what is going wrong, am I missing a parameter in the php.ini?
once again: this same code worked on a different server, so I think some setting is wrong or I forgot to install something.
:-) Thanks,
Alex
$eol = PHP_EOL; is likely to cause problems if your server isn't running Windows.
Each line in an email MUST end in CRLF, irrespective of OS, so you should hard-code $eol = "\r\n";
Sometimes, servers and clients will cope with either CR or LF, but it's non-standard and they really don't have to.
.
If you still have problems after this, please can you add the message source to the question (for brevity, perhaps trim the base64 bit to 2 lines)?
mail($emailemployee, $subject, "", $headers);
your basically sending a empty message with the whole content somehow stuffed into
$headers....
Try putting everything below $headers .= "Content-Transfer-Encoding: 7bit".$eol; in a $body variable instead of $headers and then send with
mail($emailemployee, $subject, $body, $headers);
(also replace $eol = PHP_EOL with $eol = "\r\n" as suggested by SimonMayer)
I'm trying to send an email using the mail() function in php with a pdf attachment.
I'm running the script on localmachine. I set up the smtp ip in php.ini.
I can send a text email perfectly but with an attachment I get the following error:
Warning: mail() [function.mail]: SMTP server response: 503 Unexpected command or sequence of commands in C:\AppServ\www\PhpProject1\CV-Generator\testemail2.php on line 55
Can anyone tell me what's wrong please?
Here is my code:
<?php
// download fpdf class (http://fpdf.org)
require('./pdf/fpdf.php');
// fpdf object
$pdf = new FPDF();
// generate a simple PDF (for more info, see http://fpdf.org/en/tutorial/)
$pdf->AddPage();
$pdf->SetFont("Arial","B",14);
$pdf->Cell(40,10, "this is a pdf example");
// email stuff (change data below)
$to = $_GET['send'];
$from = "info#asaltechd.com";
$subject = "send email with pdf attachment";
$message = "<p>Please see the attachment.</p>";
// a random hash will be necessary to send mixed content
$separator = md5(time());
// carriage return type (we use a PHP end of line constant)
$eol = PHP_EOL;
// attachment name
$filename = "example.pdf";
// encode data (puts attachment in proper format)
$pdfdoc = $pdf->Output("", "S");
$attachment = chunk_split(base64_encode($pdfdoc));
// main header (multipart mandatory)
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;
$headers .= "Content-Transfer-Encoding: 7bit".$eol;
$headers .= "This is a MIME encoded message.".$eol.$eol;
// message
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$headers .= $message.$eol.$eol;
// attachment
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= "Content-Disposition: attachment".$eol.$eol;
$headers .= $attachment.$eol.$eol;
$headers .= "--".$separator."--";
// send message
mail($to, $subject, "", $headers);
?>
The attachment doesn't go in the headers! They should only declare the MIME headers:
// main header (multipart mandatory)
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol; // see below
$headers .= "Content-Transfer-Encoding: 7bit".$eol;
// message
$msg = "--".$separator.$eol;
$msg .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$msg .= $message.$eol.$eol;
// attachment
$msg .= "--".$separator.$eol;
$msg .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Disposition: attachment".$eol;
$msg .= $attachment.$eol;
$msg .= "--".$separator."--".$eol;
// send message
mail($to, $subject, $msg, $headers);
Note also that you should NEVER have 2 consecutive line terminations within the headers - SMTP uses a blank line as the seperator between headers and the body.
Also, the EOL should NOT be the default on your operating system - it should be the EOL sequence as defined by SMTP - i.e. CR+LF
I use PHP's SwiftMailer (http://swiftmailer.org/):
require_once('../lib/swiftMailer/lib/swift_required.php');
...
$body="Dear $fname,\n\nPlease find attached, an invoice for the period $startDate - $endDate\n\nBest regards,\n\nMr X";
$message = Swift_Message::newInstance('Subject goes here')
->setFrom(array($email => "no-reply#mydomain.com"))
->setTo(array($email => "$fname $lname"))
->setBody($body);
$message->attach(Swift_Attachment::fromPath("../../invoices_unpaid/$id.pdf"));
$result = $mailer->send($message);
I would suggest that you use PHP Mailer to send emails from your PHP. I've used it with great success on many different configurations. The class has all necessary methods for handling encodings, attachments, custome headers, sending via sendmail, etc., etc.