Posting in the Magento forums has been disabled pending the implementation of a new and improved forum solution which should better serve the community.

For new questions please post at magento.stackexchange.com, the community-run support site for the Magento community. We will be providing updates on the new forum solution soon. For questions or concerns please email community@magento.com.

Magento Forum

Page 1 of 5
Trying to add a PDF attachment to the order email…PLEASE HELP!!! 
 
Lance Monotone
Member
 
Avatar
Total Posts:  63
Joined:  2008-04-16
North Adams, MA. 01247
 

Hi all,

I’ve been at this for 5 days and thirty thousand and two different ways and nothing seems to work.  I’m trying to attach a packing slip PDF to a packing slip email that is send to the store admin when a new order is placed.  I don’t know if the problem is with me (probably) or with Zend_Pdf or with Zend_Mail or with Magento.

I have customized a couple of methods and saved them in my code/local directory…

Mage/Sales/Model/Order.php

I tweaked the method to add the packing slip template, guest packing slip template and admin email.  I also added a couple of parameters to the Template->sendTransactional method, which I’ve shown below.  This is just background in case you were wondering where the next method gets its values.  This all seems to work fine.  I can send the packing slip email to the store admin.  I just can’t attach anything to it.

Mage/Core/Model/Email/Template.php

It’s the last method that does the heavy lifting, specifically between the /*** ATTACH PDF ***/ tags.  There are a couple of things happening (or not) here. 

1. I’ve tried to create a Zend_Pdf document based on the text of the packing slip email (which I am able to generate if I don’t attempt the attachment)
2. I’ve tried to attach it to the Zend_Mail message.

What happens is that when I attempt an order without the attachment code, I get the order confirmation email and packing slip email with no problems, and the onepage checkout goes on to the success page.  All good.

However, if I attempt to do anything else to this method, my checkout attempt returns an alert dialog that either says ‘undefined’ or ‘There was a problem with your order...try again (or words to that effect),’ and only the order confirmation email comes through BUT the checkout page remains.  The order IS processed by both Magento and Authorize.net, but the success page isn’t displayed. It’s as if either the PDF or attachment called a die() but there are no error messages so I can’t tell what’s happening.

My functions are below.  The third post by me in this thread has the relevant code I’m having problems with.  The other two are so you can follow along at home.  They seem to work fine.

My questions are:

1. What is the relationship between the order confirmation email and the success page?  If the order is successfully processed why wouldn’t the success page be displayed?  I think this might be a bug, or at least bad logic.

2. Am I doing something wrong in my usage of the PDF or Mail classes?

 
Magento Community Magento Community
Magento Community
Magento Community
 
Lance Monotone
Member
 
Avatar
Total Posts:  63
Joined:  2008-04-16
North Adams, MA. 01247
 

Mage/Sales/Model/Order.php

/**
     * Sending email with order data
     *
     * @return Mage_Sales_Model_Order
     */
     public function sendNewOrderEmail()
     
{
          $itemsBlock 
Mage::getBlockSingleton('sales/order_email_items')->setOrder($this);
          
$shipItemsBlock Mage::getBlockSingleton('sales/order_email_shipitems')->setOrder($this);

          
$paymentBlock Mage::helper('payment')->getInfoBlock($this->getPayment())
          ->
setIsSecureMode(true);

          
$vars = array(
               
'order'             => $this,
               
'billing'           => $this->getBillingAddress(),
               
'payment_html'      => $paymentBlock->toHtml(),
               
'items_html'        => $itemsBlock->toHtml(),
               
'shipitems_html'    => $shipItemsBlock->toHtml(),
          );

          
/* @var $mailTemplate Mage_Core_Model_Email_Template */
          
$mailTemplate Mage::getModel('core/email_template');

          if (
$bcc $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO)) {
               $mailTemplate
->addBcc($bcc);
          
}

          
if ($this->getCustomerIsGuest()) {
               $template 
Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE$this->getStoreId());
               
$shiptemplate Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_SHIP_TEMPLATE$this->getStoreId());
               
$customerName $this->getBillingAddress()->getName();
          
else {
               $template 
Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE$this->getStoreId());
               
$shiptemplate Mage::getStoreConfig(self::XML_PATH_EMAIL_SHIP_TEMPLATE$this->getStoreId());
               
$customerName $this->getCustomerName();
          
}

          $mailTemplate
->setDesignConfig(array('area'=>'frontend''store'=>$this->getStoreId()));

          
//sendTransactional($templateId, $shipTemplateId, $sender, $email, $adminEmail, $name, $vars=array(), $storeId=null)
          
$mailTemplate->sendTransactional(
               
$template,
               
$shiptemplate,  //packing slip template
               
Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY$this->getStoreId()),
               
$this->getCustomerEmail(),
               
Mage::getStoreConfig(self::XML_PATH_EMAIL_SHIP_COPY_TO$this->getStoreId()), //admin email
               
$customerName,
               
$vars
          
);
          return 
$this;
     
}

Mage/Core/Model/Email/Template.php

public function sendTransactional($templateId$shipTemplateId$sender$email$adminEmail$name$vars=array(), $storeId=null)
     
{
          
if (is_null($storeId)) {
               $storeId 
Mage::app()->getStore()->getId();
          
}

          
/*** Send Order Confirmation to Customer ***/

          /*$templateId = Mage::getStoreConfig("trans_email/trans_{$transCode}/template", $storeId);
          $identity = Mage::getStoreConfig("trans_email/trans_{$transCode}/identity", $storeId);*/
          
if (is_numeric($templateId)) {
               $this
->load($templateId);
          
else {
               $this
->loadDefault($templateId);
          
}

          
if (!$this->getId()) {
               
//foreach (debug_backtrace() as $i=>$step) {
               //    echo "[$i] {$step['file']}:{$step['line']}\n";
               //}
               
throw Mage::exception('Mage_Core'Mage::helper('core')->__('Invalid transactional email code: '.$templateId));
          
}
          
if (!is_array($sender)) {
               $this
->setSenderName(Mage::getStoreConfig('trans_email/ident_'.$sender.'/name'$storeId));
               
$this->setSenderEmail(Mage::getStoreConfig('trans_email/ident_'.$sender.'/email'$storeId));
          
else {
               $this
->setSenderName($sender['name']);
               
$this->setSenderEmail($sender['email']);
          
}

          $this
->send($email$name$vars);

          
/*** Send Packing Slip to Admin ***/

          
if (is_numeric($shipTemplateId)) {
               $this
->load($shipTemplateId);
          
else {
               $this
->loadDefault($shipTemplateId);
          
}

          
if (!$this->getId()) {
               
//foreach (debug_backtrace() as $i=>$step) {
               //    echo "[$i] {$step['file']}:{$step['line']}\n";
               //}
               
throw Mage::exception('Mage_Core'Mage::helper('core')->__('Invalid transactional email code: '.$templateId));
          
}
          
if (!is_array($sender)) {
               $this
->setSenderName(Mage::getStoreConfig('trans_email/ident_'.$sender.'/name'$storeId));
               
$this->setSenderEmail(Mage::getStoreConfig('trans_email/ident_'.$sender.'/email'$storeId));
          
else {
               $this
->setSenderName($sender['name']);
               
$this->setSenderEmail($sender['email']);
          
}

          $attachPDF 
true;

          
$this->send($adminEmail[1]$name$vars$attachPDF);

          return 
$this;
     
}
 
Magento Community Magento Community
Magento Community
Magento Community
 
Lance Monotone
Member
 
Avatar
Total Posts:  63
Joined:  2008-04-16
North Adams, MA. 01247
 

Mage/Core/Model/Email/Template.php

public function send($email$name=null, array $variables = array(), $attachPDF=false)
     
{
          
if(!$this->isValidForSend()) {
               
return false;
          
}

          
if (is_null($name)) {
               $name 
substr($email0strpos($email'@'));
          
}

          $variables[
'email'$email;
          
$variables['name'$name;

          
ini_set('SMTP'Mage::getStoreConfig('system/smtp/host'));
          
ini_set('smtp_port'Mage::getStoreConfig('system/smtp/port'));

          
$mail $this->getMail();
          if (
is_array($email)) {
               
foreach ($email as $emailOne{
                    $mail
->addTo($emailOne$name);
               
}
          }
          
else {
               $mail
->addTo($email$name);
          
}

          $this
->setUseAbsoluteLinks(true);
          
$text $this->getProcessedTemplate($variablestrue);

          
/*** BEGIN PDF ATTACHMENT ***/

          //if the email should include a PDF attachment of itself...
          
if($attachPDF){

               
//get Order Id
               
$orderID $variables['order']->getRealOrderId();

               
//instantiate Zend_Pdf
               
$pdf = new Zend_Pdf();

               
//parse processed email text to PDF
               
$pdf->parse($text);

               
//create a Zend_Mail attachment from the rendered PDF string
               
$at $mail->createAttachment($pdf->render());

               
//set the attachment type as PDF
               
$at->type 'application/pdf';

               
//set the fileame
               
$at->filename 'Order_'.$orderID.'.pdf';
          
}

          
/*** END PDF ATTACHMENT ***/

          
$mail->setSubject($this->getProcessedTemplateSubject($variables));
          
$mail->setFrom($this->getSenderEmail(), $this->getSenderName());

          if(
$this->isPlain()) {
               $mail
->setBodyText($text);
          
else {
               $mail
->setBodyHTML($text);
          
}
          
try {
               $mail
->send(); // Zend_Mail warning..
               
$this->_mail null;
          
}
          
catch (Exception $e{
               
return false;
          
}

          
return true;
     
}
 
Magento Community Magento Community
Magento Community
Magento Community
 
RPGShop
Sr. Member
 
Total Posts:  143
Joined:  2008-06-16
 

Not directly releated, but I stumbled on this post and wondered if this could help me with an issue I have. I would like to add a line of text to the email invoice sent to the customer after checkout that would include a discount link/coupon for a free PDF version of the book they bought. So I’d like to know how to tell when a specific product is sold and how to add to that invoice template.

James
http://www.rpgshop.com

 
Magento Community Magento Community
Magento Community
Magento Community
 
Lance Monotone
Member
 
Avatar
Total Posts:  63
Joined:  2008-04-16
North Adams, MA. 01247
 

After days of working on this, I’ve discovered that Zend_Pdf doesn’t work with HTML.  You have to build the PDF from scratch, which is more work than it’s worth and not easy to edit if you want to change the design.

I’ve had a tease from one of the forum people who said they’ve been able to create a PDF using the third-party DOMPDF library with Magento, which I’ve used before, and which is really easy to use.  I tried calling it directly from the /lib directory but I couldn’t load the class, and unfortunately I think the person is full of it because they haven’t posted any code to back up their claim.

I’ve not found a solution to this yet but if you do, please post it here so we can benefit.  I’ll help out where I can, as I do have some experience with DOMPDF itself (not that it’s very hard to figure out).

 
Magento Community Magento Community
Magento Community
Magento Community
 
zarya
Jr. Member
 
Total Posts:  2
Joined:  2008-09-24
 

Lance

I am trying to add a custom pdf to the email classes
in the latest version today did u ever get this all working or did you stoped trying
i am hoping to use your code examples for creating the custom pdf

Rudy

 
Magento Community Magento Community
Magento Community
Magento Community
 
Georges@Bitbol
Sr. Member
 
Avatar
Total Posts:  104
Joined:  2008-08-07
Paris, France
 

I have to attach invoice pdf visible in backend in email send for every invoice created.
Did u succeed in ?

Thx in advance

 
Magento Community Magento Community
Magento Community
Magento Community
 
zarya
Jr. Member
 
Total Posts:  2
Joined:  2008-09-24
 

I did not succeeded i left this the way is was and tried something else

Greetz

 
Magento Community Magento Community
Magento Community
Magento Community
 
flmag
Member
 
Total Posts:  49
Joined:  2008-12-08
 

app/code/core/Mage/Core/Model/Email/Template.php

$mail->setSubject('=?utf-8?B?'.base64_encode($this->getProcessedTemplateSubject($variables)).'?=');
        
$mail->setFrom($this->getSenderEmail(), $this->getSenderName());

        
//working attachement example
 
[color=red]
        $file 
file_get_contents('http://192.168.100.2/magentotest/1.1/LICENSE.txt');
        
$attachment $mail->createAttachment($file);
    
$attachment->filename 'test.txt';
[/color]
        
try {
            $mail
->send(); // Zend_Mail warning..
            
$this->_mail null;
        
}
I’ll try to get it to work for specific cases(only for orders for example)
 
Magento Community Magento Community
Magento Community
Magento Community
 
flmag
Member
 
Total Posts:  49
Joined:  2008-12-08
 

I managed to attach invoice, creditmemo and shipments to outgoing mail using the pdf models in the Sales module
For order attachment I created a custom model for pdf (not present in magento)
If someone is still interested in this please reply and I’ll post my work here.
PS: I couldn’t test yet for checkout because of a problem with my magento installation(checkout didn’t work from the beginning) but it works well for notifications from the back office

 
Magento Community Magento Community
Magento Community
Magento Community
 
James Hayton
Jr. Member
 
Total Posts:  28
Joined:  2008-09-22
 

I think I would be interested for sure.  Please post if you don’t mind.  Thanks!

 
Magento Community Magento Community
Magento Community
Magento Community
 
flmag
Member
 
Total Posts:  49
Joined:  2008-12-08
 

I created a new module for this but you can overwrite directly in the magento files just to test if it works
1. In mage/core/model/email/template.php add this method at the end of the file:

public function addAttachment(Zend_Pdf $pdf){
        $file 
$pdf->render();
        
$attachment $this->getMail()->createAttachment($file);
        
$attachment->type 'application/pdf';
    
$attachment->filename 'test.pdf';
    
}

...

 
Magento Community Magento Community
Magento Community
Magento Community
 
flmag
Member
 
Total Posts:  49
Joined:  2008-12-08
 

2 In sales/model/order/Invoice.php add the code between comments(2 lines of code) to the function sendEmail like this:

public function sendEmail($notifyCustomer=true$comment='')
    
{
        
if (!Mage::helper('sales')->canSendNewInvoiceEmail($this->getOrder()->getStore()->getId())) {
            
return $this;
        
}

        $currentDesign 
Mage::getDesign()->setAllGetOld(array(
            
'package' => Mage::getStoreConfig('design/package/name'$this->getStoreId()),
            
'store'   => $this->getStoreId()
        ));

        
$translate Mage::getSingleton('core/translate');
        
/* @var $translate Mage_Core_Model_Translate */
        
$translate->setTranslateInline(false);

        
$order  $this->getOrder();
        
$copyTo $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
        
$copyMethod Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD$this->getStoreId());

        if (!
$notifyCustomer && !$copyTo{
            
return $this;
        
}

        $paymentBlock   
Mage::helper('payment')->getInfoBlock($order->getPayment())
            ->
setIsSecureMode(true);

        
$mailTemplate Mage::getModel('core/email_template');

        if (
$order->getCustomerIsGuest()) {
            $template 
Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE$order->getStoreId());
            
$customerName $order->getBillingAddress()->getName();
        
else {
            $template 
Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE$order->getStoreId());
            
$customerName $order->getCustomerName();
        
}

        
///////
        ///////  Attachment here
         
$pdf Mage::getModel('sales/order_pdf_invoice')->getPdf(array($this));
    
$mailTemplate->addAttachment($pdf);
    
///////
        ///////

        
if ($notifyCustomer{
            $sendTo[] 
= array(
                
'name'  => $customerName,
                
'email' => $order->getCustomerEmail()
            );
            if (
$copyTo && $copyMethod == 'bcc'{
                
foreach ($copyTo as $email{
                    $mailTemplate
->addBcc($email);
                
}
            }

        }

        
if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
            
foreach ($copyTo as $email{
                $sendTo[] 
= array(
                    
'name'  => null,
                    
'email' => $email
                
);
            
}
        }

        
foreach ($sendTo as $recipient{
            $mailTemplate
->setDesignConfig(array('area'=>'frontend''store'=>$order->getStoreId()))
                ->
sendTransactional(
                    
$template,
                    
Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY$order->getStoreId()),
                    
$recipient['email'],
                    
$recipient['name'],
                    array(
                        
'order'       => $order,
                        
'invoice'     => $this,
                        
'comment'     => $comment,
                        
'billing'     => $order->getBillingAddress(),
                        
'payment_html'=> $paymentBlock->toHtml(),
                    )
                );
        
}

        $translate
->setTranslateInline(true);

        
Mage::getDesign()->setAllGetOld($currentDesign);

        return 
$this;
    
}

now when you create an invoice from the back office and you select to notify customer a pdf attachment should be sent as well

 
Magento Community Magento Community
Magento Community
Magento Community
 
flmag
Member
 
Total Posts:  49
Joined:  2008-12-08
 

Modifying sales/model/order/Shipment.php and Creditmemo.php the same way as in step 2 should work the same way for creating creditmemos and shipments

///////
        ///////
         $pdf Mage::getModel('sales/order_pdf_creditmemo')->getPdf(array($this));
        
$mailTemplate->addAttachment($pdf);
        
///////
        ///////
///////
        ///////
         $pdf Mage::getModel('sales/order_pdf_shipment')->getPdf(array($this));
        
$mailTemplate->addAttachment($pdf);
        
///////
        ///////
 
Magento Community Magento Community
Magento Community
Magento Community
 
flmag
Member
 
Total Posts:  49
Joined:  2008-12-08
 

Let me now if it worked for you
Good luck wink

 
Magento Community Magento Community
Magento Community
Magento Community
 
apitronic
Jr. Member
 
Total Posts:  27
Joined:  2008-12-14
France
 

Many thanks flmag !

It works very whell for me smile

I have add filename to your addAttachment function, and I use Invoice number to build filename :

$pdf Mage::getModel('sales/order_pdf_invoice')->getPdf(array($this));
$mailTemplate->addAttachment($pdf"INVOICE_".$this->getIncrementId().".pdf");

Thanks again !

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
Back to top
Page 1 of 5