Skip to content

Instantly share code, notes, and snippets.

@kikoseijo
Last active September 3, 2019 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kikoseijo/34a44e6083e81fea94161dd1db0c6f64 to your computer and use it in GitHub Desktop.
Save kikoseijo/34a44e6083e81fea94161dd1db0c6f64 to your computer and use it in GitHub Desktop.
Laravel Contact Form Requests
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFormRequestsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('form_requests', function (Blueprint $table) {
$table->bigIncrements('id');
$table->boolean('status')->default(1);
$table->unsignedInteger('ref_id')->nullable();
$table->unsignedInteger('assigne_id')->nullable()->index();
$table->string('tipo', 40)->default('contactForm');
$table->string('contact_name');
$table->string('contact_email');
$table->string('contact_phone')->nullable();
$table->string('contact_subject');
$table->text('contact_message');
$table->string('referer')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('form_requests');
}
}
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRecipientsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('recipients', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->nullable();
$table->string('form')->nullable();
$table->string('email')->nullable();
$table->boolean('draft')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('recipients');
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Models\FormRequest;
use App\Http\Requests\ContactFormRequest;
use App\Mail\Admin\ContactFormSubmitted;
class ContactFormController extends Controller
{
public function __invoke(ContactFormRequest $message)
{
$formResponse = FormRequest::create([
'name' => array_get($message, 'your-name'),
'phone' => array_get($message, 'your-phone'),
'email' => array_get($message, 'your-email'),
'message' => array_get($message, 'your-message'),
'subject' => array_get($message, 'your-subject'),
// 'address' => array_get($message, 'address'),
// 'postal' => array_get($message, 'postal'),
// 'city' => array_get($message, 'city'),
'tipo' => array_get($message, 'tipo') ?: 'contactForm',
'referer' => app(Referer::class)->get(),
]);
$this->processMails(ContactFormSubmitted::class, $formResponse, $formResponse->tipo);
return back()->with(['flash_message' => 'Message sent succesfully.']);
}
protected function processMails($mailable, $mailData, $referrersTipo)
{
Mail::send(new $mailable($mailData));
}
}
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ContactFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'your-name' => 'required|max:255',
'your-email' => 'required|max:255',
'your-subject' => 'required|max:255',
'your-message' => 'required',
];
}
}
@component('mail::message')
# Nuevo contacto
Hola,
Un usuario ha enviado un formulario en [{{ Request::getHost() }}]({{ url('/') }}).
@component('mail::panel')
### Datos del solicitante
Name: {{ $form->contact_name }} <br>
Email: {{ $form->contact_email }} <br>
Telephone: {{ $form->contact_phone }} <br>
Subject: {{ $form->contact_subject }} <br>
@if ($form->message)
### Comentarios del solicitante
{{ $form->message }} <br>
@endif
---
Origen de la solicitud: {{ $form->referer ?: 'Desconocida' }} <br>
@endcomponent
@slot('subcopy')
<br>
Puedes ver este y otros mensajes anteriores en la siguiente
dirección web [{{ config('app.url') }}]({{ url(config('nova.path')) }}).
@endslot
@endcomponent
<?php
namespace App\Mail\Admin;
use App\Models\FormRequest;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ContactFormSubmitted extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public $form;
public function __construct(FormRequest $form)
{
$this->form = $form;
}
public function build()
{
$toMail = recipients($this->form->tipo);
$formType = title_case($this->form->tipo);
$toName = $toMail[0]['name'];
$requestEmail = $this->form->contact_email;
// activity('mails')->log("Contact request <strong>{$formType}</strong> for {$toName} from {$requestEmail}");
if ($requestEmail == TEST_EMAIL) {
$toNames = array_pluck($toMail, 'name');
$toMail = [[
'email' => DEV_EMAIL,
'name' => implode(' + ', $toNames),
]];
}
return $this
->to($toMail)
->subject('New ' . $formType . ' from ' . $requestEmail . ' in ' . config('app.url'))
->markdown('mails.' . $this->form->tipo . 'Submitted')
->with([
'departmentName' => $toName,
]);
}
}
<form action="{{ route('front.contact.submit') }}" method="post">
@csrf
<span class="wpcf7-form-control-wrap your-name">
<input type="text" name="your-name" placeholder="Your Name" value="{{ old('your-name')}}" class="@error('your-name') is-invalid @enderror" size="40" aria-required="true" aria-invalid="false">
</span>
@error('your-name')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
<br>
<span class="wpcf7-form-control-wrap your-email">
<input type="email" name="your-email" placeholder="Your Email" value="{{ old('your-email')}}" class="@error('your-email') is-invalid @enderror" size="40" aria-required="true" aria-invalid="false">
</span>
@error('your-email')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
<br>
<span class="wpcf7-form-control-wrap your-phone">
<input type="text" name="your-phone" placeholder="Your Phone Number" value="{{ old('your-phone')}}" class="@error('your-phone') is-invalid @enderror" size="40" aria-required="true" aria-invalid="false">
</span>
@error('your-phone')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
<br>
<span class="wpcf7-form-control-wrap your-subject">
<input type="text" name="your-subject" placeholder="Subject" value="{{ old('your-subject')}}" class="@error('your-subject') is-invalid @enderror" size="40" class="wpcf7-form-control wpcf7-text" aria-invalid="false">
</span>
@error('your-subject')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
<br>
<span class="wpcf7-form-control-wrap your-message">
<textarea name="your-message" placeholder="Your Message" cols="40" rows="10" class="@error('your-message') is-invalid @enderror" aria-invalid="false">{{ old('your-name')}}</textarea>
</span>
@error('your-message')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
<p>
<input type="submit" value="Send" class="wpcf7-form-control wpcf7-submit">
<span class="ajax-loader"></span>
</p>
<div class="wpcf7-response-output wpcf7-display-none"></div>
</form>
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Maatwebsite\Excel\Facades\Excel;
use Spatie\Referer\Referer;
class FormRequest extends Model
{
protected $guarded = ['id'];
public static function boot()
{
static::creating(function (FormResponse $formResponse) {
$formResponse->referer = app(Referer::class)->get();
});
}
public static function downloadAll()
{
Excel::create('Responses ' . date('Y-m-d'), function ($excel) {
$excel->sheet('Responses', function ($sheet) {
$sheet->freezeFirstRow();
$sheet->cells('A1:Z1', function ($cells) {
$cells->setFontWeight('bold');
$cells->setBorder('node', 'none', 'solid', 'none');
});
$sheet->fromModel(self::all());
});
})->download('xlsx');
}
public function recipient()
{
return $this->belongsTo('App\Models\Recipient', 'tipo', 'form');
}
public function assigne()
{
return $this->belongsTo('App\Models\User', 'assigne_id');
}
}
<?php
return [
/*
* This will be returned by the `recipients()` helper for all forms in
* non-production environments.
*/
'development_recipients' => [
['email' => 'xxxx@gamil.com', 'name' => 'Texh Technical'],
],
/*
* Form types used by recipients.
*/
'types' => [
'contactForm' => 'Contact form',
],
];
<?php
use Spatie\Image\Image;
use App\Models\Recipient;
use Illuminate\Support\Facades\Route;
define('SESSION_TIME_LIMIT_CACHE', 'ks_session_limit');
define('TEST_EMAIL','XXXXX@gmail.com');
define('DEV_EMAIL','XXXXXXX@gmail.com');
function recipients(string $formName): array
{
return Recipient::forForm($formName);
}
function locale(): string
{
return app()->getLocale();
}
function locales(): Collection
{
return collect(config('app.locales'));
}
if (!function_exists('normalizeString')) {
function normalizeString($text, $limit = 0): string
{
if (!$text) {
return '';
}
$res = '';
if ($limit > 0) {
$res = str_limit($text, $limit);
} else {
$res = $text;
}
return ucfirst(mb_strtolower($res));
}
}
if (!function_exists('route_has')) {
function route_has($route_name, $params=[], $absolute=true): string
{
if (str_contains($route_name, '@')) {
return action($route_name, $params);
}
if (!Route::has($route_name)) {
return url($route_name);
}
return route($route_name, $params, $absolute);
}
}
if (!function_exists('get_img_sizes')) {
function get_img_sizes($image): array
{
$res = [0, 0];
try {
$spatiImage = Image::load($image);
$res[0] = $spatiImage->getWidth();
$res[1] = $spatiImage->getHeight();
} catch (\Exception $e) {
}
return $res;
}
}
if (!function_exists('number')) {
function number($number): string
{
if (app()->getLocale() == 'es') {
return number_format(floatval($number), 0, ',', '.');
} else {
return number_format(floatval($number), 0, '.', ',');
}
}
}
if (!function_exists('logi')) {
function logi($data)
{
\Log::info(transform_log($data));
}
}
if (!function_exists('loge')) {
function loge($data)
{
\Log::error(transform_log($data));
}
}
if (!function_exists('logc')) {
function logc($data)
{
\Log::critical(transform_log($data));
}
}
if (!function_exists('transform_log')) {
function transform_log($data)
{
if (is_array($data)) {
return json_encode($data);
} else {
return $data;
}
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Recipient extends Model
{
protected $guarded = ['id'];
public static $rules = [
'name' => 'required|string|max:255',
'form' => 'required|string|max:255',
'email' => 'required|string|max:255',
];
public static function forForm(string $form): array
{
if (!app()->environment('production')) {
return config('forms.development_recipients');
}
$records = static::where('form', $form)->get();
return $records->map(function (Recipient $recipient) {
return [
'email' => $recipient->email,
'name' => $recipient->name,
];
})->toArray();
}
public function forms()
{
return $this->hasMany('App\Models\FormRequest', 'tipo', 'form');
}
}
<?php
namespace App\Nova;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\DateTime;
use Illuminate\Http\Request;
use Laravel\Nova\Http\Requests\NovaRequest;
class Recipients extends Resource
{
/**
* The model the resource corresponds to.
*
* @var string
*/
public static $model = 'App\Models\Recipient';
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'name';
/**
* The columns that should be searched.
*
* @var array
*/
public static $search = [
'form', 'name', 'email'
];
/**
* Get the fields displayed by the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Boolean::make('Draft', 'draft')
->sortable(),
Select::make(__('Type'), 'form')
->options(config('forms.types'))
->rules('required', 'max:40')
->displayUsingLabels(),
Text::make('Name'),
Text::make('Email'),
DateTime::make(__('Created at'), 'created_at')
->format('DD MMM HH:mm')
->hideWhenCreating(),
];
}
/**
* Get the cards available for the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function actions(Request $request)
{
return [];
}
}
@kikoseijo
Copy link
Author

might need to

composer require maatwebsite/excel spatie/laravel-referer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment