Reputation: 2533
Sometimes we have to integrate custom mail provider. But Laravel has a fixed list of them. Here they are:
Instructions for these drivers you can find in framework/src/Illuminate/Mail/TransportManager.php
The problem is that those instructions are fixed. Of course you can modify vendor-file but will be a dirty hack. So In the answer I'll provide some instruction how to implement your own custom mail driver in right way.
Upvotes: 5
Views: 4141
Reputation: 2533
First of all we have to create custom Transport
for our mailer.
Our mailer will communicate with another server by some API interface. File bellow is a model so I've put it to my Model's folder. If you haven't separate folder for models you can just put the file into app
directory.
Lets call it SmithTransport.php
:
<?php
use GuzzleHttp\ClientInterface;
use Illuminate\Mail\Transport\Transport;
class SmithTransport extends Transport
{
protected $client;
protected $key;
protected $domain;
protected $url;
public function __construct(ClientInterface $client, $key, $domain)
{
$this->key = $key;
$this->client = $client;
$this->setDomain($domain);
}
public function send(Swift_Mime_Message $message, &$failedRecipients = null)
{
$this->beforeSendPerformed($message);
$options = ['auth' => ['api', $this->key]];
$message->setBcc([]);
$from_email = '';
$from_name = '';
$to_email = '';
$to_name = '';
foreach ($message->getFrom() as $email => $name) {
$from_email = $email;
$from_name = $name;
}
foreach ($message->getTo() as $email => $name) {
$to_email = $email;
$to_name = $name;
}
$options['form_params'] = [
'from_email' => $from_email,
'from_name' => $from_name,
'to_email' => $to_email,
'to_name' => $to_name,
'subject' => $message->getSubject(),
'body' => $message->getBody()
];
return $this->client->post($this->url, $options);
}
public function getKey()
{
return $this->key;
}
public function setKey($key)
{
return $this->key = $key;
}
public function getDomain()
{
return $this->domain;
}
public function setDomain($domain)
{
$this->url = 'https://api.mymailer.com/send?key=' . $this->key;
return $this->domain = $domain;
}
}
Next step is extending TransportManager
. Because we have to add instructions for our custom Transport.
So it will be SmithTransportManager.php
in model's directory or in app
directory if you haven't separate directory for models.
<?php
use Illuminate\Mail\TransportManager;
class SmithTransportManager extends TransportManager
{
protected function createSmithDriver()
{
$config = $this->app['config']->get('services.smith', []);
return new SmithTransport(
$this->guggle($config),
$config['secret'], $config['domain']
);
}
}
Next step is extending existing MailServiceProvider
.
So our provider will be in app/Providers/MailServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Mail\MailServiceProvider as MailProvider;
class MailServiceProvider extends MailProvider
{
protected function registerSwiftTransport()
{
$this->app->singleton('swift.transport', function ($app) {
return new \SmithTransportManager($app);
});
}
}
And the final step is modifying config files.
In the config/app.php
you have to remove (or comment line) standard Illuminate\Mail\MailServiceProvider::class,
And add App\Providers\MailServiceProvider::class,
to the providers
section.
In the config/services.php
we have to add config getters:
'smith' => [
'domain' => env('SMITH_DOMAIN'),
'secret' => env('SMITH_SECRET'),
],
That's all! Hope it helps 'cause I didn't find any information in the docs of somewhere else about custom MailTransport.
Upvotes: 16