feat: Ajoute la fonctionnalité de demande d'accès à l'API publique

Ce commit introduit une nouvelle fonctionnalité permettant aux utilisateurs de demander l'accès à l'API publique via un formulaire. Il inclut également l'envoi d'e-mails de notification.

Les changements suivants ont été effectués :

- Ajout du template `templates/api/quote.twig` pour le formulaire de demande d'accès à l'API.
- Ajout des templates `templates/mails/api/quote.twig` et `templates/mails/api/quote-team.twig` pour les e-mails de notification (client et équipe).
- Modification du contrôleur `src/Controller/Api/Public/RootController.php` pour gérer l'affichage du formulaire et le traitement de la soumission, y compris la validation CSRF et l'envoi d'e-mails.
This commit is contained in:
Serreau Jovann
2025-07-18 12:41:05 +02:00
parent 89301a7aa2
commit ca0bce9f94
4 changed files with 252 additions and 4 deletions

View File

@@ -2,10 +2,13 @@
namespace App\Controller\Api\Public;
use App\Entity\Mail;
use App\Service\Mailer\Mailer;
use Nelmio\ApiDocBundle\Attribute\Security;
use OpenApi\Attributes as OA;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@@ -41,7 +44,7 @@ class RootController extends AbstractController
return $this->json($data);
}
#[Route('/api/public/quote', name: 'api_public_quote', methods: ['GET'])]
#[Route('/api/public/quote', name: 'api_public_quote', methods: ['GET','POST'])]
#[OA\Get(
path: '/api/public/quote',
description: 'Form quote access api',
@@ -66,10 +69,22 @@ class RootController extends AbstractController
]
)]
#[Security(name: '')]
public function quote(): Response
public function quote(Mailer $mailer,Request $request): Response
{
$html = '<html><body><h1>Public API Quote Form</h1></body></html>';
if($request->isMethod('POST')){
$data = $request->request->all();
return new Response($html, 200, ['Content-Type' => 'text/html']);
if (!$this->isCsrfTokenValid('quote_api',$data['_token'])) {
$this->addFlash("error", "Une erreur de sécurité est survenue. Veuillez réessayer.");
return $this->redirectToRoute('api_public_quote');
}
unset($data['_token']);
$mailer->send($data['email'],$data['first_name']." ".$data['last_name'],"[Mainframe] - Demmande d'acceés à l'api","mails/api/quote.twig",$data);
$mailer->send('s.com@siteconseil.fr',"SARL SITECONSEIl","[Mainframe] - Demmande d'acceés à l'api","mails/api/quote-team.twig",$data);
$this->addFlash("success", "Votre demande a été envoyée avec succès ! Nous vous répondrons dans les plus brefs délais.");
return $this->redirectToRoute('api_public_quote');
}
return $this->render('api/quote.twig');
}
}

98
templates/api/quote.twig Normal file
View File

@@ -0,0 +1,98 @@
{% extends 'admin/base.twig' %}
{% block title %}Demande d'accès à l'API Esy-Web{% endblock %}
{% block content %}
<div class="min-h-screen flex items-center justify-center bg-gray-900 p-4">
<div class="bg-gray-800 p-8 rounded-lg shadow-xl w-full max-w-md border border-gray-700">
<h2 class="text-2xl font-bold text-white mb-6 text-center">Demande d'accès à l'API Esy-Web</h2>
<p class="text-gray-300 mb-6 text-center">
<strong class="text-indigo-400">Cette demande d'accès à l'API est réservée exclusivement aux clients Esy-Web.</strong>
Veuillez remplir le formulaire ci-dessous. Nous examinerons votre demande et vous répondrons dans les plus brefs délais.
</p>
{# Flash Messages Section #}
{% if flash_messages is defined and flash_messages is not empty %}
{% for type, messages in flash_messages %}
{% for message in messages %}
{% if type == 'success' %}
<div class="bg-green-500 text-white px-4 py-3 rounded-lg relative mb-4" role="alert">
<strong class="font-bold">Succès!</strong>
<span class="block sm:inline">{{ message }}</span>
</div>
{% elseif type == 'error' %}
<div class="bg-red-500 text-white px-4 py-3 rounded-lg relative mb-4" role="alert">
<strong class="font-bold">Erreur!</strong>
<span class="block sm:inline">{{ message }}</span>
</div>
{% elseif type == 'warning' %}
<div class="bg-yellow-500 text-white px-4 py-3 rounded-lg relative mb-4" role="alert">
<strong class="font-bold">Attention!</strong>
<span class="block sm:inline">{{ message }}</span>
</div>
{% else %} {# Default or 'info' messages #}
<div class="bg-blue-500 text-white px-4 py-3 rounded-lg relative mb-4" role="alert">
<strong class="font-bold">Info:</strong>
<span class="block sm:inline">{{ message }}</span>
</div>
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{# End Flash Messages Section #}
<form data-turbo="false" method="POST" class="space-y-6">
<input name="_token" type="hidden" required hidden value="{{ csrf_token('quote_api') }}">
<div>
<label for="esyweb_client_url" class="block text-sm font-medium text-gray-200">URL de votre site client Esy-Web <span class="text-gray-400">(Votre ID Client)</span></label>
<input type="url" id="esyweb_client_url" name="esyweb_client_url" required
class="mt-1 block w-full px-3 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="https://votre-site.esy-web.com">
<p class="mt-2 text-sm text-gray-400">Ceci est l'URL de votre site propulsé par le CMS Esy-Web et sert à vous identifier en tant que client.</p>
</div>
<div>
<label for="first_name" class="block text-sm font-medium text-gray-200">Prénom</label>
<input type="text" id="first_name" name="first_name" required
class="mt-1 block w-full px-3 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Votre prénom">
</div>
<div>
<label for="last_name" class="block text-sm font-medium text-gray-200">Nom</label>
<input type="text" id="last_name" name="last_name" required
class="mt-1 block w-full px-3 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Votre nom de famille">
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-200">Adresse E-mail</label>
<input type="email" id="email" name="email" required
class="mt-1 block w-full px-3 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="votre.email@example.com">
</div>
<div>
<label for="phone" class="block text-sm font-medium text-gray-200">Téléphone (optionnel)</label>
<input type="tel" id="phone" name="phone"
class="mt-1 block w-full px-3 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="+33 6 12 34 56 78">
</div>
<div>
<label for="description" class="block text-sm font-medium text-gray-200">Description de votre projet / utilisation de l'API</label>
<textarea id="description" name="description" rows="4" required
class="mt-1 block w-full px-3 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Décrivez brièvement comment vous prévoyez d'utiliser l'API Esy-Web pour votre projet..."></textarea>
</div>
<div>
<button type="submit"
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 focus:ring-offset-gray-800">
Envoyer la demande
</button>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,68 @@
{% extends 'mails/base.twig' %}
{% block content %}
<mj-section background-color="#e6f7ff"> {# Lighter background for internal alert #}
<mj-column>
<mj-text font-size="22px" color="#1a73e8" font-family="Helvetica" align="center" padding-bottom="20px">
<strong style="color:#1a73e8;">Nouvelle Demande d'Accès API Esy-Web !</strong>
</mj-text>
<mj-text font-size="16px" color="#333333" font-family="Helvetica" line-height="24px">
Bonjour,
</mj-text>
<mj-text font-size="16px" color="#333333" font-family="Helvetica" line-height="24px">
Une nouvelle demande d'accès à l'API Esy-Web a été soumise. Veuillez trouver les détails ci-dessous pour examen.
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" padding-top="30px" padding-bottom="30px">
<mj-column>
<mj-text font-size="18px" color="#333333" font-family="Helvetica" font-weight="bold" padding-bottom="15px">
Informations du demandeur :
</mj-text>
<mj-table font-size="15px" color="#555555" font-family="Helvetica">
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Prénom :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;">{{ datas.first_name }}</td>
</tr>
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Nom :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;">{{ datas.last_name }}</td>
</tr>
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Email :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;"><a href="mailto:{{ datas.email }}" style="color:#1a73e8; text-decoration:none;">{{ datas.email }}</a></td>
</tr>
{% if datas.phone is not empty %}
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Téléphone :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;"><a href="tel:{{ datas.phone }}" style="color:#1a73e8; text-decoration:none;">{{ datas.phone }}</a></td>
</tr>
{% endif %}
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Site Client Esy-Web :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;"><a href="{{ datas.esyweb_client_url }}" style="color:#1a73e8; text-decoration:none;">{{ datas.esyweb_client_url }}</a></td>
</tr>
<tr>
<td style="padding: 8px 0; width: 30%; vertical-align: top;"><strong>Description du projet :</strong></td>
<td style="padding: 8px 0;">{{ datas.description | nl2br }}</td>
</tr>
<tr>
<td style="padding: 8px 0; border-top: 1px solid #eeeeee; width: 30%; vertical-align: top;"><strong>Date de la demande :</strong></td>
<td style="padding: 8px 0; border-top: 1px solid #eeeeee;">{{ "now"|date("d/m/Y H:i:s") }}</td>
</tr>
</mj-table>
</mj-column>
</mj-section>
<mj-section background-color="#f0f0f0" padding-top="20px" padding-bottom="20px">
<mj-column>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px">
Veuillez procéder à l'examen de cette demande et prendre les mesures nécessaires.
</mj-text>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px" padding-top="10px">
Cordialement,<br/>
Votre Système de Notification Esy-Web
</mj-text>
</mj-column>
</mj-section>
{% endblock %}

View File

@@ -0,0 +1,67 @@
{% extends 'mails/base.twig' %}
{% block content %}
<mj-section background-color="#f0f0f0">
<mj-column>
<mj-text font-size="20px" color="#333333" font-family="Helvetica" align="center" padding-bottom="20px">
<strong style="color:#2a7ffc;">Demande d'accès à l'API Esy-Web Reçue !</strong>
</mj-text>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px">
Cher(e) {{ datas.first_name }} {{ datas.last_name }},
</mj-text>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px">
Nous avons bien reçu votre demande d'accès à l'API Esy-Web concernant votre site <a href="{{ datas.esyweb_client_url }}" style="color:#2a7ffc; text-decoration:none;">{{ datas.esyweb_client_url }}</a>.
</mj-text>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px">
Notre équipe va examiner votre projet et l'utilisation prévue de l'API. Nous mettons tout en œuvre pour traiter votre demande dans les plus brefs délais.
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" padding-top="30px" padding-bottom="30px">
<mj-column>
<mj-text font-size="18px" color="#333333" font-family="Helvetica" font-weight="bold" padding-bottom="15px">
Détails de votre demande :
</mj-text>
<mj-table font-size="15px" color="#555555" font-family="Helvetica">
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Prénom :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;">{{ datas.first_name }}</td>
</tr>
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Nom :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;">{{ datas.last_name }}</td>
</tr>
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Email :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;"><a href="mailto:{{ datas.email }}" style="color:#2a7ffc; text-decoration:none;">{{ datas.email }}</a></td>
</tr>
{% if datas.phone is not empty %}
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Téléphone :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;">{{ datas.phone }}</td>
</tr>
{% endif %}
<tr>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee; width: 30%;"><strong>Site Esy-Web :</strong></td>
<td style="padding: 8px 0; border-bottom: 1px solid #eeeeee;"><a href="{{ datas.esyweb_client_url }}" style="color:#2a7ffc; text-decoration:none;">{{ datas.esyweb_client_url }}</a></td>
</tr>
<tr>
<td style="padding: 8px 0; width: 30%; vertical-align: top;"><strong>Description du projet :</strong></td>
<td style="padding: 8px 0;">{{ datas.description | nl2br }}</td>
</tr>
</mj-table>
</mj-column>
</mj-section>
<mj-section background-color="#f0f0f0" padding-top="20px" padding-bottom="20px">
<mj-column>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px">
En cas de questions ou pour toute information complémentaire, n'hésitez pas à nous contacter.
</mj-text>
<mj-text font-size="16px" color="#555555" font-family="Helvetica" line-height="24px" padding-top="10px">
Cordialement,<br/>
L'équipe Esy-Web
</mj-text>
</mj-column>
</mj-section>
{% endblock %}