https://extait.com/blog/how-to-send-email-with-attachment-in-magento-2-3/
I have tried above link, and below is the code: Now I am receiving emails without attachment. Full code as below: Custom\Module\Mail\Template\TransportBuilder.php
<?php
namespace Custom\Module\Mail\Template;
class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
/**
* @var \Extait\Attachment\Mail\Message
*/
protected $message;
/**
* Add an attachment to the message.
*
* @param string $content
* @param string $fileName
* @param string $fileType
* @return $this
*/
public function addAttachment($fileName, $fileType)
{
$this->message->setBodyAttachment($fileName, $fileType);
return $this;
}
/**
* After all parts are set, add them to message body.
*
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function prepareMessage()
{
parent::prepareMessage();
$this->message->setPartsToBody();
return $this;
}
}
File: Vendor\Module\Mail\Message.php
namespace Vendor\Module\Mail;
use Zend\Mime\Mime;
use Zend\Mime\PartFactory;
use Zend\Mail\MessageFactory as MailMessageFactory;
use Zend\Mime\MessageFactory as MimeMessageFactory;
class Message implements \Magento\Framework\Mail\MailMessageInterface
{
/**
* @var \Zend\Mime\PartFactory
*/
protected $partFactory;
/**
* @var \Zend\Mime\MessageFactory
*/
protected $mimeMessageFactory;
/**
* @var \Zend\Mail\Message
*/
private $zendMessage;
/**
* @var \Zend\Mime\Part[]
*/
protected $parts = [];
/**
* Message constructor.
*
* @param \Zend\Mime\PartFactory $partFactory
* @param \Zend\Mime\MessageFactory $mimeMessageFactory
* @param string $charset
*/
public function __construct(PartFactory $partFactory, MimeMessageFactory $mimeMessageFactory, $charset = 'utf-8')
{
$this->partFactory = $partFactory;
$this->mimeMessageFactory = $mimeMessageFactory;
$this->zendMessage = MailMessageFactory::getInstance();
$this->zendMessage->setEncoding($charset);
}
/**
* Add the HTML mime part to the message.
*
* @param string $content
* @return $this
*/
public function setBodyText($content)
{
$textPart = $this->partFactory->create();
$textPart->setContent($content)
->setType(Mime::TYPE_TEXT)
->setCharset($this->zendMessage->getEncoding());
$this->parts[] = $textPart;
return $this;
}
/**
* Add the text mime part to the message.
*
* @param string $content
* @return $this
*/
public function setBodyHtml($content)
{
$htmlPart = $this->partFactory->create();
$htmlPart->setContent($content)
->setType(Mime::TYPE_HTML)
->setCharset($this->zendMessage->getEncoding());
$this->parts[] = $htmlPart;
return $this;
}
/**
* Add the attachment mime part to the message.
*
* @param string $content
* @param string $fileName
* @param string $fileType
* @return $this
*/
public function setBodyAttachment($file, $name)
{
$attachmentPart = $this->partFactory->create();
$attachmentPart->setType($file)
->setFileName($name);
$this->parts[] = $attachmentPart;
return $this;
}
/**
* Set parts to Zend message body.
*
* @return $this
*/
public function setPartsToBody()
{
$mimeMessage = $this->mimeMessageFactory->create();
$mimeMessage->setParts($this->parts);
$this->zendMessage->setBody($mimeMessage);
return $this;
}
/**
* {@inheritdoc}
*/
public function setBody($body)
{
return $this;
}
/**
* {@inheritdoc}
*/
public function setSubject($subject)
{
$this->zendMessage->setSubject($subject);
return $this;
}
/**
* {@inheritdoc}
*/
public function getSubject()
{
return $this->zendMessage->getSubject();
}
/**
* {@inheritdoc}
*/
public function getBody()
{
return $this->zendMessage->getBody();
}
/**
* {@inheritdoc}
*/
public function setFrom($fromAddress)
{
$this->setFromAddress($fromAddress, null);
return $this;
}
/**
* {@inheritdoc}
*/
public function setFromAddress($fromAddress, $fromName = null)
{
$this->zendMessage->setFrom($fromAddress, $fromName);
return $this;
}
/**
* {@inheritdoc}
*/
public function addTo($toAddress)
{
$this->zendMessage->addTo($toAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function addCc($ccAddress)
{
$this->zendMessage->addCc($ccAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function addBcc($bccAddress)
{
$this->zendMessage->addBcc($bccAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function setReplyTo($replyToAddress)
{
$this->zendMessage->setReplyTo($replyToAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRawMessage()
{
return $this->zendMessage->toString();
}
/**
* @inheritDoc
*/
public function setMessageType($type)
{
return $this;
}
==========================================
File: Vendor\Module\Controller\Index\Sendemail.php
$yourFolderName = 'careers-resumes/';
// "my_custom_file" is the HTML input file name
$yourInputFileName = 'careers-resume';
try{
$postValues = $this->getRequest()->getPost();
$file = $this->getRequest()->getFiles($yourInputFileName);
$fileName = ($file && array_key_exists('name', $file)) ? $file['name'] : null;
if ($file && $fileName) {
$target = $this->mediaDirectory->getAbsolutePath($yourFolderName);
/** @var $uploader \Magento\MediaStorage\Model\File\Uploader */
$uploader = $this->fileUploader->create(['fileId' => $yourInputFileName]);
// set allowed file extensions
$uploader->setAllowedExtensions(['doc', 'docx', 'pdf']);
// allow folder creation
$uploader->setAllowCreateFolders(true);
// rename file name if already exists
$uploader->setAllowRenameFiles(true);
$result = $uploader->save($target);
$filePath = $result['path'].$result['file'];
$fileName = $result['name'];
if ($result['file']) {
$storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
$templateOptions = [
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => 1
];
$store = $this->_storeManager->getStore()->getId();
$transport = $this->_transportBuilder->setTemplateIdentifier(5)
->setTemplateOptions(['area' => 'frontend', 'store' => $store])
->setTemplateVars(
[
'store' => $this->_storeManager->getStore(),
]
)
->setFrom('general')
// you can config general email address in Store -> Configuration -> General -> Store Email Addresses
->addTo('[email protected]', 'Customer Name')
->addAttachment($filePath, $fileName)
->getTransport();
$transport->sendMessage();
$this->_redirect('careers');
$this->messageManager->addSuccess(__('File has been successfully uploaded & mail sent.'));
}
}
} catch (\Exception $e) {
$this->messageManager->addError($e->getMessage());
}
I am receiving email without attachment.
-
can you share full both files code?Magento2 Devloper– Magento2 Devloper2019年06月24日 06:17:34 +00:00Commented Jun 24, 2019 at 6:17
-
I have edited my question with full code.Dinesh Rajput– Dinesh Rajput2019年06月24日 07:55:07 +00:00Commented Jun 24, 2019 at 7:55
-
I have already given answer below. Its working.Dinesh Rajput– Dinesh Rajput2019年08月02日 07:06:32 +00:00Commented Aug 2, 2019 at 7:06
3 Answers 3
Your overwrite looks good. Problem is where you send email. You maybe missing following part:
$transport->setTemplateVars([])
OR
$template->setVars([]);
[Update]
Replace addAttachment method by following code:
/**
* @param $body
* @param $mimeType
* @param $disposition
* @param $encoding
* @param null $filename
* @return $this
*/
public function addAttachment(
$body,
$mimeType = \Zend_Mime::TYPE_OCTETSTREAM,
$disposition = \Zend_Mime::DISPOSITION_ATTACHMENT,
$encoding = \Zend_Mime::ENCODING_BASE64,
$filename = null
) {
if($disposition == null) {
$disposition = \Zend_Mime::DISPOSITION_ATTACHMENT;
}
if($encoding == null) {
$encoding = \Zend_Mime::ENCODING_BASE64;
}
$this->message->createAttachment($body, $mimeType, $disposition, $encoding, $filename);
return $this;
}
And call following way:
$this->transportBuilder->addAttachment(file_get_contents($_FILES['attach']['tmp_name']), $_FILES['attach']['type'], null, null, $_FILES['attach']['name']);
-
I have edited my question with full code.Dinesh Rajput– Dinesh Rajput2019年06月24日 08:48:42 +00:00Commented Jun 24, 2019 at 8:48
-
check updated answerSohel Rana– Sohel Rana2019年06月24日 09:10:47 +00:00Commented Jun 24, 2019 at 9:10
-
Hello @Sohel Rana. is that possible to multiple files import in current code? how? can you please share?Magento2 Devloper– Magento2 Devloper2019年06月24日 09:23:45 +00:00Commented Jun 24, 2019 at 9:23
-
multiple attachments?Sohel Rana– Sohel Rana2019年06月24日 09:27:31 +00:00Commented Jun 24, 2019 at 9:27
-
Yes multiple attachmentsMagento2 Devloper– Magento2 Devloper2019年06月24日 09:36:02 +00:00Commented Jun 24, 2019 at 9:36
Here is my working code as below:
Controller:
Here we've to pass parameter as below line:
$filePath = uploaded attachment file path.
->addAttachment(file_get_contents($filePath), $fileName, $fileType)
public function execute()
{
$yourFolderName = 'careers-resumes/';
// "my_custom_file" is the HTML input file name
$yourInputFileName = 'careers-resume';
try{
$postValues = $this->getRequest()->getPost();
$file = $this->getRequest()->getFiles($yourInputFileName);
$fileName = ($file && array_key_exists('name', $file)) ? $file['name'] : null;
if ($file && $fileName) {
$target = $this->mediaDirectory->getAbsolutePath($yourFolderName);
/** @var $uploader \Magento\MediaStorage\Model\File\Uploader */
$uploader = $this->fileUploader->create(['fileId' => $yourInputFileName]);
// set allowed file extensions
$uploader->setAllowedExtensions(['doc', 'docx', 'pdf']);
// allow folder creation
$uploader->setAllowCreateFolders(true);
// rename file name if already exists
$uploader->setAllowRenameFiles(true);
$fileName = $fileName;
$fileExt = strtolower(substr(strrchr($fileName, ".") ,1));
$fileNamewoe = rtrim($fileName, $fileExt);
$fileName = $fileNamewoe . date("m-d-Y") . '-' .date("h:i:sa") . '.' . $fileExt;
$fileType = $file['type'];
$result = $uploader->save($target,$fileName);
$filePath = $result['path'].$result['file'];
if ($result['file']) {
$applicantName = $postValues['name'];
$applicantEmail = $postValues['email'];
$applicantTelephone = $postValues['telephone_number'];
$applicantPositionAppliedFor = $postValues['position'];
$sender = [
'name' => $applicantName,
'email' => $applicantEmail
];
$templateVars = [
'store' => $this->_storeManager->getStore(),
'applicant_name' => $applicantName,
'applicant_email' => $applicantEmail,
'applicant_phone' => $applicantTelephone,
'applicant_position' => $applicantPositionAppliedFor
];
$templateOptions = [
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => $this->_storeManager->getStore()->getId()
];
$storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
$notifyEmail = $this->scopeConfig->getValue(self::XML_NOTIFY_VALUE, $storeScope);
$transport = $this->_transportBuilder->setTemplateIdentifier('careerspositions_email_template')
->setTemplateOptions($templateOptions)
->setTemplateVars($templateVars)
->setFrom($sender)
// you can config general email address in Store -> Configuration -> General -> Store Email Addresses
->addTo($notifyEmail, 'Receiver Name')
->addAttachment(file_get_contents($filePath), $fileName, $fileType)
->getTransport();
try {
$transport->sendMessage();
$this->getCatalogSession()->setMySession($applicantEmail);
$this->_redirect('careers/index/success');
return;
}
catch(\Exception $e) {
$this->messageManager->addError('Unable to send email. Please check that the details you have entered are correct.');
$this->_redirect('careers');
}
}
}
} catch (\Exception $e) {
$this->messageManager->addError('Something went wrong. Please make sure the details you have entered are correct.');
}
$this->_redirect('careers');
}
In Vendor\Module\Mail\Message.php as below same as this github reference link:
https://github.com/extait-com/email-attachment/blob/master/Mail/Message.php Here we've to check setBodyAttachment() function that should be defined in TransportBuilder.php
<?php
/**
* NOTICE OF LICENSE
*
* This source file is subject to the commercial license
* that is bundled with this package in the file LICENSE.txt.
*
* @category Extait
* @package Extait_Attachment
* @copyright Copyright (c) 2016-2018 Extait, Inc. (http://www.extait.com)
*/
namespace Vendor\Module\Mail;
use Zend\Mime\Mime;
use Zend\Mime\PartFactory;
use Zend\Mail\MessageFactory as MailMessageFactory;
use Zend\Mime\MessageFactory as MimeMessageFactory;
class Message implements \Magento\Framework\Mail\MailMessageInterface
{
/**
* @var \Zend\Mime\PartFactory
*/
protected $partFactory;
/**
* @var \Zend\Mime\MessageFactory
*/
protected $mimeMessageFactory;
/**
* @var \Zend\Mail\Message
*/
private $zendMessage;
/**
* @var \Zend\Mime\Part[]
*/
protected $parts = [];
/**
* Message constructor.
*
* @param \Zend\Mime\PartFactory $partFactory
* @param \Zend\Mime\MessageFactory $mimeMessageFactory
* @param string $charset
*/
public function __construct(PartFactory $partFactory, MimeMessageFactory $mimeMessageFactory, $charset = 'utf-8')
{
$this->partFactory = $partFactory;
$this->mimeMessageFactory = $mimeMessageFactory;
$this->zendMessage = MailMessageFactory::getInstance();
$this->zendMessage->setEncoding($charset);
}
/**
* Add the HTML mime part to the message.
*
* @param string $content
* @return $this
*/
public function setBodyText($content)
{
$textPart = $this->partFactory->create();
$textPart->setContent($content)
->setType(Mime::TYPE_TEXT)
->setCharset($this->zendMessage->getEncoding());
$this->parts[] = $textPart;
return $this;
}
/**
* Add the text mime part to the message.
*
* @param string $content
* @return $this
*/
public function setBodyHtml($content)
{
$htmlPart = $this->partFactory->create();
$htmlPart->setContent($content)
->setType(Mime::TYPE_HTML)
->setCharset($this->zendMessage->getEncoding());
$this->parts[] = $htmlPart;
return $this;
}
/**
* Add the attachment mime part to the message.
*
* @param string $content
* @param string $fileName
* @param string $fileType
* @return $this
*/
public function setBodyAttachment($content, $fileName, $fileType)
{
$attachmentPart = $this->partFactory->create();
$attachmentPart->setContent($content)
->setFileName($fileName)
->setType($fileType)
->setEncoding(Mime::ENCODING_BASE64) /*Add this*/
->setDisposition(Mime::DISPOSITION_ATTACHMENT);
$this->parts[] = $attachmentPart;
return $this;
}
/**
* Set parts to Zend message body.
*
* @return $this
*/
public function setPartsToBody()
{
$mimeMessage = $this->mimeMessageFactory->create();
$mimeMessage->setParts($this->parts);
$this->zendMessage->setBody($mimeMessage);
return $this;
}
/**
* {@inheritdoc}
*/
public function setBody($body)
{
return $this;
}
/**
* {@inheritdoc}
*/
public function setSubject($subject)
{
$this->zendMessage->setSubject($subject);
return $this;
}
/**
* {@inheritdoc}
*/
public function getSubject()
{
return $this->zendMessage->getSubject();
}
/**
* {@inheritdoc}
*/
public function getBody()
{
return $this->zendMessage->getBody();
}
/**
* {@inheritdoc}
*/
public function setFrom($fromAddress)
{
$this->setFromAddress($fromAddress, null);
return $this;
}
/**
* {@inheritdoc}
*/
public function setFromAddress($fromAddress, $fromName = null)
{
$this->zendMessage->setFrom($fromAddress, $fromName);
return $this;
}
/**
* {@inheritdoc}
*/
public function addTo($toAddress)
{
$this->zendMessage->addTo($toAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function addCc($ccAddress)
{
$this->zendMessage->addCc($ccAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function addBcc($bccAddress)
{
$this->zendMessage->addBcc($bccAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function setReplyTo($replyToAddress)
{
$this->zendMessage->setReplyTo($replyToAddress);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRawMessage()
{
return $this->zendMessage->toString();
}
/**
* @inheritDoc
*/
public function setMessageType($type)
{
return $this;
}
}
File: Vendor\Module\Mail\Template\TransportBuilder.php
<?php
namespace vendor\Module\Mail\Template;
class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
/**
* @var \Extait\Attachment\Mail\Message
*/
protected $message;
/**
* Add an attachment to the message.
*
* @param string $content
* @param string $fileName
* @param string $fileType
* @return $this
*/
public function addAttachment($content, $fileName, $fileType)
{
$this->message->setBodyAttachment($content, $fileName, $fileType);
return $this;
}
/**
* After all parts are set, add them to message body.
*
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function prepareMessage()
{
parent::prepareMessage();
$this->message->setPartsToBody();
return $this;
}
}
-
2doesn't work after update to 2.3.3 ;/K. Maliszewski– K. Maliszewski2019年10月16日 07:37:12 +00:00Commented Oct 16, 2019 at 7:37
Override \Magento\Framework\Mail\Template\TransportBuilder in di.xml
<?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="TM\ShipmentEmail\Model\Mail\Template\TransportBuilder" />
</config>
Define this constant if you need in overrides file and add following data
const MIME_TYPES = [
'png' => 'image/png',
'jpg' => 'image/jpg'
];
//check file type
protected function prepareMessage()
{
$snapshotFileTypes = self::MIME_TYPES[ (string) substr($snapshot, strrpos($snapshot, '.') + 1); ];
//call for attachment in custom function
$this->addAttachment(file_get_contents($fullSnapshotPath), $endSnap, $snapshotFileType );
}
// finally add attachment in this funtion
public function addAttachment(?string $content, ?string $fileName, ?string $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;
}