feat(ReserverController): Ajoute route de confirmation de réservation.
 feat(FeedController): Crée un contrôleur pour les flux RSS.
 feat(templates): Ajoute un template pour les flux RSS.
 feat(templates): Ajoute des liens RSS dans la base du template.
```
This commit is contained in:
Serreau Jovann
2026-01-31 15:36:53 +01:00
parent db6c5d5fa6
commit cb13f988cd
4 changed files with 106 additions and 1 deletions

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Controller;
use App\Entity\Formules;
use App\Entity\Product;
use App\Repository\FormulesRepository;
use App\Repository\ProductRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class FeedController extends AbstractController
{
#[Route('/rss/{channel}', name: 'app_rss_feed', defaults: ['channel' => 'all'])]
public function rss(
string $channel,
ProductRepository $productRepo,
FormulesRepository $formuleRepo
): Response {
$items = [];
if ($channel === 'all' || $channel === 'products') {
$items = array_merge($items, $productRepo->findBy([], ['updatedAt' => 'DESC'], 20));
}
if ($channel === 'all' || $channel === 'formules') {
$items = array_merge($items, $formuleRepo->findBy(['isPublish' => true], ['updatedAt' => 'DESC'], 20));
}
// Sort everything by date descending
usort($items, fn($a, $b) => $b->getUpdatedAt() <=> $a->getUpdatedAt());
return $this->render('feed/rss.xml.twig', [
'items' => $items,
'current_channel' => $channel
], new Response('', 200, ['Content-Type' => 'application/xml']));
}
}

View File

@@ -232,6 +232,21 @@ class ReserverController extends AbstractController
]);
}
#[Route('/flow/{sessionId}/confirmed', name: 'reservation_flow_confirmed', methods: ['GET', 'POST'])]
public function flowConfirmed(
string $sessionId,
AuthenticationUtils $authenticationUtils,
OrderSessionRepository $repository,
ProductRepository $productRepository,
UploaderHelper $uploaderHelper
): Response {
$session = $repository->findOneBy(['uuid' => $sessionId]);
if (!$session) {
return $this->render('revervation/session_lost.twig');
}
}
#[Route('/flow/{sessionId}', name: 'reservation_flow', methods: ['GET', 'POST'])]
public function flowLogin(
string $sessionId,
@@ -349,7 +364,7 @@ class ReserverController extends AbstractController
$em->flush();
return $this->redirectToRoute('reservation_flow', ['sessionId' => $sessionId]);
return $this->redirectToRoute('reservation_flow_confirmed', ['sessionId' => $sessionId]);
}
#[Route('/umami', name: 'reservation_umami', methods: ['POST'])]

View File

@@ -0,0 +1,45 @@
{# templates/feed/rss.xml.twig #}
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>
LudikEvent -
{% if current_channel == 'products' %}Nos Produits
{% elseif current_channel == 'formules' %}Nos Formules
{% else %}Tout le catalogue{% endif %}
</title>
<description>Découvrez les nouveautés de réservation LudikEvent.</description>
<link>{{ url('app_crm_reservation') }}</link>
<language>fr-fr</language>
<lastBuildDate>{{ "now"|date('r') }}</lastBuildDate>
<atom:link href="{{ url('app_rss_feed', {channel: current_channel}) }}" rel="self" type="application/rss+xml" />
{% for item in items %}
<item>
{# Détection du type d'objet pour adapter le lien #}
{# Si l'objet a un champ 'slug' et n'est pas une 'Formule', c'est un Produit #}
<title>{{ item.name|e('html') }}</title>
{% if item.isPublish is not defined %}
<link>{{ url('reservation_product_show', {id: item.slug}) }}</link>
<guid isPermaLink="true">{{ url('reservation_product_show', {id: item.slug}) }}</guid>
<category>Produit</category>
{% else %}
<link>{{ url('reservation_formule_show', {slug: item.slug}) }}</link>
<guid isPermaLink="true">{{ url('reservation_formule_show', {slug: item.slug}) }}</guid>
<category>Formule</category>
{% endif %}
<description><![CDATA[{{ item.description|raw }}]]></description>
<pubDate>{{ item.updatedAt|date('r') }}</pubDate>
{% set image_url = item.imageName
? absolute_url(vich_uploader_asset(item, 'imageFile')|imagine_filter('webp'))
: absolute_url(asset('provider/images/favicon.webp'))
%}
<enclosure url="{{ image_url }}" length="50000" type="image/webp" />
</item>
{% endfor %}
</channel>
</rss>

View File

@@ -39,6 +39,10 @@
{{ vite_asset('reserve.js',{}) }}
{% block stylesheets %}{% endblock %}
<link rel="alternate" type="application/rss+xml" title="LudikEvent - Tout" href="{{ url('app_rss_feed', {channel: 'all'}) }}">
<link rel="alternate" type="application/rss+xml" title="LudikEvent - Produits" href="{{ url('app_rss_feed', {channel: 'products'}) }}">
<link rel="alternate" type="application/rss+xml" title="LudikEvent - Formules" href="{{ url('app_rss_feed', {channel: 'formules'}) }}">
</head>
<body class="bg-gray-50 text-gray-900 font-sans antialiased min-h-screen flex flex-col">