https://meetanshi.com/blog/add-attachments-with-email-in-magento-2-3-x/
在di.xml中添加以下代码注意:如果你想在前端附加文件- vendor\module\etc\frontend\di.xml如果你想在后端
附加文件- vendor\module\etc\adminhtml\di。 xml如果你想在前端和后端附加文件- vendor\module\etc\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"> <type name="Vendor\Module\Mail\Template\TransportBuilder"> <arguments> <argument name="message" xsi:type="object" >vendor\module\Mail\Message</argument> <argument name="messageFactory" xsi:type="object" >vendor\module\Mail\MessageFactory</argument> </arguments> </type> </config>
在Vendor\Module\Mail\Message.php中创建Message.php 文件
<?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;
use Magento\Framework\Mail\MailMessageInterface;
class Message implements MailMessageInterface
{
protected $partFactory;
protected $mimeMessageFactory;
private $zendMessage;
protected $parts = [];
public function __construct(
PartFactory $partFactory,
MimeMessageFactory $mimeMessageFactory,
$charset = 'utf-8'
)
{
$this->partFactory = $partFactory;
$this->mimeMessageFactory = $mimeMessageFactory;
$this->zendMessage = MailMessageFactory::getInstance();
$this->zendMessage->setEncoding($charset);
}
public function setBodyText($content)
{
$textPart = $this->partFactory->create();
$textPart->setContent($content)
->setType(Mime::TYPE_TEXT)
->setCharset($this->zendMessage->getEncoding());
$this->parts[] = $textPart;
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;
}
public function setBodyAttachment($content, $fileName)
{
$fileType = Mime::TYPE_OCTETSTREAM;
$attachmentPart = $this->partFactory->create();
$attachmentPart->setContent($content)
->setType($fileType)
->setFileName($fileName)
->setDisposition(Mime::DISPOSITION_ATTACHMENT)
->setEncoding(Mime::ENCODING_BASE64);
$this->parts[] = $attachmentPart;
return $this;
}
public function setPartsToBody()
{
$mimeMessage = $this->mimeMessageFactory->create();
$mimeMessage->setParts($this->parts);
$this->zendMessage->setBody($mimeMessage);
return $this;
}
public function setBody($body)
{
return $this;
}
public function setSubject($subject)
{
$this->zendMessage->setSubject($subject);
return $this;
}
public function getSubject()
{
return $this->zendMessage->getSubject();
}
public function getBody()
{
return $this->zendMessage->getBody();
}
public function setFrom($fromAddress)
{
$this->zendMessage->setFrom($fromAddress);
return $this;
}
public function addTo($toAddress)
{
$this->zendMessage->addTo($toAddress);
return $this;
}
public function addCc($ccAddress)
{
$this->zendMessage->addCc($ccAddress);
return $this;
}
public function addBcc($bccAddress)
{
$this->zendMessage->addBcc($bccAddress);
return $this;
}
public function setReplyTo($replyToAddress)
{
$this->zendMessage->setReplyTo($replyToAddress);
return $this;
}
public function getRawMessage()
{
return $this->zendMessage->toString();
}
public function setMessageType($type)
{
return $this;
}
}在Vendor\Module\Mail\MessageFactory.php中创建MessageFactory.php文件
<?php
namespace Vendor\Module\Mail;
class MessageFactory extends \Magento\Framework\Mail\MessageInterfaceFactory
{
/**
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $_objectManager;
/**
* Factory constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param string $instanceName
*/
public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Extait\\Attachment\\Mail\\Message')
{
$this->_objectManager = $objectManager;
$this->_instanceName = $instanceName;
}
/**
* Create class instance with specified parameters
*
* @param array $data
* @return \Magento\Framework\Mail\MessageInterface
*/
public function create(array $data = [])
{
return $this->_objectManager->create($this->_instanceName, $data);
}
}在Vendor\Module\Model\Mail\Template\TransportBuilder.php中创建TransportBuilder.php 文件
<?php
namespace Vendor\Module\Model\Mail\Template;
class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
public function addAttachment($fileString,$filename)
{
$arrContextOptions = [
"ssl" => [
"verify_peer" => false,
"verify_peer_name" => false,
]
];
/* if $fileString is url of file */
$this->message->setBodyAttachment(file_get_contents($fileString, false, stream_context_create($arrContextOptions)), $filename);
/* if $fileString is string data */
$this->message->setBodyAttachment($fileString, $filename);
return $this;
}
protected function prepareMessage()
{
parent::prepareMessage();
$this->message->setPartsToBody();
return $this;
}
}在要在电子邮件中添加附件的文件中使用TransportBuilder 对象。
例如 Vendor/Module/Helper/Data.php
<?php
namespace Vendor\Extension\Helper;
use Magento\Customer\Model\Session;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
const XML_PATH_EMAIL_DEMO = 'emaildemo/email/email_demo_template';
protected $inlineTranslation;
protected $transportBuilder;
protected $template;
protected $storeManager;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
\Vendor\Module\Model\Mail\Template\TransportBuilder $transportBuilder,
\Magento\Store\Model\StoreManagerInterface $storeManager
)
{
$this->inlineTranslation = $inlineTranslation;
$this->transportBuilder = $transportBuilder;
$this->storeManager = $storeManager;
parent::__construct($context);
}
public function generateTemplate()
{
// path for attachment File
$attachmentFile = 'file_path/email.pdf';
$fileName = 'email.pdf';
$emailTemplateVariables['message'] = 'This is a test message by meetanshi.';
//load your email tempate
$this->_template = $this->scopeConfig->getValue(
self::XML_PATH_EMAIL_DEMO,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$this->_storeManager->getStore()->getStoreId()
);
$this->_inlineTranslation->suspend();
$this->_transportBuilder->setTemplateIdentifier($this->_template)
->setTemplateOptions(
[
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => $this->_storeManager->getStore()->getId(),
]
)
->setTemplateVars($emailTemplateVariables)
->setFrom([
'name' => 'Meetanshi',
'email' => 'meetanshi@meetanshi.com',
])
->addTo('yourname@gmail.com', 'Your Name')
->addAttachment($attachmentFile,$fileName); //Attachment goes here.
try {
$transport = $this->_transportBuilder->getTransport();
$transport->sendMessage();
$this->_inlineTranslation->resume();
} catch (\Exception $e) {
echo $e->getMessage(); die;
}
}在app/code/vendor/module/etc/创建di.xml文件
<preference for="\Magento\Framework\Mail\Template\TransportBuilder" type="Vendor\Module\Model\Mail\Template\TransportBuilder" />
在app/code/vendor/module/model/mail/template/创建TransportBuilder.php
<?php
declare(strict_types=1);
namespace Vendor\Module\Model\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:
$part['type'] = MimeInterface::TYPE_TEXT;
break;
case TemplateTypesInterface::TYPE_HTML:
$part['type'] = MimeInterface::TYPE_HTML;
break;
default:
throw new LocalizedException(
new Phrase('Unknown template type')
);
}
$mimePart = $this->mimePartInterfaceFactory->create(['content' => $content]);
$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
);
}
}
/**
* @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;
}
}在电子邮件中添加附件,例如:
$this->transportBuilder->addAttachment($content, $fileName, 'application/pdf');
这就是在 Magento 2.3.x 中实现带有附件的电子邮件所需要做的全部
请使用下面的评论部分提出对该主题的任何疑问。我很乐意帮助你。
您可以通过社交媒体与 Magento 社区分享上述解决方案。
谢谢。