4

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.

Mohit Rane
2,0001 gold badge17 silver badges52 bronze badges
asked Jun 24, 2019 at 6:05
3
  • can you share full both files code? Commented Jun 24, 2019 at 6:17
  • I have edited my question with full code. Commented Jun 24, 2019 at 7:55
  • I have already given answer below. Its working. Commented Aug 2, 2019 at 7:06

3 Answers 3

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']);
answered Jun 24, 2019 at 6:10
14
  • I have edited my question with full code. Commented Jun 24, 2019 at 8:48
  • check updated answer Commented Jun 24, 2019 at 9:10
  • Hello @Sohel Rana. is that possible to multiple files import in current code? how? can you please share? Commented Jun 24, 2019 at 9:23
  • multiple attachments? Commented Jun 24, 2019 at 9:27
  • Yes multiple attachments Commented Jun 24, 2019 at 9:36
3

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;
 }
}
Anas Mansuri
2,6371 gold badge12 silver badges29 bronze badges
answered Jun 28, 2019 at 4:51
1
  • 2
    doesn't work after update to 2.3.3 ;/ Commented Oct 16, 2019 at 7:37
1

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;
 }
answered Apr 5, 2022 at 8:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.