0

please help me out of sending an email with a PDF attachment.

1
$inlineTranslation = $objectManager->create('\Magento\Framework\Translate\Inline\StateInterface');

    $transport = $transportBuilder->setTemplateIdentifier($USPSlabelemailtemplateid) // My email template
                        ->setTemplateOptions( [
                            'area' => \Magento\Framework\App\Area::AREA_FRONTEND, 
                            'store' => $storeid,
                        ])
                        ->setTemplateVars($finalerrormsgtosendemail)
                        ->setFrom('general')
                        ->addTo($_shippingLabel['SenderEmail'])
                        ->addBcc($generalemail)
                        ->getTransport();

              $html= $transport->getMessage()->getBody()->generateMessage();            
                          $bodyMessage = new \Zend\Mime\Part($html);
                          $bodyMessage->type = 'text/html';
                          $attachment=$transportBuilder->attachFile(file_get_contents($pdfFile),'ReturnLabel.pdf');      
                          $bodyPart = new \Zend\Mime\Message();
                          $bodyPart->setParts(array($bodyMessage,$attachment));
                          $transport->getMessage()->setBody($bodyPart);                
                          $transport->sendMessage();
                          $inlineTranslation->resume();

and override the file in di.xml

     <preference for="\Magento\Framework\Mail\Template\TransportBuilder" type="vendor\module\Model\Mail\TransportBuilderemail" />

In vendor\module\Model\Mail\TransportBuilderemail.php create a function like below
public function attachFile($file, $name) {      
$attachment = new \Zend\Mime\Part($file);
$attachment->type = 'application/pdf';
$attachment->disposition = \Zend_Mime::DISPOSITION_ATTACHMENT;
$attachment->encoding = \Zend_Mime::ENCODING_BASE64;
$attachment->filename = $name;
return $attachment;
}

That's it and now pdf file will be attached in email's.

  • Thanks, Sundeep – P Ramulu Sep 12 at 4:57
0

You need to do some basic steps like:

Step 1: create an email_templates.xml file in app/code/OSCP/Module/etc folder with the following content.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
   <template id="sales_email_oscp_accounting_customer_email" label="Customer Report" file="email_report.html" type="html" module="OSCP_Module" area="frontend"/>
</config>

Step 2: Create a template file in the path app/code/OSCP/Module/view/frontend/email/email_report.html and the content for email can be added by declaring the template variables from the action file.

<!--@subject Customer Credit Application@-->
<!--@vars {
"var data.email":"Sender Email",
"var data.name":"Sender Name"
} @-->
{{template config_path="design/email/header_template"}}

<ul>
   <li>
       <strong>Customer Details:</strong>
       <div>
           <p>{{trans “Name:  %name" name=$templateParams.name}}</p>
           <p>{{trans “Email:  %Email" Email=$templateParams.email}}</p>
       </div>
   </li>
</ul>

Step 3: The created email template can be configured from the admin by creating the system.xml file. Add a file system.xml with the following code in the path app/code/OSCP/Module/etc/adminhtml/. This will hold a default value for email template which will be defined in config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
   <system>
       <section id="section_id" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
           <group id="group_id" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
               <field id="field_id" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                   <label>Label to your field</label>
                   <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
               </field>
           </group>
       </section>
   </system>
</config>

{{template config_path="design/email/footer_template"}}

we are using the ‘Sales’ section in the back end where the email template for the credit email can be configured. The section id is going to be ‘sales_email’, under which a separate group with group id as ‘oscp_accounting’ will be created and labeled it as ‘OSCP Accounting’.

It’s time to create a field under the group with the field id as ‘credit_email_template’.

Also, there is one more field from which the receiver email (Accounting email ) could be configured with the field id as copy_to_accounting. The email id can be validated while saving the configuration, provided that required-entry validate-email is given.

The field created will be given with the source model ‘Magento\Config\Model\Config\Source\Email\Template’ with the all available email templates. The source model is a model of data that we can use for configuration.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
   <system>
       <section id="sales_email" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
           <group id="oscp_accounting" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
               <label>OSCP Accounting</label>
               <field id="customer_credit_email" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                   <label>Credit Application Email to Accounting</label>
                   <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
               </field>
               <field id="copy_to_accounting" translate="label comment" type="text" sortOrder="111" showInDefault="1" showInWebsite="1" showInStore="1">
                   <label>Send Email To Accounting</label>
                   <validate>required-entry validate-email</validate>
               </field>
           </group>
       </section>
   </system>
</config>

Step 4: Create a config.xml file in the path app/code/OSCP/Module/etc/ for setting the default template value (i.e., email_report.html as default) in the admin custom field that has been created using system.xml.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
   <default>
       <section_id>
           <group_id>
               <field_id>section_id_group_id_field_id</field_id>
           </group_id>
       </section_id>
   </default>
</config>

Step 5: Once the code for the email template and the configuration file has been added it’s time to formulate the email send function in the helper class as follows in path app/code/OSCP/Module/Helper/Emailreport.php. The following code will be able to send the pdf attachments in the email if the path of the PDF file path is defined.

The function sendEmailReport is responsible for sending the email. This function can be used from any of the actions for sending the email with the pdf file or without the pdf file.

<?php
/**
 * @author OSCP Team
 * @copyright Copyright (c) 2019 OSCP (https://www.oscprofessionals.com)
 * @package OSCP_Module
 */

namespace OSCP\Module\Helper;

use Magento\Framework\App\Area;

/**
 * Class Emailreport
 * @package OSCP\Module\Helper
 */
class Emailreport extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;
    /**
     * @var \Magento\Framework\Translate\Inline\StateInterface
     */
    private $inlineTranslation;
    /**
     * @var \Magento\Framework\Mail\Template\TransportBuilder
         */
        private $transportBuilder;
        /**
         * @var \Magento\Framework\Filesystem\Directory\Read
         */
        private $reader;

        /**
         * Emailreport constructor.
         * @param \Magento\Framework\App\Helper\Context $context
         * @param \Magento\Store\Model\StoreManagerInterface $storeManager
         * @param \Magento\Framework\Translate\Inline\StateInterface         $inlineTranslation
         * @param \Magento\Framework\Mail\Template\TransportBuilder     $transportBuilder
         * @param \Magento\Framework\Filesystem\Driver\File $reader
         */
        public function __construct(
            \Magento\Framework\App\Helper\Context $context,
            \Magento\Store\Model\StoreManagerInterface $storeManager,
            \Magento\Framework\Translate\Inline\StateInterface     $inlineTranslation,
                \Magento\Framework\Mail\Template\TransportBuilder     $transportBuilder,
            \Magento\Framework\Filesystem\Driver\File $reader
        ) {
            parent::__construct($context);
            $this->storeManager = $storeManager;
            $this->inlineTranslation = $inlineTranslation;
            $this->transportBuilder = $transportBuilder;
            $this->reader = $reader;
        }

        /**
         * @param $path
     * @param $storeId
     * @return mixed
     */
    public function getConfigValue($path, $storeId)
    {
        return $this->scopeConfig->getValue(
            $path,
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }

    /**
     * @return \Magento\Store\Api\Data\StoreInterface
     */
    public function getStore()
    {
        return $this->storeManager->getStore();
    }

    /**
     * @param $template
     * @param $senderInfo
     * @param $receiverInfo
     * @param array $templateParams
     * @param null $pdfFile
     * @return $this
     */
    public function sendEmailReport(
        $template,
        $senderInfo,
        $receiverInfo,
        $templateParams = [],
        $pdfFile = null
    ) {
        $this->inlineTranslation->suspend();
        $templateId = $this->getConfigValue($template, $this->getStore()->getStoreId());
        if ($pdfFile) {
            $transport =     $this->transportBuilder->setTemplateIdentifier($templateId)
                ->setTemplateOptions(
                    [
                        'area' => Area::AREA_FRONTEND,
                        'store' => $this->getStore()->getId(),
                    ]
                )
                ->setTemplateVars($templateParams)
                ->setFrom($senderInfo)
                ->addTo($receiverInfo['email'], $receiverInfo['name'])
                ->addAttachment($this->reader->fileGetContents($pdfFile), 'Credit Application')
                ->getTransport();
        } else {
            $transport =     $this->_transportBuilder->setTemplateIdentifier($templateId)
                ->setTemplateOptions(
                    [
                        'area' => Area::AREA_FRONTEND,
                        'store' => $this->getStore()->getId(),
                    ]
                )
                ->setTemplateVars($templateParams)
                ->setFrom($senderInfo)
                ->addTo($receiverInfo['email'], $receiverInfo['name'])
                ->getTransport();
        }
        $transport->sendMessage();
        $this->inlineTranslation->resume();

        return $this;
    }
}

Step 6: If your email has the requisite for attachment of pdf file then the following file has to be built in…app/code/OSCP/Module/Model/Mail/TransportBuilder.php. Magento uses Magento\Framework\Mail\Template\TransportBuilder to send email in which adding attachment has not been supported yet. Hence we are overriding the class in our custom module.

<?php

namespace OSCP\Module\Model\Mail;

/**
* Class TransportBuilder
* @package OSCP\Module\Model\Mail
*/
class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
   /**
    * @param string $pdfString
    * @param string $filename
    * @return mixed
    */
   public function addAttachment($pdfString, $filename)
   {
       If ($filename == '') {
           $filename="attachment";
       }
       $this->message->createAttachment(
           $pdfString,
           'application/pdf',
           \Zend_Mime::DISPOSITION_ATTACHMENT,
           \Zend_Mime::ENCODING_BASE64,
           $filename.'.pdf'
       );
       return $this;
   }
}

Step 7: Add di.xml in the file path app/code/OSCP/Module/etc/di.xml to set the preference to our custom TransportBuilder class for the core TransportBuilder.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <preference for="Magento\Framework\Mail\Template\TransportBuilder" type="OSCP\Module\Model\Mail\TransportBuilder"/>

Step 8:It’s all set now! We will be able to send an email to accounting team with the pdf file attached by the customer.

The following snippet can be added in any action from which the email has to be sent. Declare the template path in a variable as follows

<?php
namespace OSCP\Module\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use OSCP\Module\Helper\Emailreport;
use Magento\Framework\Filesystem;

class CreditEmail extends Template
{
    /* A constant is declared with custom field in admin created using system.xml */

    const XML_PATH_CUSTOM_EMAIL_TEMPLATE= 'sales_email/oscp_accounting/customer_credit_email';   // section_id/group_id/field_id

    private $emailReport;
    private $fileSystem;

    public function __construct(
    Context $context,
    Emailreport $emailReport,
    Filesystem $fileSystem,
    array $data = []
){
    $this->emailReport = $emailReport;
    $this->fileSystem = $fileSystem;
    parent::__construct($context, $data);
}


public function sendEmailReport()
    {
        /* Sender Detail */
        $senderInfo = [
            'name' => 'sender',
            'email' => 'sender@domain.com'
        ];

        /* Receiver Detail */
        $receiverInfo = [
            'name' => 'receiver',
            'email' => 'receiver@domain.com'
        ];

        /* To assign the values to template variables */

        $customerName = $receiverInfo['name'];
        $customerEmail = $receiverInfo['email'];

        $customerDetails = [];
        $customerDetails['name'] = $customerName;
        $customerDetails['email'] = $customerEmail;

            /* The Pdf file path has to be assigned to the variable for the     email attachment*/

            $mediaPath = $this->fileSystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)
                ->getAbsolutePath();
            $pdf_file = $mediaPath.'pdfFileName.pdf';

            $this->emailReport->sendEmailReport(
                self::XML_PATH_CUSTOM_EMAIL_TEMPLATE,
                $senderInfo,
            $receiverInfo,
            $customerDetails,
            $pdf_file
        );
    }
}

Beacuse of all this steps you are able to attach PDF File in Email.

  • Hi, Where u have defined createAttachment function? – gajjala sandeep Sep 11 at 9:06
  • addAttachment Function is here in Step no: 06, Path: OSCP\Module\Model\Mail\TransportBuilder.php – Oscprofessionals Sep 11 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.