From 28763e7ee19139159982161845ce1f13fed53dbe Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Thu, 19 Mar 2026 10:19:41 +0100 Subject: [PATCH] Add contact page with form, email template, and tests - Create ContactController with GET/POST handling and MailerService integration - Create contact page template with name, surname, email, message form - Create dedicated email template for contact messages - Update navbar links (desktop + mobile) to point to /contact route - Add ContactControllerTest with 5 tests covering form submission and validation Co-Authored-By: Claude Opus 4.6 (1M context) --- src/Controller/ContactController.php | 55 ++++++++++++++++ templates/base.html.twig | 4 +- templates/contact/index.html.twig | 74 +++++++++++++++++++++ templates/email/contact.html.twig | 24 +++++++ tests/Controller/ContactControllerTest.php | 76 ++++++++++++++++++++++ 5 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 src/Controller/ContactController.php create mode 100644 templates/contact/index.html.twig create mode 100644 templates/email/contact.html.twig create mode 100644 tests/Controller/ContactControllerTest.php diff --git a/src/Controller/ContactController.php b/src/Controller/ContactController.php new file mode 100644 index 0000000..f8a3464 --- /dev/null +++ b/src/Controller/ContactController.php @@ -0,0 +1,55 @@ +isMethod('POST')) { + $name = trim($request->request->getString('name')); + $surname = trim($request->request->getString('surname')); + $email = trim($request->request->getString('email')); + $message = trim($request->request->getString('message')); + + if ('' === $name || '' === $surname || '' === $email || '' === $message) { + $this->addFlash('error', 'Tous les champs sont obligatoires.'); + + return $this->redirectToRoute('app_contact'); + } + + $html = $this->renderView('email/contact.html.twig', [ + 'name' => $name, + 'surname' => $surname, + 'email' => $email, + 'message' => $message, + ]); + + $mailerService->sendEmail( + to: 'contact@e-cosplay.fr', + subject: sprintf('Contact de %s %s', $surname, $name), + content: $html, + replyTo: $email, + withUnsubscribe: false, + ); + + $this->addFlash('success', 'Votre message a bien ete envoye. Nous vous repondrons dans les plus brefs delais.'); + + return $this->redirectToRoute('app_contact'); + } + + return $this->render('contact/index.html.twig', [ + 'breadcrumbs' => [ + ['name' => 'Accueil', 'url' => '/'], + ['name' => 'Contact', 'url' => '/contact'], + ], + ]); + } +} diff --git a/templates/base.html.twig b/templates/base.html.twig index 1fd4d27..3d29018 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -84,7 +84,7 @@
@@ -112,7 +112,7 @@
Accueil Evenements - Contact + Contact {% if app.user %} Mon espace {% else %} diff --git a/templates/contact/index.html.twig b/templates/contact/index.html.twig new file mode 100644 index 0000000..c8132b8 --- /dev/null +++ b/templates/contact/index.html.twig @@ -0,0 +1,74 @@ +{% extends 'base.html.twig' %} + +{% block title %}Contact - E-Ticket{% endblock %} +{% block description %}Contactez l'equipe E-Ticket pour toute question sur la plateforme de billetterie associative{% endblock %} + +{% block body %} +
+

Contact

+

Une question, une demande ? Ecrivez-nous.

+ + {% for message in app.flashes('success') %} +
+

{{ message }}

+
+ {% endfor %} + + {% for message in app.flashes('error') %} +
+

{{ message }}

+
+ {% endfor %} + +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ +
+

Autres moyens de contact

+ +
+
+{% endblock %} diff --git a/templates/email/contact.html.twig b/templates/email/contact.html.twig new file mode 100644 index 0000000..9ddc354 --- /dev/null +++ b/templates/email/contact.html.twig @@ -0,0 +1,24 @@ +{% extends 'email/base.html.twig' %} + +{% block title %}Nouveau message de contact{% endblock %} + +{% block content %} +

Nouveau message de contact

+ + + + + + + + + + + + + +
Nom{{ name }}
Prenom{{ surname }}
Email{{ email }}
+
+ {{ message|nl2br }} +
+{% endblock %} diff --git a/tests/Controller/ContactControllerTest.php b/tests/Controller/ContactControllerTest.php new file mode 100644 index 0000000..6b10229 --- /dev/null +++ b/tests/Controller/ContactControllerTest.php @@ -0,0 +1,76 @@ +request('GET', '/contact'); + + self::assertResponseIsSuccessful(); + } + + public function testContactFormSubmitRedirectsWithSuccess(): void + { + $client = static::createClient(); + + $mailer = $this->createMock(MailerService::class); + $mailer->expects(self::once())->method('sendEmail'); + static::getContainer()->set(MailerService::class, $mailer); + + $client->request('POST', '/contact', [ + 'name' => 'Dupont', + 'surname' => 'Jean', + 'email' => 'jean@exemple.fr', + 'message' => 'Bonjour, je voudrais des informations.', + ]); + + self::assertResponseRedirects('/contact'); + $client->followRedirect(); + self::assertSelectorExists('.font-black.text-sm'); + } + + public function testContactFormEmptyFieldsRedirectsWithError(): void + { + $client = static::createClient(); + $client->request('POST', '/contact', [ + 'name' => '', + 'surname' => 'Jean', + 'email' => 'jean@exemple.fr', + 'message' => 'Bonjour', + ]); + + self::assertResponseRedirects('/contact'); + } + + public function testContactFormAllEmptyRedirectsWithError(): void + { + $client = static::createClient(); + $client->request('POST', '/contact', [ + 'name' => '', + 'surname' => '', + 'email' => '', + 'message' => '', + ]); + + self::assertResponseRedirects('/contact'); + } + + public function testContactFormWhitespaceOnlyRedirectsWithError(): void + { + $client = static::createClient(); + $client->request('POST', '/contact', [ + 'name' => ' ', + 'surname' => 'Jean', + 'email' => 'jean@exemple.fr', + 'message' => 'Bonjour', + ]); + + self::assertResponseRedirects('/contact'); + } +}