php laravel laravel-5 laravel-5.2

php - Agregue un nuevo controlador de transporte a Laravel''s Mailer



laravel-5 laravel-5.2 (1)

Bueno, he logrado que funcione de la manera que sugerí en mi pregunta (escribiendo mi propio ServiceProvider y TransportManager para permitirme proporcionar un controlador). Esto es lo que he hecho para cualquiera que se encuentre con esto:

config / app.php - Reemplace MailServiceProvider de Laravel con el mío

// ... ''providers'' => [ // ... // Illuminate/Mail/MailServiceProvider::class, App/MyMailer/MailServiceProvider::class, // ...

app / MyMailer / MailServiceProvider.php : cree un proveedor de servicios que amplíe MailServiceProvider de Laravel y anule el método registerSwiftTransport()

<?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 - Agregue un método createMailjetDriver que haga que mi controlador MailjetTransport esté disponible para 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 - Mi propio controlador de transporte que envía correos electrónicos a través de Mailjet.

Actualizado para contener mi implementación del controlador de transporte Mailjet. Usando la guía de Mailjet para enviar un correo electrónico básico a través de su API como 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); } } } }

En mi archivo .env tengo:

MAIL_DRIVER=mailjet

..que me permite usar el paquete de correo de Laravel (a través de Facade o inyección de dependencia) de forma normal:

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

Necesito agregar un nuevo controlador de transporte al paquete de correo de Laravel para que pueda enviar correos electrónicos a través de un servicio externo (Mailjet) que no es compatible por defecto.

Escribir el controlador de transporte no será un problema, pero no puedo encontrar una manera de engancharme y agregar uno nuevo para poder seguir utilizando el programa de Laravel como siempre. No puedo encontrar ninguna documentación sobre la extensión de la Aplicación de correo.

La única forma en que se me ocurre es reemplazar donde se hace referencia al MailServiceProvider de Laravel en config/app.php con mi propio proveedor de servicios, que luego podría usar para registrar mi propio TransportManager y mi propio controlador de transporte.

¿Hay una mejor manera de agregar otro controlador de transporte?