在Laravel的Mailer中添加新的传输驱动程序 [英] Add a new transport driver to Laravel's Mailer

查看:67
本文介绍了在Laravel的Mailer中添加新的传输驱动程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Laravel的邮件包中添加一个新的传输驱动程序,以便我可以通过默认情况下不支持的外部服务(Mailjet)发送电子邮件.

I need to add a new transport driver to Laravel's mail package so that I can send e-mails through an external service (Mailjet) that isn't supported by default.

编写传输驱动程序不会有问题,但是我找不到连接并添加新驱动程序的方法,因此我可以像往常一样继续使用Laravel的邮件程序.我找不到有关扩展Mailer的任何文档.

Writing the transport driver won't be a problem, but I can't find a way to hook in and add a new one so I can continue to use Laravel's mailer as normal. I can't find any documentation on extending the Mailer.

我想出的唯一方法是用我自己的服务提供商替换在config/app.php中引用Laravel MailServiceProvider的位置,然后我可以使用它注册我自己的TransportManager和我自己的传输驱动程序

The only way I can come up with would be to replace where Laravel's MailServiceProvider is being referenced in config/app.php with my own service provider, which I could then use to register my own TransportManager and my own transport driver.

是否有更好的方法来添加另一个传输驱动程序?

Is there a better way to add another transport driver?

推荐答案

好,我设法按照问题中的建议进行工作(通过编写自己的ServiceProviderTransportManager来允许我提供驱动程序).这是我为可能遇到此问题的任何人所做的事情:

Well I've managed to get it working in the way I suggested in my question (By writing my own ServiceProvider and TransportManager to allow me to provider a driver). This is what I've done for anyone that might come across this:

config/app.php -用我自己的替换Laravel的MailServiceProvider

config/app.php - Replace Laravel's MailServiceProvider with my own

// ...
'providers' => [
    // ...

    // Illuminate\Mail\MailServiceProvider::class,
    App\MyMailer\MailServiceProvider::class,

    // ...

app/MyMailer/MailServiceProvider.php -创建一个扩展Laravel MailServiceProvider并覆盖registerSwiftTransport()方法

app/MyMailer/MailServiceProvider.php - Create a service provider that extends Laravel's MailServiceProvider and override the registerSwiftTransport() method

<?php

namespace App\MyMailer;

class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider
{
    public function registerSwiftTransport()
    {
        $this->app['swift.transport'] = $this->app->share(function ($app) {
            // Note: This is my own implementation of transport manager as shown below
            return new TransportManager($app);
        });
    }
}

app/MyMailer/TransportManager.php -添加createMailjetDriver方法,使我的MailjetTransport驱动程序可用于Laravel Mailer

app/MyMailer/TransportManager.php - Add a createMailjetDriver method which makes my MailjetTransport driver available to Laravel's Mailer

<?php

namespace App\MyMailer;

use App\MyMailer\Transport\MailjetTransport;

class TransportManager extends \Illuminate\Mail\TransportManager
{
    protected function createMailjetDriver()
    {
        $config = $this->app['config']->get('services.mailjet', []);

        return new MailjetTransport(
            $this->getHttpClient($config),
            $config['api_key'],
            $config['secret_key']
        );
    }
}

app/MyMailer/Transport/MailjetTransport.php -我自己的传输驱动程序,可通过Mailjet发送电子邮件.

app/MyMailer/Transport/MailjetTransport.php - My own Transport driver that sends e-mails through Mailjet.

已更新,其中包含我对Mailjet传输驱动程序的实现.使用 Mailjet指南通过其API发送基本电子邮件作为基础.

Updated to contain my implementation of the Mailjet transport driver. Using the Mailjet guide for sending a basic e-mail through their API as a base.

<?php

namespace App\MyMailer\Transport;

use GuzzleHttp\ClientInterface;
use Illuminate\Mail\Transport\Transport;
use Swift_Mime_Message;

class MailjetTransport extends Transport
{
    /**
     * Guzzle HTTP client.
     *
     * @var ClientInterface
     */
    protected $client;

    /**
     * The Mailjet "API key" which can be found at https://app.mailjet.com/transactional
     *
     * @var string
     */
    protected $apiKey;

    /**
     * The Mailjet "Secret key" which can be found at https://app.mailjet.com/transactional
     *
     * @var string
     */
    protected $secretKey;

    /**
     * The Mailjet end point we're using to send the message.
     *
     * @var string
     */
    protected $endPoint = 'https://api.mailjet.com/v3/send';

    /**
     * Create a new Mailjet transport instance.
     *
     * @param  \GuzzleHttp\ClientInterface $client
     * @param $apiKey
     * @param $secretKey
     */
    public function __construct(ClientInterface $client, $apiKey, $secretKey)
    {
        $this->client = $client;
        $this->apiKey = $apiKey;
        $this->secretKey = $secretKey;
    }

    /**
     * Send the given Message.
     *
     * Recipient/sender data will be retrieved from the Message API.
     * The return value is the number of recipients who were accepted for delivery.
     *
     * @param Swift_Mime_Message $message
     * @param string[] $failedRecipients An array of failures by-reference
     *
     * @return int
     */
    public function send(Swift_Mime_Message $message, &$failedRecipients = null)
    {
        $this->beforeSendPerformed($message);

        $payload = [
            'header' => ['Content-Type', 'application/json'],
            'auth' => [$this->apiKey, $this->secretKey],
            'json' => []
        ];

        $this->addFrom($message, $payload);
        $this->addSubject($message, $payload);
        $this->addContent($message, $payload);
        $this->addRecipients($message, $payload);

        return $this->client->post($this->endPoint, $payload);
    }

    /**
     * Add the from email and from name (If provided) to the payload.
     *
     * @param Swift_Mime_Message $message
     * @param array $payload
     */
    protected function addFrom(Swift_Mime_Message $message, &$payload)
    {
        $from = $message->getFrom();

        $fromAddress = key($from);
        if ($fromAddress) {
            $payload['json']['FromEmail'] = $fromAddress;

            $fromName = $from[$fromAddress] ?: null;
            if ($fromName) {
                $payload['json']['FromName'] = $fromName;
            }
        }
    }

    /**
     * Add the subject of the email (If provided) to the payload.
     *
     * @param Swift_Mime_Message $message
     * @param array $payload
     */
    protected function addSubject(Swift_Mime_Message $message, &$payload)
    {
        $subject = $message->getSubject();
        if ($subject) {
            $payload['json']['Subject'] = $subject;
        }
    }

    /**
     * Add the content/body to the payload based upon the content type provided in the message object. In the unlikely
     * event that a content type isn't provided, we can guess it based on the existence of HTML tags in the body.
     *
     * @param Swift_Mime_Message $message
     * @param array $payload
     */
    protected function addContent(Swift_Mime_Message $message, &$payload)
    {
        $contentType = $message->getContentType();
        $body = $message->getBody();

        if (!in_array($contentType, ['text/html', 'text/plain'])) {
            $contentType = strip_tags($body) != $body ? 'text/html' : 'text/plain';
        }

        $payload['json'][$contentType == 'text/html' ? 'Html-part' : 'Text-part'] = $message->getBody();
    }

    /**
     * Add to, cc and bcc recipients to the payload.
     *
     * @param Swift_Mime_Message $message
     * @param array $payload
     */
    protected function addRecipients(Swift_Mime_Message $message, &$payload)
    {
        foreach (['To', 'Cc', 'Bcc'] as $field) {
            $formatted = [];
            $method = 'get' . $field;
            $contacts = (array) $message->$method();
            foreach ($contacts as $address => $display) {
                $formatted[] = $display ? $display . " <$address>" : $address;
            }

            if (count($formatted) > 0) {
                $payload['json'][$field] = implode(', ', $formatted);
            }
        }
    }
}

在我的.env文件中,我有:

MAIL_DRIVER=mailjet

..这使我可以正常使用Laravel的mailer软件包(通过Facade或依赖项注入):

..which allows me to use Laravel's mailer package (Through the Facade or dependency injection) as normal:

\Mail::send('view', [], function($message) {
    $message->to('me@domain.com');
    $message->subject('Test');
});

这篇关于在Laravel的Mailer中添加新的传输驱动程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆