FEATURE #1552 @1h: save sent messages into database
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateSentEmailsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run migration
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('sent_emails', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->string('subject');
|
||||||
|
$table->string('from');
|
||||||
|
$table->string('to');
|
||||||
|
$table->text('message');
|
||||||
|
$table->boolean('is_new')->default(true)->commect('Was this message read (in admin)?');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback migration
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('sent_emails');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\ContactForm\Entities;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class SentEmail extends Model
|
||||||
|
{
|
||||||
|
protected $fillable = [
|
||||||
|
'from',
|
||||||
|
'to',
|
||||||
|
'subject',
|
||||||
|
'message'
|
||||||
|
];
|
||||||
|
protected $casts = ['is_new' => 'boolean'];
|
||||||
|
}
|
||||||
+12
-14
@@ -1,13 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Modules\ContactForm\Handlers;
|
namespace Modules\ContactForm\Handlers;
|
||||||
|
|
||||||
use App\CMS\Contracts\Content\AdvancedContentModifier;
|
use App\CMS\Contracts\Content\AdvancedContentModifier;
|
||||||
use App\CMS\Contracts\Content\ContentTitles;
|
use App\CMS\Contracts\Content\ContentTitles;
|
||||||
use App\CMS\Enumerations\ModulesHandlerToId;
|
use App\CMS\Enumerations\ModulesHandlerToId;
|
||||||
use App\CMS\Handlers\AdminHandler;
|
use App\CMS\Handlers\AdminHandler;
|
||||||
use App\Http\Requests\Request;
|
|
||||||
use App\Models\Content\Content;
|
use App\Models\Content\Content;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Modules\ContactForm\Entities\SentEmail;
|
||||||
|
|
||||||
class ContactForm extends AdminHandler implements ContentTitles, AdvancedContentModifier
|
class ContactForm extends AdminHandler implements ContentTitles, AdvancedContentModifier
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,6 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for section names in creating/editing content resource
|
* Getter for section names in creating/editing content resource
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function getExtendedFormSections()
|
public static function getExtendedFormSections()
|
||||||
@@ -40,9 +40,7 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for views used in extended part of form for creating new content
|
* Getter for views used in extended part of form for creating new content
|
||||||
*
|
|
||||||
* This method should return pairs <section, view-name>. View is returned only as name in plain text
|
* This method should return pairs <section, view-name>. View is returned only as name in plain text
|
||||||
*
|
|
||||||
* @return array of views/templates/html codes divided into section
|
* @return array of views/templates/html codes divided into section
|
||||||
*/
|
*/
|
||||||
public static function getExtendedFormInputsCreate()
|
public static function getExtendedFormInputsCreate()
|
||||||
@@ -64,7 +62,6 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Register admin menu (or multiple ones)
|
* Register admin menu (or multiple ones)
|
||||||
*
|
|
||||||
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
||||||
* starting any middleware..
|
* starting any middleware..
|
||||||
*
|
*
|
||||||
@@ -77,15 +74,21 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
$submenu = $menu->whereTitle(trans('admin/mainMenu.contentPages'));
|
$submenu = $menu->whereTitle(trans('admin/mainMenu.contentPages'));
|
||||||
$submenu->dropdown(trans('contactform::admin/adminMenu.contactForm'), function ($submenu) use ($user) {
|
$submenu->dropdown(trans('contactform::admin/adminMenu.contactForm'), function ($submenu) use ($user) {
|
||||||
$submenu->route('content.new', trans('contactform::admin/adminMenu.new'), ['moduleId' => self::getModuleId()], 10, ['icon' => 'fa fa-plus']);
|
$submenu->route('content.new', trans('contactform::admin/adminMenu.new'), ['module' => config('contactform.alias')], 10, ['icon' => 'fa fa-plus']);
|
||||||
$submenu->route('content.overview', trans('contactform::admin/adminMenu.overview'), ['moduleId' => self::getModuleId()], 20, ['icon' => 'fa fa-list']);
|
$submenu->route('content.overview', trans('contactform::admin/adminMenu.overview'), ['module' => config('contactform.alias')], 20, ['icon' => 'fa fa-list']);
|
||||||
// $submenu->route('emails.sent', trans('contactform::admin/adminMenu.sentMessages'), [], 30, ['icon' => 'fa fa-send']);
|
|
||||||
}, 25, ['icon' => 'fa fa-envelope-o']);
|
}, 25, ['icon' => 'fa fa-envelope-o']);
|
||||||
|
|
||||||
|
|
||||||
|
$new = SentEmail::where('is_new', true)->count();
|
||||||
|
|
||||||
|
$suffix = ($new == 0) ? '' : ' ('.$new.')';
|
||||||
|
|
||||||
|
$menu->route('sentEmails.index', trans('contactform::admin/adminMenu.sentMessages'). $suffix , [], 50, ['icon' => 'fa fa-send']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does given module manage content? Or is it just module with widgets/something internal/something absolutely else?
|
* Does given module manage content? Or is it just module with widgets/something internal/something absolutely else?
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function managesContent()
|
public static function managesContent()
|
||||||
@@ -95,9 +98,7 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get translated title for pages overview of given type.
|
* Get translated title for pages overview of given type.
|
||||||
*
|
|
||||||
* This value is used for rendering list of all content pages of given type in administration.
|
* This value is used for rendering list of all content pages of given type in administration.
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getOverviewTitle()
|
public static function getOverviewTitle()
|
||||||
@@ -107,7 +108,6 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Title displayed above for for creating new content page
|
* Title displayed above for for creating new content page
|
||||||
*
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getCreateNewTitle()
|
public static function getCreateNewTitle()
|
||||||
@@ -129,7 +129,6 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this module support categories?
|
* Does this module support categories?
|
||||||
*
|
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public static function supportCategories()
|
public static function supportCategories()
|
||||||
@@ -139,7 +138,6 @@ class ContactForm extends AdminHandler implements ContentTitles, AdvancedContent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called right after content page is marked as deleted
|
* Method called right after content page is marked as deleted
|
||||||
*
|
|
||||||
* This method is supposed to clean after "deleted" page.
|
* This method is supposed to clean after "deleted" page.
|
||||||
*
|
*
|
||||||
* @param Content $content
|
* @param Content $content
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\ContactForm\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Admin\Controller;
|
||||||
|
use Modules\ContactForm\Entities\SentEmail;
|
||||||
|
|
||||||
|
class SentEmails extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$emails = SentEmail::orderBy('created_at', 'desc')
|
||||||
|
->paginate();
|
||||||
|
return view('contactform::admin.sent', compact('emails'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(SentEmail $email)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($email->is_new) {
|
||||||
|
$email->is_new = false;
|
||||||
|
$email->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('contactform::admin.emailDetail', compact('email'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Modules\ContactForm\Http\Controllers\Visitor;
|
namespace Modules\ContactForm\Http\Controllers\Visitor;
|
||||||
|
|
||||||
use App\CMS\Helpers\Template;
|
use App\CMS\Helpers\Template;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Content\Content;
|
use App\Models\Content\Content;
|
||||||
use Illuminate\Mail\Message;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Modules\ContactForm\Http\Requests\SendNewEmailRequest;
|
use Modules\ContactForm\Http\Requests\SendNewEmailRequest;
|
||||||
|
use Modules\ContactForm\Mail\ContactFormMessage;
|
||||||
|
|
||||||
class CreateNewMessage extends Controller
|
class CreateNewMessage extends Controller
|
||||||
{
|
{
|
||||||
@@ -26,35 +27,29 @@ class CreateNewMessage extends Controller
|
|||||||
|
|
||||||
// select template
|
// select template
|
||||||
$template = isset($form->moduleSettings['emailTemplate']) ? $form->moduleSettings['emailTemplate'] : 'contactform::emails.default';
|
$template = isset($form->moduleSettings['emailTemplate']) ? $form->moduleSettings['emailTemplate'] : 'contactform::emails.default';
|
||||||
|
$subject = isset($form->moduleSettings['subject']) ? $form->moduleSettings['subject'] : trans('contactform::admin/contents.defaultSubject');
|
||||||
|
$data = $request->except('_token', 'g-recaptcha-response');
|
||||||
|
|
||||||
// send email
|
Mail::to($form->moduleSettings['contactEmail'])
|
||||||
$status = Mail::send(Template::name($template), ['data' => $request], function (Message $message) use ($request, $form) {
|
->send(new ContactFormMessage($data, $subject, Template::name($template)));
|
||||||
$message->from($request->email, $request->name);
|
|
||||||
|
|
||||||
// get message subject
|
|
||||||
$subject = isset($form->moduleSettings['subject']) ? $form->moduleSettings['subject'] : trans('contactform::admin/contents.defaultSubject');
|
|
||||||
|
|
||||||
$message->to($form->moduleSettings['email'])
|
|
||||||
->subject($subject);
|
|
||||||
});
|
|
||||||
|
|
||||||
// inform user about success or failure
|
// inform user about success or failure
|
||||||
return $this->sendResponse($status, $request, $form);
|
return $this->sendResponse($request, $form);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sendResponse($status, SendNewEmailRequest $request, $form)
|
private function sendResponse(SendNewEmailRequest $request, $form)
|
||||||
{
|
{
|
||||||
// send response for ajax
|
// send response for ajax
|
||||||
if ($request->ajax()) {
|
if ($request->ajax()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => $status ? 'success' : 'failed',
|
'status' => 'success',
|
||||||
'redirectUrl' => $form->url
|
'redirectUrl' => $form->url
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
// redirect user to previous form
|
// redirect user to previous form
|
||||||
$response = redirect()->back();
|
$response = redirect()->back();
|
||||||
|
|
||||||
return $status ? $response->with('success', 'sent') : $response->with('error', 'cannotSend');
|
return $response->with('success', 'sent');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ class SendNewEmailRequest extends Request
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
|
|||||||
@@ -9,4 +9,16 @@ Route::group([
|
|||||||
|
|
||||||
Route::post('/message/{formId}', 'CreateNewMessage@postMessage')
|
Route::post('/message/{formId}', 'CreateNewMessage@postMessage')
|
||||||
->name('email.send');
|
->name('email.send');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::group([
|
||||||
|
'middleware' => ['admin', 'bindings'],
|
||||||
|
'namespace' => '\Modules\ContactForm\Http\Controllers\Admin',
|
||||||
|
'prefix' => LaravelLocalization::setLocale() . '/contactform'
|
||||||
|
], function () {
|
||||||
|
|
||||||
|
Route::get('sent', 'SentEmails@index')
|
||||||
|
->name('sentEmails.index');
|
||||||
|
|
||||||
|
Route::get('send/{email}', 'SentEmails@show')->name('sentEmails.show');
|
||||||
});
|
});
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\ContactForm\Listeners;
|
||||||
|
|
||||||
|
use Modules\ContactForm\Entities\SentEmail;
|
||||||
|
|
||||||
|
class SaveSentEmail
|
||||||
|
{
|
||||||
|
public function handle(\Illuminate\Mail\Events\MessageSending $event)
|
||||||
|
{
|
||||||
|
$email = $event->message;
|
||||||
|
|
||||||
|
$from = key($email->getFrom());
|
||||||
|
$to = key($email->getTo());
|
||||||
|
|
||||||
|
SentEmail::create([
|
||||||
|
'from' => $from,
|
||||||
|
'to' => $to,
|
||||||
|
'subject' => $email->getSubject(),
|
||||||
|
'message' => $email->getBody()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\ContactForm\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ContactFormMessage extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
protected $data;
|
||||||
|
/**
|
||||||
|
* @var
|
||||||
|
*/
|
||||||
|
private $template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @param $data
|
||||||
|
* @param $template
|
||||||
|
*/
|
||||||
|
public function __construct($data, $subject, $template)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
$this->template = $template;
|
||||||
|
$this->subject = $subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
return $this->subject($this->subject)
|
||||||
|
->from($this->data['email'])
|
||||||
|
->view($this->template, ['data' => $this->data]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ class ContactFormServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
|
$this->app->register(EventServiceProvider::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerWidgets()
|
private function registerWidgets()
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\ContactForm\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
|
|
||||||
|
class EventServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
protected $listen = [
|
||||||
|
\Illuminate\Mail\Events\MessageSending::class => [
|
||||||
|
\Modules\ContactForm\Listeners\SaveSentEmail::class
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
"contactForm" => "Kontaktní formulář",
|
"contactForm" => "Kontaktní formulář",
|
||||||
"emails" => "E-mailové šablony",
|
"emails" => "E-mailové šablony",
|
||||||
"new" => "Nový",
|
"new" => "Nový",
|
||||||
"overview" => "Všechny formuláře",
|
"overview" => "Všechny formuláře",
|
||||||
"sentMessages" => "Zprávy",
|
"sentMessages" => "Přijaté zprávy",
|
||||||
"templatePath" => "Kontaktní formulář",
|
"templatePath" => "Kontaktní formulář",
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'from' => 'Od',
|
||||||
|
'to' => 'Komu',
|
||||||
|
'subject' => 'Předmět',
|
||||||
|
'createdAt' => 'Odesláno',
|
||||||
|
'overview' => 'Přehled přijatých e-mailů',
|
||||||
|
'detail' => 'Detail e-mailu'
|
||||||
|
];
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
@extends('admin.layoutWithNavigation')
|
||||||
|
|
||||||
|
@section('pageHeading', @trans('contactform::sent.detail'))
|
||||||
|
|
||||||
|
@section('headerButtons')
|
||||||
|
<a class="btn btn-secondary btn-sm rounded" href="{{route('sentEmails.index')}}"><i class="fa fa-list"></i></a>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="card items">
|
||||||
|
<div class="card-block">
|
||||||
|
<h2>{{$email->subject}}</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{$email->message}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
@extends('admin.layoutWithNavigation')
|
||||||
|
|
||||||
|
@section('pageHeading', @trans('contactform::sent.overview'))
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
@if (count($emails))
|
||||||
|
<div class="card items">
|
||||||
|
<div class="card-block">
|
||||||
|
<table class="table table-striped full-width">
|
||||||
|
<tr>
|
||||||
|
<th>@lang('contactform::sent.from')</th>
|
||||||
|
<th>@lang('contactform::sent.to')</th>
|
||||||
|
<th>@lang('contactform::sent.createdAt')</th>
|
||||||
|
<th>@lang('contactform::sent.subject')</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
@foreach($emails as $email)
|
||||||
|
<tr @if ($email->is_new) class="bold" @endif >
|
||||||
|
<td>{{$email->from}}</td>
|
||||||
|
<td>{{$email->to}}</td>
|
||||||
|
<td>@date($email->created_at)</td>
|
||||||
|
<td>{{$email->subject}}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{route('sentEmails.show', compact('email'))}}" class="btn btn-sm rounded btn-secondary">
|
||||||
|
<i class="fa fa-eye"></i>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
{!! $emails->render() !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@else
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<em>@lang('contactform::sent.noEntries')</em>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@stop
|
||||||
Reference in New Issue
Block a user