getting blank pdf file attachment using phpmailer and mpdf - php

I'm using mPDF to generate PDF's when a button is clicked and the i save them inside a folder. I am looking for a way to add the PDF to an attachment using PHPmailer. Here is what I've tried:
$dir = $_SERVER['DOCUMENT_ROOT'].dirname($_SERVER['PHP_SELF']);
$pdfexist = $dir."/classes/pdf/feestructure_".$student['rollno'].".pdf";
$mail = new PHPMailer;
$mail->isSMTP();
$mail->From="xyz#abc.com";
$mail->FromName="xyz";
$mail->addAddress("xyz#abc.com");
//echo $email."<br/>";
$mail->addAddress("xyz#abc.com");
$mail->addAddress("xyz#abc.com");
$mail->Subject = 'XYZ';
$pdfstring = $pdfexist;
$mail->AddStringAttachment($pdfstring, "feestructure_".$roll.".pdf", $encoding = 'base64', $type = 'application/pdf');
The size of my generated pdf is 13k but its showing 1 k in mail attachment.help me guys.
Here is the output from mpdf:
$mpdf->WriteHTML(file_get_contents("$dir/feestructure_pdf.php?rollno=$rollno"));
$pdfname="feestructure_".$rollno.".pdf";
$mpdf->Output("classes/pdf/".$pdfname,"F");

Your $pdfexists / $pdfstring variable contains a file path, not binary PDF data, so you should be using AddAttachment(), not AddstringAttachment(). AddAttachment attaches files (like your PDF), AddStringAttachment attaches strings, like what you might get back from a web call or a database.
$mail->AddAttachment($pdfstring, "feestructure_".$roll.".pdf", $encoding = 'base64', $type = 'application/pdf');

Related

PHPmailer arabic attachment name issue

I use dompdf to generate a PDF file, Then I send it using PHPmailer. But the issue is that the file name of the generated PDF name is not correct.
Here is the code:
//PDF from dompdf
$pdf = $dompdf->output();
//PHPmailer confiurgation
$mail->IsSMTP();
$mail->CharSet = 'UTF-8';
//PDF name
$name = 'محمد احمد علي';
$pdfName = str_replace(" ", "_", $name); //Replace spaces with _
$pdfName .= ".pdf";
//Attach PDF
$mail->AddStringAttachment($pdf, $pdfName);
The PDf name should be محمد_احمد_علي.pdf in this case. But it's _احمد_علي.pdf
I tried:
$encoding = 'base64';
$type = 'application/pdf';
$mail->AddStringAttachment($pdf, $pdfName, $encoding, $type);
Also:
$mail->Encoding = "base64";
But no success.
I don't see that there is an issue with the string name, As when I run the following code:
$name = 'محمد علي احمد';
$name = str_replace(' ', "_", $name);
echo $name . '.pdf';
I get the expected result.
How to solve this issue?
Update
I just tried:
$dompdf->stream($filename);
To download the PDF without sending it. And it's the same result, So I don't know where the issue is coming from.
New Update
In case this happens to anyone in the future.
I found out why this is happening. Dompdf is using basename() on the file name. And with my Arabic name that function makes it go wrong like that.
It's really sad how programming languages and libraries are ignoring RTL languages like Arabic.
So running this code:
echo basename('محمد احمد علي');
Would return احمد علي

How to send fillable pdf (filled with pdftk) via PHPMailer?

I have a form on a website that customers fill. When user filles the form and clicks submit data is sent to a pdf(invoice) I've already created and certain spots in pdf are filled with that data. I did this using PDFTK library:
public function generate($data)
{
$filename = date("d-m-Y-His") . ".pdf";
$pdf = new Pdf('./form.pdf');
$pdf->fillForm($data)
->flatten()
->saveAs('./completed/' . $filename);
$path = './completed/' .$filename;
return $path;
}
The problem is, i dont know how to send this filled pdf via PHPMailer library, as pdf is recquired to be a string in order to work with phpmailer.
$pdf = new GeneratePDF;
$response = $pdf->generate($data);
$email = new PHPMailer();
$email->SetFrom('you#example.com', 'Your Name');
$email->Subject = 'Test';
$email->Body = 'Test';
$email->AddAddress( 'mail exmp' );
$email->AddAttachment( $response , 'NameOfFile.pdf' );
$email->Send();
And how to actually save file in cpanel server, as when i do this it doesnt work on a server.
pdf is recquired to be a string in order to work with phpmailer
This is not true. addAttachment() requires that you pass in a path to a local file on disk, so you could do:
$email->addAttachment(generate(), 'NameOfFile.pdf');
You can pass in a binary string using addStringAttachment(), but that's not what you're asking for here.

How add inline images in mailgun using PHP and image contents instead of path

I am trying to add an inline image to an email sent using the mailgun api using only the contents of the image file.
As far as i know mailgun-php only allows for paths to be specified in the inline element.
Is there a way to add images using their contents without modifying the mailgun-php library?
I've tried inlining the whole thing inside of html img tag but that doesn't work in all email clients (for instance gmail):
<img src="data:image/png;base64,BASE64CONTENTSHERE==" />
I have not found a way to do this without modifying the mailgun-php code so I eneded up using the following to store the file in the temporary folder.
$prefix = 'someprefix'; // Used to easily identify the file if needed
$filename = uniqid($prefix, true).'.png';
$path = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
$f = fopen($path, 'w');
fwrite($f, $binaryImageContent);
fclose($f);
Then to send the email and remove the temporary file
$mailgun = new \MailgunClient();
$response = $mailgun->sendEmail(
$fromEmail,
$replyTo,
array($toEmail),
$subject,
$html,
array(
'inline' => $path
)
);
unlink($path);
Below is what the MailgunClient class looks like, I had to explicitly set the Guzzle http client, since the default was failing. Note MAILGUN_API_KEY and MAILGUN_DOMAIN have to be set as constants somewhere else in the code using define('MAILGUN_API_KEY', 'key_here'); and define('MAILGUN_DOMAIN', 'domain.com');
<?php
use Mailgun\Mailgun;
class MailgunClient {
public function sendEmail($from, $replyTo, $to, $subject, $html, $inline = null) {
$client = new \Http\Adapter\Guzzle6\Client();
$mailgun = new \Mailgun\Mailgun(MAILGUN_API_KEY, $client);
$domain = MAILGUN_DOMAIN;
$params = array();
$params['from'] = $from;
$params['h:Reply-To'] = $replyTo;
$params['subject'] = $subject;
$params['text'] = $html;
$params['html'] = $html;
$params['inline'] = $inline;
$params['to'] = $to;
$mailgun->sendMessage($domain, $params, $inline);
}
}
Finally in the email use the following tag to reference the inlined image. The src attribute has to be cid:the_filename_created to match what the library outputs in the email.
<img src="cid:'.$filename.'.png" alt="logo" style="width:auto;height:150px;max-height:150px;"/>

edit docx file using phpword

is it possible to edit existing docx file using phpword?
i want to add footer text to my existing docx file.
there are lot of examples but those examples are creating the doc file from scratch not editing the file
can someone link to me an example? thank you
just like this.
<?php
require_once 'PHPWord.php';
// New Word Document
$PHPWord = new PHPWord();
// New portrait section
$section = $PHPWord->createSection();
// Add header
$header = $section->createHeader();
$table = $header->addTable();
$table->addRow();
$table->addCell(4500)->addText('This is the header.');
$table->addCell(4500)->addImage('_earth.jpg', array('width'=>50, 'height'=>50, 'align'=>'right'));
// Add footer
$footer = $section->createFooter();
$footer->addPreserveText('Page {PAGE} of {NUMPAGES}.', array('align'=>'center'));
// Write some text
$section->addTextBreak();
$section->addText('Some text...');
// Save File
$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save('HeaderFooter.docx');
?>
Yes you can edit.
From documentation
PHPWord is a library written in pure PHP that provides a set of
classes to write to and read from different document file formats. The
current version of PHPWord supports Microsoft Office Open XML (OOXML
or OpenXML), OASIS Open Document Format for Office Applications
(OpenDocument or ODF), and Rich Text Format (RTF).
Actually this is the procedure
Load our existing file as template.
Edit
Save
From the Documentation, I found an example,
<?php
include_once 'Sample_Header.php';
// Template processor instance creation
echo date('H:i:s'), ' Creating new TemplateProcessor instance...', EOL;
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('resources/Sample_07_TemplateCloneRow.docx');
// Variables on different parts of document
$templateProcessor->setValue('weekday', htmlspecialchars(date('l'))); // On section/content
$templateProcessor->setValue('time', htmlspecialchars(date('H:i'))); // On footer
$templateProcessor->setValue('serverName', htmlspecialchars(realpath(__DIR__))); // On header
// Simple table
$templateProcessor->cloneRow('rowValue', 10);
$templateProcessor->setValue('rowValue#1', htmlspecialchars('Sun'));
$templateProcessor->setValue('rowValue#2', htmlspecialchars('Mercury'));
$templateProcessor->setValue('rowValue#3', htmlspecialchars('Venus'));
$templateProcessor->setValue('rowValue#4', htmlspecialchars('Earth'));
$templateProcessor->setValue('rowValue#5', htmlspecialchars('Mars'));
$templateProcessor->setValue('rowValue#6', htmlspecialchars('Jupiter'));
$templateProcessor->setValue('rowValue#7', htmlspecialchars('Saturn'));
$templateProcessor->setValue('rowValue#8', htmlspecialchars('Uranus'));
$templateProcessor->setValue('rowValue#9', htmlspecialchars('Neptun'));
$templateProcessor->setValue('rowValue#10', htmlspecialchars('Pluto'));
$templateProcessor->setValue('rowNumber#1', htmlspecialchars('1'));
$templateProcessor->setValue('rowNumber#2', htmlspecialchars('2'));
$templateProcessor->setValue('rowNumber#3', htmlspecialchars('3'));
$templateProcessor->setValue('rowNumber#4', htmlspecialchars('4'));
$templateProcessor->setValue('rowNumber#5', htmlspecialchars('5'));
$templateProcessor->setValue('rowNumber#6', htmlspecialchars('6'));
$templateProcessor->setValue('rowNumber#7', htmlspecialchars('7'));
$templateProcessor->setValue('rowNumber#8', htmlspecialchars('8'));
$templateProcessor->setValue('rowNumber#9', htmlspecialchars('9'));
$templateProcessor->setValue('rowNumber#10', htmlspecialchars('10'));
// Table with a spanned cell
$templateProcessor->cloneRow('userId', 3);
$templateProcessor->setValue('userId#1', htmlspecialchars('1'));
$templateProcessor->setValue('userFirstName#1', htmlspecialchars('James'));
$templateProcessor->setValue('userName#1', htmlspecialchars('Taylor'));
$templateProcessor->setValue('userPhone#1', htmlspecialchars('+1 428 889 773'));
$templateProcessor->setValue('userId#2', htmlspecialchars('2'));
$templateProcessor->setValue('userFirstName#2', htmlspecialchars('Robert'));
$templateProcessor->setValue('userName#2', htmlspecialchars('Bell'));
$templateProcessor->setValue('userPhone#2', htmlspecialchars('+1 428 889 774'));
$templateProcessor->setValue('userId#3', htmlspecialchars('3'));
$templateProcessor->setValue('userFirstName#3', htmlspecialchars('Michael'));
$templateProcessor->setValue('userName#3', htmlspecialchars('Ray'));
$templateProcessor->setValue('userPhone#3', htmlspecialchars('+1 428 889 775'));
echo date('H:i:s'), ' Saving the result document...', EOL;
$templateProcessor->saveAs('results/Sample_07_TemplateCloneRow.docx');
echo getEndingNotes(array('Word2007' => 'docx'));
if (!CLI) {
include_once 'Sample_Footer.php';
}
Now see the lines of code given below , how to access existing header and footer
$headers = $section->getHeaders();
$header1 = $headers[1]; // note that the first index is 1 here (not 0)
$elements = $header1->getElements();
$element1 = $elements[0]; // and first index is 0 here normally
// for example manipulating simple text information ($element1 is instance of Text object)
$element1->setText("adding text here - old part: " . $element1->getText());
$footers = $section->getFooters(); // to access footer
You can find more examples here . If you want to add more styles, please read this page. And you can also see some recipes in their documentation.
In the footer of your file(template) docx, you can put a variable like this ${var1}.
Open a file as template with "TemplateProcessor".
$templateObject = new TemplateProcessor($filename);
Replace var1 variable in your file
$templateObject->setValue('var1', 'test');
Transform your template into a PhpWord
$fileName = $templateObject->save();
$phpWordObject = IOFactory::load($fileName);
unlink($fileName);
return $phpWordObject;
Save/Render your phpWord instance
// create the writer
$writer = $this->wordService->createWriter($phpWordObject, 'Word2007');
// create the response
$response = $this->wordService->createStreamedResponse($writer);
// adding headers
$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'export.docx'
);
$response->headers->set('Content-Type', 'application/msword');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
$response->headers->set('Content-Disposition', $dispositionHeader);
Might be useful for Laravel 5 users. You can use this in your controllers.
public function wordDocumentFromWordTemplate() {
$templateFile = public_path('templates') . '/template-file.docx';
$templateObject = new TemplateProcessor($templateFile);
$templateObject->setValue('var1', 'Text for var1');
$wordDocumentFile = $templateObject->save();
$headers = [
'Content-Type' => 'application/msword',
'Cache-Control' => 'max-age=0'
];
return response()->download($wordDocumentFile, 'result.docx', $headers);
}

Edit .doc or .docx file using php

I have to modify the uploaded .doc or .docx file in php. I googled but i only found how to read that. I want the word file as it is and put text at the bottom of that MS Word file at run time. How is this possible anyone know please reply or give me example script.
Thanks,
I'm the developer of PHPWord. You can use the PHPWord_Template Class to open an existing DOCX File and then replace some text marks with your individual text.
Alternatively you can open the DOCX file with the ZipArchive extension and then read/write every xml File (document.xml, header.xml, footer.xml, ...) you want. This method is nothing else than the PHPWord_Template class. ;)
You can use PHPWord.
I have same requirement for Edit .doc or .docx file using php and i have find solution for it.
And i have write post on It :: http://www.onlinecode.org/update-docx-file-using-php/
if($zip_val->open($full_path) == true)
{
// In the Open XML Wordprocessing format content is stored.
// In the document.xml file located in the word directory.
$key_file_name = 'word/document.xml';
$message = $zip_val->getFromName($key_file_name);
$timestamp = date('d-M-Y H:i:s');
// this data Replace the placeholders with actual values
$message = str_replace("client_full_name", "onlinecode org", $message);
$message = str_replace("client_email_address", "ingo#onlinecode.org", $message);
$message = str_replace("date_today", $timestamp, $message);
$message = str_replace("client_website", "www.onlinecode.org", $message);
$message = str_replace("client_mobile_number", "+1999999999", $message);
//Replace the content with the new content created above.
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
}
You only replace the predefined variables.
In the following code
https://github.com/PHPOffice/PHPWord
I also did this problem in phpword using the following code
if(!file_exists('file/word.docx')){
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('demo.docx');
$templateProcessor->setValue('name', 'Akbarali');
$templateProcessor->setValue('time','13.02.2021');
$templateProcessor->setValue('month', 'January');
$templateProcessor->setValue('state','Uzbekistan');
$templateProcessor->saveAs('file/word.docx');
}
This will change the words in the demo.docx file. The new file is then saved in the word.docx file folder.
you can define variables in the form of ${name} in the demo word file.
that is, ${name}, ${time}, ${month} and ${state}
In this post we will show you How to update docx file using php, hear for How to update docx file using php we will give you demo and example for implement.
Hear we will show you how to Edit .doc or .docx file using php. Hear we use “client_full_name”, “client_email_address”, “date_today”, “client_website”, “client_mobile_number” in .doc or .docx files
$template_file_name = 'template.docx';
$rand_no = rand(111111, 999999);
$fileName = "results_" . $rand_no . ".docx";
$folder = "results_";
$full_path = $folder . '/' . $fileName;
try
{
if (!file_exists($folder))
{
mkdir($folder);
}
//Copy the Template file to the Result Directory
copy($template_file_name, $full_path);
// add calss Zip Archive
$zip_val = new ZipArchive;
//Docx file is nothing but a zip file. Open this Zip File
if($zip_val->open($full_path) == true)
{
// In the Open XML Wordprocessing format content is stored.
// In the document.xml file located in the word directory.
$key_file_name = 'word/document.xml';
$message = $zip_val->getFromName($key_file_name);
$timestamp = date('d-M-Y H:i:s');
// this data Replace the placeholders with actual values
$message = str_replace("client_full_name", "onlinecode org", $message);
$message = str_replace("client_email_address", "ingo#onlinecode", $message);
$message = str_replace("date_today", $timestamp, $message);
$message = str_replace("client_website", "www.onlinecode", $message);
$message = str_replace("client_mobile_number", "+1999999999", $message);
//Replace the content with the new content created above.
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
}
}
catch (Exception $exc)
{
$error_message = "Error creating the Word Document";
var_dump($exc);
}
Try having a look at http://www.tinybutstrong.com/ as it can create and edit Word documents, we use it in a mail merge style for generating invoices in doc and pdf.
Some of these answers dont contain the full steps so here is what ive done:
Create your word document. With in this document anything you want to replace with PHPWORD mark it like this -> ${variable_name} so for example ${value1}
$file = "docs/input/word/source.docx";
$output_file = "docs/input/word/modified.docx";
$PHPWord = new \PhpOffice\PhpWord\PhpWord();
$document = $PHPWord->loadTemplate($file);
$document->setValue('value1', 'Enter Your Text Here');
$document->saveAs($output_file);

Categories