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?