Filament - Comment générer un PDF des Conditions Générales et l'envoyer à l'utilisateur après consentement

Julien BOYER
Julien BOYER (aka. yebor974) Buy Me A Coffee
Publié le 22 août 2024
Cet article explique comment générer un PDF de vos conditions générales lors de leur publication et l'envoyer à l'utilisateur après qu'il ait donné son consentement.

Cet article utilise le Plugin Filament Terms Guard and nécessite la version minimale ^1.1.1.

  1. Installation et configuration du plugin

Pour installer le plugin, suivez la documentation officielle.

Pour cet article, nous utilisons deux panels identifiés par l'ID admin et member.

  • Le panel admin est un panel d'administration pour lequel nous activons le plugin avec la resource TermResource afin de gérer les conditions générales d'utilisation :
use Yebor974\FilamentTermsGuard\TermsGuardPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            TermsGuardPlugin::make()
                ->termsResource()
        ])
}
  • Le panel member est un panel à destination des utilisateurs de notre site où nous souhaitons que l'utilisateur consente à nos conditions générales d'utilisation.
use Yebor974\FilamentTermsGuard\TermsGuardPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            TermsGuardPlugin::make()
        ])
}

Nous ajoutons la clé suivante dans le fichier .env pour activer la vérification des CGU suivant l'utilisateur connecté :

TERMS_GUARD_PANELS=member
  1. Publication de nos CGU et génération du PDF associé

Dans le panel admin, nous pouvons créer, modifier et publier des CGU :

Index of terms and conditions view

Lors de l'action de publication l'évènement TermPublished est émis. Nous pouvons donc y associer un listener pour faire du traitement complémentaire (ici générer le PDF associé à nos CGU publiée).

Pour créer le listener GenerateTermPDF lié à l'évènement TermPublished :

php artisan make:listener GenerateTermPDF --event=\\Yebor974\\FilamentTermsGuard\\Events\\TermPublished

Associez ces deux éléments dans le provider EventServiceProvider :

use App\Listeners\GenerateTermPDF;
use Yebor974\FilamentTermsGuard\Events\TermPublished;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        // ...
        TermPublished::class => [
            GenerateTermPDF::class
        ],
    ];
	
	  //...
}

Vous pouvez ensuite gérer la génération de votre PDF dans la méthode handle de votre listener :

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Yebor974\FilamentTermsGuard\Events\TermPublished;

class GenerateTermPDF
{
    /**
     * Create the event listener.
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     */
    public function handle(TermPublished $event): void
    {
        // $event->term;
        if(!Storage::directoryExists('cgu')) {
            Storage::makeDirectory('cgu');
        }

        Pdf::html("<div class='prose'>{$event->term->content}</div>")
            ->format(Format::A4)
            ->margins(10, 0, 15, 0)
            ->save(storage_path("app/cgu/{$event->term->id}.pdf"));
    }
}

J'utilise en général le plugin Laravel-PDF de Spatie pour générer ce PDF documentation officielle. L'exemple précédent est basique et n'intègre pas de titre de document ou encore de thème CSS. Vous pouvez vous reporter à la document de Laravel-PDF pour plus de personnalisation.

  1. Consentement des membres et envoi de mail avec les CGU consenties

Comme précédemment, vous pouvez créer un listener SendTermByMail pour envoyer par mail les CGU acceptées par l'utilisateur. Le plugin émet pour cela l'évènement TermAccepted.

Créez tout d'abord une notification email nommée SendAcceptedTerm :

php artisan make:notification SendAcceptedTerm
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Yebor974\FilamentTermsGuard\Models\Term;

class SendAcceptedTerm extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     */
    public function __construct(protected Term $term)
    {
        $this->afterCommit();
    }

    /**
     * Get the notification's delivery channels.
     *
     * @return array<int, string>
     */
    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     */
    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
                    ->subject("New Terms and Conditions")
                    ->line('You have accepted the new terms and conditions of the platform.')
                    ->line('Please find them attached!')
                    ->attach(storage_path("app/cgu/{$this->term->id}.pdf"), [ // here we add attachment and rename sending file
                        'as' => "Terms and Conditions - {$this->term->name}.pdf",
                        'mime' => 'application/pdf',
                    ]);
    }

    // ...
}

Puis créez le listener SendTermByMail lié à l'évènement TermAccepted :

php artisan make:listener SendTermByMail --event=\\Yebor974\\FilamentTermsGuard\\Events\\TermAccepted

Associez ces deux éléments dans le provider EventServiceProvider :

use App\Listeners\SendTermByMail;
use Yebor974\FilamentTermsGuard\Events\TermAccepted;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        // ...
        TermAccepted::class => [
            SendTermByMail::class
        ],
    ];
	
	  //...
}

Vous pouvez ensuite gérer l'envoi d'un mail à l'utilisateur ayant accepté les CGU avec le document associé dans la méthode handle de votre listener :

use App\Notifications\SendAcceptedTerm;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Yebor974\FilamentTermsGuard\Events\TermAccepted;

class SendTermByMail
{
    /**
     * Create the event listener.
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     */
    public function handle(TermAccepted $event): void
    {
        // $event->user
        // $event->term
        $event->user->notify(new SendAcceptedTerm($event->term));
    }
}

Autres articles

Plugins

Me contacter

Que vous ayez une idée à concrétiser, une problématique à résoudre ou un défi technique de grande envergure à relever, ne perdez plus de temps. Contactez-moi dès maintenant et laissez-moi vous aider à transformer vos ambitions en réalité. Mon expertise est à votre disposition pour concrétiser vos projets avec succès.

Situation géographique

Paris & Ile de la Réunion (France - UTC+4)