Magento 2.3 – Custom Module Send Email Programmatically with Image Attachment

emailmagento2.3programmatically

I want to send email with the image attachment into custom module Programmatically.

How to do this?

Thanks in Advance

Best Answer

I've done this by creating below post controller for the custom form to send data with attachment in Magento 2.

<?php

namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Backend\App\Action;
use Magento\Framework\Filesystem;

class Post extends \Magento\Framework\App\Action\Action {

    const XML_PATH_EMAIL_RECIPIENT = 'section/email/recipient_email';
    const XML_PATH_EMAIL_SENDER = 'section/email/sender_email_identity';
    const XML_PATH_EMAIL_TEMPLATE = 'section/email/email_template';


    /**
     * @var \Magento\Framework\Mail\Template\TransportBuilder
     */
    protected $_transportBuilder;

    /**
     * @var \Magento\Framework\Translate\Inline\StateInterface
     */
    protected $inlineTranslation;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Framework\Escaper
     */
    protected $_escaper;

    /**
     * @var \Magento\Framework\File\UploaderFactory
     */
    protected $uploaderFactory;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
     * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
     */
    public function __construct(
        Filesystem $filesystem,
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Escaper $escaper,
        \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
    ) {
        parent::__construct($context);
        $this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->_transportBuilder = $transportBuilder;
        $this->inlineTranslation = $inlineTranslation;
        $this->scopeConfig = $scopeConfig;
        $this->storeManager = $storeManager;
        $this->_escaper = $escaper;
        $this->uploaderFactory = $uploaderFactory;
    }

    /**
     * Post user question
     *
     * @return void
     * @throws \Exception
     */
    public function execute()
    {
        $post = $this->getRequest()->getPostValue();
        if (!$post) {
            $this->_redirect('*/*/');
            return;
        }

        $this->inlineTranslation->suspend();
        try {
            $postObject = new \Magento\Framework\DataObject();
            $postObject->setData($post);

            $error = false;
            if (!\Zend_Validate::is(trim($post['name']), 'NotEmpty')) {
                $error = true;
            }

            $photos = array();
            foreach ($_FILES['photo']['name'] as $key => $image) {

                if (empty($image)) {
                    continue;
                }

                $fileName = '';
                if (isset($_FILES['photo']['name'][$key]) && $_FILES['photo']['name'][$key] != '') {
                    try {
                        $target = $this->_mediaDirectory->getAbsolutePath('rga');
                        $fileName = $_FILES['photo']['name'][$key];
                        $fileExt = strtolower(substr(strrchr($fileName, "."), 1));

                        $fileNamewoe = rtrim($fileName, $fileExt);

                        $fileName = preg_replace('/[^A-Za-z0-9\-]/', '', $fileNamewoe) . time() . $key . '.' . $fileExt;
                        if (!in_array($fileExt, array('jpg', 'jpeg', 'png', 'gif'))) {
                            $this->messageManager->addError(__('Only jpg, jpeg, png and gif file types are allowed.'));
                            session_write_close();
                            $this->_redirect('*/*/');
                            return;
                        }
                        array_push($photos, $fileName);
                        $uploader = $this->uploaderFactory->create(['fileId' => 'photo['.$key.']']);
                        $uploader->setAllowedExtensions(['jpg', 'jpeg', 'png', 'gif']);
                        $uploader->setAllowRenameFiles(false);
                        $uploader->setFilesDispersion(false);
                        $uploader->save($target,$fileName);
                    } catch (Exception $e) {
                        $error = true;
                    }
                }
            }

            if ($error) {
                $this->messageManager->addError(__('Unable to submit your request. Please, try again later'));
                session_write_close();
                throw new \Exception();
            }

            $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
            $transport = $this->_transportBuilder
                ->setTemplateIdentifier($this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, $storeScope)) // this code we have mentioned in the email_templates.xml
                ->setTemplateOptions(
                    [
                        'area' => \Magento\Framework\App\Area::AREA_FRONTEND, // this is using frontend area to get the template file
                        'store' => $this->storeManager->getStore()->getId(),
                    ]
                )
                ->setTemplateVars(['data' => $postObject])
                ->setFrom($this->scopeConfig->getValue(self::XML_PATH_EMAIL_SENDER, $storeScope))
                ->setReplyTo($post['EmailAddress'])
                ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope));

            /* add photos to attachment; */
            foreach($photos as $pic) {
                $attachmentFilePath = $this->_mediaDirectory->getAbsolutePath('rga').'/'. $pic;
                if(file_exists($attachmentFilePath)){
                    $transport->addAttachment(file_get_contents($attachmentFilePath,$pic));
                }
            }

            $transport = $transport->getTransport();           
            $transport->sendMessage(); 
            $this->inlineTranslation->resume();
            $this->messageManager->addSuccess(
                __('Your inquiry was submitted and will be responded to as soon as possible. Thank you for contacting us.')
            );
            $this->_redirect('*/*/');
            return;
        } catch (\Exception $e) {
            $this->inlineTranslation->resume();
            $this->messageManager->addError(
                __('Unable to submit your request. Please, try again later.')
            );
            $this->_redirect('*/*/');
            return;
        }
    }
}

Hope it helps!!!