Edit the mail config from the dashboard and provide testing button

This commit is contained in:
James Brooks 2016-11-29 18:31:37 +00:00
parent 72056e2ac5
commit 9dc80b4229
12 changed files with 439 additions and 0 deletions

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Commands\System\Config;
/**
* This is the update config command class.
*
* @author James Brooks <james@alt-three.com>
*/
class UpdateConfigCommand
{
/**
* This is the config key/values array.
*
* @var array
*/
public $values;
/**
* Create a new update config command instance.
*
* @param array $values
*
* @return void
*/
public function __construct($values)
{
$this->values = $values;
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Commands\System\Mail;
use CachetHQ\Cachet\Models\User;
/**
* This is the test mail command class.
*
* @author James Brooks <james@alt-three.com>
*/
class TestMailCommand
{
/**
* The user to send the notification to.
*
* @var \CachetHQ\Cachet\Models\User
*/
public $user;
/**
* Create a new test mail command.
*
* @param \CachetHQ\Cachet\Models\User $user
*
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Handlers\Commands\System\Config;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
/**
* This is the update config command handler class.
*
* @author James Brooks <james@alt-three.com>
*/
class UpdateConfigCommandHandler
{
/**
* Handle update config command handler instance.
*
* @param \CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand $command
*
* @return void
*/
public function handle(UpdateConfigCommand $command)
{
foreach ($command->values as $setting => $value) {
$this->writeEnv($setting, $value);
}
}
/**
* Writes to the .env file with given parameters.
*
* @param string $key
* @param mixed $value
*
* @return void
*/
protected function writeEnv($key, $value)
{
$dir = app()->environmentPath();
$file = app()->environmentFile();
$path = "{$dir}/{$file}";
try {
(new Dotenv($dir, $file))->load();
$envKey = strtoupper($key);
$envValue = env($envKey) ?: 'null';
file_put_contents($path, str_replace(
"{$envKey}={$envValue}",
"{$envKey}={$value}",
file_get_contents($path)
));
} catch (InvalidPathException $e) {
throw $e;
}
}
}

View File

@ -0,0 +1,64 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Handlers\Commands\System\Mail;
use CachetHQ\Cachet\Bus\Commands\System\Mail\TestMailCommand;
use Illuminate\Contracts\Mail\MailQueue;
/**
* This is the test mail command handler class.
*
* @author James Brooks <james@alt-three.com>
*/
class TestMailCommandHandler
{
/**
* The mailer instance.
*
* @var \Illuminate\Contracts\Mail\Mailer
*/
protected $mailer;
/**
* Create a test mail command handler.
*
* @param \Illuminate\Contracts\Mail\Mailer $mailer
*
* @return void
*/
public function __construct(MailQueue $mailer)
{
$this->mailer = $mailer;
}
/**
* Handle the test mail command.
*
* @param \CachetHQ\Cachet\Bus\Commands\System\Mail\TestMailCommand $command
*
* @return void
*/
public function handle(TestMailCommand $command)
{
$mail = [
'email' => $command->user->email,
'subject' => trans('dashboard.settings.mail.email.subject'),
];
$this->mailer->queue([
'html' => 'emails.system.test-html',
'text' => 'emails.system.test-text',
], $mail, function ($message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
});
}
}

View File

@ -0,0 +1,85 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Composers;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use CachetHQ\Cachet\Models\Schedule;
use CachetHQ\Cachet\Models\Subscriber;
use Illuminate\Contracts\View\View;
/**
* This is the settings composer.
*
* @author James Brooks <james@alt-three.com>
*/
class SettingsComposer
{
/**
* Array of cache drivers.
*
* @var string[]
*/
protected $cacheDrivers = [
'apc' => 'APC(u)',
'array' => 'Array',
'database' => 'Database',
'file' => 'File',
'memcached' => 'Memcached',
'redis' => 'Redis',
];
/**
* Array of cache drivers.
*
* @var string[]
*/
protected $mailDrivers = [
'smtp' => 'SMTP',
'mail' => 'Mail',
'sendmail' => 'Sendmail',
'mailgun' => 'Mailgun',
'mandrill' => 'Mandrill',
// 'ses' => 'Amazon SES', this will be available only if aws/aws-sdk-php is installed
'sparkpost' => 'SparkPost',
'log' => 'Log (Testing)',
];
/**
* Array of queue drivers.
*
* @var string[]
*/
protected $queueDrivers = [
'null' => 'None',
'sync' => 'Synchronous',
'database' => 'Database',
'beanstalkd' => 'Beanstalk',
'sqs' => 'Amazon SQS',
'redis' => 'Redis',
];
/**
* Bind data to the view.
*
* @param \Illuminate\Contracts\View\View $view
*
* @return void
*/
public function compose(View $view)
{
$view->withCacheDrivers($this->cacheDrivers);
$view->withMailDrivers($this->mailDrivers);
$view->withQueueDrivers($this->queueDrivers);
}
}

View File

@ -21,6 +21,7 @@ use CachetHQ\Cachet\Composers\Modules\ScheduledComposer as ScheduledModuleCompos
use CachetHQ\Cachet\Composers\Modules\StatusComposer as StatusModuleComposer;
use CachetHQ\Cachet\Composers\Modules\StickiedComposer as StickiedModuleComposer;
use CachetHQ\Cachet\Composers\Modules\TimelineComposer as TimelineModuleComposer;
use CachetHQ\Cachet\Composers\SettingsComposer;
use CachetHQ\Cachet\Composers\ThemeComposer;
use CachetHQ\Cachet\Composers\TimezoneLocaleComposer;
use Illuminate\Contracts\View\Factory;
@ -48,6 +49,7 @@ class ComposerServiceProvider extends ServiceProvider
$factory->composer('partials.modules.scheduled', ScheduledModuleComposer::class);
$factory->composer('partials.modules.status', StatusModuleComposer::class);
$factory->composer('partials.modules.timeline', TimelineModuleComposer::class);
$factory->composer(['dashboard.settings.mail', 'setup.*'], SettingsComposer::class);
}
/**

View File

@ -11,12 +11,15 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
use CachetHQ\Cachet\Bus\Commands\System\Mail\TestMailCommand;
use CachetHQ\Cachet\Integrations\Contracts\Credits;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
use Exception;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
@ -96,6 +99,12 @@ class SettingsController extends Controller
'icon' => 'ion-ios-list',
'active' => false,
],
'mail' => [
'title' => trans('dashboard.settings.mail.mail'),
'url' => cachet_route('dashboard.settings.mail'),
'icon' => 'ion-paper-airplane',
'active' => false,
],
'about' => [
'title' => CACHET_VERSION,
'url' => 'javascript: void(0);',
@ -266,6 +275,47 @@ class SettingsController extends Controller
return View::make('dashboard.settings.log')->withLog($logContents)->withSubMenu($this->subMenu);
}
/**
* Show the mail settings view.
*
* @return \Illuminate\View\View
*/
public function showMailView()
{
$this->subMenu['mail']['active'] = true;
return View::make('dashboard.settings.mail')->withConfig(Config::get('mail'));
}
/**
* Test the mail config.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function testMail()
{
dispatch(new TestMailCommand(Auth::user()));
return cachet_redirect('dashboard.settings.mail')
->withSuccess(trans('dashboard.notifications.awesome'));;
}
/**
* Handle updating of the settings.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postMail()
{
$config = Binput::get('config');
dispatch(new UpdateConfigCommand($config));
return cachet_redirect('dashboard.settings.mail')
->withInput(Binput::all())
->withSuccess(trans('dashboard.notifications.awesome'));
}
/**
* Updates the status page settings.
*

View File

@ -78,6 +78,18 @@ class SettingRoutes
'as' => 'get:dashboard.settings.log',
'uses' => 'SettingsController@showLogView',
]);
$router->get('mail', [
'as' => 'get:dashboard.settings.mail',
'uses' => 'SettingsController@showMailView',
]);
$router->post('mail', [
'as' => 'post:dashboard.settings.mail',
'uses' => 'SettingsController@postMail',
]);
$router->post('mail/test', [
'as' => 'post:dashboard.settings.mail.test',
'uses' => 'SettingsController@testMail',
]);
$router->post('/', [
'as' => 'post:dashboard.settings',

View File

@ -214,6 +214,14 @@ return [
'header' => 'Custom Header HTML',
'footer' => 'Custom Footer HTML',
],
'mail' => [
'mail' => 'Mail',
'test' => 'Test',
'email' => [
'subject' => 'Test notification from Cachet',
'body' => 'This is a test notification from Cachet.',
],
],
'security' => [
'security' => 'Security',
'two-factor' => 'Users without two-factor authentication',

View File

@ -0,0 +1,60 @@
@extends('layout.dashboard')
@section('content')
<div class="content-panel">
@if(isset($sub_menu))
@include('dashboard.partials.sub-sidebar')
@endif
<div class="content-wrapper">
<div class="header sub-header" id="application-setup">
<span class="uppercase">
{{ trans('dashboard.settings.mail.mail') }}
</span>
</div>
<div class="row">
<div class="col-sm-12">
<form id="settings-form" name="SettingsForm" class="form-vertical" role="form" action="{{ cachet_route('dashboard.settings.mail', [], 'post') }}" method="POST" enctype="multipart/form-data">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
@include('dashboard.partials.errors')
<fieldset>
<div class="form-group">
<label>{{ trans('forms.setup.mail_driver') }}</label>
<select name="config[mail_driver]" class="form-control" required>
<option disabled>{{ trans('forms.setup.mail_driver') }}</option>
@foreach($mail_drivers as $driver => $driverName)
<option value="{{ $driver }}" {{ Binput::old('config.mail_driver', $config['driver']) == $driver ? "selected" : null }}>{{ $driverName }}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label>{{ trans('forms.setup.mail_host') }} (optional)</label>
<input type="text" class="form-control" name="config[mail_host]" value="{{ Binput::old('config.mail_host', $config['host']) }}" placeholder="{{ trans('forms.setup.mail_host') }}">
</div>
<div class="form-group">
<label>{{ trans('forms.setup.mail_address') }}</label>
<input type="text" class="form-control" name="config[mail_address]" value="{{ Binput::old('config.mail_address', $config['from']['address']) }}" placeholder="notifications@alt-three.com">
</div>
<div class="form-group">
<label>{{ trans('forms.setup.mail_username') }}</label>
<input type="text" class="form-control" name="config[mail_username]" value="{{ Binput::old('config.mail_username', $config['username']) }}" placeholder="{{ trans('forms.setup.mail_username') }}">
</div>
<div class="form-group">
<label>{{ trans('forms.setup.mail_password') }}</label>
<input type="password" class="form-control" name="config[mail_password]" value="{{ Binput::old('config.mail_password', $config['password']) }}" autocomplete="off" placeholder="{{ trans('forms.setup.mail_password') }}">
</div>
</fieldset>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<button type="submit" class="btn btn-success">{{ trans('forms.save') }}</button>
<a href="{{ cachet_route('dashboard.settings.mail.test', null, 'post') }}" class="btn btn-info confirm-action" data-method='POST'>{{ trans('dashboard.settings.mail.test') }}</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
@stop

View File

@ -0,0 +1,5 @@
@extends('layout.emails')
@section('content')
{{ trans('dashboard.settings.mail.email.body') }}
@stop

View File

@ -0,0 +1,5 @@
{{ trans('dashboard.settings.mail.email.body') }}
@if($show_support)
{!! trans('cachet.powered_by', ['app' => $app_name]) !!}
@endif