using PHPMailer's AddAttachment method on PHP 5, it seems I can't get any mail client to decode base64 section.
Practically, receiving the e-mail message with Thunderbird, instead of my attached file "asyF074.tmp", I find attached a "Part1.2" file, which contains section headers (
name="asyF074.tmp"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="asyF074.tmp"
) followed by base64 representation of file contents.
I can't figure out what is going wrong with the attachment:
$filename = tempnam ( "" , "asy" );
$f = fopen($filename, "wb");
fwrite($f, $tbl, strlen($tbl));
fclose($f);
/*
* Send mail...
*/
$mail = new phpmailer();
$mail->IsSMTP();
$mail->From = "andrew#" . $domain;
$mail->FromName = "Andrew";
$mail->Host = $mail_host;
$mail->Port = $mail_port;
$mail->AddAddress($mail_destination);
$mail->IsHTML(true);
$mail->Subject = "2011 Polls";
$mail->Body = $msg;
$mail->AddAttachment($filename, "2011-Polls.xls", "quoted-printable", "application/vnd.ms-excel");
$mail->Send(); // send message
unlink($filename);
Also, even if I explicitly set encoding to "quoted-printable", the attachment always comes encoded in base64.
Thanks.
It may not be an answer to your problem but I suggest you try Zend_Mail from the Zend_Framework I've never say problems like these using it.
... found! I don't know why, but it was due to the PHPMailer version I was using (I know what you're thinking: "This guy blew the former download", but I can assure you that I downloaded the proper lib).
I re-downloaded (2 days later) the same library for PHP 5 and now it's working.
Didn't have the time to check, but there was something wrong into the library code.
Related
The way I create my Word document is this :
// I use my templace that's with my files :
$templateProcessor = new TemplateProcessor('Template.docx');
// I fill the template values from an sql query :
$templateProcessor->setValue('titre', $options['titre']);
$templateProcessor->setValue('source', $options['source']);
$templateProcessor->setValue('auteur', $options['auteur']);
$templateProcessor->setValue('date_pub', $options['date_pub']);
$templateProcessor->setValue('contenu', $options['contenu']);
// I give the user the file (I don't fully understand how this works but it does)
header("Content-Disposition: attachment; filename=$title.docx");
$templateProcessor->saveAs('php://output');
The way people recommend attaching files to php mails is the following:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$email = new PHPMailer();
$email->SetFrom('you#example.com', 'Your Name'); //Name is optional
$email->Subject = 'Message Subject';
$email->Body = $bodytext;
$email->AddAddress( 'destinationaddress#example.com' );
$file_to_attach = 'PATH_OF_YOUR_FILE_HERE';
$email->AddAttachment( $file_to_attach , 'NameOfFile.pdf' );
return $email->Send();
I have a problem with the PATH_OF_YOUR_FILE_Here part, The code I use for creating the word document just serves it to the user so they download it, but what is the path to it ?
Help is really appreciated, thanks
You need to create the file on your server first in order to attach it to an email. You can delete the file from your server after sending the email.
The header() and php://output are telling the user's browser to download the file, so if you remove the header and change saveAs() to be a real (writeable) path on your server, you should end up with a file that you can then attach to an email.
I'd recommend writing the file to a new location (above your server root) to store these temporary files rather than within the source code. Then ->saveAs('/path/to/file/File.docx'); and $file_to_attach = '/path/to/file/File.docx';.
I tried to attach my local file using PHP Mailer. I'm getting attachment only if the attachment file is in own server, but when I tried to attach the file from my c drive say [C:\Users\emp10144\Downloads], am getting attachment but with blank page. Did I need to modify my codings. Below is the codings I have used.
$mail->From = 'admin123#sampledemos123.online';
$mail->FromName = 'Admin';
$mail->AddAddress('targetmail#gmail.com', 'User'); // Add a recipient
//$mail->AddAddress('ellen#example.com'); // Name is optional
//$mail->AddAttachment('Daily_Milk_Report.csv','Daily_Milk_Report.csv');
This is working fine as the attcahment file is in own server
$filename = "C:\Users\emp10144\Downloads','Daily_Milk_Report.csv"; // Need to attcah this file from C drive/folder.
//$string = file_get_contents("C:\Users\emp10144\Downloads\sample.pdf");
$mail->AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/vnd.ms-excel');
$mail->IsHTML(true); // Set email format to HTML
No, you cannot pass a URL to addAttachment and have it fetch the resource.
This is intentional; PHPMailer is not an HTTP client, and actively avoids being one. If you want to do this, you need to take responsibility for the fetch yourself, which is most easily achieved like this:
$mail->addStringAttachment(file_get_contents($url, 'myfile.png'));
So I've spent the last 3 days trying to figure out why the email I'm trying to send from PHP won't attach my excel file. It's a file that is generated on the server and I've verified that the .xlsx file is being created without error, but when I receive the email that it should be attached to, there is nothing there.
I found an answer here on SO that suggested trying to attach it as a string instead. This made it so I was able to see the attachment when I opened the email, but the file was corrupted and could not be opened in excel.
Here is a copy of my code:
$email = new PHPMailer();
$email->From = 'my#email.address';
$email->addReplyTo('my#email.address');
$email->FromName = 'My Name';
$email->Subject = $reportName;
$email->Body = 'Here is your report good sir.';
$email->AddAddress('myother#test.email');
$fullPath = $_SERVER['DOCUMENT_ROOT'] . '/' . $reportName;
$email->addAttachment($fullPath, 'Session_Report.xlsx', 'base64',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$email->Send();
I would greatly appreciate any help you can provide!
It just so happens we have two files that are the exact same size that we some times try to send together. We can send anything else we want with these files but as soon as we include both of them it only sends the first one. I'll include my phpmailer code just to be safe but its worked thus far.
$mail = new PHPMailer(true);
$mail->IsSendMail();
$mail->SetFrom($from_addy, $from_name);
foreach(explode(',',$to) as $address1){
foreach(explode(';',$address1) as $address2){
if($address2 != ''){
$mail->AddAddress($address2);
}
}
}
$mail->WordWrap = 70;
$mail->IsHTML(true);
$mail->Subject = $subject;
$mail->Body = $css.$message;
$mail->AltBody = nl2br($message);
$mail->MsgHTML($css.$message);
if(is_array($attachments)){
foreach($attachments as $attachment){
$file = file_get_contents($attachment['tmp_name']);
$mail->AddStringAttachment($file,$attachment['name']);
// I have put checks here and both attachments do make it this far.
}
}
You're not checking the return value from addStringAttachment so you don't know if it's working or not. PHPMailer doesn't throw exceptions for everything, and while you've requested them, you're not catching them anyway. Why read the file and use addStringAttachment - why not read the attachment directly from the file with addAttachment? String attachments are more useful when you need to attach the results of a remote API call, PDF generation etc. Like this:
if (!$mail->addAttachment($attachment['tmp_name'], $attachment['name'])) {
echo "Failed to attach ".$attachment['tmp_name'];
}
Why are you using isSendmail()? It's unlikely you need that.
You've not presented any evidence that it's got anything to do with the file size - it's not as if attachments are indexed by their size value or anything.
You're setting AltBody before calling msgHTML(), which overwrites AltBody. Calling nl2br() on AltBody contents is pointless because AltBody will usually be presented as plain text, so <br> tags will show up.
It looks like your $attachment array may be sourced from $_FILES, in which case it looks you are handling file uploads unsafely. read the PHP docs on that, and look at the "send file upload" example provided with PHPMailer.
Overall, it looks like you've based your code on a very old PHPMailer example, so make sure you're using the latest version, and look at the examples provided with it.
I already tried several solutions, the closest (for me) should look like this:
$file = $pdf->Output('', 'E');
$message->attach(Swift_Attachment::newInstance($file, 'name.pdf', 'application/pdf'));
$pdf is an instance of TCPDF and $message is an instance of Swift_Message.
Using above the email is being sent ok, file is attached but when I try to open it I get the error message that file is corrupted or badly encoded.
My question is: how to send pdf generated by TCPDF as Swiftmailer attachment without saving the file to server and deleting it after sending the email. Here is the link to the TCPDF output method documentation, maybe somebody can see something I have missed.
I am using something like this and it is working. For the PDF content I am using one of the simplest examples on the PDF library.
[...]
$pdf_as_string = $pdf->Output('', 'S'); // $pdf is a TCPDF instance
[...]
$transport = Swift_MailTransport::newInstance(); // using php mail function
$message->setTo(array(
"client#customdomain.com" => "Main Email",
"client#publicdomain.com" => "Secondary Email"
));
$message->setSubject("This email is sent using Swift Mailer");
$message->setBody("You're our best client ever.");
$message->setFrom("developers#mydomain.com", "Developers United");
$attachment = Swift_Attachment::newInstance($pdf_as_string, 'my-file.pdf', 'application/pdf');
$message->attach($attachment);
[...]
Maybe this answer comes a little late since I am using swiftmailer v4_3_0 and TCPDF v6_0_002. But just in case is worth to someone.
I have had no problems attaching TCPDFs on the fly.
I call a function which eventually returns the PDF using the Output type 'S':
return $pdf->Output('TE_Invoice.pdf', 'S');
I attach the file using:
$message->attach(Swift_Attachment::newInstance()
->setFilename('TE_Invoice.pdf')
->setContentType('application/pdf')
->setBody($val['file']));
Where $val['file'] is the returned value from above.
I am using TCPDF Version: 5.9.134 and Swift Mailer Version: 4.1.3
You can use outputmode 'E' to get base64String.
$base64PdfString = $pdf->Output('', 'E');
Beware: Maybe you have to cut the first 5-6 lines, because of
Content-Type: application/pdf; name=""
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=""
Base64StringStartsHere....
cut
$base64PdfArray = explode("\r\n", $base64PdfString);
$base64 = '';
for($i = 5; $i < count($base64PdfArray); $i++) {
$base64 .= $base64PdfArray[$i];
}
Now you have the Email as base64String.
Before sending you have to decode it.
$mail->attach(new \Swift_Attachment(base64_decode($base64), 'Pdf.pdf', 'application/pdf'));
Did you try this?
$file = $pdf->Output('', 'S');
I'm doing this with another mail backend in PHP, and this does work. I guess the mail backend takes care of encoding the attachment, so there is no need to encode it as base64 manually.