I am using FPDF and Phpmailer to generate a PDF file and sending it as an email attachment.
My script for PDF generation and phpmailer are working perfectly when I use them as independent scripts.
Now, when I combine both scripts to generate and display the PDF form (without saving it to to the filesystem) and send this PDF document as an attachment, it is not working thouht it generates the PDF and display it on browser, but does not sent it by mail.
My code is:
<?php declare(strict_types=1);
use PHPMailer\PHPMailer\PHPMailer;
require 'vendor/autoload.php';
$pdf = new mypdf();
$pdf->AliasNbPages();
$pdf->AddPage('P', 'A4', 0);
$pdf->Header();
$pdf->headerTable();
$pdf->viewTable();
$pdf->footer();
$pdf->setMargins(20, 20, 20);
$pdf->output();
$pdfString = $pdf->output();
$mail = new PHPMailer;
// getting post values
$first_name = $_POST['fname'];
$to_email = "receipent#gmail.com";
$subject = "stationery issued";
$message = "Dear sir your requested stationery has been issued by Stationery store ";
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'sender#gmail.com'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 25; // TCP port to connect to
$mail->setFrom('sender#gmail.com', 'Your_Name');
$mail->addReplyTo('sender#gmail.com', 'Your_Name');
$mail->addAddress($to_email); // Add a recipient
$mail->addStringAttachment((string)$pdfString, 'name file.pdf');
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = 'Dear ' . $first_name . '<p>' . $message . '</p>';
$mail->send();
You have left unclear which Phpmailer version you're using and which FPDF version, therefore it is hard to say what the error exactly is.
On first glance this hit my attention:
$pdfString = $pdf->output();
If the intend is to have $pdf->output() to return a string, then the invocation looks wrong to me.
That is because the invocation as $pdf->output() is doing the default output, which is sending to the browser.
Which you said is working, and that is already the line above:
$pdf->output();
$pdfString = $pdf->output();
PHP is an imperative language, that means, it does not make a difference to the method call whether or not you assign a variable to the return value.
So both method calls will behave the same:
$pdf->output();
$pdfString = $pdf->output();
It's like writing
$pdf->output();
$pdf->output();
Perhaps just an oversight in the heat of the debugging. For debugging, check the preconditions early, verify your script step-by-step. Don't ask longer than five minutes. Just verify then.
Potential fix:
$pdfString = $pdf->output('S');
may do it, better check with the documentation you have at hand for your version in use.
Related
I am sending email with PHPMailer. My email design is available in the template.php file. I am pulling the contents of the template.php file with the file_get_contents method in my mail.php file. But I have such a problem, all my php codes in the template.php file are also visible. How can I hide them?
Mail.php
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
require_once 'assets/standart/db.php';
require 'assets/class/all.php';
$connect = new baglan();
$settings = new ayarlar();
// SMTP settings connect
$connect->connect('settings_smtp', '', '', 0);
$smtp_settings = $connect->connect->fetch(PDO::FETCH_ASSOC);
$smtp_mail = $smtp_settings['mail'];
// /SMTP settings connect
$template_file = 'PHPMailer/template.php';
if(file_exists($template_file)){
$mail_template = htmlspecialchars(file_get_contents($template_file));
}else{
die("Unable to locate the template file");
}
//Load Composer's autoloader
// require 'vendor/autoload.php';
//Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = $smtp_settings['host'];
$mail->SMTPAuth = true;
$mail->Username = $smtp_settings['mail'];
$mail->Password = $smtp_settings['password'];
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = $smtp_settings['port'];
//Recipients
$mail->setFrom("$smtp_mail", 'Mailer');
$mail->addAddress('example#gmail.com', 'Joe User'); //Add a recipient
// $mail->addAddress('ellen#example.com'); //Name is optional
// $mail->addReplyTo('info#example.com', 'Information');
// $mail->addCC('cc#example.com');
// $mail->addBCC('bcc#example.com');
//Attachments
// $mail->addAttachment('/var/tmp/file.tar.gz'); //Add attachments
// $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); //Optional name
//Content
$mail->isHTML(true);
$mail->CharSet = 'UTF-8';
$mail->Subject = 'Here is the subject';
$mail->Body = $mail_template;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
Template.php
<?php
echo $forexample = 'Some words here';
?>
Don’t use file_get_contents for that, use include with output buffering. That way it will run the PHP code and you’ll see the results of its execution instead of the code itself.
You have to run the template file, not simply read it.
You can do that like this:
ob_start();
include ( $template_file );
$mail_template = ob_get_clean();
ob_start() (output-buffer start) causes all php script output (from echo etc) to go into an output buffer. output_get_clean() retrieves that output.
With
$mail_template = htmlspecialchars(file_get_contents($template_file));
you will just get the contents of the file into the variable $mail_template
You could use the eval() function as described here: https://www.php.net/manual/en/function.eval.php
But be very careful using it!
Caution: The eval() language construct is very dangerous because it allows
execution of arbitrary PHP code. Its use thus is discouraged. If you
have carefully verified that there is no other option than to use this
construct, pay special attention not to pass any user provided data
into it without properly validating it beforehand.
You could use it like this:
$mail_template_php = htmlspecialchars(file_get_contents($template_file));
$mail_template = eval($mail_template_php);
Good morning all ,
I would like to attach a PDF created following a form with HTML2PDF then send it with PHMailer.
Everything works, the email goes well, I managed to create the PDF by saving it on my hard drive.
But when I try to attach it to my email, the pdf is fine in pj but I can't open it.
enter image description here
It is the same size of my locally created pdf.
I followed the tutorial and wiki of the two libraries, well I think ^^
Here is my PHPMailer code:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require './vendor/phpmailer/phpmailer/src/Exception.php';
require './vendor/phpmailer/phpmailer/src/PHPMailer.php';
require './vendor/phpmailer/phpmailer/src/SMTP.php';
require './vendor/autoload.php';
// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
$mail->CharSet = 'UTF-8';
try {
//Server settings
$mail->SMTPDebug = 0; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = '******'; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = '*****'; // SMTP username
$mail->Password = '*****'; // SMTP password
//$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
$mail->Port = ****; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
//Recipients
$mail->setFrom('****#****.com', '****');
$mail->addAddress($to); // Add a recipient
//$mail->addAddress('ellen#example.com'); // Name is optional
$mail->addReplyTo($shop_email, 'Votre magasin');
//$mail->addCC('cc#example.com');
$mail->addBCC($shop_email);
// Attachments
$mail->addStringAttachment($pdf_done, 'myPdf.pdf'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $message;
$mail->AltBody = strip_tags($message);
$mail->send();
echo '';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
?>
and here is the code for HTML2PDF:
ob_start();
// --> mon code HTML de creeation du PDF
$content = ob_get_clean();
require_once dirname(__FILE__).'/../vendor/autoload.php';
use Spipu\Html2Pdf\Html2Pdf;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use Spipu\Html2Pdf\Exception\ExceptionFormatter;
try{
$pdf = new \Spipu\Html2Pdf\Html2Pdf('P', 'A4', 'fr');
$pdf->writeHTML($content);
$pdf_done = $pdf->output('myPdf.pdf', 'S');
}catch(\Spipu\Html2Pdf\Exception\Html2PdfException $e){
die($e);
}
?>
I tried adding ", 'base64', 'application / pdf'" in the addStringAttachment but it doesn't change anything.
Do you have any idea of my mistake?
Thank you all
Debug one thing at a time. First download the PDF manually and make sure it looks correct – if the PDF is bad to start with, emailing it isn't going to improve things. Next check that it is readable from PHP – for example serve it using readfile(). Then when you try to attach it, check the return value of your call to addAttachment() like this:
if (!$mail->addAttachment('/path/to/myPdf.pdf')) {
die('could not read PDF');
}
Also note the difference between addAttachment and addStringAttachment; you're adding a file that's been saved to disk, so you want the first one, not the second.
I have managed to generate pdf from my HTML page but unable to send the pdf as an attachment using phpmailer. Please, see my code below. What am I missing?
Key points:
The html(tractpage2.php) renders well to PDF
PHPmailer works but it only sends the $message without the attachment.
Problem is that the pdf does not attach the mail
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
require 'PHPMailer/src/Exception.php';
//reference the dompdf namescape
use Dompdf\Dompdf;
//initialise dompdf class
// get/setup the htmlpage
ob_start();
require("tractpage2.php"); // The html document
$page = ob_get_contents();
ob_end_clean();
// convert to pdf
$document = new Dompdf();
$document->set_option('defaultFont', 'Courier');
$document->load_html($page);
// set paper orientation
$document->set_paper('A4', 'portrait');
// Render the HTML as PDF
$document->render();
// Output the generated PDF to Browser
$document->stream("contract.pdf", array("Attachment"=>0));
//1 = download
//0= preview
$fileupload = $document->output();
// setup email
$message = "Am new to programming and loving it";
$mail = new PHPMailer;
//Server settings
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'xxxx#gmail.com'; // SMTP username
$mail->Password = 'xxxxxx'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
//Recipients
$mail->setFrom('xxxxx#gmail.com', 'james');
$mail->addAddress('xxxx#aol.com', 'name of receiver'); // Add a recipient
$mail->addAddress('xxxxx#yahoo.com'); // Name is optional
//Attachments
$mail->addAttachment($fileupload); // Add attachments
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = $message;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if ($mail->send()){
echo 'Message has been sent';}
else { echo 'Message could not be sent.';}
?>
You would want to create your file on server and save and then pass absolute path of pdf file to addAttachment or alternatively you can also directly attach the DomPDF output without creating a file, like so:
$mail->addAttachment($fileupload,'application/pdf','output.pdf', false);
I have a web app where users can click a button to download a PDF report.
My users requested that when the PDF is downloaded, it's immediately opened as an email attachment (sort of like when a mailto anchor is clicked).
Is this even possible? I was thinking maybe using js to generate an anchor tag behind-the-scenes but I read that mailto doesn't really support attachments.
If this matters, the PDF is generated server side using PHP mPDF set to download output mode.
mailto supports attachment if the file is available locally. You can use the attach parameter to specify that.
e.g. mailto:lastname.firstname#xxx.com?subject=Test&attach=C:\Documents%20and%20Settings\username\Desktop\foldername\file.extn
However, I'm unsure how you would use this in your code as users can download the file to any location on their machine. If it's of any use, the attach parameter supports shared drive locations if the user has appropriate access.
For this you have to separate process in two step.
Generate PDF on server in some directory using http://wkhtmltopdf.org/
Send generated pdf as part of email attachement using https://github.com/PHPMailer/PHPMailer
configure both the service will help you achieve your task.
Below is the sample code which will help you
//generate PDF file for bill and send it in email
public function sendInvoiceInEmail($register_no, $html_string, $guest_email_id)
{
//create mailer class
$mail = new PHPMailer;
//remove old invoice file if exist at public/doc
// here i have used my path you have to use your path
if(file_exists(__DIR__.'/../../public/docs/invoice.pdf')){
unlink(__DIR__.'/../../public/docs/invoice.pdf');
}
// You can pass a filename, a HTML string, an URL or an options array to the constructor
$pdf = new Pdf([
'commandOptions' => [
'useExec' => false,
'escapeArgs' => false,
'procOptions' => array(
// This will bypass the cmd.exe which seems to be recommended on Windows
'bypass_shell' => true,
// Also worth a try if you get unexplainable errors
'suppress_errors' => true,
),
],
]);
$globalOptions = array(
'no-outline'
);
$pdf->setOptions($globalOptions);
$pdf->addPage($html_string);
//for Windows in my system i have setup wkhtmltopdf here
$pdf->binary = '"C:/Program Files/wkhtmltopdf/bin/wkhtmltopdf.exe"';
// for linux when you will host you have to setp on linux abd comment windows path and uncomment below line
//$pdf->binary = '/home/username/wkhtmltox/bin/wkhtmltopdf';
if (!$pdf->saveAs(__DIR__.'/../../public/docs/invoice.pdf')) {
throw new Exception('Could not create PDF: '.$pdf->getError());
}
//now send email and attach invoice.pdf file from public/doc/invoice.pdf
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'hostname'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->setFrom('from_email_address', 'From Name',FALSE);
$mail->addAddress('to_email_address'); // Add a recipient
$mail->addAttachment(__DIR__.'/../../public/docs/invoice.pdf'); // Add attachments
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Subject';
$mail->Body = 'email message body';
$is_email_sent = false;
if(!$mail->send()) {
// echo 'Message could not be sent.';
// echo 'Mailer Error: ' . $mail->ErrorInfo;
$is_email_sent = false;
} else {
// echo 'Message has been sent';
$is_email_sent = true;
}
return true;
}
I am working on a web application using PHP as a server-side and a jQuery framework as a client-side.
One of the scenarios of the application is to send an email with pdf file attached I am doing this using PHPMailer and Dompdf libraries.
I had created a function named sendMail in a file name send.php accept 4 params (receiver email,subject,data,email number) the last param is because I have 5 different emails may be sent depending on the situation and data param is the data will be rendered in the html email body.
The problem is when I call the function from send.php it work as expected the email sent and pdf file created and attached to the email .
but when I require send.php in any other file and call sendMail function I get the email only without any pdf file and the file not even generated or saved on the server.
send.php
<?php
require_once 'dompdf/autoload.inc.php';
// reference the Dompdf namespace
use Dompdf\Dompdf;
require 'PHPMailerAutoload.php';
$body = "test message";
sendMail('peter#w34.co','MLS mail',$body,5);
function sendMail($email,$subject,$body,$index){
$mail = new PHPMailer;
$mail->IsSMTP(); // telling the class to use SMTP
$mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only
$mail->SMTPAuth = true; // SMTP authentication
$mail->SMTPSecure = 'tls'; // secure transfer enabled REQUIRED for GMail
$mail->Host = "smtp.gmail.com"; // SMTP server
$mail->Port = 587; // SMTP Port
$mail->Username = "peterwilson.intake34#gmail.com"; // SMTP account username
$mail->Password = "Password"; // SMTP account password // TCP port to connect to
$mail->From = 'peter#example.com';
$mail->FromName = 'Wilson';
$mail->addAddress($email); // Add a recipient
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body=$body;
// instantiate and use the dompdf class
$dompdf = new Dompdf();
$dompdf->loadHtml($body);
// Render the HTML as PDF
$dompdf->render();
$output = $dompdf->output();
$file_to_save= "../work-orderes/file.pdf";
file_put_contents($file_to_save, $output);
$mail->addAttachment('../work-orderes/file.pdf');
if(!$mail->send()) {
// echo $mail->ErrorInfo;
} else {
return 1;
}
}
?>
save.php
<?php
require("sendSmtp/send.php");
session_start();
$body = "Hello World!";
sendMail('peter#w34.co','MLS mail',$body,5);
?>
Any suggestions about why Dompdf not works when calling it from any other file ??
What I have tried
removing dompdf and reinstall the latest stable version from
here
cleaning all code and just leave sendMail function and calling it
try to write the code from the beginnig
I solved it finally!
after debugging I found that everything going fine till $output = $dompdf->output(); after that I get an error on save the file using $file_to_save= "../work-orderes/file.pdf";
this work properly when I call the function sendMail() from send.php but when I call it from another file I get an error regarding accessing the path.
The Answer here that I should use the absolute path not the relative one like below
$file_to_save= $_SERVER['DOCUMENT_ROOT']."\work-orderes/file.pdf";
now the file saved successfully and attached to the email like expected!