In this tutorial, we will learn about how to add attachment (browse) button in Magento2 contact us form.
We will first override default contact us form with our module's phtml file. Add file upload buton in phtml file. And then override contact us post controller to make it work as per our custom logic.
Let's start it by creating custom module.
Find complete module on Github.
Create folder in
app/code/
Magelearn/ContactAttachmentStep 1: Create module registration file
Add registration.php file in it:
1 2 3 4 5 6 7 8 | <?php /** * Copyright © All rights reserved. * See COPYING.txt for license details. */ use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magelearn_ContactAttachment' , __DIR__); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | { "name" : "magelearn/contactattachment" , "description" : "Magento 2 add attachment to attach files to the contact us form" , "type" : "magento2-module" , "license" : "OSL-3.0" , "authors" : [ { "email" : "info@mage2gen.com" , "name" : "Mage2Gen" }, { "email" : "vijaymrami@gmail.com" , "name" : "vijay rami" } ], "minimum-stability" : "dev" , "require" : {}, "autoload" : { "files" : [ "registration.php" ], "psr-4" : { "Magelearn\\ContactAttachment\\" : "" } } } |
Add etc/module.xml file in it:
1 2 3 4 5 6 7 8 9 | <? xml version = "1.0" ?> < config xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "urn:magento:framework:Module/etc/module.xsd" > < module name = "Magelearn_ContactAttachment" setup_version = "1.0.0" > < sequence > < module name = "Magento_Contact" /> < module name = "Magento_Framework" /> </ sequence > </ module > </ config > |
Now first let's modify default Magento2 Contact us form HTML with layout xml file.
Add contact_index_index.xml file in
view/frontend/layout
1234567891011121314 <?
xml
version
=
"1.0"
?>
<
page
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
layout
=
"1column"
xsi:noNamespaceSchemaLocation
=
"urn:magento:framework:View/Layout/etc/page_configuration.xsd"
>
<
body
>
<
referenceBlock
name
=
"contactForm"
remove
=
"true"
/>
<
referenceContainer
name
=
"content"
>
<
block
class
=
"Magento\Contact\Block\ContactForm"
name
=
"magelearn.contact.attachment"
template
=
"Magelearn_ContactAttachment::form.phtml"
>
<
container
name
=
"form.additional.info"
label
=
"Form Additional Info"
/>
<
arguments
>
<
argument
name
=
"view_model"
xsi:type
=
"object"
>Magento\Contact\ViewModel\UserDataProvider</
argument
>
</
arguments
>
</
block
>
</
referenceContainer
>
</
body
>
</
page
>
Now add our custom phtml file.
Add form.phtml file in view/frontend/templates
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 <?
php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
/** @var \Magento\Contact\Block\ContactForm $block */
/** @var \Magento\Contact\ViewModel\UserDataProvider $viewModel */
$viewModel = $block->getViewModel();
?>
<
form
class
=
"form contact"
action="<?= $block->escapeUrl($block->getFormAction()) ?>"
id="contact-form"
method="post"
data-hasrequired="<?= $block->escapeHtmlAttr(__('* Required Fields')) ?>"
data-mage-init='{"validation":{}}'
enctype="multipart/form-data">
<
fieldset
class
=
"fieldset"
>
<
legend
class
=
"legend"
><
span
><?= $block->escapeHtml(__('Write Us')) ?></
span
></
legend
>
<
div
class
=
"field note no-label"
><?= $block->escapeHtml(__('Jot us a note and we’ll get back to you as quickly as possible.')) ?></
div
>
<
div
class
=
"field name required"
>
<
label
class
=
"label"
for
=
"name"
><
span
><?= $block->escapeHtml(__('Name')) ?></
span
></
label
>
<
div
class
=
"control"
>
<
input
name
=
"name"
id
=
"name"
title="<?= $block->escapeHtmlAttr(__('Name')) ?>"
value="<?= $block->escapeHtmlAttr($viewModel->getUserName()) ?>"
class="input-text"
type="text"
data-validate="{required:true}"/>
</
div
>
</
div
>
<
div
class
=
"field email required"
>
<
label
class
=
"label"
for
=
"email"
><
span
><?= $block->escapeHtml(__('Email')) ?></
span
></
label
>
<
div
class
=
"control"
>
<
input
name
=
"email"
id
=
"email"
title="<?= $block->escapeHtmlAttr(__('Email')) ?>"
value="<?= $block->escapeHtmlAttr($viewModel->getUserEmail()) ?>"
class="input-text"
type="email"
data-validate="{required:true, 'validate-email':true}"/>
</
div
>
</
div
>
<
div
class
=
"field telephone"
>
<
label
class
=
"label"
for
=
"telephone"
><
span
><?= $block->escapeHtml(__('Phone Number')) ?></
span
></
label
>
<
div
class
=
"control"
>
<
input
name
=
"telephone"
id
=
"telephone"
title="<?= $block->escapeHtmlAttr(__('Phone Number')) ?>"
value="<?= $block->escapeHtmlAttr($viewModel->getUserTelephone()) ?>"
class="input-text"
type="tel" />
</
div
>
</
div
>
<
div
class
=
"field comment required"
>
<
label
class
=
"label"
for
=
"comment"
><
span
><?= $block->escapeHtml(__('What’s on your mind?')) ?></
span
></
label
>
<
div
class
=
"control"
>
<
textarea
name
=
"comment"
id
=
"comment"
title="<?= $block->escapeHtmlAttr(__('What’s on your mind?')) ?>"
class="input-text"
cols="5"
rows="3"
data-validate="{required:true}"><?= $block->escapeHtml($viewModel->getUserComment()) ?></
textarea
>
</
div
>
</
div
>
<
div
class
=
"field attachment"
>
<
label
class
=
"label"
for
=
"attachment"
><
span
><?= $block->escapeHtml(__('Attachment')) ?></
span
></
label
>
<
div
class
=
"control"
>
<
input
name
=
"attachment"
id
=
"attachment"
title="<?= $block->escapeHtmlAttr(__('Attachment')) ?>" value="<?= $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('attachment')) ?>" class="input-text" type="file"/>
</
div
>
</
div
>
<?= $block->getChildHtml('form.additional.info') ?>
</
fieldset
>
<
div
class
=
"actions-toolbar"
>
<
div
class
=
"primary"
>
<
input
type
=
"hidden"
name
=
"hideit"
id
=
"hideit"
value
=
""
/>
<
button
type
=
"submit"
title="<?= $block->escapeHtmlAttr(__('Submit')) ?>" class="action submit primary">
<
span
><?= $block->escapeHtml(__('Submit')) ?></
span
>
</
button
>
</
div
>
</
div
>
</
form
>
Add Data.php file in Helper
123456789101112131415161718192021222324252627282930313233343536373839404142 <?php
namespace
Magelearn\ContactAttachment\Helper;
use
Magento\Framework\App\Helper\AbstractHelper;
use
Magento\Framework\App\ProductMetadataInterface;
use
Magento\Framework\ObjectManagerInterface;
/**
* Class Data
* @package Magelearn\ContactAttachment\Helper
*/
class
Data
extends
AbstractHelper
{
/**
* @type ObjectManagerInterface
*/
protected
$objectManager
;
/**
* @param \Magento\Framework\App\Helper\Context $context
*/
public
function
__construct(
\Magento\Framework\App\Helper\Context
$context
,
ObjectManagerInterface
$objectManager
) {
$this
->objectManager =
$objectManager
;
parent::__construct(
$context
);
}
/**
* @param $ver
* @param string $operator
* @return mixed
*/
public
function
versionCompare(
$ver
,
$operator
=
'>='
)
{
$productMetadata
=
$this
->objectManager->get(ProductMetadataInterface::
class
);
$version
=
$productMetadata
->getVersion();
return
version_compare(
$version
,
$ver
,
$operator
);
}
}
Now, we will override default post action of Magento and override with our code by adding file upload functionality. But now magento new version use ZendFramework2 some of old functions like createAttachment() and addAttachment() are not available anymore.
So we also have to override Magento\Framework\Mail\Template\TransportBuilder
and Magento\Framework\Mail\Message
.
Ref. https://magento.stackexchange.com/questions/252506/magento-2-3-custom-email-attachment-not-working
Now, Considering all above point Add etc/di.xml file:12345 <
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
=
"Magelearn\ContactAttachment\Rewrite\Magento\Framework\Mail\Template\TransportBuilder"
/>
<
preference
for
=
"Magento\Framework\Mail\Message"
type
=
"Magelearn\ContactAttachment\Mail\Message"
/>
<
preference
for
=
"Magento\Contact\Controller\Index\Post"
type
=
"Magelearn\ContactAttachment\Rewrite\Magento\Contact\Controller\Index\Post"
/>
</
config
>
As createAttachment() method is no more available, we will override Magento\Framework\Mail\Message and create a class which will implement Magento\Framework\Mail\MailMessageInterface.
Add Mail/Message.php file123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 <?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 Magelearn
* @package Magelearn_ContactAttachment
* @copyright Copyright (c) 2016-2018 Extait, Inc. (http://www.extait.com)
*/
namespace
Magelearn\ContactAttachment\Mail;
use
Magento\Framework\Mail\MailMessageInterface;
use
Zend\Mime\Mime;
use
Zend\Mime\Part;
use
Zend\Mime\PartFactory;
use
Zend\Mail\MessageFactory
as
MailMessageFactory;
use
Zend\Mime\MessageFactory
as
MimeMessageFactory;
class
Message
implements
MailMessageInterface
{
/**
* @var \Zend\Mime\PartFactory
*/
protected
$partFactory
;
/**
* @var \Zend\Mime\MessageFactory
*/
protected
$mimeMessageFactory
;
/**
* @var \Zend\Mail\Message
*/
private
$zendMessage
;
private
$messageType
= self::TYPE_TEXT;
/**
* @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
)
{
$this
->setMessageType(self::TYPE_TEXT);
$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
)
{
$this
->setMessageType(self::TYPE_HTML);
$htmlPart
=
$this
->partFactory->create();
$htmlPart
->setContent(
$content
)
->setType(Mime::TYPE_HTML)
->setCharset(
$this
->zendMessage->getEncoding());
$this
->parts[] =
$htmlPart
;
$mimeMessage
=
new
\Zend\Mime\Message();
$mimeMessage
->addPart(
$htmlPart
);
$this
->zendMessage->setBody(
$mimeMessage
);
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
)
->setType(
$fileType
)
->setFileName(
$fileName
)
->setDisposition(Mime::DISPOSITION_ATTACHMENT)
->setEncoding(Mime::ENCODING_BASE64);
$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
)
{
if
(
is_string
(
$body
) &&
$this
->messageType === self::TYPE_HTML) {
$body
= self::createHtmlMimeFromString(
$body
);
}
$this
->zendMessage->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
->zendMessage->setFrom(
$fromAddress
);
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();
}
private
function
createHtmlMimeFromString(
$htmlBody
)
{
$htmlPart
=
new
Part(
$htmlBody
);
$htmlPart
->setCharset(
$this
->zendMessage->getEncoding());
$htmlPart
->setType(Mime::TYPE_HTML);
$mimeMessage
=
new
\Zend\Mime\Message();
$mimeMessage
->addPart(
$htmlPart
);
return
$mimeMessage
;
}
/**
* @inheritDoc
*/
public
function
setMessageType(
$type
)
{
$this
->messageType =
$type
;
return
$this
;
}
}
After implementation of the Mail\Message class we need to extend the \Magento\Framework\Mail\Template\TransportBuilder class.
This class is used for building the \Magento\Framework\Mail\Transport class which is in turn used for email sending.Here, we will define our addAttachment() function.
Add TransportBuilder.php at Rewrite/Magento/Framework/Mail/Template/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 <?php
namespace
Magelearn\ContactAttachment\Rewrite\Magento\Framework\Mail\Template;
use
Magento\Framework\App\TemplateTypesInterface;
use
Magento\Framework\Exception\LocalizedException;
use
Magento\Framework\Exception\MailException;
use
Magento\Framework\Mail\EmailMessageInterface;
use
Magento\Framework\Mail\EmailMessageInterfaceFactory;
use
Magento\Framework\Mail\AddressConverter;
use
Magento\Framework\Mail\Exception\InvalidArgumentException;
use
Magento\Framework\Mail\MessageInterface;
use
Magento\Framework\Mail\MessageInterfaceFactory;
use
Magento\Framework\Mail\MimeInterface;
use
Magento\Framework\Mail\MimeMessageInterfaceFactory;
use
Magento\Framework\Mail\MimePartInterfaceFactory;
use
Magento\Framework\Mail\Template\FactoryInterface;
use
Magento\Framework\Mail\Template\SenderResolverInterface;
use
Magento\Framework\Mail\TemplateInterface;
use
Magento\Framework\Mail\TransportInterface;
use
Magento\Framework\Mail\TransportInterfaceFactory;
use
Magento\Framework\ObjectManagerInterface;
use
Magento\Framework\Phrase;
use
Zend\Mime\Mime;
use
Zend\Mime\PartFactory;
/**
* TransportBuilder
*
* @api
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @since 100.0.2
*/
class
TransportBuilder
extends
\Magento\Framework\Mail\Template\TransportBuilder
{
/**
* Template Identifier
*
* @var string
*/
protected
$templateIdentifier
;
/**
* Template Model
*
* @var string
*/
protected
$templateModel
;
/**
* Template Variables
*
* @var array
*/
protected
$templateVars
;
/**
* Template Options
*
* @var array
*/
protected
$templateOptions
;
/**
* Mail Transport
*
* @var TransportInterface
*/
protected
$transport
;
/**
* Template Factory
*
* @var FactoryInterface
*/
protected
$templateFactory
;
/**
* Object Manager
*
* @var ObjectManagerInterface
*/
protected
$objectManager
;
/**
* Message
*
* @var EmailMessageInterface
*/
protected
$message
;
/**
* Sender resolver
*
* @var SenderResolverInterface
*/
protected
$_senderResolver
;
/**
* @var TransportInterfaceFactory
*/
protected
$mailTransportFactory
;
/**
* Param that used for storing all message data until it will be used
*
* @var array
*/
private
$messageData
= [];
/**
* @var EmailMessageInterfaceFactory
*/
private
$emailMessageInterfaceFactory
;
/**
* @var MimeMessageInterfaceFactory
*/
private
$mimeMessageInterfaceFactory
;
/**
* @var MimePartInterfaceFactory
*/
private
$mimePartInterfaceFactory
;
/**
* @var AddressConverter|null
*/
private
$addressConverter
;
protected
$attachments
= [];
protected
$partFactory
;
/**
* TransportBuilder constructor
*
* @param FactoryInterface $templateFactory
* @param MessageInterface $message
* @param SenderResolverInterface $senderResolver
* @param ObjectManagerInterface $objectManager
* @param TransportInterfaceFactory $mailTransportFactory
* @param MessageInterfaceFactory|null $messageFactory
* @param EmailMessageInterfaceFactory|null $emailMessageInterfaceFactory
* @param MimeMessageInterfaceFactory|null $mimeMessageInterfaceFactory
* @param MimePartInterfaceFactory|null $mimePartInterfaceFactory
* @param addressConverter|null $addressConverter
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public
function
__construct(
FactoryInterface
$templateFactory
,
MessageInterface
$message
,
SenderResolverInterface
$senderResolver
,
ObjectManagerInterface
$objectManager
,
TransportInterfaceFactory
$mailTransportFactory
,
MessageInterfaceFactory
$messageFactory
= null,
EmailMessageInterfaceFactory
$emailMessageInterfaceFactory
= null,
MimeMessageInterfaceFactory
$mimeMessageInterfaceFactory
= null,
MimePartInterfaceFactory
$mimePartInterfaceFactory
= null,
AddressConverter
$addressConverter
= null
) {
$this
->templateFactory =
$templateFactory
;
$this
->objectManager =
$objectManager
;
$this
->_senderResolver =
$senderResolver
;
$this
->mailTransportFactory =
$mailTransportFactory
;
$this
->emailMessageInterfaceFactory =
$emailMessageInterfaceFactory
?:
$this
->objectManager
->get(EmailMessageInterfaceFactory::
class
);
$this
->mimeMessageInterfaceFactory =
$mimeMessageInterfaceFactory
?:
$this
->objectManager
->get(MimeMessageInterfaceFactory::
class
);
$this
->mimePartInterfaceFactory =
$mimePartInterfaceFactory
?:
$this
->objectManager
->get(MimePartInterfaceFactory::
class
);
$this
->addressConverter =
$addressConverter
?:
$this
->objectManager
->get(AddressConverter::
class
);
$this
->partFactory =
$objectManager
->get(PartFactory::
class
);
parent::__construct(
$templateFactory
,
$message
,
$senderResolver
,
$objectManager
,
$mailTransportFactory
,
$messageFactory
,
$emailMessageInterfaceFactory
,
$mimeMessageInterfaceFactory
,
$mimePartInterfaceFactory
,
$addressConverter
);
}
/**
* Add cc address
*
* @param array|string $address
* @param string $name
*
* @return $this
*/
public
function
addCc(
$address
,
$name
=
''
)
{
$this
->addAddressByType(
'cc'
,
$address
,
$name
);
return
$this
;
}
/**
* Add to address
*
* @param array|string $address
* @param string $name
*
* @return $this
* @throws InvalidArgumentException
*/
public
function
addTo(
$address
,
$name
=
''
)
{
$this
->addAddressByType(
'to'
,
$address
,
$name
);
return
$this
;
}
/**
* Add bcc address
*
* @param array|string $address
*
* @return $this
* @throws InvalidArgumentException
*/
public
function
addBcc(
$address
)
{
$this
->addAddressByType(
'bcc'
,
$address
);
return
$this
;
}
/**
* Set Reply-To Header
*
* @param string $email
* @param string|null $name
*
* @return $this
* @throws InvalidArgumentException
*/
public
function
setReplyTo(
$email
,
$name
= null)
{
$this
->addAddressByType(
'replyTo'
,
$email
,
$name
);
return
$this
;
}
/**
* Set mail from address
*
* @param string|array $from
*
* @return $this
* @throws InvalidArgumentException
* @see setFromByScope()
*
* @deprecated 102.0.1 This function sets the from address but does not provide
* a way of setting the correct from addresses based on the scope.
*/
public
function
setFrom(
$from
)
{
return
$this
->setFromByScope(
$from
);
}
/**
* Set mail from address by scopeId
*
* @param string|array $from
* @param string|int $scopeId
*
* @return $this
* @throws InvalidArgumentException
* @throws MailException
* @since 102.0.1
*/
public
function
setFromByScope(
$from
,
$scopeId
= null)
{
$result
=
$this
->_senderResolver->resolve(
$from
,
$scopeId
);
$this
->addAddressByType(
'from'
,
$result
[
'email'
],
$result
[
'name'
]);
return
$this
;
}
/**
* Set template identifier
*
* @param string $templateIdentifier
*
* @return $this
*/
public
function
setTemplateIdentifier(
$templateIdentifier
)
{
$this
->templateIdentifier =
$templateIdentifier
;
return
$this
;
}
/**
* Set template model
*
* @param string $templateModel
*
* @return $this
*/
public
function
setTemplateModel(
$templateModel
)
{
$this
->templateModel =
$templateModel
;
return
$this
;
}
/**
* Set template vars
*
* @param array $templateVars
*
* @return $this
*/
public
function
setTemplateVars(
$templateVars
)
{
$this
->templateVars =
$templateVars
;
return
$this
;
}
/**
* Set template options
*
* @param array $templateOptions
* @return $this
*/
public
function
setTemplateOptions(
$templateOptions
)
{
$this
->templateOptions =
$templateOptions
;
return
$this
;
}
/**
* Get mail transport
*
* @return TransportInterface
* @throws LocalizedException
*/
public
function
getTransport()
{
try
{
$this
->prepareMessage();
$mailTransport
=
$this
->mailTransportFactory->create([
'message'
=>
clone
$this
->message]);
} finally {
$this
->reset();
}
return
$mailTransport
;
}
/**
* Reset object state
*
* @return $this
*/
protected
function
reset()
{
$this
->messageData = [];
$this
->templateIdentifier = null;
$this
->templateVars = null;
$this
->templateOptions = null;
return
$this
;
}
/**
* Get template
*
* @return TemplateInterface
*/
protected
function
getTemplate()
{
return
$this
->templateFactory->get(
$this
->templateIdentifier,
$this
->templateModel)
->setVars(
$this
->templateVars)
->setOptions(
$this
->templateOptions);
}
/**
* Prepare message.
*
* @return $this
* @throws LocalizedException if template type is unknown
*/
protected
function
prepareMessage()
{
$template
=
$this
->getTemplate();
$content
=
$template
->processTemplate();
switch
(
$template
->
getType
()) {
case
TemplateTypesInterface::TYPE_TEXT:
$partType
= MimeInterface::TYPE_TEXT;
break
;
case
TemplateTypesInterface::TYPE_HTML:
$partType
= MimeInterface::TYPE_HTML;
break
;
default
:
throw
new
LocalizedException(
new
Phrase(
'Unknown template type'
)
);
}
$mimePart
=
$this
->mimePartInterfaceFactory->create(
[
'content'
=>
$content
,
'type'
=>
$partType
]
);
$parts
=
count
(
$this
->attachments) ?
array_merge
([
$mimePart
],
$this
->attachments) : [
$mimePart
];
$this
->messageData[
'body'
] =
$this
->mimeMessageInterfaceFactory->create(
[
'parts'
=>
$parts
]
);
$this
->messageData[
'subject'
] = html_entity_decode(
(string)
$template
->getSubject(),
ENT_QUOTES
);
$this
->message =
$this
->emailMessageInterfaceFactory->create(
$this
->messageData);
return
$this
;
}
/**
* Handles possible incoming types of email (string or array)
*
* @param string $addressType
* @param string|array $email
* @param string|null $name
*
* @return void
* @throws InvalidArgumentException
*/
private
function
addAddressByType(string
$addressType
,
$email
, ?string
$name
= null): void
{
if
(
is_string
(
$email
)) {
$this
->messageData[
$addressType
][] =
$this
->addressConverter->convert(
$email
,
$name
);
return
;
}
$convertedAddressArray
=
$this
->addressConverter->convertMany(
$email
);
if
(isset(
$this
->messageData[
$addressType
])) {
$this
->messageData[
$addressType
] =
array_merge
(
$this
->messageData[
$addressType
],
$convertedAddressArray
);
}
else
{
$this
->messageData[
$addressType
] =
$convertedAddressArray
;
}
}
/**
* @param string|null $content
* @param string|null $fileName
* @param string|null $fileType
* @return TransportBuilder
*/
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
;
}
}
Add Post.php file in Rewrite/Magento/Contact/Controller/Index/
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 <?php
namespace
Magelearn\ContactAttachment\Rewrite\Magento\Contact\Controller\Index;
use
Magento\Store\Model\StoreManagerInterface;
use
Magento\Contact\Model\ConfigInterface;
use
Magento\Contact\Model\MailInterface;
use
Magento\Framework\App\Action\Context;
use
Magento\Framework\App\Area;
use
Magento\Framework\App\Filesystem\DirectoryList;
use
Magento\Framework\App\Request\DataPersistorInterface;
use
Magento\Framework\Controller\Result\Redirect;
use
Magento\Framework\Exception\LocalizedException;
use
Magento\Framework\Filesystem;
use
Magento\Framework\Translate\Inline\StateInterface;
use
Psr\Log\LoggerInterface;
use
Magento\Framework\App\ObjectManager;
use
Magento\Framework\DataObject;
use
Magento\MediaStorage\Model\File\UploaderFactory;
use
Magelearn\ContactAttachment\Rewrite\Magento\Framework\Mail\Template\TransportBuilder;
use
Magento\Framework\App\Config\ScopeConfigInterface;
use
Magento\Framework\Filesystem\Io\File;
/**
* Post controller class
*/
class
Post
extends
\Magento\Contact\Controller\Index\Post
{
const
FOLDER_LOCATION =
'contactattachment'
;
/**
* @var DataPersistorInterface
*/
private
$dataPersistor
;
/**
* @var Context
*/
private
$context
;
/**
* @var MailInterface
*/
private
$mail
;
/**
* @var LoggerInterface
*/
private
$logger
;
/**
* @var UploaderFactory
*/
private
$fileUploaderFactory
;
/**
* @var Filesystem
*/
private
$fileSystem
;
/**
* @var StateInterface
*/
private
$inlineTranslation
;
/**
* @var ConfigInterface
*/
private
$contactsConfig
;
/**
* @var TransportBuilder
*/
private
$transportBuilder
;
/**
* @var StoreManagerInterface
*/
private
$storeManager
;
/**
* Post constructor.
* @param Context $context
* @param MailInterface $mail
* @param DataPersistorInterface $dataPersistor
* @param LoggerInterface|null $logger
* @param UploaderFactory $fileUploaderFactory
* @param Filesystem $fileSystem
* @param StateInterface $inlineTranslation
* @param ConfigInterface $contactsConfig
* @param TransportBuilder $transportBuilder
*/
public
function
__construct(
Context
$context
,
MailInterface
$mail
,
DataPersistorInterface
$dataPersistor
,
LoggerInterface
$logger
= null,
UploaderFactory
$fileUploaderFactory
,
Filesystem
$fileSystem
,
StateInterface
$inlineTranslation
,
ConfigInterface
$contactsConfig
,
TransportBuilder
$transportBuilder
,
StoreManagerInterface
$storeManager
,
ScopeConfigInterface
$scopeConfig
,
File
$file
) {
$this
->context =
$context
;
$this
->mail =
$mail
;
$this
->dataPersistor =
$dataPersistor
;
$this
->logger =
$logger
?: ObjectManager::getInstance()->get(LoggerInterface::
class
);
$this
->fileUploaderFactory =
$fileUploaderFactory
;
$this
->fileSystem =
$fileSystem
;
$this
->inlineTranslation =
$inlineTranslation
;
$this
->contactsConfig =
$contactsConfig
;
$this
->transportBuilder =
$transportBuilder
;
$this
->storeManager =
$storeManager
;
$this
->scopeConfig =
$scopeConfig
;
$this
->file =
$file
;
parent::__construct(
$context
,
$contactsConfig
,
$mail
,
$dataPersistor
,
$logger
);
}
/**
* Post user question
* @return Redirect
*/
public
function
execute()
{
if
(!
$this
->getRequest()->isPost()) {
return
$this
->resultRedirectFactory->create()->setPath(
'*/*/'
);
}
try
{
$this
->sendEmail(
$this
->validatedParams());
$this
->messageManager->addSuccessMessage(
__(
'Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.'
)
);
$this
->dataPersistor->clear(
'contact_us'
);
}
catch
(LocalizedException
$e
) {
$this
->messageManager->addErrorMessage(
$e
->getMessage());
$this
->dataPersistor->set(
'contact_us'
,
$this
->getRequest()->getParams());
}
catch
(\Exception
$e
) {
$this
->logger->critical(
$e
);
$this
->messageManager->addErrorMessage(
__(
'An error occurred while processing your form. Please try again later.'
)
);
$this
->dataPersistor->set(
'contact_us'
,
$this
->getRequest()->getParams());
}
return
$this
->resultRedirectFactory->create()->setPath(
'contact/index'
);
}
/**
* @param
array
$post
Post data from contact form
* @
return
void
*/
private
function
sendEmail(
$post
)
{
$this
->send(
$post
[
'email'
],
[
'data'
=>
new
DataObject(
$post
)]
);
}
/**
* Send email from contact form
* @param string $replyTo
* @param array $variables
* @return void
*/
public
function
send(
$replyTo
,
array
$variables
)
{
$filePath
= null;
$fileName
= null;
$uploaded
= false;
try
{
$fileCheck
=
$this
->fileUploaderFactory->create([
'fileId'
=>
'attachment'
]);
$file
=
$fileCheck
->validateFile();
$attachment
=
$file
[
'name'
] ?? null;
}
catch
(\Exception
$e
) {
$attachment
= null;
}
if
(
$attachment
) {
$upload
=
$this
->fileUploaderFactory->create([
'fileId'
=>
'attachment'
]);
$upload
->setAllowRenameFiles(true);
$upload
->setFilesDispersion(true);
$upload
->setAllowCreateFolders(true);
$upload
->setAllowedExtensions([
'txt'
,
'csv'
,
'jpg'
,
'jpeg'
,
'gif'
,
'png'
,
'pdf'
,
'doc'
,
'docx'
]);
$path
=
$this
->fileSystem
->getDirectoryRead(DirectoryList::MEDIA)
->getAbsolutePath(self::FOLDER_LOCATION);
$result
=
$upload
->save(
$path
);
$uploaded
= self::FOLDER_LOCATION .
$upload
->getUploadedFilename();
$filePath
=
$result
[
'path'
] .
$result
[
'file'
];
$fileName
=
$result
[
'name'
];
}
/** @see \Magento\Contact\Controller\Index\Post::validatedParams() */
$replyToName
= !
empty
(
$variables
[
'data'
][
'name'
]) ?
$variables
[
'data'
][
'name'
] : null;
$this
->inlineTranslation->suspend();
$storeScope
= \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
$transport
=
$this
->transportBuilder
->setTemplateIdentifier(
$this
->contactsConfig->emailTemplate())
->setTemplateOptions(
[
'area'
=> Area::AREA_FRONTEND,
'store'
=>
$this
->storeManager->getStore()->getId(),
]
)
->setTemplateVars(
$variables
)
->setFrom(
$this
->contactsConfig->emailSender())
->addTo(
$this
->contactsConfig->emailRecipient())
->setReplyTo(
$replyTo
,
$replyToName
)
->getTransport();
if
(
$uploaded
&& !
empty
(
$filePath
) &&
$this
->file->fileExists(
$filePath
)) {
$mimeType
= mime_content_type(
$filePath
);
$transport
=
$this
->transportBuilder
->setTemplateIdentifier(
$this
->contactsConfig->emailTemplate())
->setTemplateOptions(
[
'area'
=> Area::AREA_FRONTEND,
'store'
=>
$this
->storeManager->getStore()->getId(),
]
)
->addAttachment(
$this
->file->read(
$filePath
),
$fileName
,
$mimeType
)
->setTemplateVars(
$variables
)
->setFrom(
$this
->contactsConfig->emailSender())
->addTo(
$this
->contactsConfig->emailRecipient())
->setReplyTo(
$replyTo
,
$replyToName
)
->getTransport();
}
$transport
->sendMessage();
$this
->inlineTranslation->resume();
}
/**
* @return array
* @throws \Exception
*/
private
function
validatedParams()
{
$request
=
$this
->getRequest();
if
(trim(
$request
->getParam(
'name'
)) ===
''
) {
throw
new
LocalizedException(__(
'Name is missing'
));
}
if
(trim(
$request
->getParam(
'comment'
)) ===
''
) {
throw
new
LocalizedException(__(
'Comment is missing'
));
}
if
(false === \
strpos
(
$request
->getParam(
'email'
),
'@'
)) {
throw
new
LocalizedException(__(
'Invalid email address'
));
}
if
(trim(
$request
->getParam(
'hideit'
)) !==
''
) {
throw
new
LocalizedException(__(
'Error'
));
}
return
$request
->getParams();
}
}
Add email_templates.xml file inside etc/
12345678910 <?
xml
version
=
"1.0"
?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<
config
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation
=
"urn:magento:module:Magento_Email:etc/email_templates.xsd"
>
<
template
id
=
"contact_email_attachment_email_template"
label
=
"Contact Form with Attachment"
file
=
"submitted_form.html"
type
=
"html"
module
=
"Magelearn_ContactAttachment"
area
=
"frontend"
/>
</
config
>
Add submitted_form.html file inside view/frontend/email/
123456789101112131415161718192021222324252627282930313233 <!--@subject {{trans "Contact Form with Attachment"}} @-->
<!--@vars {
"var data.comment":"Comment",
"var data.email":"Sender Email",
"var data.name":"Sender Name",
"var data.telephone":"Sender Telephone",
"var data.attachment":"Sender Attachment"
} @-->
{{template config_path="design/email/header_template"}}
<
table
class
=
"message-details"
>
<
tr
>
<
td
><
strong
>{{trans "Name"}}</
strong
></
td
>
<
td
>{{var data.name}}</
td
>
</
tr
>
<
tr
>
<
td
><
strong
>{{trans "Email"}}</
strong
></
td
>
<
td
>{{var data.email}}</
td
>
</
tr
>
<
tr
>
<
td
><
strong
>{{trans "Phone"}}</
strong
></
td
>
<
td
>{{var data.telephone}}</
td
>
</
tr
>
<
tr
>
<
td
><
strong
>{{trans "Attachment"}}</
strong
></
td
>
<
td
>{{var data.attachment}}</
td
>
</
tr
>
</
table
>
<
p
><
strong
>{{trans "Message"}}</
strong
></
p
>
<
p
>{{var data.comment}}</
p
>
{{template config_path="design/email/footer_template"}}
After adding above files just run below commands:
php bin/magento set:upgphp bin/magento set:d:cphp bin/magento set:s:d -f en_USphp bin/magento c:cphp bin/magento set:c:f
You will find new browse buton will be added in contactus form and after submitting it admin email receipt will get email notification with attachment in mail.
Tag :
Magento2,
Magento2 Extensions
0 Comments On "Magento 2 add attachment to attach files to the contact us form"