Created
September 25, 2019 01:56
-
-
Save hailwood/2fa45c53e2b00f4ec8a8c69c2c1d3f50 to your computer and use it in GitHub Desktop.
Laravel Alternative Mailer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Services\AlternateMailer; | |
use Illuminate\Mail\Mailer; | |
use Swift_Mailer; | |
use Illuminate\Support\Arr; | |
use Illuminate\Support\Str; | |
use Swift_DependencyContainer; | |
use Illuminate\Support\ServiceProvider; | |
class AlternateMailerServiceProvider extends ServiceProvider | |
{ | |
/** | |
* Indicates if loading of the provider is deferred. | |
* | |
* @var bool | |
*/ | |
protected $defer = true; | |
/** | |
* Register the service provider. | |
* | |
* @return void | |
*/ | |
public function register() | |
{ | |
$this->registerSwiftMailer(); | |
$this->registerIlluminateMailer(); | |
} | |
/** | |
* Register the Illuminate mailer instance. | |
* | |
* @return void | |
*/ | |
protected function registerIlluminateMailer() | |
{ | |
$this->app->singleton('alternate-mailer.mailer', function () { | |
$config = $this->app->make('config')->get('alternate-mailer'); | |
// Once we have create the mailer instance, we will set a container instance | |
// on the mailer. This allows us to resolve mailer classes via containers | |
// for maximum testability on said classes instead of passing Closures. | |
$mailer = new Mailer( | |
$this->app['view'], | |
$this->app['alternate-mailer.swift.mailer'], | |
$this->app['events'] | |
); | |
if ($this->app->bound('queue')) { | |
$mailer->setQueue($this->app['queue']); | |
} | |
// Next we will set all of the global addresses on this mailer, which allows | |
// for easy unification of all "from" addresses as well as easy debugging | |
// of sent messages since they get be sent into a single email address. | |
foreach (['from', 'reply_to', 'to'] as $type) { | |
$this->setGlobalAddress($mailer, $config, $type); | |
} | |
return $mailer; | |
}); | |
} | |
/** | |
* Set a global address on the mailer by type. | |
* | |
* @param \Illuminate\Mail\Mailer $mailer | |
* @param array $config | |
* @param string $type | |
* @return void | |
*/ | |
protected function setGlobalAddress($mailer, array $config, $type) | |
{ | |
$address = Arr::get($config, $type); | |
if (is_array($address) && isset($address['address'])) { | |
$mailer->{'always'.Str::studly($type)}($address['address'], $address['name']); | |
} | |
} | |
/** | |
* Register the Swift Mailer instance. | |
* | |
* @return void | |
*/ | |
public function registerSwiftMailer() | |
{ | |
$this->registerSwiftTransport(); | |
// Once we have the transporter registered, we will register the actual Swift | |
// mailer instance, passing in the transport instances, which allows us to | |
// override this transporter instances during app start-up if necessary. | |
$this->app->singleton('alternate-mailer.swift.mailer', function () { | |
if ($domain = $this->app->make('config')->get('alternate-mailer.domain')) { | |
Swift_DependencyContainer::getInstance() | |
->register('mime.idgenerator.idright') | |
->asValue($domain); | |
} | |
return new Swift_Mailer($this->app['alternate-mailer.swift.transport']->driver()); | |
}); | |
} | |
/** | |
* Register the Swift Transport instance. | |
* | |
* @return void | |
*/ | |
protected function registerSwiftTransport() | |
{ | |
$this->app->singleton('alternate-mailer.swift.transport', function () { | |
return new TransportManager($this->app); | |
}); | |
} | |
/** | |
* Get the services provided by the provider. | |
* | |
* @return array | |
*/ | |
public function provides() | |
{ | |
return [ | |
'alternate-mailer.mailer', 'alternate-mailer.swift.mailer', 'alternate-mailer.swift.transport' | |
]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function getMailer($type) | |
{ | |
if ($type === 'secondary') { | |
return app('alternate-mailer.mailer'); | |
} else { | |
return app('mailer'); | |
} | |
} | |
getMailer($type) | |
->to($recipient) | |
->send(new \App\Mail\AnEmailMessage($something)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Services\AlternateMailer; | |
use Aws\Ses\SesClient; | |
use Psr\Log\LoggerInterface; | |
use Illuminate\Log\LogManager; | |
use Swift_SmtpTransport as SmtpTransport; | |
use Illuminate\Mail\Transport\LogTransport; | |
use Swift_SendmailTransport as SendmailTransport; | |
class TransportManager extends \Illuminate\Mail\TransportManager | |
{ | |
/** | |
* Create an instance of the SMTP Swift Transport driver. | |
* | |
* @return \Swift_SmtpTransport | |
*/ | |
protected function createSmtpDriver() | |
{ | |
$config = $this->app->make('config')->get('alternate-mailer'); | |
// The Swift SMTP transport instance will allow us to use any SMTP backend | |
// for delivering mail such as Sendgrid, Amazon SES, or a custom server | |
// a developer has available. We will just pass this configured host. | |
$transport = new SmtpTransport($config['host'], $config['port']); | |
if (isset($config['encryption'])) { | |
$transport->setEncryption($config['encryption']); | |
} | |
// Once we have the transport we will check for the presence of a username | |
// and password. If we have it we will set the credentials on the Swift | |
// transporter instance so that we'll properly authenticate delivery. | |
if (isset($config['username'])) { | |
$transport->setUsername($config['username']); | |
$transport->setPassword($config['password']); | |
} | |
// Next we will set any stream context options specified for the transport | |
// and then return it. The option is not required any may not be inside | |
// the configuration array at all so we'll verify that before adding. | |
if (isset($config['stream'])) { | |
$transport->setStreamOptions($config['stream']); | |
} | |
return $transport; | |
} | |
/** | |
* Create an instance of the Sendmail Swift Transport driver. | |
* | |
* @return \Swift_SendmailTransport | |
*/ | |
protected function createSendmailDriver() | |
{ | |
return new SendmailTransport($this->app['config']['alternate-mailer']['sendmail']); | |
} | |
/** | |
* Create an instance of the Log Swift Transport driver. | |
* | |
* @return \Illuminate\Mail\Transport\LogTransport | |
*/ | |
protected function createLogDriver() | |
{ | |
$logger = $this->app->make(LoggerInterface::class); | |
if ($logger instanceof LogManager) { | |
$logger = $logger->channel($this->app['config']['alternate-mailer.log_channel']); | |
} | |
return new LogTransport($logger); | |
} | |
/** | |
* Get the default mail driver name. | |
* | |
* @return string | |
*/ | |
public function getDefaultDriver() | |
{ | |
return $this->app['config']['alternate-mailer.driver']; | |
} | |
/** | |
* Set the default mail driver name. | |
* | |
* @param string $name | |
* @return void | |
*/ | |
public function setDefaultDriver($name) | |
{ | |
$this->app['config']['alternate-mailer.driver'] = $name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment