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;
}
}