Magento 2: Ekli e-posta gönder


Yanıtlar:


19

M2 kutudan çıkmaz, ancak zend çerçevesine yerleştirilmiş bir özelliktir. İşte bu işlevselliğin magento'ya nasıl ekleneceğine dair iyi bir referans: https://blog.bitexpert.de/blog/sending-mails-with-attachments-in-magento-2/

Bağlantının kesilmesi durumunda aşağıdakileri oluşturun

<?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;
    }
}

sonra etc / di.xml dosyasına ekleyin

<?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>

Artık addAttachment()sitenizin her yerinde kullanabilirsiniz .


8
Hala neden magento TransportBuilder bu yöntemi olmadığını merak ediyorum
Murtuza Zabuawala

4
Özel e-posta magento 2.3'e nasıl dosya ekleyebiliriz? çünkü zendframework 2 kullanıyor ve bu cevap artık çalışmıyor
Manish Maheshwari

3
Magento 2.3 içinde ekli e-posta nasıl gönderilir?
Dhaduk Mitesh

@ManishMaheshwari & Mitesh Çözümünüz var mı?
Sameer Bhayani

1
Bu çözüm Magento2.3'te artık çalışmıyor. Bağlanma alternatifi var mı?
nishu

8

Magento 2.2.7'den itibaren, yukarıda tarif edilen çözümler \Magento\Framework\Mail\Messagedüştükçe uzandığı için artık çalışmaz \Zend_Mail.
Aktarım oluşturucu aracılığıyla (şu anda böyle bir işlev için doğru yer gibi görünüyor) ekler eklemenin kolay bir yolunun eksikliğini önlemek için, birinin TransportBuilder için bir yedek oluşturması ve kullanılması gerekir \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;
    }
}

Orijinali \Magento\Framework\Mail\Template\TransportBuilderuygulamanızla değiştirmeyi unutmayın di.xml.

Bu uygulamanın, Magento'nun \Magento\Framework\Mail\MessageInterface::setBody()kullanımdan kaldırıldığı gibi yakında yayınlanacağını ve yakında kaldırılabileceğini unutmayın.

HTH


Selam! Kodunuzda addAttachment yönteminiz var, ancak bunları nereye çağırdınız? Görmüyorum.
Nikolai Silin

Teşekkürler! Iletisim yöntemi ve everithing çalışır döngü ekledi
Nikolai Silin

@NikolaiSilin nasıl bir png veya diğer dosyaları göndermek için.
sumeet bajaj

1

Magento 2 Modül'den özel e-posta, Görüntü eki sağlamaz.

Resim ekini Magento 2'de e-posta şablonlarıyla kullanmak istiyorsanız, sınıfı geçersiz kılmanız gerekir, Magento \ Framework \ Mail \ Template \ TransportBuilder

Kutudan çıktığı Magento, e-posta için ek özelliği sağlamaz. Resim eki göndermek için bloglara ayrıntılı olarak başvurabilir,

Aşağıdaki gibi bir mantık eklemeniz gerekir,

 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;
    }

1
Magento 2.3'te bunu başarmaya yardımcı olabilir misiniz?
Sameer Bhayani

Ekleri 2.2.7'ye kadar bu şekilde oluşturdu. 2.2.8 ve 2.3+ çalışmıyor
Matthias Kleine

Ben 2.3.x @MatthiasKleine
domdambrogia

merhaba, base64 kodlama dizesi varsa nasıl ekleyebilirim?
Ketan Borada

1

İşte magetno 2.3 e-posta pdf göndermek için mükemmel bir cevap

$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();

Merhaba,
Önemli

Aktarımınızda zaten bir mesaj olduğunda gereksiz olan yeni bir mesaj oluşturuyorsunuz. Neden sadece yerinde olana bir parça eklemiyorsunuz? Bu dağınık ve takip edilmesi zor. Bu sorunu çözmek için gereken işi ve belleği ikiye katladığınızdan bahsetmiyoruz bile.
domdambrogia

1

Magento 2.3.x Uyumlu:

Bu Magento 2.3 için cevabımdı, çünkü bu Google'da en iyi soru ve yorumlarda bir sürü insan var gibi görünüyor.

Diğer TransportBuildersınıflarda varsayılan sınıfın üzerine yazma konusunda çok fazla arzu var gibi görünüyor etc/di.xml, ancak üzerinde çalıştığım modül varsayılandan sorumlu olmasını istemediğim kadar küçükTransportBuilder yüzden bir Yardımcı sınıf ( büyük olasılıkla beyan edilen e-posta şablonuna ne kadar bağlı olduğuna dayanan bir model olabilir - ama konudan ayrıldım).

Bunun TransportBuilderherkese açık erişimi yoktur TransportInterface, bunun yerine her seferinde bir klon oluşturur ve ardından oluşturucuyu sıfırlar. Örneğimi oluşturmayı TransportInterfaceve sonra ek Partnesnelerimi aktarımın iletisine eklemeyi daha kolay buldum . TransportBuilderBağımlılık enjeksiyon tercihi ile varsayılanın üzerine yazmanın gerekli olduğunu düşünüyorsanız , genel yöntemleri güncellemeye dikkat edin. Uygulamaya unutmayın O kodunuzu tutarak zaman KATI !

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;
    }
}

Düzgün çalışması için alamıyorum, her zaman "Yakalanmayan Hata: üye işlev addPart () dize çağrısı" diyerek bir istisna olsun ... bu konuda herhangi bir fikir? : /
hallleron

1
@hallleron Garip bir şekilde bu benim aldığımdan farklı, ama haklısın. MessageInterface::getBodyYöntem imzası bir dize dönüş türünü gösterir. TransportInterfaceNesnenizde kazmak zorunda kalabilirsiniz , ancak addPartyöntemin bir Zend\Mime\Messagenesne üzerinde var olduğunu söyleyebilirim . Magento muhtemelen bu sınıfı kendi sınıfları için genişlettiğinden, Messagedenemek akıllıca olacağını düşünüyorum$transport->getMessage()->addpart($part);
domdambrogia

0

Önceki yanıtlarda belirtildiği gibi, magento2'nin ekleri olan postaları göndermek için hazır bir işlevi yoktur.

En iyi uygulama olup olmadığını bilmiyorum, ancak Zend_Mailözel bir işlev oluşturmadan ve geçersiz kılmadan Magento\Framework\Mail\Template\TransportBuilder, bunu yapmak için doğrudan sınıfı çağırabilirsiniz

$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();

-1 vermek önce, bu yorum textarea kullanmak için önerilmektedir, o zaman herkes neyin yanlış olduğunu anlayabiliyordu, thx
LucScu

$ ulaşım-> getMessage () -> setBody ($ bodypart);
imtiazau

yakalanmayan bu hatayı alıyorum: undefined yöntemini çağırın Magento \\ Framework \\ Mail \\ EmailMessage :: setBody ()
imtiazau

Bu yorumların cevabı ile ilgili değil
LucScu

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.