<?php
namespace App\Controller;
use App\Entity\Notification;
use App\Service\NotificationService;
use Doctrine\ORM\EntityManagerInterface;
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\Annotation\Route;
class NotificationController extends AbstractController
{
#[Route('/api/notifications/count', name: 'api_notifications_count', methods: ['GET'])]
public function count(NotificationService $notificationService): JsonResponse
{
if (!$this->getUser()) {
return $this->json(['count' => 0]);
}
$count = $notificationService->getUnreadCount($this->getUser());
return $this->json(['count' => $count]);
}
#[Route('/notifications', name: 'notifications_list')]
public function list(NotificationService $notificationService, EntityManagerInterface $entityManager, Request $request): Response
{
if (!$this->getUser()) {
return $this->redirectToRoute('ui_app_login');
}
$showArchived = $request->query->getBoolean('archived', false);
$type = $request->query->get('type', '');
$notifications = $notificationService->getUserNotifications($this->getUser(), 12, false, $showArchived, false, $type !== '' ? $type : null, 0);
$unreadCount = $notificationService->getUnreadCount($this->getUser());
// Récupérer tous les types de notifications pour le sélecteur
$allTypes = $entityManager->getRepository(Notification::class)
->createQueryBuilder('n')
->select('DISTINCT n.type')
->where('n.user = :user')
->andWhere('n.isArchived = :archived')
->andWhere('n.isDeleted = :deleted')
->setParameter('user', $this->getUser())
->setParameter('archived', $showArchived)
->setParameter('deleted', false)
->getQuery()
->getResult();
$types = array_filter(array_column($allTypes, 'type'));
// Vérifier s'il y a des notifications sans type pour afficher l'option "non spécifié"
$hasNonSpecified = $entityManager->getRepository(Notification::class)
->createQueryBuilder('n')
->select('COUNT(n.id)')
->where('n.user = :user')
->andWhere('(n.type IS NULL OR n.type = :emptyType)')
->andWhere('n.isArchived = :archived')
->andWhere('n.isDeleted = :deleted')
->setParameter('user', $this->getUser())
->setParameter('emptyType', '')
->setParameter('archived', $showArchived)
->setParameter('deleted', false)
->getQuery()
->getSingleScalarResult() > 0;
return $this->render('account/notifications.html.twig', [
'notifications' => $notifications,
'unreadCount' => $unreadCount,
'showArchived' => $showArchived,
'selectedType' => $type,
'availableTypes' => $types,
'hasNonSpecified' => $hasNonSpecified,
]);
}
#[Route('/api/notifications', name: 'api_notifications_list', methods: ['GET'])]
public function getNotifications(NotificationService $notificationService, Request $request): JsonResponse
{
if (!$this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 401);
}
$limit = (int) $request->query->get('limit', 12);
$offset = (int) $request->query->get('offset', 0);
$unreadOnly = $request->query->getBoolean('unread_only', false);
$showArchived = $request->query->getBoolean('archived', false);
$type = $request->query->get('type', '');
$notifications = $notificationService->getUserNotifications(
$this->getUser(),
$limit,
$unreadOnly,
$showArchived,
false,
$type !== '' ? $type : null,
$offset
);
$data = [];
foreach ($notifications as $notification) {
$data[] = [
'id' => $notification->getId(),
'title' => $notification->getTitle(),
'message' => $notification->getMessage(),
'type' => $notification->getType(),
'isRead' => $notification->isIsRead(),
'priority' => $notification->getPriority(),
'createdAt' => $notification->getCreatedAt()->format('Y-m-d H:i:s'),
'readAt' => $notification->getReadAt()?->format('Y-m-d H:i:s'),
'isArchived' => $notification->isIsArchived(),
'archivedAt' => $notification->getArchivedAt()?->format('Y-m-d H:i:s'),
];
}
return $this->json([
'notifications' => $data,
'hasMore' => count($notifications) === $limit,
'count' => count($data)
]);
}
#[Route('/api/notifications/{id}/read', name: 'api_notification_read', methods: ['POST'])]
public function markAsRead(int $id, NotificationService $notificationService, EntityManagerInterface $em): JsonResponse
{
if (!$this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 401);
}
$notification = $em->getRepository(Notification::class)->find($id);
if (!$notification || $notification->getUser() !== $this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 403);
}
$notificationService->markAsRead($notification);
return $this->json(['success' => true]);
}
#[Route('/api/notifications/read-all', name: 'api_notifications_read_all', methods: ['POST'])]
public function markAllAsRead(NotificationService $notificationService): JsonResponse
{
if (!$this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 401);
}
$notificationService->markAllAsRead($this->getUser());
return $this->json(['success' => true]);
}
#[Route('/api/notifications/{id}/archive', name: 'api_notification_archive', methods: ['POST'])]
public function archiveNotification(int $id, NotificationService $notificationService, EntityManagerInterface $em): JsonResponse
{
if (!$this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 401);
}
$notification = $em->getRepository(Notification::class)->find($id);
if (!$notification || $notification->getUser() !== $this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 403);
}
$notificationService->archiveNotification($notification);
return $this->json(['success' => true]);
}
#[Route('/api/notifications/{id}/delete', name: 'api_notification_delete', methods: ['POST'])]
public function deleteNotification(int $id, NotificationService $notificationService, EntityManagerInterface $em): JsonResponse
{
if (!$this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 401);
}
$notification = $em->getRepository(Notification::class)->find($id);
if (!$notification || $notification->getUser() !== $this->getUser()) {
return $this->json(['error' => 'Non autorisé'], 403);
}
$notificationService->deleteNotification($notification);
return $this->json(['success' => true]);
}
}