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 = 'rga/email/recipient_email';
const XML_PATH_EMAIL_SENDER = 'rga/email/sender_email_identity';
const XML_PATH_EMAIL_TEMPLATE = 'rga/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;
}
}
}
For whole module with email template, you can follow the below artice
https://www.brainacts.com/blog/magento-2-how-to-send-email-programmatically
Hope it helps!!!