Câu trả lời:
M2 không đi kèm với hộp tuy nhiên nó là một tính năng được tích hợp trong khung zend. Dưới đây là một tài liệu tham khảo tốt về cách thêm chức năng này vào magento: https://blog.bitexpert.de/blog/seinating-mails-with-attachments-in-magento-2/
Trong trường hợp liên kết bị chết, hãy tạo như sau
<?php
namespace Your\CustomModule\Magento\Mail\Template;
class TransportBuilder
extends \Magento\Framework\Mail\Template\TransportBuilder
{
public function addAttachment(
$body,
$mimeType = Zend_Mime::TYPE_OCTETSTREAM,
$disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
$encoding = Zend_Mime::ENCODING_BASE64,
$filename = null
) {
$this->message->createAttachment($body, $mimeType, $disposition, $encoding, $filename);
return $this;
}
}
sau đó thêm vào 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">
<preference for="\Magento\Framework\Mail\Template\TransportBuilder"
type="\Your\CustomModule\Magento\Mail\Template\TransportBuilder" />
</config>
Bây giờ bạn có thể sử dụng addAttachment()
trên toàn bộ trang web của bạn.
Kể từ Magento 2.2.7, các giải pháp được mô tả ở trên không hoạt động nữa kể từ khi \Magento\Framework\Mail\Message
mở rộng \Zend_Mail
.
Để tránh việc thiếu một cách dễ dàng để thêm tệp đính kèm thông qua trình xây dựng giao thông (hiện tại có vẻ là vị trí chính xác cho chức năng đó), người ta cần tạo một thay thế cho TransportBuilder và sử dụng \Zend\Mime\Part
:
<?php
namespace Your\CustomModule\Magento\Mail\Template;
use Magento\Framework\Mail\MessageInterface;
use Magento\Framework\Mail\MessageInterfaceFactory;
use Magento\Framework\Mail\Template\FactoryInterface;
use Magento\Framework\Mail\Template\SenderResolverInterface;
use Magento\Framework\Mail\TransportInterfaceFactory;
use Magento\Framework\ObjectManagerInterface;
use Zend\Mime\Mime;
use Zend\Mime\Part as MimePart;
use Zend\Mime\PartFactory as MimePartFactory;
use Zend\Mime\Message as MimeMessage;
use Zend\Mime\MessageFactory as MimeMessageFactory;
class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
/** @var MimePart[] */
private $parts = [];
/** @var MimeMessageFactory */
private $mimeMessageFactory;
/** @var MimePartFactory */
private $mimePartFactory;
public function __construct(
FactoryInterface $templateFactory,
MessageInterface $message,
SenderResolverInterface $senderResolver,
ObjectManagerInterface $objectManager,
TransportInterfaceFactory $mailTransportFactory,
MimePartFactory $mimePartFactory,
MimeMessageFactory $mimeMessageFactory,
MessageInterfaceFactory $messageFactory = null
) {
parent::__construct(
$templateFactory,
$message,
$senderResolver,
$objectManager,
$mailTransportFactory,
$messageFactory
);
$this->mimePartFactory = $mimePartFactory;
$this->mimeMessageFactory = $mimeMessageFactory;
}
protected function prepareMessage()
{
parent::prepareMessage();
$mimeMessage = $this->getMimeMessage($this->message);
foreach ($this->parts as $part) {
$mimeMessage->addPart($part);
}
$this->message->setBody($mimeMessage);
return $this;
}
public function addAttachment(
$body,
$mimeType = Mime::TYPE_OCTETSTREAM,
$disposition = Mime::DISPOSITION_ATTACHMENT,
$encoding = Mime::ENCODING_BASE64,
$filename = null
) {
$this->parts[] = $this->createMimePart($body, $mimeType, $disposition, $encoding, $filename);
return $this;
}
private function createMimePart(
$content,
$type = Mime::TYPE_OCTETSTREAM,
$disposition = Mime::DISPOSITION_ATTACHMENT,
$encoding = Mime::ENCODING_BASE64,
$filename = null
) {
/** @var MimePart $mimePart */
$mimePart = $this->mimePartFactory->create(['content' => $content]);
$mimePart->setType($type);
$mimePart->setDisposition($disposition);
$mimePart->setEncoding($encoding);
if ($filename) {
$mimePart->setFileName($filename);
}
return $mimePart;
}
private function getMimeMessage(MessageInterface $message)
{
$body = $message->getBody();
if ($body instanceof MimeMessage) {
return $body;
}
/** @var MimeMessage $mimeMessage */
$mimeMessage = $this->mimeMessageFactory->create();
if ($body) {
$mimePart = $this->createMimePart((string)$body, Mime::TYPE_TEXT, Mime::DISPOSITION_INLINE);
$mimeMessage->setParts([$mimePart]);
}
return $mimeMessage;
}
}
Đừng quên thay thế bản gốc \Magento\Framework\Mail\Template\TransportBuilder
bằng cách triển khai của bạn thông qua di.xml
.
Lưu ý rằng việc triển khai này có thể sẽ bị phá vỡ với bản phát hành sắp tới của Magento vì \Magento\Framework\Mail\MessageInterface::setBody()
không được chấp nhận và có thể bị xóa sớm.
HTH
Magento 2 Email tùy chỉnh từ Module, Không cung cấp tệp đính kèm hình ảnh.
Nếu bạn muốn sử dụng tệp đính kèm hình ảnh với các mẫu email trong Magento 2, bạn cần ghi đè lớp, Magento \ Framework \ Mail \ Template \ TransportBuilder
Magento Out-of-box không cung cấp tính năng đính kèm cho email. Bạn có thể giới thiệu blog để gửi tệp đính kèm hình ảnh chi tiết,
Bạn cần thêm logic như cách dưới đây,
public function addAttachment(
$body,
$mimeType = \Zend_Mime::TYPE_OCTETSTREAM,
$disposition = \Zend_Mime::DISPOSITION_ATTACHMENT,
$encoding = \Zend_Mime::ENCODING_BASE64,
$filename = null
) {
$this->message->createAttachment($body, $mimeType, $disposition, $encoding, $filename);
return $this;
}
Đây là câu trả lời hoàn hảo để gửi pdf trong Email trong magetno 2.3
$transport = $_transportBuilder->setTemplateIdentifier(20)
->setTemplateOptions($templateOptions)
->setTemplateVars($templateVars)
->setFrom($from)
->addTo($vendor_email)
->getTransport();
$html = $transport->getMessage()>getBody()->generateMessage();
$bodyMessage = new \Zend\Mime\Part($html);
$bodyMessage->type = 'text/html';
$attachment = $_transportBuilder->addAttachment($pdfData,$fileName);
$bodyPart = new \Zend\Mime\Message();
$bodyPart->setParts(array($bodyMessage,$attachment));
$transport->getMessage()->setBody($bodyPart);
$transport->sendMessage();
$inlineTranslation->resume();
Như đã đề cập trong các câu trả lời trước, magento2 không có chức năng ngoài hộp để gửi thư có tệp đính kèm.
Tôi không biết nếu đó là một cách thực hành tốt nhất, nhưng bạn có thể gọi Zend_Mail
lớp trực tiếp để thực hiện, mà không cần tạo chức năng tùy chỉnh và ghi đè Magento\Framework\Mail\Template\TransportBuilder
, như bên dưới
$mail = new \Zend_Mail('utf-8');
$mail->setFrom($senderEmail);
$mail->addTo($receiverEmail);
$mail->setSubject($subject);
$mail->setBodyHtml($text);
$content = file_get_contents($attachmentAbsolutePath);
$attachment = new \Zend_Mime_Part($content);
$attachment->type = 'text/xml'; // attachment's mime type
$attachment->disposition = \Zend_Mime::DISPOSITION_ATTACHMENT;
$attachment->encoding = \Zend_Mime::ENCODING_BASE64;
$attachment->filename = $filename;
$mail->addAttachment($attachment);
$mail->send();
Đây là câu trả lời của tôi cho Magento 2.3 vì đây là câu hỏi hàng đầu trên google và dường như có rất nhiều người trong các bình luận đang tìm kiếm.
Dường như có rất nhiều mong muốn trong các bài đăng khác về việc ghi đè TransportBuilder
lớp mặc định thông qua etc/di.xml
, tuy nhiên mô-đun tôi đang làm việc quá nhỏ đến mức tôi không muốn nó chịu trách nhiệm về mặc định TransportBuilder
nên tôi đã xây dựng lớp Trình trợ giúp (nên có thể là một mô hình dựa trên cách kết hợp nó với mẫu email được khai báo - nhưng tôi lạc đề).
Các TransportBuilder
không có quyền truy cập công cộng đến TransportInterface
, nhưng thay vì tạo ra một bản sao mỗi lần và sau đó reset builder. Tôi thấy việc xây dựng TransportInterface
cá thể của mình dễ dàng hơn và sau đó đính kèm Part
các đối tượng đính kèm của tôi vào thông điệp của phương tiện giao thông. Nếu bạn thấy cần phải ghi đè mặc định TransportBuilder
thông qua tùy chọn tiêm phụ thuộc, hãy cẩn thận về việc cập nhật các phương thức công khai. Hãy nhớ thực hành O khi giữ mã của bạn RẮN !
namespace Vendor\Module\Helper;
use Magento\Framework\App\Area;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\DataObject;
use Magento\Framework\Filesystem\Io\File;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Mail\TransportInterface;
use Magento\Store\Model\StoreManagerInterface;
use Zend_Mime;
use Zend\Mime\Part;
/**
* This was initially built out to send a single email. Abstract this as you
* wish.
*
* @package Vendor\Module\Helper
*/
class Mail extends AbstractHelper
{
/**
* @var Context
*/
protected $context;
/**
* @var TransportBuilder
*/
protected $transportBuilder;
/**
* @var StoreManagerInterface
*/
protected $storeManager;
/**
* @var Config
*/
protected $config;
/**
* Mail constructor.
*
* @param Context $context
* @param TransportBuilder $transportBuilder
* @param StoreManagerInterface $storeManager
* @param Config $config
* @param File $file
*/
public function __construct(
Context $context,
TransportBuilder $transportBuilder,
StoreManagerInterface $storeManager,
Config $config,
File $file
) {
parent::__construct($context);
$this->transportBuilder = $transportBuilder;
$this->storeManager = $storeManager;
$this->config = $config;
$this->file = $file;
}
/**
* Send the email for a Help Center submission.
*
* @param DataObject $templateParams
* @param array $attachments
* @return void
*/
public function send(DataObject $templateParams, array $attachments = [])
{
$storeId = $this->storeManager->getStore()->getId();
// Build transport
/** @var \Magento\Framework\Mail\TransportInterface $transport */
$transport = $this->transportBuilder
->setTemplateOptions(['area' => Area::AREA_FRONTEND, 'store' => $storeId])
->setTemplateIdentifier($this->config->getEmailTemplate())
->setTemplateVars($templateParams->toArray())
->setFrom($this->config->getEmailSender())
->addTo($this->config->getEmailRecipient(), 'Help Center')
/**
* Something important to note is that when the getTransport()
* function is run, the message is compiled and then the builder
* class resets (as of 2.3.1).
*
* This is note worthy because if you want to send > 1 attachment,
* your $builder will be reset -- losing all of the ->set* functions
* you just used above as well as your attachment.
*
* Since we append attachments to the transport, it's easier to:
* build -> attach -> send. And this way multiple attachments
* can be included. :thumbsup:
*/
->getTransport();
// Attach Images to transport
foreach ($attachments as $a) {
$transport = $this->addAttachment($transport, $a);
}
// Send transport
$transport->sendMessage();
}
/**
* Add an attachment to the message inside the transport builder.
*
* @param TransportInterface $transportBuilder
* @param array $file Sanitized index from $_FILES
* @return TransportInterface
*/
protected function addAttachment(TransportInterface $transport, array $file): TransportInterface
{
$part = $this->createAttachment($file);
$transport->getMessage()->addPart($part);
return $transport;
}
/**
* Create an zend mime part that is an attachment to attach to the email.
*
* This was my usecase, you'll need to edit this to your own needs.
*
* @param array $file Sanitized index from $_FILES
* @return Part
*/
protected function createAttachment(array $file): Part
{
$ext = '.' . explode('/', $file['type'])[1];
$fileName = md5(uniqid(microtime()), true) . $ext;
$attachment = new Part($this->file->read($file['tmp_name']));
$attachment->disposition = Zend_Mime::TYPE_OCTETSTREAM;
$attachment->encoding = Zend_Mime::ENCODING_BASE64;
$attachment->filename = $fileName;
return $attachment;
}
}
MessageInterface::getBody
phương pháp chữ ký cho thấy một loại chuỗi trở lại. Bạn có thể phải đào xung quanh trong TransportInterface
đối tượng của mình , nhưng tôi có thể nói với bạn rằng addPart
phương thức này tồn tại trên một Zend\Mime\Message
đối tượng. Vì magento có khả năng mở rộng lớp học đó cho lớp học của riêng họ Message
, tôi nghĩ sẽ rất thông minh khi thử$transport->getMessage()->addpart($part);