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 社区分享上述解决方案。
谢谢。