Skip to content

Commit

Permalink
Merge pull request #10 from iwasherefirst2/extract-config
Browse files Browse the repository at this point in the history
Extract config
  • Loading branch information
iwasherefirst2 authored Oct 25, 2020
2 parents 18cea70 + 93878e4 commit 6ecf93a
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 78 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ composer.lock
.phpunit.result.cache
tests/_report
.env
.idea
35 changes: 32 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ This package works for `SMTP` and `log` drivers.
- [Special Settings](#special-settings)
- [Multiple Mail Providers](#multiple-mail-providers)
- [Default mailaccount](#default-mailaccount)
- [Testing](#testing)
- [Troubleshoot](#troubleshoot)
- [Testing](#testing)
- [Get Mail From Database](#get-mail-from-database)
- [Troubleshoot](#troubleshoot)

## Requirements

Expand Down Expand Up @@ -224,7 +225,35 @@ To avoid latency, I recommend to always use the `log` mail driver when `phpunit`
#### Use Mocking

If you want to use the mocking feature [Mail fake](https://laravel.com/docs/mocking#mail-fake) during your tests, enable `use_default_mail_facade_in_tests`
in your config file `config/multimail.php`. Note that `assertQueued` will never be true, because `queued` mails are actually send through `sent` through a job. Therefore, always use `assertSent`.
in your config file `config/multimail.php`. Note that `assertQueued` will never be true, because `queued` mails are actually send through `sent` through a job.

### Get Mail From Database

If you want to load your mail account configuration from database
or anything else, just create a class that implements `\IWasHereFirst2\LaravelMultiMail\MailSettings`
and specify the class in `config/multimail.php` under the key `mail_settings_class`.

For example:

<?php

return [
/*
|--------------------------------------------------------------------------
| List your email providers
|--------------------------------------------------------------------------
|
| Enjoy a life with multimail
|
*/
'use_default_mail_facade_in_tests' => true,

'mail_settings_class' => \App\MyCustomMailSettings::class,

];

Notice that you do not need to specify `email` or `provider` in the config anymore.
They should be loaded by your custom class `\App\MyCustomMailSettings::class`.

## Troubleshoot

Expand Down
12 changes: 12 additions & 0 deletions src/Exceptions/NotInitializedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace IWasHereFirst2\LaravelMultiMail\Exceptions;

class NotInitializedException extends \Exception
{
public function __construct()
{
$this->message = 'Please call loadConfiguration($key) before anything else.';
parent::__construct();
}
}
123 changes: 57 additions & 66 deletions src/Config.php → src/FileConfigMailSettings.php
Original file line number Diff line number Diff line change
@@ -1,59 +1,67 @@
<?php


namespace IWasHereFirst2\LaravelMultiMail;

class Config
use \IWasHereFirst2\LaravelMultiMail\MailSettings;

class FileConfigMailSettings implements MailSettings
{
/**
* Name from mail sender.
*
* @var string
*/
protected $name;
private $name;

/**
* Email from mail sender.
* Has to be set in `config/multimail.php`
*
* @var string
*/
protected $email;
private $email;

/**
* Driver, Host, Port & Encryption.
*
* @var array
*/
protected $provider;
private $provider;

/**
* Email settings.
* This may include credentials, name, provider.
*
* @var [type]
* @var array
*/
protected $settings;
private $settings;

/**
* Load config settings by key
*
* @param mixed Either string of email, or array of form ['email' => .., 'name' => .. ]
*/
public function __construct($key)
public function initialize($key)
{
// Retreive email
$this->parseEmail($key);

$this->loadConfiguration();
try {
$this->settings = config('multimail.emails')[$this->email];
} catch (\Exception $e) {
throw new Exceptions\EmailNotInConfigException($this->email);
}

if (empty($this->name)) {
$this->name = $this->settings['from_name'] ?? null;
}

$this->loadProvider();

// If credentials are empty, load default values.
// This makes local testing for many emails
// very convenient.
if ($this->isEmpty()) {
$this->loadDefault();
}
}

return $this;
}
/**
* Check if log driver is used.
*
Expand Down Expand Up @@ -130,80 +138,63 @@ public function getEmail()
}

/**
* Parse $key into email and possible from name
* Check if email, pass and username are not empty
*
* @param mixed string/array
* @return void
* @return boolean
*/
protected function parseEmail($key)
private function isEmpty()
{
if (is_array($key)) {
$this->name = $key['name'] ?? null;

if (empty($key['email'])) {
throw new Exceptions\InvalidConfigKeyException;
}
$this->email = $key['email'];
} else {
$this->email = $key;
}
return (empty($this->email) || empty($this->settings) || empty($this->settings['pass']) || empty($this->settings['username']));
}

/**
* Load config settings and provder from email
* Load default setting. If default setting is
* invalid throw exception
*
* @return void
*/
protected function loadConfiguration()
private function loadDefault()
{
try {
$this->settings = config('multimail.emails')[$this->email];
} catch (\Exception $e) {
throw new Exceptions\EmailNotInConfigException($this->email);
}

if (empty($this->name)) {
$this->name = $this->settings['from_name'] ?? null;
}
$this->settings = config('multimail.emails.default');

$this->loadProvider();
}

protected function loadProvider()
{
if (isset($this->settings['provider']) && !empty($provider = $this->settings['provider'])) {
$this->provider = config('multimail.provider.' . $provider);
}

if (empty($this->provider)) {
$this->provider = config('multimail.provider.default');
if ((!isset($this->provider['driver']) || $this->provider['driver'] != 'log') && (empty($this->settings['pass']) || empty($this->settings['username']))) {
throw new Exceptions\NoDefaultException($this->email);
}
}

/**
* Check if email, pass and username are not empty
* Parse $key into email and possible from name
*
* @return boolean
* @param mixed string/array
* @return void
*/
protected function isEmpty()
private function parseEmail($key)
{
return (empty($this->email) || empty($this->settings) || empty($this->settings['pass']) || empty($this->settings['username']));
if (!is_array($key)) {
$this->email = $key;
return;
}

$this->name = $key['name'] ?? null;

if (empty($key['email'])) {
throw new Exceptions\InvalidConfigKeyException;
}

$this->email = $key['email'];
}

/**
* Load default setting. If default setting is
* invalid throw exception
*
* @return void
*/
protected function loadDefault()
{
$this->settings = config('multimail.emails.default');

$this->loadProvider();
private function loadProvider()
{
if (!empty($this->settings['provider'])) {
$this->provider = config('multimail.provider.' . $this->settings['provider']);
}

if ((!isset($this->provider['driver']) || $this->provider['driver'] != 'log') && (empty($this->settings) || empty($this->settings['pass']) || empty($this->settings['username']))) {
throw new Exceptions\NoDefaultException($this->email);
if (empty($this->provider)) {
$this->provider = config('multimail.provider.default');
}
}
}
}
63 changes: 63 additions & 0 deletions src/MailSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace IWasHereFirst2\LaravelMultiMail;

interface MailSettings
{
public function initialize($key);

/**
* Check if log driver is currently used.
*
* @return boolean
*/
public function isLogDriver();

/**
* Get provider.
*
* @return array
*/
public function getProvider();

/**
* Get setting.
*
* @return array
*/
public function getSetting();

/**
* Return email of sender.
*
* @return string
*/
public function getFromEmail();

/**
* Return name of sender.
*
* @return string
*/
public function getFromName();

/**
* Return email of sender.
*
* @return string
*/
public function getReplyEmail();

/**
* Return name of sender.
*
* @return string
*/
public function getReplyName();

/**
* Return email
* @return string
*/
public function getEmail();
}
10 changes: 9 additions & 1 deletion src/MultiMailServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ public function register()
public function boot()
{
$this->app->bind('iwasherefirst2-laravelmultimail', function () {
return new MultiMailer();
if(config()->has('multimail.config_class')){
$configClass = config('multimail.mail_settings_class');
$config = new $configClass();
}
else{
$config = new FileConfigMailSettings();
}

return new MultiMailer($config);
});

$this->publishes([
Expand Down
16 changes: 15 additions & 1 deletion src/MultiMailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ class MultiMailer
*/
protected $mailers;

/**
* @var FileConfigMailSettings
*/
private $config;

/**
* MultiMailer constructor.
* @param FileConfigMailSettings $config
*/
public function __construct(MailSettings $config)
{
$this->config = $config;
}

/**
* Create mailer from config/multimail.php
* If its not a log driver, add AntiFloodPlugin.
Expand All @@ -36,7 +50,7 @@ class MultiMailer
*/
public function getMailer($key, $timeout = null, $frequency = null)
{
$config = new Config($key);
$config = $this->config->initialize($key);

if (isset($this->mailers[$config->getEmail()])) {
return $this->mailers[$config->getEmail()];
Expand Down
Loading

0 comments on commit 6ecf93a

Please sign in to comment.