2026-01-19 21:08:04 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Controller;
|
|
|
|
|
|
|
|
|
|
use App\Entity\Account;
|
|
|
|
|
use App\Entity\AccountResetPasswordRequest;
|
2026-01-23 09:25:11 +01:00
|
|
|
use App\Entity\Customer;
|
2026-01-27 20:24:02 +01:00
|
|
|
use App\Entity\CustomerTracking;
|
2026-01-20 14:31:12 +01:00
|
|
|
use App\Entity\Product;
|
2026-01-30 17:58:12 +01:00
|
|
|
use App\Entity\ProductReserve;
|
2026-01-27 23:36:11 +01:00
|
|
|
use App\Entity\SitePerformance;
|
2026-01-19 21:08:04 +01:00
|
|
|
use App\Form\RequestPasswordConfirmType;
|
|
|
|
|
use App\Form\RequestPasswordRequestType;
|
|
|
|
|
use App\Logger\AppLogger;
|
2026-01-23 09:20:53 +01:00
|
|
|
use App\Repository\CustomerRepository;
|
2026-01-27 20:24:02 +01:00
|
|
|
use App\Repository\CustomerTrackingRepository;
|
2026-01-28 10:00:58 +01:00
|
|
|
use App\Repository\FormulesRepository;
|
2026-01-20 13:22:01 +01:00
|
|
|
use App\Repository\ProductRepository;
|
2026-01-30 17:58:12 +01:00
|
|
|
use App\Repository\ProductReserveRepository;
|
2026-01-20 13:22:01 +01:00
|
|
|
use App\Service\Mailer\Mailer;
|
2026-01-19 21:08:04 +01:00
|
|
|
use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent;
|
|
|
|
|
use App\Service\ResetPassword\Event\ResetPasswordEvent;
|
2026-01-23 08:43:47 +01:00
|
|
|
use App\Service\Search\Client;
|
2026-01-19 21:08:04 +01:00
|
|
|
use Doctrine\ORM\EntityManagerInterface;
|
2026-01-20 11:20:28 +01:00
|
|
|
use Fkrzski\RobotsTxt\RobotsTxt;
|
2026-01-19 21:08:04 +01:00
|
|
|
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
|
|
|
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
2026-01-20 13:22:01 +01:00
|
|
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
|
|
|
|
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
|
|
|
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
2026-01-19 21:08:04 +01:00
|
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
|
|
|
use Symfony\Component\HttpFoundation\Response;
|
2026-01-20 13:22:01 +01:00
|
|
|
use Symfony\Component\Mailer\MailerInterface;
|
2026-01-19 21:08:04 +01:00
|
|
|
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
|
|
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
|
|
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
|
|
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
2026-01-23 08:43:47 +01:00
|
|
|
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
|
|
|
|
|
use Vich\UploaderBundle\Templating\Helper\UploaderHelperInterface;
|
2026-01-19 21:08:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class ReserverController extends AbstractController
|
|
|
|
|
{
|
|
|
|
|
|
2026-01-20 11:20:28 +01:00
|
|
|
#[Route('/robots.txt', name: 'robots_txt', defaults: ['_format' => 'txt'])]
|
|
|
|
|
public function index(Request $request): Response
|
|
|
|
|
{
|
|
|
|
|
$robots = new RobotsTxt();
|
|
|
|
|
$robots->disallow('/signature');
|
|
|
|
|
$robots->disallow('/payment');
|
|
|
|
|
$robots->crawlDelay(60);
|
|
|
|
|
$robots->allow('/reservation');
|
2026-01-20 14:31:12 +01:00
|
|
|
$robots->sitemap($request->getSchemeAndHttpHost().'/seo/sitemap.xml');
|
2026-01-20 11:20:28 +01:00
|
|
|
|
|
|
|
|
return new Response($robots->toString(),Response::HTTP_OK,[
|
|
|
|
|
'Content-Type' => 'text/plain'
|
|
|
|
|
]);
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/', name: 'reservation')]
|
2026-01-28 10:00:58 +01:00
|
|
|
public function revervation(FormulesRepository $formulesRepository,ProductRepository $productRepository): Response
|
2026-01-19 21:08:04 +01:00
|
|
|
{
|
2026-01-30 12:48:11 +01:00
|
|
|
$products =$productRepository->findBy(['category'=>'3-15 ans'], ['updatedAt' => 'DESC'],3);
|
|
|
|
|
$formules =$formulesRepository->findBy(['isPublish'=>true], ['pos' => 'ASC'],3);
|
2026-01-20 13:22:01 +01:00
|
|
|
return $this->render('revervation/home.twig',[
|
2026-01-28 10:00:58 +01:00
|
|
|
'products' => $products,
|
|
|
|
|
'formules' => $formules,
|
2026-01-20 13:22:01 +01:00
|
|
|
]);
|
2026-01-20 13:51:23 +01:00
|
|
|
}
|
2026-01-30 17:58:12 +01:00
|
|
|
|
|
|
|
|
#[Route('/produit/check', name: 'produit_check', methods: ['GET', 'POST'])]
|
|
|
|
|
public function productCheck(Request $request, ProductReserveRepository $productReserveRepository, ProductRepository $productRepository): Response
|
|
|
|
|
{
|
|
|
|
|
$productId = $request->get('id');
|
|
|
|
|
$startStr = $request->get('start');
|
|
|
|
|
$endStr = $request->get('end');
|
|
|
|
|
|
|
|
|
|
if (!$productId && $request->isMethod('POST')) {
|
|
|
|
|
$payload = $request->getPayload();
|
|
|
|
|
$productId = $payload->get('id');
|
|
|
|
|
$startStr = $payload->get('start');
|
|
|
|
|
$endStr = $payload->get('end');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$productId || !$startStr || !$endStr) {
|
|
|
|
|
return new JsonResponse(['error' => 'Missing parameters'], Response::HTTP_BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$product = $productRepository->find($productId);
|
|
|
|
|
if (!$product) {
|
|
|
|
|
return new JsonResponse(['error' => 'Product not found'], Response::HTTP_NOT_FOUND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$start = new \DateTimeImmutable($startStr);
|
|
|
|
|
$end = new \DateTimeImmutable($endStr);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return new JsonResponse(['error' => 'Invalid date format'], Response::HTTP_BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$reserve = new ProductReserve();
|
|
|
|
|
$reserve->setProduct($product);
|
|
|
|
|
$reserve->setStartAt($start);
|
|
|
|
|
$reserve->setEndAt($end);
|
|
|
|
|
|
|
|
|
|
$isAvailable = $productReserveRepository->checkAvailability($reserve);
|
|
|
|
|
|
|
|
|
|
return new JsonResponse(['dispo' => $isAvailable]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/web-vitals', name: 'reservation_web-vitals', methods: ['POST'])]
|
2026-01-27 23:36:11 +01:00
|
|
|
public function webVitals(Request $request, EntityManagerInterface $em): Response
|
|
|
|
|
{
|
|
|
|
|
$data = json_decode($request->getContent(), true);
|
|
|
|
|
|
|
|
|
|
if (!$data || !isset($data['name'], $data['value'])) {
|
|
|
|
|
return new Response('Invalid data', Response::HTTP_BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// On vérifie si cet ID de métrique existe déjà pour éviter les doublons
|
|
|
|
|
// (web-vitals peut renvoyer plusieurs fois la même métrique si elle s'affine)
|
|
|
|
|
$existing = $em->getRepository(SitePerformance::class)->findOneBy(['metricId' => $data['id']]);
|
|
|
|
|
|
|
|
|
|
$perf = $existing ?? new SitePerformance();
|
|
|
|
|
|
|
|
|
|
$perf->setName($data['name']);
|
|
|
|
|
$perf->setValue((float)$data['value']);
|
|
|
|
|
$perf->setPath($data['path'] ?? '/');
|
|
|
|
|
$perf->setMetricId($data['id'] ?? null);
|
2026-01-28 09:20:51 +01:00
|
|
|
$perf->setCreatedAt(new \DateTimeImmutable());
|
2026-01-27 23:36:11 +01:00
|
|
|
|
|
|
|
|
if (!$existing) {
|
|
|
|
|
$em->persist($perf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$em->flush();
|
|
|
|
|
|
|
|
|
|
return new Response('', Response::HTTP_NO_CONTENT);
|
|
|
|
|
}
|
2026-01-27 20:24:02 +01:00
|
|
|
|
2026-01-30 18:10:01 +01:00
|
|
|
#[Route('/basket/json', name: 'reservation_basket_json', methods: ['POST'])]
|
|
|
|
|
public function basketJson(Request $request, ProductRepository $productRepository, UploaderHelper $uploaderHelper): Response
|
|
|
|
|
{
|
|
|
|
|
$data = json_decode($request->getContent(), true);
|
|
|
|
|
$ids = $data['ids'] ?? [];
|
|
|
|
|
|
|
|
|
|
// Protection contre les données invalides
|
|
|
|
|
if (!is_array($ids)) {
|
|
|
|
|
$ids = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Récupération des produits
|
|
|
|
|
$products = [];
|
|
|
|
|
if (!empty($ids)) {
|
|
|
|
|
$products = $productRepository->findBy(['id' => $ids]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$items = [];
|
|
|
|
|
$totalHT = 0;
|
|
|
|
|
$tvaEnabled = isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true";
|
|
|
|
|
$tvaRate = $tvaEnabled ? 0.20 : 0;
|
|
|
|
|
|
|
|
|
|
foreach ($products as $product) {
|
|
|
|
|
$priceHT = $product->getPriceDay();
|
|
|
|
|
|
|
|
|
|
$items[] = [
|
|
|
|
|
'id' => $product->getId(),
|
|
|
|
|
'name' => $product->getName(),
|
|
|
|
|
'image' => $uploaderHelper->asset($product, 'imageFile'),
|
|
|
|
|
'priceHt1Day' => $priceHT,
|
|
|
|
|
'priceHTSupDay' => $product->getPriceSup(),
|
|
|
|
|
'priceTTC1Day' => $priceHT * (1 + $tvaRate),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$totalHT += $priceHT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$totalTva = $totalHT * $tvaRate;
|
|
|
|
|
$totalTTC = $totalHT + $totalTva;
|
|
|
|
|
|
|
|
|
|
// Récupération des dates depuis la session si disponibles (exemple)
|
|
|
|
|
$session = $request->getSession();
|
|
|
|
|
$startDate = $session->get('reservation_start');
|
|
|
|
|
$endDate = $session->get('reservation_end');
|
|
|
|
|
|
|
|
|
|
return new JsonResponse([
|
|
|
|
|
'start_date' => $startDate, // Format attendu : "DD/MM/YYYY" ou similaire par le JS ? Le JS affiche tel quel.
|
|
|
|
|
'end_date' => $endDate,
|
|
|
|
|
'products' => $items,
|
|
|
|
|
'total' => [
|
|
|
|
|
'totalHT' => $totalHT,
|
|
|
|
|
'totalTva' => $totalTva,
|
|
|
|
|
'totalTTC' => $totalTTC
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/umami', name: 'reservation_umami', methods: ['POST'])]
|
2026-01-27 20:24:02 +01:00
|
|
|
public function umami(
|
|
|
|
|
Request $request,
|
|
|
|
|
CustomerTrackingRepository $customerTrackingRepository,
|
|
|
|
|
EntityManagerInterface $em
|
|
|
|
|
): Response {
|
|
|
|
|
/** @var Customer $user */
|
|
|
|
|
$user = $this->getUser();
|
|
|
|
|
if (!$user) {
|
|
|
|
|
return new JsonResponse(['error' => 'User not found'], Response::HTTP_UNAUTHORIZED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = json_decode($request->getContent(), true);
|
|
|
|
|
$umamiSessionId = $data['umami_session'] ?? null;
|
|
|
|
|
|
|
|
|
|
if (!$umamiSessionId) {
|
|
|
|
|
return new JsonResponse(['error' => 'No session provided'], Response::HTTP_BAD_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// On cherche si un tracking existe déjà pour cet ID Umami
|
|
|
|
|
$track = $customerTrackingRepository->findOneBy(['trackId' => $umamiSessionId]);
|
|
|
|
|
|
|
|
|
|
if (!$track) {
|
|
|
|
|
$track = new CustomerTracking();
|
|
|
|
|
$track->setTrackId($umamiSessionId);
|
|
|
|
|
$track->setCreateAT(new \DateTime()); // Utilise Immutable si possible
|
|
|
|
|
$track->setCustomer($user);
|
|
|
|
|
|
|
|
|
|
$em->persist($track);
|
|
|
|
|
} else {
|
|
|
|
|
// Si le track existe déjà mais n'était pas lié à l'utilisateur
|
|
|
|
|
if ($track->getCustomer() !== $user) {
|
|
|
|
|
$track->setCustomer($user);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$em->flush();
|
|
|
|
|
|
|
|
|
|
return new JsonResponse(['status' => 'success']);
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/catalogue', name: 'reservation_catalogue')]
|
2026-01-20 13:51:23 +01:00
|
|
|
public function revervationCatalogue(ProductRepository $productRepository): Response
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/catalogue.twig',[
|
|
|
|
|
'products' => $productRepository->findAll(),
|
2026-01-30 09:13:01 +01:00
|
|
|
'tvaEnabled' => isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true",
|
|
|
|
|
|
2026-01-20 13:51:23 +01:00
|
|
|
]);
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/formules', name: 'reservation_formules')]
|
2026-01-28 11:55:38 +01:00
|
|
|
public function revervationFormules(FormulesRepository $formulesRepository): Response
|
2026-01-27 22:43:36 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/formules.twig',[
|
2026-01-30 10:35:02 +01:00
|
|
|
'formules' => $formulesRepository->findBy(['isPublish'=>true],['pos' => 'ASC']),
|
2026-01-30 09:13:01 +01:00
|
|
|
'tvaEnabled' => isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true",
|
|
|
|
|
|
2026-01-27 22:43:36 +01:00
|
|
|
]);
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/formules/{slug}', name: 'reservation_formule_show')]
|
2026-01-28 11:55:38 +01:00
|
|
|
public function revervationView(string $slug,FormulesRepository $formulesRepository): Response
|
2026-01-28 10:00:58 +01:00
|
|
|
{
|
2026-01-28 11:55:38 +01:00
|
|
|
$parts = explode('-', $slug);
|
|
|
|
|
$realId = $parts[0]; // Récupère le tout premier élément (l'index 0)
|
2026-01-28 10:00:58 +01:00
|
|
|
|
2026-01-28 11:55:38 +01:00
|
|
|
// 2. Récupération du produit par son ID numérique
|
|
|
|
|
$formule = $formulesRepository->find($realId);
|
|
|
|
|
|
|
|
|
|
if (!$formule) {
|
|
|
|
|
throw $this->createNotFoundException('Formules introuvable');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/formule/show.twig',[
|
2026-01-30 09:13:01 +01:00
|
|
|
'formule' => $formule,
|
|
|
|
|
'tvaEnabled' => isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true",
|
|
|
|
|
|
2026-01-28 10:00:58 +01:00
|
|
|
]);
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/comment-reserver', name: 'reservation_workflow')]
|
2026-01-21 13:54:50 +01:00
|
|
|
public function revervationWorkfkow(): Response
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/workflow.twig',[
|
|
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
}
|
2026-01-22 09:27:22 +01:00
|
|
|
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/options/{id}', name: 'reservation_options_show')]
|
2026-01-22 09:27:22 +01:00
|
|
|
public function revervationShowOpitons(string $id, ProductRepository $productRepository): Response
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/produit/{id}', name: 'reservation_product_show')]
|
2026-01-20 14:31:12 +01:00
|
|
|
public function revervationShowProduct(string $id, ProductRepository $productRepository): Response
|
2026-01-20 13:51:23 +01:00
|
|
|
{
|
2026-01-20 14:31:12 +01:00
|
|
|
// 1. Extraction de l'ID (ex: "15-chateau-fort" -> 15)
|
|
|
|
|
$parts = explode('-', $id);
|
|
|
|
|
$realId = $parts[0]; // Récupère le tout premier élément (l'index 0)
|
2026-01-20 13:51:23 +01:00
|
|
|
|
2026-01-20 14:31:12 +01:00
|
|
|
// 2. Récupération du produit par son ID numérique
|
|
|
|
|
$product = $productRepository->find($realId);
|
2026-01-20 13:51:23 +01:00
|
|
|
|
2026-01-20 14:31:12 +01:00
|
|
|
if (!$product) {
|
|
|
|
|
throw $this->createNotFoundException('Produit introuvable');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3. Logique des suggestions (inchangée)
|
|
|
|
|
$allInCat = $productRepository->findBy(['category' => $product->getCategory()], [], 5);
|
|
|
|
|
|
|
|
|
|
$otherProducts = array_filter($allInCat, function($p) use ($product) {
|
|
|
|
|
return $p->getId() !== $product->getId();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/produit.twig', [
|
|
|
|
|
'product' => $product,
|
2026-01-30 09:13:01 +01:00
|
|
|
'tvaEnabled' => isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true",
|
2026-01-20 14:31:12 +01:00
|
|
|
'otherProducts' => array_slice($otherProducts, 0, 4)
|
|
|
|
|
]);
|
2026-01-19 21:08:04 +01:00
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/connexion', name: 'reservation_login')]
|
2026-01-23 08:43:47 +01:00
|
|
|
public function revervationLogin(AuthenticationUtils $authenticationUtils): Response
|
2026-01-22 21:16:29 +01:00
|
|
|
{
|
2026-01-22 23:25:35 +01:00
|
|
|
return $this->render('revervation/login.twig',[
|
2026-01-23 08:43:47 +01:00
|
|
|
'last_username' => $authenticationUtils->getLastUsername(),
|
|
|
|
|
'error' => $authenticationUtils->getLastAuthenticationError()
|
|
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/logout', name: 'reservation_logout')]
|
2026-01-23 09:15:15 +01:00
|
|
|
public function revervationLogout(): Response
|
|
|
|
|
{
|
|
|
|
|
return $this->redirectToRoute('reservation');
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/creation-compte', name: 'reservation_register')]
|
2026-01-23 09:25:11 +01:00
|
|
|
public function revervationRegister(
|
|
|
|
|
Request $request,
|
|
|
|
|
Mailer $mailer,
|
|
|
|
|
EntityManagerInterface $em,
|
|
|
|
|
UserPasswordHasherInterface $hasher
|
|
|
|
|
): Response {
|
2026-01-29 10:06:39 +01:00
|
|
|
|
2026-01-23 09:25:11 +01:00
|
|
|
if ($request->isMethod('POST')) {
|
|
|
|
|
$payload = $request->getPayload();
|
2026-01-23 08:43:47 +01:00
|
|
|
|
2026-01-23 09:25:11 +01:00
|
|
|
$customer = new Customer();
|
|
|
|
|
$customer->setEmail($payload->getString('email'));
|
|
|
|
|
$customer->setName($payload->getString('name'));
|
|
|
|
|
$customer->setSurname($payload->getString('surname'));
|
|
|
|
|
$customer->setPhone($payload->getString('phone'));
|
|
|
|
|
$customer->setCiv($payload->getString('civ'));
|
|
|
|
|
$customer->setType($payload->getString('type')); // 'particular' ou 'buisness'
|
|
|
|
|
|
|
|
|
|
if ($customer->getType() === 'buisness') {
|
|
|
|
|
$customer->setSiret($payload->getString('siret'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hachage du mot de passe
|
|
|
|
|
$hashedPassword = $hasher->hashPassword($customer, $payload->getString('password'));
|
|
|
|
|
$customer->setPassword($hashedPassword);
|
|
|
|
|
$customer->setRoles(['ROLE_USER']);
|
|
|
|
|
$mailer->send($customer->getEmail(),
|
|
|
|
|
$customer->getName()." ".$customer->getSurname(),
|
|
|
|
|
"[Ludikevent] - Code de récupération",
|
|
|
|
|
"mails/welcome.twig",[
|
|
|
|
|
'account' => $customer,
|
|
|
|
|
]);
|
|
|
|
|
$em->persist($customer);
|
|
|
|
|
$em->flush();
|
|
|
|
|
|
|
|
|
|
$this->addFlash('success', 'Votre compte a été créé avec succès ! Connectez-vous.');
|
|
|
|
|
return $this->redirectToRoute('reservation_login');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/register.twig');
|
2026-01-23 08:43:47 +01:00
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/mot-de-passe', name: 'reservation_password')]
|
2026-01-23 09:20:53 +01:00
|
|
|
public function forgotPassword(
|
|
|
|
|
Request $request,
|
|
|
|
|
CustomerRepository $repository,
|
|
|
|
|
EntityManagerInterface $em,
|
|
|
|
|
Mailer $mailer,
|
|
|
|
|
UserPasswordHasherInterface $hasher
|
|
|
|
|
): Response {
|
|
|
|
|
$session = $request->getSession();
|
|
|
|
|
$step = $request->query->get('step', 'request');
|
|
|
|
|
|
|
|
|
|
if ($request->isMethod('POST')) {
|
|
|
|
|
$payload = $request->getPayload();
|
|
|
|
|
|
|
|
|
|
// ÉTAPE 1 : Générer le code et l'envoyer
|
|
|
|
|
if ($payload->has('email_request')) {
|
|
|
|
|
$email = $payload->getString('email_request');
|
|
|
|
|
$customer = $repository->findOneBy(['email' => $email]);
|
|
|
|
|
|
|
|
|
|
if ($customer) {
|
|
|
|
|
$code = str_pad((string)random_int(0, 999999), 6, '0', STR_PAD_LEFT);
|
|
|
|
|
|
|
|
|
|
// On stocke en session : email + code
|
|
|
|
|
$session->set('reset_password', [
|
|
|
|
|
'email' => $email,
|
|
|
|
|
'code' => $code,
|
|
|
|
|
'expires' => time() + 900 // Valable 15 minutes
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$mailer->send($customer->getEmail(),
|
|
|
|
|
$customer->getName()." ".$customer->getSurname(),
|
|
|
|
|
"[Ludikevent] - Code de récupération",
|
|
|
|
|
"mails/code_password.twig",[
|
|
|
|
|
'code' => $code
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return $this->redirectToRoute('reservation_password', ['step' => 'verify']);
|
|
|
|
|
}
|
|
|
|
|
$this->addFlash('danger', 'Email inconnu.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ÉTAPE 2 : Vérifier le code en session
|
|
|
|
|
if ($payload->has('code_verify')) {
|
|
|
|
|
$data = $session->get('reset_password');
|
|
|
|
|
$inputCode = $payload->getString('code_verify');
|
|
|
|
|
|
|
|
|
|
if ($data && $data['code'] === $inputCode && time() < $data['expires']) {
|
|
|
|
|
return $this->redirectToRoute('reservation_password', ['step' => 'reset']);
|
|
|
|
|
}
|
|
|
|
|
$this->addFlash('danger', 'Code invalide ou expiré.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ÉTAPE 3 : Changer le mot de passe
|
|
|
|
|
if ($payload->has('new_password')) {
|
|
|
|
|
$data = $session->get('reset_password');
|
|
|
|
|
|
|
|
|
|
if ($data) {
|
|
|
|
|
$customer = $repository->findOneBy(['email' => $data['email']]);
|
|
|
|
|
if ($customer) {
|
|
|
|
|
$newEncoded = $hasher->hashPassword($customer, $payload->getString('new_password'));
|
|
|
|
|
$customer->setPassword($newEncoded);
|
|
|
|
|
$em->flush();
|
|
|
|
|
|
|
|
|
|
$session->remove('reset_password'); // On nettoie la session
|
|
|
|
|
$this->addFlash('success', 'Mot de passe mis à jour !');
|
|
|
|
|
return $this->redirectToRoute('reservation_login');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-22 23:25:35 +01:00
|
|
|
|
2026-01-23 09:20:53 +01:00
|
|
|
return $this->render('reservation/password.twig', [
|
|
|
|
|
'step' => $step,
|
|
|
|
|
'email' => $session->get('reset_password')['email'] ?? null
|
2026-01-22 23:25:35 +01:00
|
|
|
]);
|
2026-01-22 21:16:29 +01:00
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/contact', name: 'reservation_contact')]
|
2026-01-20 13:22:01 +01:00
|
|
|
public function revervationContact(Request $request, Mailer $mailer): Response
|
2026-01-19 21:08:04 +01:00
|
|
|
{
|
2026-01-20 13:22:01 +01:00
|
|
|
$form = $this->createFormBuilder()
|
|
|
|
|
->add('name', TextType::class, [
|
|
|
|
|
'label' => 'Nom',
|
|
|
|
|
'required' => true,
|
|
|
|
|
])
|
|
|
|
|
->add('surname', TextType::class, [
|
|
|
|
|
'label' => 'Prenom',
|
|
|
|
|
'required' => true,
|
|
|
|
|
])
|
|
|
|
|
->add('email', EmailType::class, [
|
|
|
|
|
'label' => 'Email',
|
|
|
|
|
'required' => true,
|
|
|
|
|
])
|
|
|
|
|
->add('phone', TextType::class, [
|
|
|
|
|
'label' => 'Telephone',
|
|
|
|
|
'required' => true,
|
|
|
|
|
])
|
|
|
|
|
->add('message', TextareaType::class, [
|
|
|
|
|
'label' => 'Message',
|
|
|
|
|
'required' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$formObject = $form->getForm();
|
|
|
|
|
$formObject->handleRequest($request);
|
|
|
|
|
|
|
|
|
|
if ($formObject->isSubmitted() && $formObject->isValid()) {
|
|
|
|
|
$data = $formObject->getData();
|
|
|
|
|
|
|
|
|
|
$mailer->send(
|
|
|
|
|
'lilian@ludikevent.fr',
|
|
|
|
|
"Ludikevent",
|
|
|
|
|
"[Ludikevent] - Demande de contact via la plateforme de reservation",
|
|
|
|
|
"mails/reserve/contact.twig",
|
|
|
|
|
$data
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Ajout du message flash de succès
|
|
|
|
|
$this->addFlash('success', 'Votre message a bien été envoyé ! Notre équipe vous répondra dans les plus brefs délais.');
|
|
|
|
|
|
|
|
|
|
return $this->redirectToRoute('reservation_contact');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->render('revervation/contact.twig', [
|
|
|
|
|
'form' => $formObject->createView()
|
|
|
|
|
]);
|
2026-01-19 21:08:04 +01:00
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/recherche', name: 'reservation_search')]
|
2026-01-23 08:43:47 +01:00
|
|
|
public function recherche(UploaderHelper $uploaderHelper,Client $client,Request $request,ProductRepository $productRepository): Response
|
2026-01-19 21:08:04 +01:00
|
|
|
{
|
2026-01-23 08:43:47 +01:00
|
|
|
$results = $client->search('product',$request->query->get('q',''));
|
|
|
|
|
$items = [];
|
|
|
|
|
foreach ($results['hits'] as $result) {
|
|
|
|
|
$p = $productRepository->find($result['id']);
|
|
|
|
|
if($p instanceof Product) {
|
|
|
|
|
$items[] = [
|
|
|
|
|
'image' => $uploaderHelper->asset($p, 'imageFile') ?: "/provider/images/favicon.png",
|
|
|
|
|
"name" => $p->getName(),
|
|
|
|
|
"price" => $p->getPriceDay(),
|
|
|
|
|
"price1day" => $p->getPriceDay(),
|
|
|
|
|
"caution" => $p->getCaution(),
|
|
|
|
|
"priceSup" => $p->getPriceSup(),
|
|
|
|
|
'link' => $this->generateUrl('reservation_product_show',['id'=>$p->slug()]),
|
|
|
|
|
];
|
2026-01-23 11:57:51 +01:00
|
|
|
|
2026-01-23 08:43:47 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $this->render('revervation/search.twig',[
|
|
|
|
|
'products' => $items
|
|
|
|
|
]);
|
2026-01-19 21:08:04 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/mentions-legales', name: 'reservation_mentions-legal')]
|
2026-01-19 21:08:04 +01:00
|
|
|
public function revervationLegal()
|
|
|
|
|
{
|
|
|
|
|
return $this->render('revervation/legal.twig');
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/rgpd', name: 'reservation_rgpd')]
|
2026-01-19 21:08:04 +01:00
|
|
|
public function revervationRgpd()
|
|
|
|
|
{
|
|
|
|
|
return $this->render('revervation/rgpd.twig');
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/cookies', name: 'reservation_cookies')]
|
2026-01-19 21:08:04 +01:00
|
|
|
public function revervationCookies()
|
|
|
|
|
{
|
|
|
|
|
return $this->render('revervation/cookies.twig');
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/cgv', name: 'reservation_cgv')]
|
2026-01-19 21:08:04 +01:00
|
|
|
public function revervationCgv()
|
|
|
|
|
{
|
|
|
|
|
return $this->render('revervation/cgv.twig');
|
|
|
|
|
}
|
2026-01-28 13:41:31 +01:00
|
|
|
#[Route('/hosting', name: 'reservation_hosting')]
|
2026-01-19 21:08:04 +01:00
|
|
|
public function revervationHosting()
|
|
|
|
|
{
|
|
|
|
|
return $this->render('revervation/hosting.twig');
|
|
|
|
|
}
|
|
|
|
|
}
|