Home > Software design >  How to send email with attachement in Magento 2.4
How to send email with attachement in Magento 2.4

Time:07-30

I am new to Magneto. and i searched and tried different solution online but they didn't work. I have an observer from which I generate CSV file whenever a customer place an order. I'm using <sales_order_place_after> to get it triggered. now i want to add the code to send the email with the generated CSV file in attachment to the customer. What's the way to do this in Magento 2.4. the solution i found online is not working. I want to add the code in the execute(\Magento\Framework\Event\Observer $observer) function of this file.


    public function __construct(
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Sales\Model\Order $order,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        Filesystem $filesystem,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Customer\Model\Customer $customer,
        \Magento\Store\Model\StoreManagerInterface $storemanager,

        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Sales\Model\OrderFactory $orderFactory,
        \Magento\Framework\ObjectManager\ObjectManager $objectManager,

        
        \Psr\Log\LoggerInterface $logger,
        \Magento\Catalog\Model\ProductFactory $productFactory,

        \Magento\Catalog\Model\ProductRepository $productRepository

    ) { 
        $this->_scopeConfig = $scopeConfig;
        $this->_customer = $customer;
        $this->_storemanager = $storemanager;
        $this->_request = $request;
        $this->_order = $order;
        $this->_fileFactory = $fileFactory;
        $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
        $this->_productRepository = $productRepository;

    }
 
    public function execute(\Magento\Framework\Event\Observer $observer) {
        
        
        
        $order = $observer->getEvent()->getOrder();
    

 
        $websiteID = $this->_storemanager->getStore()->getWebsiteId();

        
        $headers = array('Company Name', 'Contact Name', 'Contact Email', 'Contact Phone','Shipping Address' ,'SKU','QTY','Price','Total','Weight');

           
                
            
            $name = strtotime('now');
            $file = 'customorderexport/'.$name.'_detailed_orderexport.csv';
            $this->directory->create('customorderexport');
            $stream = $this->directory->openFile($file, 'w ');
            $stream->lock();
            $stream->writeCsv($headers);
            
            $orderdetail['Company Name'] = "";
            $orderdetail['Contact Name'] = $order->getCustomerName();
            $orderdetail['Contact Email'] = $order->getCustomerEmail();
            $orderdetail['Contact Phone'] = $order->getShippingAddress()->getTelephone();

            $streetadd = $order->getShippingAddress()->getStreet();
            
            $orderdetail['Shipping Address'] = $streetadd[0];



            $items = $order->getAllItems();
            foreach ($items as $item) {
            
                $orderdetail['SKU'] = $item->getSKU();              
                $orderdetail['QTY'] = $item->getQtyOrdered();
                $orderdetail['Price'] = $item->getPrice();
                $orderdetail['Total'] = $item->getRowTotalInclTax();
                $quantity = $item->getQtyOrdered();
                $orderdetail['Weight'] = $item->getWeight() * $quantity ;
                $stream->writeCsv($orderdetail);
            }

            $stream->unlock();
            $stream->close();

        }
    
}

CodePudding user response:

You need to use Plugin for this -

Note - Use you csv generation code before mail send to attach the file

  1. Create di.xml inside etc folder

    <?xml version="1.0"?>
     <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
          <type name="Magento\Sales\Model\Order\Email\Sender\OrderSender">
                     <plugin name="AttachEmail" type="Vendor\Module_Name\Plugin\Model\Email\Sender\OrderSender"/>
                 </type>
     <type name="Magento\Framework\Mail\TransportInterface">
             <plugin name="AttachEmailTransport" type="Vendor\Module_Name\Plugin\Model\Transport"/>
         </type>
     </config>
    
  2. Inside the OrderSender Model

Important file to identify if order email

 <?php
    namespace Vendor\Module_Name\Plugin\Model\Email\Sender;
    use Magento\Framework\Registry;
    class OrderSender
    {
       
        public function __construct(
            Registry $registry
        ) {
            $this->registry = $registry;
        }
    
       
        public function beforeSend(
            $subject,
            $order
        ) {
            $this->registry->unregister('email_attachments_type');
            $this->registry->unregister('email_attachments_source');
            $this->registry->register('email_attachments_type', 'order');
            $this->registry->register('email_attachments_source', $order);
        }
    }
?>
  1. Vendor\Module_Name\Plugin\Model\Transport

In this file -

<?php

namespace Vendor\Module_Name\Plugin\Model;

use Magento\Framework\Mail\TransportInterface as Subject;
use Magento\Framework\Registry;
use Zend\Mime\Message;
use Zend\Mime\Part;
use Zend_Mime;
use function GuzzleHttp\Psr7\mimetype_from_filename;
use Magento\Framework\Filesystem;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\ObjectManagerInterface;


class Transport 
{
    
    protected $_filterProvider;
    protected $_storeManager;
    protected $_blockFactory;
    
    public function __construct(
        Registry $registry,
        Filesystem $filesystem,
        ObjectManagerInterface $objectManager,
        \Magezon\Core\Helper\Data $coreHelper,
        \Magezon\EmailAttachments\Helper\Data $dataHelper,
        \Magento\Cms\Model\Template\FilterProvider $filterProvider,
        \Magento\Store\Model\StoreManagerInterface $storeManager
    ) {
        $this->objectManager = $objectManager;
        $this->registry = $registry;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->coreHelper = $coreHelper;
        $this->dataHelper = $dataHelper;
        $this->_filterProvider = $filterProvider;
        $this->_storeManager = $storeManager;
    }

    public function beforeSendMessage(
        Subject $subject
    ) {
    
        $type = $this->registry->registry('mgz_email_attachments_type');
        $source = $this->registry->registry('mgz_email_attachments_source');
        
        if($source && $type == 'order'){
            
                   try {
                    //pass file name and it will get from media directory
                       $filename = '';
                       $this->prepareMessage(
                        $message,
                        file_get_contents($this->getAbsolutePathFile($filename)),
                        'test.csv',
                        mimetype_from_filename($this->getFileUrl($filename))
                    );
                   } catch (\Exception $e) {
                      
                       
                   }
            
            }
          
            
       }
   }
 

   public function prepareMessage($message, $content, $name, $type)
   {
    $this->setParts($message->getBody()->getParts());
    $this->createAttachment(
        $content,
        $type,
        Zend_Mime::DISPOSITION_ATTACHMENT,
        Zend_Mime::ENCODING_BASE64,
        $name
    );
    $parts = $this->getParts();
    $mimeMessage = new Message();
    $mimeMessage->setParts($parts);
    $message->setBody($mimeMessage);
}

public function createAttachment(
    $body,
    $mimeType,
    $disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
    $encoding = Zend_Mime::ENCODING_BASE64,
    $filename = null
) {
    $mp = new Part($body);
    $mp->encoding = $encoding;
    $mp->type = $mimeType;
    $mp->disposition = $disposition;
    $mp->filename = $filename;
    $this->_addAttachment($mp);
    return $mp;
}

    /**
     * Adds an existing attachment to the mail message
     *
     * @param Zend_Mime_Part $attachment
     * @return Zend_Mail Provides fluent interface
     */
    public function _addAttachment($attachment)
    {
        $this->addPart($attachment);
        return $this;
    }

    /**
     * @param Zend_Mime_Part $part
     */
    public function addPart($part)
    {
        $this->_parts[] = $part;
    }

    /**
     * @return array
     */
    public function getParts()
    {
        return $this->_parts;
    }

    /**
     * @param array $parts
     */
    public function setParts($parts)
    {
        $this->_parts = $parts;
        return $this;
    }

    /**
     * @return string
     */
    public function getAbsolutePathFile($fileName)
    {
        return $this->mediaDirectory->getAbsolutePath($fileName);
    }

    /**
     * @return string
     */
    public function getFileUrl($fileName)
    {
        return $this->coreHelper->getMediaUrl() . $fileName;
    }

    protected function generateLog($message){
        $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/ETicket.log');
        $logger = new \Zend_Log();
        $logger->addWriter($writer);
        $logger->info($message);
    }

    protected function generateLogCreditMemo($message){
        $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/CreditMemo.log');
        $logger = new \Zend_Log();
        $logger->addWriter($writer);
        $logger->info($message);
    }
}

Hope this will help

  • Related