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. i'm getting this error: Unable to send mail: Unknown error {"exception":"[object] (Laminas\Mail\Transport\Exception\RuntimeException(code: 0): Unable to send mail: Unknown error at /home/lenovo/Ven/vendor/laminas/laminas-mail/src/Transport/Sendmail.php:298)"} []
Storeven/Orders/Observers/OrderExport.php
<?php namespace Storeven\Orders\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\WriteInterface; use Magento\Store\Model\ScopeInterface; use Magento\Framework\Mail\Template\TransportBuilder; use Magento\Framework\Translate\Inline\StateInterface; class Orderexport implements ObserverInterface { //changes protected $_objectManager; private $logger; private $productFactory; //-----// protected $_transportBuilder; protected $inlineTranslation; protected $_request; protected $_order; protected $_productRepository; protected $_scopeConfig; protected $_customer; protected $_storemanager; protected $_dir; 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, \Magento\Framework\Filesystem\DirectoryList $dir, \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder ) { $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; $this->_transportBuilder = $transportBuilder; $this->logger = $logger; $this->dir = $dir; } public function getRootDirectory() { return $this->dir->getRoot(); } public function execute(\Magento\Framework\Event\Observer $observer) { $order = $observer->getEvent()->getOrder(); $store = $this->_storemanager->getStore()->getName(); $websiteID = $this->_storemanager->getStore()->getWebsiteId(); $headers = array('Company Name', 'Contact Name', 'Contact Email', 'Contact Phone','Shipping Address' ,'SKU','ProductColorID','QTY','Price','Total','CBM','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['ProductColorID']= ""; $orderdetail['QTY'] = $item->getQtyOrdered(); $orderdetail['Price'] = $item->getPrice(); $orderdetail['Total'] = $item->getRowTotalInclTax(); // $id = $item->getProdcutId(); // $product = $this->_productRepository->getById($id); // $orderdetail['CBM'] = $product->getcbm(); $orderdetail['CBM'] = ""; $quantity = $item->getQtyOrdered(); $orderdetail['Weight'] = $item->getWeight() * $quantity ; $stream->writeCsv($orderdetail); } $stream->unlock(); $stream->close(); //Email code //$Email_template_name="AddEmailAttachemnt"; // $file_url = 'storeven/var/customorderexport/'.$name.'_detailed_orderexport.csv'; try { $file_url = '/home/lenovo/storeven/var/customorderexport/1654160951_detailed_orderexport.csv'; $emailTemplateVariables['message'] = 'This is a test message.'; $file_content = file_get_contents($file_url); $file_name = $name."_detailed_orderexport.csv"; $extension="text/csv"; $transport = $this->_transportBuilder->setTemplateIdentifier('myemail_email_template') ->setTemplateVars($emailTemplateVariables) ->setTemplateOptions([ 'area' => \Magento\Framework\App\Area::AREA_FRONTEND, 'store' => $this->_storemanager->getStore()->getId() ]) ->setFrom([ 'email' => '[email protected]', 'name' => 'my store' ]) ->addTo('[email protected]') // Receiver Email Address ->addAttachment($file_content, $file_name, $extension) // here Addtement are add with Email ->getTransport(); } catch (\Exception $e) { $this->logger->critical($e->getMessage()); } } } Orders/Model/Mail/Template/AddEmailAttachemnt.php
namespace Storeven\Orders\Model\Mail\Template; use Magento\Framework\App\TemplateTypesInterface; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Mail\AddressConverter; use Magento\Framework\Mail\EmailMessageInterfaceFactory; use Magento\Framework\Mail\MessageInterface; use Magento\Framework\Mail\MessageInterfaceFactory; use Magento\Framework\Mail\MimeInterface; use Magento\Framework\Mail\MimeMessageInterfaceFactory; use Magento\Framework\Mail\MimePartInterfaceFactory; use Magento\Framework\Mail\Template\FactoryInterface; use Magento\Framework\Mail\Template\SenderResolverInterface; use Magento\Framework\Mail\TransportInterfaceFactory; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Phrase; use Laminas\Mime\Mime; use Laminas\Mime\PartFactory; class AddEmailAttachemnt extends \Magento\Framework\Mail\Template\TransportBuilder { protected $templateIdentifier; protected $templateModel; protected $templateVars; protected $templateOptions; protected $transport; protected $templateFactory; protected $objectManager; protected $message; protected $_senderResolver; protected $mailTransportFactory; private $messageData = []; private $emailMessageInterfaceFactory; private $mimeMessageInterfaceFactory; private $mimePartInterfaceFactory; private $addressConverter; protected $attachments = []; protected $partFactory; public function __construct( FactoryInterface $templateFactory, MessageInterface $message, SenderResolverInterface $senderResolver, ObjectManagerInterface $objectManager, TransportInterfaceFactory $mailTransportFactory, MessageInterfaceFactory $messageFactory = null, EmailMessageInterfaceFactory $emailMessageInterfaceFactory = null, MimeMessageInterfaceFactory $mimeMessageInterfaceFactory = null, MimePartInterfaceFactory $mimePartInterfaceFactory = null, AddressConverter $addressConverter = null ) { $this->templateFactory = $templateFactory; $this->objectManager = $objectManager; $this->_senderResolver = $senderResolver; $this->mailTransportFactory = $mailTransportFactory; $this->emailMessageInterfaceFactory = $emailMessageInterfaceFactory ?: $this->objectManager ->get(EmailMessageInterfaceFactory::class); $this->mimeMessageInterfaceFactory = $mimeMessageInterfaceFactory ?: $this->objectManager ->get(MimeMessageInterfaceFactory::class); $this->mimePartInterfaceFactory = $mimePartInterfaceFactory ?: $this->objectManager ->get(MimePartInterfaceFactory::class); $this->addressConverter = $addressConverter ?: $this->objectManager ->get(AddressConverter::class); $this->partFactory = $objectManager->get(PartFactory::class); parent::__construct( $templateFactory, $message, $senderResolver, $objectManager, $mailTransportFactory, $messageFactory, $emailMessageInterfaceFactory, $mimeMessageInterfaceFactory, $mimePartInterfaceFactory, $addressConverter ); } public function addCc($address, $name = '') { $this->addAddressByType('cc', $address, $name); return $this; } public function addTo($address, $name = '') { $this->addAddressByType('to', $address, $name); return $this; } public function addBcc($address) { $this->addAddressByType('bcc', $address); return $this; } public function setReplyTo($email, $name = null) { $this->addAddressByType('replyTo', $email, $name); return $this; } public function setFrom($from) { return $this->setFromByScope($from); } public function setFromByScope($from, $scopeId = null) { $result = $this->_senderResolver->resolve($from, $scopeId); $this->addAddressByType('from', $result['email'], $result['name']); return $this; } public function setTemplateIdentifier($templateIdentifier) { $this->templateIdentifier = $templateIdentifier; return $this; } public function setTemplateModel($templateModel) { $this->templateModel = $templateModel; return $this; } public function setTemplateVars($templateVars) { $this->templateVars = $templateVars; return $this; } public function setTemplateOptions($templateOptions) { $this->templateOptions = $templateOptions; return $this; } public function getTransport() { try { $this->prepareMessage(); $mailTransport = $this->mailTransportFactory->create(['message' => clone $this->message]); } finally { $this->reset(); } return $mailTransport; } protected function reset() { $this->messageData = []; $this->templateIdentifier = null; $this->templateVars = null; $this->templateOptions = null; return $this; } protected function getTemplate() { return $this->templateFactory->get($this->templateIdentifier, $this->templateModel) ->setVars($this->templateVars) ->setOptions($this->templateOptions); } protected function prepareMessage() { $template = $this->getTemplate(); $content = $template->processTemplate(); switch ($template->getType()) { case TemplateTypesInterface::TYPE_TEXT: $part['type'] = MimeInterface::TYPE_TEXT; break; case TemplateTypesInterface::TYPE_HTML: $part['type'] = MimeInterface::TYPE_HTML; break; default: throw new LocalizedException( new Phrase('Unknown template type') ); } $mimePart = $this->mimePartInterfaceFactory->create(['content' => $content]); $parts = count($this->attachments) ? array_merge([$mimePart], $this->attachments) : [$mimePart]; $this->messageData['body'] = $this->mimeMessageInterfaceFactory->create( ['parts' => $parts] ); $this->messageData['subject'] = html_entity_decode( (string) $template->getSubject(), ENT_QUOTES ); $this->message = $this->emailMessageInterfaceFactory->create($this->messageData); return $this; } private function addAddressByType($addressType, $email, $name = null): void { if (is_string($email)) { $this->messageData[$addressType][] = $this->addressConverter->convert($email, $name); return; } $convertedAddressArray = $this->addressConverter->convertMany($email); if (isset($this->messageData[$addressType])) { $this->messageData[$addressType] = array_merge( $this->messageData[$addressType], $convertedAddressArray ); } } public function addAttachment($content, $fileName, $fileType) { $attachmentPart = $this->partFactory->create(); $attachmentPart->setContent($content) ->setType($fileType) ->setFileName($fileName) ->setDisposition(Mime::DISPOSITION_ATTACHMENT) ->setEncoding(Mime::ENCODING_BASE64); $this->attachments[] = $attachmentPart; return $this; } } 