3

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('customer@email.com', '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 Jun 24 at 6:17
  • I have edited my question with full code. – Dinesh Rajput Jun 24 at 7:55
  • I have already given answer below. Its working. – Dinesh Rajput Aug 2 at 7:06
2

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 Jun 24 at 8:48
  • check updated answer – Sohel Rana Jun 24 at 9:10
  • Hello @Sohel Rana. is that possible to multiple files import in current code? how? can you please share? – Magento2 Devloper Jun 24 at 9:23
  • multiple attachments? – Sohel Rana Jun 24 at 9:27
  • Yes multiple attachments – Magento2 Devloper Jun 24 at 9:36
2

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

}
  • doesn't work after update to 2.3.3 ;/ – K. Maliszewski Oct 16 at 7:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.