如何在 Magento 2.3.x 中添加电子邮件附件

https://meetanshi.com/blog/add-attachments-with-email-in-magento-2-3-x/



在 Magento 2.3.x 中添加电子邮件附件的方法:

  1. 在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;
        }
    }

Magento 2.3.3 添加邮件附件方法:


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

    谢谢。


    nba2k2球员数据
    请先登录后发表评论
    • 最新评论
    • 总共0条评论