PlanController
extends AbstractController
in package
Administre le catalogue des offres d'abonnement (plans) de la plateforme.
Couvre le CRUD complet des plans, leur activation/désactivation, ainsi que leur ordre d'affichage
(sortOrder) réorganisable par glisser-déposer. Deux règles métier structurent ce contrôleur :
un seul plan peut porter le drapeau « populaire » à la fois (les autres sont démarqués
automatiquement), et un plan ne peut pas être supprimé tant qu'il reste des abonnements actifs
qui lui sont rattachés.
Préfixe de route : /admin/plans. Réservé à ROLE_ADMIN pour l'ensemble des actions.
Attributes
- #[IsGranted]
- 'ROLE_ADMIN'
- #[Route]
- '/admin/plans'
Table of Contents
Properties
- $entityManager : EntityManagerInterface
- $planRepository : PlanRepository
- $subscriptionRepository : SubscriptionRepository
Methods
- __construct() : mixed
- delete() : Response
- Supprime définitivement un plan d'abonnement.
- edit() : Response
- Modifie un plan d'abonnement existant.
- index() : Response
- Affiche la liste paginée des plans d'abonnement.
- new() : Response
- Crée un nouveau plan d'abonnement.
- reorder() : Response
- Réordonne les plans à partir d'une liste d'identifiants envoyée en JSON.
- show() : Response
- Affiche le détail d'un plan et son usage.
- toggleStatus() : Response
- Bascule l'état actif/inactif d'un plan.
- removePopularFlagFromOtherPlans() : void
- Retire le drapeau « populaire » de tous les plans, éventuellement sauf un.
Properties
$entityManager read-only
private
EntityManagerInterface
$entityManager
$planRepository read-only
private
PlanRepository
$planRepository
$subscriptionRepository read-only
private
SubscriptionRepository
$subscriptionRepository
Methods
__construct()
public
__construct(EntityManagerInterface $entityManager, PlanRepository $planRepository, SubscriptionRepository $subscriptionRepository) : mixed
Parameters
- $entityManager : EntityManagerInterface
-
Gestionnaire d'entités (persistance, suppression, requêtes de mise à jour en masse).
- $planRepository : PlanRepository
-
Dépôt des plans (listing trié, récupération unitaire pour la réorganisation).
- $subscriptionRepository : SubscriptionRepository
-
Dépôt des abonnements, utilisé pour compter les abonnements actifs par plan.
delete()
Supprime définitivement un plan d'abonnement.
public
delete(Request $request, Plan $plan) : Response
La suppression n'est tentée que si le jeton CSRF delete<id> est valide. Un garde-fou métier
bloque l'opération lorsque le plan compte au moins un abonnement actif : un message flash
d'erreur est alors affiché et le plan est conservé. Si le jeton CSRF est invalide, aucune
action ni aucun message n'est produit.
Route : /admin/plans/{id} (POST), nom admin_plan_delete.
Parameters
- $request : Request
-
Requête HTTP courante, contenant le jeton CSRF
_token. - $plan : Plan
-
Plan résolu automatiquement depuis l'identifiant de l'URL.
Attributes
- #[Route]
- '/{id}'
- $name: 'admin_plan_delete'
- $methods: ['POST']
Return values
Response —Redirection vers admin_plan_index dans tous les cas.
edit()
Modifie un plan d'abonnement existant.
public
edit(Request $request, Plan $plan) : Response
Si le plan est marqué comme populaire, PlanController::removePopularFlagFromOtherPlans()
est appelé en excluant l'identifiant du plan courant, afin que celui-ci reste le seul
populaire. La date updatedAt est rafraîchie avant le flush.
Route : /admin/plans/{id}/edit (GET, POST), nom admin_plan_edit.
Parameters
- $request : Request
-
Requête HTTP courante, utilisée pour traiter le formulaire.
- $plan : Plan
-
Plan résolu automatiquement depuis l'identifiant de l'URL.
Attributes
- #[Route]
- '/{id}/edit'
- $name: 'admin_plan_edit'
- $methods: ['GET', 'POST']
Return values
Response —Rendu du template admin/plan/edit.html.twig, ou redirection vers
admin_plan_index après modification réussie.
index()
Affiche la liste paginée des plans d'abonnement.
public
index(Request $request, PaginatorInterface $paginator) : Response
Les plans sont triés par sortOrder croissant, puis par date de création décroissante, et
paginés par blocs de 10 (paramètre de requête page, défaut 1).
Route : /admin/plans/ (GET), nom admin_plan_index.
Parameters
- $request : Request
-
Requête HTTP courante (paramètre
page). - $paginator : PaginatorInterface
-
Service de pagination KnpPaginator.
Attributes
- #[Route]
- '/'
- $name: 'admin_plan_index'
- $methods: ['GET']
Return values
Response —Rendu du template admin/plan/index.html.twig avec les plans paginés.
new()
Crée un nouveau plan d'abonnement.
public
new(Request $request) : Response
Si le plan soumis est marqué comme populaire, PlanController::removePopularFlagFromOtherPlans() est appelé sans exclusion afin de retirer ce drapeau de tous les autres plans (l'ordre des opérations fait que la mise à jour en masse précède la persistance du nouveau plan, qui conserve donc bien son drapeau).
Route : /admin/plans/new (GET, POST), nom admin_plan_new.
Parameters
- $request : Request
-
Requête HTTP courante, utilisée pour traiter le formulaire.
Attributes
- #[Route]
- '/new'
- $name: 'admin_plan_new'
- $methods: ['GET', 'POST']
Return values
Response —Rendu du template admin/plan/new.html.twig, ou redirection vers
admin_plan_index après création réussie.
reorder()
Réordonne les plans à partir d'une liste d'identifiants envoyée en JSON.
public
reorder(Request $request) : Response
Le corps de la requête doit contenir une clé order sous forme de tableau d'identifiants de
plans dans l'ordre souhaité ; à défaut, une réponse JSON {success: false} est renvoyée avec
le message « Données invalides » (statut HTTP 200). Pour chaque identifiant trouvé, sortOrder
reçoit la position dans le tableau + 1 et updatedAt est rafraîchi ; les identifiants
inconnus sont ignorés silencieusement. Un unique flush est effectué à la fin.
Attention : cette route est déclarée après /{id} (POST) dans le fichier ; selon l'ordre de
résolution du routeur, une requête POST sur /admin/plans/reorder peut être captée par la
route de suppression.
Route : /admin/plans/reorder (POST), nom admin_plan_reorder.
Parameters
- $request : Request
-
Requête HTTP courante, dont le corps JSON contient la clé
order.
Attributes
- #[Route]
- '/reorder'
- $name: 'admin_plan_reorder'
- $methods: ['POST']
Return values
Response —Réponse JSON {"success": true} en cas de succès, ou
{"success": false, "message": "Données invalides"} si la charge utile est incorrecte.
show()
Affiche le détail d'un plan et son usage.
public
show(Plan $plan, SubscriptionRepository $subscriptionRepository) : Response
Calcule le nombre d'abonnements actifs sur ce plan via le dépôt injecté dans le constructeur,
puis récupère un seul abonnement associé au plan (findOneBy) — la variable subscriptions
transmise à la vue contient donc un unique objet ou null, et non une collection.
Route : /admin/plans/{id} (GET), nom admin_plan_show.
Parameters
- $plan : Plan
-
Plan résolu automatiquement depuis l'identifiant de l'URL.
- $subscriptionRepository : SubscriptionRepository
-
Dépôt des abonnements injecté par argument (utilisé pour le
findOneBy).
Attributes
- #[Route]
- '/{id}'
- $name: 'admin_plan_show'
- $methods: ['GET']
Return values
Response —Rendu du template admin/plan/show.html.twig.
toggleStatus()
Bascule l'état actif/inactif d'un plan.
public
toggleStatus(Request $request, Plan $plan) : Response
Protégée par le jeton CSRF toggle<id> : sans jeton valide, rien n'est modifié. Sinon,
l'indicateur active est inversé, updatedAt est rafraîchi et un message flash indique
« activé » ou « désactivé » selon le nouvel état.
Route : /admin/plans/{id}/toggle-status (POST), nom admin_plan_toggle_status.
Parameters
- $request : Request
-
Requête HTTP courante, contenant le jeton CSRF
_token. - $plan : Plan
-
Plan résolu automatiquement depuis l'identifiant de l'URL.
Attributes
- #[Route]
- '/{id}/toggle-status'
- $name: 'admin_plan_toggle_status'
- $methods: ['POST']
Return values
Response —Redirection vers admin_plan_index.
removePopularFlagFromOtherPlans()
Retire le drapeau « populaire » de tous les plans, éventuellement sauf un.
private
removePopularFlagFromOtherPlans([int|null $excludeId = null ]) : void
Exécute une requête DQL de mise à jour en masse positionnant popular à false. Lorsqu'un
identifiant d'exclusion est fourni, la clause p.id != :excludeId préserve le plan concerné.
Cette requête contourne l'UnitOfWork de Doctrine : les entités déjà chargées en mémoire ne
sont pas rafraîchies. Utilisée par PlanController::new() et PlanController::edit().
Parameters
- $excludeId : int|null = null
-
Identifiant du plan à ne pas démarquer ;
nullpour tous les démarquer.