Implement mail driver classes (#1169)

This adds an interface for mail drivers to implement, defining several
methods that we need throughout Flarum to configure, validate and use
the various email drivers we can support through Laravel.

More mail drivers can be added by `extend()`ing the container binding
"mail.supported_drivers" with an arbitrary key and the name of a class
that implements our new `DriverInterface`.

This will ensure that drivers added by extensions can be properly built
and validated, even in the frontend.
This commit is contained in:
Franz Liedke 2019-03-13 21:21:36 +01:00
parent 09d4459f9e
commit c6b6898caf
7 changed files with 188 additions and 87 deletions

View File

@ -23,6 +23,7 @@ use Flarum\Forum\ForumServiceProvider;
use Flarum\Frontend\FrontendServiceProvider;
use Flarum\Group\GroupServiceProvider;
use Flarum\Locale\LocaleServiceProvider;
use Flarum\Mail\MailServiceProvider;
use Flarum\Notification\NotificationServiceProvider;
use Flarum\Post\PostServiceProvider;
use Flarum\Search\SearchServiceProvider;

View File

@ -1,87 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Foundation;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Mail\Mailer;
use Illuminate\Mail\Transport\LogTransport;
use InvalidArgumentException;
use Psr\Log\LoggerInterface;
use Swift_Mailer;
use Swift_SendmailTransport;
use Swift_SmtpTransport;
use Swift_Transport;
class MailServiceProvider extends AbstractServiceProvider
{
public function register()
{
$this->app->singleton('mail.supported_drivers', function () {
return ['smtp', 'mail', 'log'];
});
$this->app->singleton('swift.mailer', function ($app) {
$settings = $app->make(SettingsRepositoryInterface::class);
return new Swift_Mailer(
$this->buildTransport($settings)
);
});
$this->app->singleton('mailer', function ($app) {
$mailer = new Mailer(
$app['view'], $app['swift.mailer'], $app['events']
);
if ($app->bound('queue')) {
$mailer->setQueue($app->make('queue'));
}
$settings = $app->make(SettingsRepositoryInterface::class);
$mailer->alwaysFrom($settings->get('mail_from'), $settings->get('forum_title'));
return $mailer;
});
}
private function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
{
switch ($driver = $settings->get('mail_driver')) {
case 'smtp':
return $this->buildSmtpTransport($settings);
case 'mail':
return new Swift_SendmailTransport;
case 'log':
return new LogTransport($this->app->make(LoggerInterface::class));
default:
if ($this->app->bound('mail.driver.'.$driver)) {
return $this->app->make('mail.driver.'.$driver);
}
throw new InvalidArgumentException('Invalid mail driver configuration');
}
}
private function buildSmtpTransport(SettingsRepositoryInterface $settings): Swift_Transport
{
$transport = new Swift_SmtpTransport(
$settings->get('mail_host'),
$settings->get('mail_port'),
$settings->get('mail_encryption')
);
$transport->setUsername($settings->get('mail_username'));
$transport->setPassword($settings->get('mail_password'));
return $transport;
}
}

View File

@ -0,0 +1,31 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Mail;
use Flarum\Settings\SettingsRepositoryInterface;
use Swift_Transport;
/**
* An interface for a mail service
*
* This interface provides all methods necessary for configuring, checking and
* using one of Laravel's various email drivers throughout Flarum.
*
* @public
*/
interface DriverInterface
{
/**
* Build a mail transport based on Flarum's current settings
*/
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport;
}

View File

@ -0,0 +1,36 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Mail;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Support\MessageBag as MessageBagContract;
use Illuminate\Mail\Transport\LogTransport;
use Psr\Log\LoggerInterface;
use Swift_Transport;
class LogDriver implements DriverInterface
{
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
{
return new LogTransport($this->logger);
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Mail;
use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Mail\Mailer;
use Swift_Mailer;
class MailServiceProvider extends AbstractServiceProvider
{
public function register()
{
$this->app->singleton('mail.supported_drivers', function () {
return [
'smtp' => SmtpDriver::class,
'mail' => SendmailDriver::class,
'log' => LogDriver::class,
];
});
$this->app->singleton('mail.driver', function () {
$settings = $this->app->make(SettingsRepositoryInterface::class);
$drivers = $this->app->make('mail.supported_drivers');
return $this->app->make($drivers[$settings->get('mail_driver')]);
});
$this->app->alias('mail.driver', DriverInterface::class);
$this->app->singleton('swift.mailer', function ($app) {
return new Swift_Mailer(
$app->make('mail.driver')->buildTransport(
$app->make(SettingsRepositoryInterface::class)
)
);
});
$this->app->singleton('mailer', function ($app) {
$mailer = new Mailer(
$app['view'], $app['swift.mailer'], $app['events']
);
if ($app->bound('queue')) {
$mailer->setQueue($app->make('queue'));
}
$settings = $app->make(SettingsRepositoryInterface::class);
$mailer->alwaysFrom($settings->get('mail_from'), $settings->get('forum_title'));
return $mailer;
});
}
}

View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Mail;
use Flarum\Settings\SettingsRepositoryInterface;
use Swift_SendmailTransport;
use Swift_Transport;
class SendmailDriver implements DriverInterface
{
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
{
return new Swift_SendmailTransport;
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Mail;
use Flarum\Settings\SettingsRepositoryInterface;
use Swift_SmtpTransport;
use Swift_Transport;
class SmtpDriver implements DriverInterface
{
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
{
$transport = new Swift_SmtpTransport(
$settings->get('mail_host'),
$settings->get('mail_port'),
$settings->get('mail_encryption')
);
$transport->setUsername($settings->get('mail_username'));
$transport->setPassword($settings->get('mail_password'));
return $transport;
}
}