2016-08-23 10 views
0

Ich muss einen neuen Transporttreiber zu Laravels Mail-Paket hinzufügen, damit ich E-Mails über einen externen Dienst (Mailjet) senden kann, der standardmäßig nicht unterstützt wird.Hinzufügen eines neuen Transporttreibers zu Laravels Mailer

Das Schreiben des Transporttreibers wird kein Problem sein, aber ich kann keine Möglichkeit finden, einen neuen einzufügen und hinzuzufügen, damit ich Laravels Mailer weiterhin normal verwenden kann. Ich kann keine Dokumentation finden, um den Mailer zu erweitern.

Der einzige Weg, ich würde kommen können zu ersetzen, wo die Laravel MailServiceProvider in config/app.php mit meinen eigenen Service-Provider verwiesen wird, die ich dann mein eigenes TransportManager und mein eigenes Transporttreiber registrieren nutzen könnte.

Gibt es eine bessere Möglichkeit, einen weiteren Transporttreiber hinzuzufügen?

+1

Ja, Sie müssen Ihre eigene "Mailer" -Klasse erstellen. Vorzugsweise sollte Ihre Klasse [Mailer] (https://github.com/laravel/framework/blob/5.1/src/Illuminate/Contracts/Mail/Mailer.php) und [MailQueue] (https://github.com) implementieren /laravel/framework/blob/5.1/src/Illuminate/Contracts/Mail/MailQueue.php) Schnittstellen. – Skysplit

+0

Danke für Ihre Antwort. Das scheint ein wenig übertrieben, nur um meinen eigenen Treiber für einen anderen Dienst hinzufügen zu können. Ich würde eher in Laravels Funktionalität einsteigen. Sehen Sie meine Antwort unten für wie ich es bis jetzt umgesetzt habe. – Jonathon

Antwort

5

Nun, ich habe es geschafft, funktioniert es in der Art und Weise, wie ich in meiner Frage vorgeschlagen (Durch Schreiben meiner eigenen ServiceProvider und TransportManager, damit ich einen Treiber bereitstellen). Das ist, was ich für jemand getan, die sich über diese kommen könnte:

config/app.php - Ersetzen Laravel des MailServiceProvider mit meinem eigenen

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

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

    // ... 

app/MyMailer/MailServiceProvider.php - erstellen Sie einen Dienstleister, der Laravel der MailServiceProvider und überschreiben die registerSwiftTransport() Methode

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

erstreckt app/MyMailer/TransportManager.php - Fügen Sie eine createMailjetDriver Methode, die zu Laravel des Mailer

meine MailjetTransport Treiber zur Verfügung stellt
<?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 - Meine eigenen Transport-Treiber, der senden e- Mails über Mailjet.

Aktualisiert, um meine Implementierung des Mailjet-Transporttreibers zu enthalten. Verwenden the Mailjet guide for sending a basic e-mail through their API als Basis.

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

In meiner .env Datei ich habe:

MAIL_DRIVER=mailjet 

..welche mich Laravel des Versenders Paket (durch die Fassade oder Dependency Injection) als normal verwenden können:

\Mail::send('view', [], function($message) { 
    $message->to('[email protected]'); 
    $message->subject('Test'); 
}); 
+0

Hast du am Ende funktioniert? Vielleicht mit der Mailjet API? 'MailjetTransport :: send()' –

+0

Ich habe die Implementierung noch nicht abgeschlossen, aber ich habe die Mailjet API bereits implementiert, daher bin ich ziemlich zuversichtlich, dass es funktionieren wird, wenn ich fertig bin. Ich benutze Guzzle, um ihren 'send'-Endpunkt zu treffen. – Jonathon

+0

Danke für die Tipps, ich werde das auch versuchen. –

Verwandte Themen