Practical work: Real estate agency, contact request — Laravel 10 Discovery Training

In this chapter we will set up the contact form which will allow users to contact the agency when they are interested in properties. This chapter will be an opportunity to discover the system of Mailablewhich allows to send users from Laravel.

Configuration

If you try to send emails with Laravel, by default, in development mode, it is configured to write sent emails to the log file. This method is practical because it allows you to test your emails without necessarily needing an SMTP server, but it is not necessarily easy to read this file to view the emails.

Also I advise you to use tools like mailhog which will allow you to create an SMTP server on your machine which will be able to capture the emails that will be sent. These tools then offer you a web interface, which looks like an email client, in which you will be able to consult the emails that have been captured.

You will then have to modify the environment file to put the information corresponding to this tool.

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025

You can also look at the configuration file config/mail.php to see the different protocols that are supported and the basic configuration.

Mailable

To start managing the sending of emails, we must create a class that will represent the email to be sent.

php artisan make:mail PropertyContactMail

This command will create a class that extends from Illuminate\Mail\Mailable which we will have to modify according to our needs. In our case, we are going to modify the constructor to pass it the information that interests us (the form data as well as the asset associated with the request).

<?php

namespace App\Mail;

use App\Models\Property;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class PropertyContactMail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(
        public Property $property, 
        public array $data
    )
    {
    }

    public function envelope(): Envelope
    {
        return new Envelope(
            to: 'admin@doe.fr',
            replyTo: $this->data['email'],
            subject: 'Property Contact Mail'
        );
    }

    public function content(): Content
    {
        return new Content(
            markdown: 'emails.property.contact',
        );
    }

    /**
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }
}

The method envelope() allows to define attributes on our email while the method content() allows you to define what the content of the email will look like. For this content part, the email can be defined in different ways (text, html or markdown) using the path to a blade view.

The markdown option is interesting because it allows you to build the email faster by not having to manage the complex HTML structure necessary for it to work properly on the different email clients.

<x-mail::message>
# Nouvelle demande de contact

Une nouvelle demande de contact a été fait pour le bien <a href="https://grafikart.fr/tutoriels/{{ route("property.show', ['slug' => $property->getSlug(), 'property' => $property]) }}">{{ $property->title }}</a>.

- Prénom : {{ $data['firstname'] }}
- Nom : {{ $data['lastname'] }}
- Téléphone : {{ $data['phone'] }}
- Email : {{ $data['email'] }}

**Message :**<br/>
{{ $data['message'] }}
</x-mail::message>

Mail

Now that we have our class that allows us to represent an email, we will have to instantiate it and send it.

use App\Http\Requests\PropertyContactRequest;
use App\Http\Requests\SearchPropertiesRequest;
use App\Mail\PropertyContactMail;
use App\Models\Property;
use Illuminate\Support\Facades\Mail;

public function contact(
    Property $property,
    PropertyContactRequest $request
)
{
    Mail::send(new PropertyContactMail($property, $request->validated()));
    return back()->with('success', 'Votre demande de contact a bien été envoyé');
}

Laravel has a facade Illuminate\Support\Facades\Mailwhich expects an instance of Mailable.