Create a Contact Us Form and Save Sent Message to the Database

For our local environment we will configure Mailtrap.

Mailtrap is an easy to use email sandbox to inspect and debug emails in staging, dev, and QA environments. You can test email before deploying to production.

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=your_mailtrap_port
MAIL_USERNAME=your_mailtrap_key
MAIL_PASSWORD=your_mailtrap_key
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=handle@example.com
MAIL_FROM_NAME="${APP_NAME}"

 

For our product environment we suggest using SendGrid.

SendGrid is a cloud-based SMTP provider that allows you to send email without having to maintain email servers.

Create Table for Contact Form with Database Migration

Our contact us form will collect three inputs: name, email address and message. We need to create this table in the database.

php artisan make:migration create_contact_us_table

This command will create a file, database/migrations/2022_05_01_215420_create_contact_us_table.php .

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('contact_us', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->string('name');
            $table->string('email');
            $table->text('message');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('contact_us');
    }
};

Now run the migration, and the table will be created in our database

php artisan migrate

Create the Model

php artisan make:model ContactUs

This command will create a file, app/Models/ContactUS.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ContactUs extends Model
{
    use HasFactory;

    public $fillable = [
        'name',
        'email',
        'message'
    ];
}

Create the Controller

After setting the routes, I will create a controller to handle the requests from the routes.

php artisan make:controller ContactUsController

This command will create a file, app/Http/Controllers/ContactUsController.php   

We will need to create two methods in this controller. One to handle the GET request, display the contact form,  and one to handle the POST request, to store sender and message to the database and also email the admin.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\Contact;
use App\Models\ContactUs;


class ContactUsController extends Controller
{
    public function send(Request $request)
    {

        //validate the inputs
        $request->validate([
            'name' => 'required',
            'email' => 'required',
            'message' => 'required',
        ]);
        
        //put request data in an array
        $data = [
            'from_name' => $request->name,
        	'from' => $request->email,
            'message' => $request->message
        ];

        ContactUs::create($request->all());
        
        //send email to site owner via the mailable class Contact
        Mail::to('butlerjraines@gmail.com')->send(new Contact($data));

        return redirect('/')->with(['status' => 'Thanks for Contact Us']);
    }
    
    public function page(Request $request)
    {
        return view('pages.contact');
    }
}

Create Mailable

php artisan make:mail ContactUs

This willl create a file app/Mail/Contact.php and generated a mailable class Contact

<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class Contact extends Mailable
{
    use Queueable, SerializesModels;
    /**
     * Create a new message instance.
     */
    public function __construct()
    {
        //
    }
    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Contact Us',
        );
    }
    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'emails.contact',
        );
    }
    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }
}

Create the Routes

Go to routes/web.php and add the following code. One route will be a GET request that will display the contact form. The other route will be the post route for the form submission.

use App\Http\Controllers\ContactUsController;
Route::get('contact', [ContactController::class, 'page'])->name('pages.contact');
Route::post('contact', [ContactController::class, 'send'])->name('send.contact')

 

Create the Views

The page() method returns the Blade view that displays the contact HTML form.