AdminApiController
extends AbstractController
in package
Contrôleur d'API réservé au back-office d'administration.
Il agrège les indicateurs du tableau de bord (utilisateurs, commandes, paiements, catalogue), expose la liste paginée des utilisateurs et des commandes tous comptes confondus, permet d'activer ou de désactiver un compte entreprise et de faire évoluer le statut d'une commande — cette dernière opération déclenchant une notification par email au client.
Préfixe de route : /api/admin. Toutes les actions exigent ROLE_ADMIN
(jeton JWT bearerAuth).
Attributes
- #[IsGranted]
- 'ROLE_ADMIN'
- #[Route]
- '/api/admin'
- $name: 'api_admin_'
- #[Tag]
- $name: 'Administration'
- $description: 'Endpoints d\'administration (ROLE_ADMIN requis)'
Table of Contents
Properties
- $entityManager : EntityManagerInterface
- $mailerService : MailerService
Methods
- __construct() : mixed
- activateBusiness() : JsonResponse
- Active le compte entreprise d'un utilisateur.
- dashboard() : JsonResponse
- Retourne les indicateurs agrégés du tableau de bord administrateur.
- deactivateBusiness() : JsonResponse
- Désactive le compte entreprise d'un utilisateur.
- ordersList() : JsonResponse
- Retourne la liste paginée de toutes les commandes, tous comptes confondus.
- updateOrderStatus() : JsonResponse
- Met à jour le statut d'une commande et notifie le client.
- usersList() : JsonResponse
- Retourne la liste paginée de tous les utilisateurs.
Properties
$entityManager read-only
private
EntityManagerInterface
$entityManager
$mailerService read-only
private
MailerService
$mailerService
Methods
__construct()
public
__construct(EntityManagerInterface $entityManager, MailerService $mailerService) : mixed
Parameters
- $entityManager : EntityManagerInterface
-
Gestionnaire d'entités Doctrine, utilisé pour persister les changements d'état.
- $mailerService : MailerService
-
Service d'envoi des notifications par email lors d'un changement de statut de commande.
activateBusiness()
Active le compte entreprise d'un utilisateur.
public
activateBusiness(int $id, UserRepository $userRepository) : JsonResponse
Refuse l'opération si l'utilisateur n'est rattaché à aucune entreprise. Si le compte
est déjà activé, la méthode sort en succès avec un message spécifique et sans écriture
en base. Sinon l'indicateur activated passe à true et la modification est persistée.
Aucun email n'est envoyé à l'utilisateur concerné.
Voir aussi UserApiController::activateBusiness(), qui expose une action équivalente sous un autre préfixe de route.
Route : /api/admin/users/{id}/activate-business (POST), nom api_admin_activate_business.
Requiert ROLE_ADMIN.
Réponses : 200 compte activé, 200 compte déjà activé (message distinct),
400 utilisateur sans entreprise rattachée, 404 utilisateur inexistant,
403 appelant sans ROLE_ADMIN, 401 requête non authentifiée.
Parameters
- $id : int
-
Identifiant de l'utilisateur ciblé.
- $userRepository : UserRepository
-
Dépôt utilisé pour retrouver l'utilisateur.
Attributes
- #[Post]
- $path: '/api/admin/users/{id}/activate-business'
- $description: 'Active le compte entreprise d\'un utilisateur'
- $summary: 'Active un compte entreprise'
- $security: [['bearerAuth' => []]]
- $tags: ['Administration']
- $parameters: [new OA\Parameter(name: 'id', description: 'ID de l\'utilisateur', in: 'path', required: true, schema: new OA\Schema(type: 'integer'))]
- $responses: [new OA\Response(response: 200, description: 'Compte entreprise activé avec succès', content: new OA\JsonContent(properties: [new OA\Property(property: 'message', type: 'string', example: 'Compte entreprise activé avec succès')])), new OA\Response(response: 404, description: 'Utilisateur non trouvé'), new OA\Response(response: 400, description: 'L\'utilisateur n\'a pas de compte entreprise')]
- #[Route]
- '/users/{id}/activate-business'
- $name: 'activate_business'
- $methods: ['POST']
Return values
JsonResponse —Message de confirmation, ou message d'erreur sous la clé error.
dashboard()
Retourne les indicateurs agrégés du tableau de bord administrateur.
public
dashboard(UserRepository $userRepository, OrderRepository $orderRepository, PaymentRepository $paymentRepository, CardRepository $cardRepository) : JsonResponse
Exécute une série de comptages indépendants : nombre total d'utilisateurs, comptes
disposant d'une entreprise (company IS NOT NULL), comptes activés, et inscriptions
depuis le premier jour du mois courant. Côté commandes, les statuts « en attente »,
« terminée » et « annulée » sont comptés séparément. Le chiffre d'affaires est calculé
comme la somme des montants des paiements aux statuts completed ou accepted, avec
un COALESCE pour couvrir l'absence de résultat, puis formaté à deux décimales.
Les paiements sont ventilés en total, complétés, en attente et rejetés ; le catalogue
est ventilé en cartes visibles et masquées. Aucune période n'est appliquée hors du
compteur mensuel.
Route : /api/admin/dashboard (GET), nom api_admin_dashboard. Requiert ROLE_ADMIN.
Réponses : 200 statistiques renvoyées, 403 appelant sans ROLE_ADMIN,
401 requête non authentifiée.
Parameters
- $userRepository : UserRepository
-
Dépôt utilisé pour les compteurs d'utilisateurs.
- $orderRepository : OrderRepository
-
Dépôt utilisé pour les compteurs de commandes.
- $paymentRepository : PaymentRepository
-
Dépôt utilisé pour les compteurs de paiements et le chiffre d'affaires.
- $cardRepository : CardRepository
-
Dépôt utilisé pour les compteurs du catalogue.
Attributes
- #[Get]
- $path: '/api/admin/dashboard'
- $description: 'Récupère les statistiques générales pour le tableau de bord admin'
- $summary: 'Tableau de bord administrateur'
- $security: [['bearerAuth' => []]]
- $tags: ['Administration']
- $responses: [new OA\Response(response: 200, description: 'Statistiques du tableau de bord', content: new OA\JsonContent(properties: [new OA\Property(property: 'users', properties: [new OA\Property(property: 'total', type: 'integer', example: 150), new OA\Property(property: 'business_accounts', type: 'integer', example: 25), new OA\Property(property: 'activated_business', type: 'integer', example: 20), new OA\Property(property: 'new_this_month', type: 'integer', example: 12)], type: 'object'), new OA\Property(property: 'orders', properties: [new OA\Property(property: 'total', type: 'integer', example: 75), new OA\Property(property: 'pending', type: 'integer', example: 5), new OA\Property(property: 'completed', type: 'integer', example: 65), new OA\Property(property: 'cancelled', type: 'integer', example: 5), new OA\Property(property: 'total_revenue', type: 'string', example: '7500.00')], type: 'object'), new OA\Property(property: 'payments', properties: [new OA\Property(property: 'total', type: 'integer', example: 70), new OA\Property(property: 'completed', type: 'integer', example: 65), new OA\Property(property: 'pending', type: 'integer', example: 3), new OA\Property(property: 'failed', type: 'integer', example: 2)], type: 'object'), new OA\Property(property: 'cards', properties: [new OA\Property(property: 'total', type: 'integer', example: 15), new OA\Property(property: 'visible', type: 'integer', example: 12), new OA\Property(property: 'hidden', type: 'integer', example: 3)], type: 'object')])), new OA\Response(response: 403, description: 'Accès refusé - ROLE_ADMIN requis')]
- #[Route]
- '/dashboard'
- $name: 'dashboard'
- $methods: ['GET']
Return values
JsonResponse —Objet JSON {users, orders, payments, cards}, chacun étant un
sous-objet de compteurs (array<string, int|string>).
deactivateBusiness()
Désactive le compte entreprise d'un utilisateur.
public
deactivateBusiness(int $id, UserRepository $userRepository) : JsonResponse
Positionne l'indicateur activated à false et persiste la modification, sans
vérifier au préalable que l'utilisateur possède effectivement une entreprise ni
qu'il était activé : l'opération est donc idempotente et applicable à tout compte.
Aucun email n'est envoyé.
Route : /api/admin/users/{id}/deactivate-business (POST), nom api_admin_deactivate_business.
Requiert ROLE_ADMIN.
Réponses : 200 compte désactivé, 404 utilisateur inexistant,
403 appelant sans ROLE_ADMIN, 401 requête non authentifiée.
Parameters
- $id : int
-
Identifiant de l'utilisateur ciblé.
- $userRepository : UserRepository
-
Dépôt utilisé pour retrouver l'utilisateur.
Attributes
- #[Post]
- $path: '/api/admin/users/{id}/deactivate-business'
- $description: 'Désactive le compte entreprise d\'un utilisateur'
- $summary: 'Désactive un compte entreprise'
- $security: [['bearerAuth' => []]]
- $tags: ['Administration']
- $parameters: [new OA\Parameter(name: 'id', description: 'ID de l\'utilisateur', in: 'path', required: true, schema: new OA\Schema(type: 'integer'))]
- $responses: [new OA\Response(response: 200, description: 'Compte entreprise désactivé avec succès', content: new OA\JsonContent(properties: [new OA\Property(property: 'message', type: 'string', example: 'Compte entreprise désactivé avec succès')])), new OA\Response(response: 404, description: 'Utilisateur non trouvé')]
- #[Route]
- '/users/{id}/deactivate-business'
- $name: 'deactivate_business'
- $methods: ['POST']
Return values
JsonResponse —Message de confirmation, ou message d'erreur sous la clé error.
ordersList()
Retourne la liste paginée de toutes les commandes, tous comptes confondus.
public
ordersList(Request $request, OrderRepository $orderRepository) : JsonResponse
page est ramené à 1 au minimum et limit est borné à l'intervalle [1, 100]
(défaut 20) ; le filtre status n'est appliqué que s'il est fourni et non vide,
sans validation de la valeur transmise. Les résultats sont triés par created_at
décroissant. Le bloc user vaut null pour les commandes passées sans compte, et
la charge utile inclut les informations de suivi (tracking_number,
shipping_carrier, shipped_at, delivered_at) absentes du schéma OpenApi.
Les lignes de commande ne sont pas incluses.
Route : /api/admin/orders (GET), nom api_admin_orders_list. Requiert ROLE_ADMIN.
Paramètres de requête : status (optionnel), page (optionnel, défaut 1),
limit (optionnel, défaut 20, plafonné à 100).
Réponses : 200 liste renvoyée, 403 appelant sans ROLE_ADMIN, 401 requête non authentifiée.
Parameters
- $request : Request
-
Requête HTTP portant le filtre de statut et la pagination.
- $orderRepository : OrderRepository
-
Dépôt utilisé pour la recherche et le comptage.
Attributes
- #[Get]
- $path: '/api/admin/orders'
- $description: 'Récupère la liste de toutes les commandes avec pagination'
- $summary: 'Liste toutes les commandes'
- $security: [['bearerAuth' => []]]
- $tags: ['Administration']
- $parameters: [new OA\Parameter(name: 'status', description: 'Filtrer par statut', in: 'query', required: false, schema: new OA\Schema(type: 'string', enum: ['En Attente', 'En traitement', 'Terminée', 'Remboursée', 'Annulée'])), new OA\Parameter(name: 'page', description: 'Numéro de page', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 1)), new OA\Parameter(name: 'limit', description: 'Nombre d\'éléments par page', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 20))]
- $responses: [new OA\Response(response: 200, description: 'Liste des commandes', content: new OA\JsonContent(properties: [new OA\Property(property: 'orders', type: 'array', items: new OA\Items(properties: [new OA\Property(property: 'id', type: 'integer'), new OA\Property(property: 'firstname', type: 'string'), new OA\Property(property: 'lastname', type: 'string'), new OA\Property(property: 'email', type: 'string'), new OA\Property(property: 'total', type: 'string'), new OA\Property(property: 'status', type: 'string'), new OA\Property(property: 'created_at', type: 'string', format: 'date-time'), new OA\Property(property: 'user', properties: [new OA\Property(property: 'id', type: 'integer'), new OA\Property(property: 'email', type: 'string'), new OA\Property(property: 'firstname', type: 'string'), new OA\Property(property: 'lastname', type: 'string')], type: 'object')])), new OA\Property(property: 'pagination', type: 'object')]))]
- #[Route]
- '/orders'
- $name: 'orders_list'
- $methods: ['GET']
Return values
JsonResponse —Objet JSON {orders: list<array<string, mixed>>, pagination: array<string, int|float>}.
updateOrderStatus()
Met à jour le statut d'une commande et notifie le client.
public
updateOrderStatus(int $id, Request $request, OrderRepository $orderRepository) : JsonResponse
Le statut transmis doit appartenir à la liste blanche des constantes de
Order (« en attente », « en traitement », « terminée », « remboursée »,
« annulée »). Aucune transition d'état n'est contrôlée : n'importe quel statut
valide peut succéder à n'importe quel autre, et les champs d'annulation ou
d'expédition ne sont pas mis à jour. Après persistance, un email de notification
est envoyé via MailerService::sendOrderStatusUpdate() ; un échec d'envoi est
seulement journalisé par error_log() et ne modifie pas la réponse renvoyée.
Route : /api/admin/orders/{id}/status (PUT), nom api_admin_update_order_status.
Requiert ROLE_ADMIN.
Corps attendu : {"status": "string — obligatoire, valeur parmi les statuts autorisés"}
Réponses : 200 statut mis à jour, 400 clé status absente, 400 statut hors liste
autorisée, 404 commande inexistante, 403 appelant sans ROLE_ADMIN,
401 requête non authentifiée.
Parameters
- $id : int
-
Identifiant de la commande à modifier.
- $request : Request
-
Requête HTTP dont le corps JSON porte le nouveau statut.
- $orderRepository : OrderRepository
-
Dépôt utilisé pour retrouver la commande.
Attributes
- #[Put]
- $path: '/api/admin/orders/{id}/status'
- $description: 'Met à jour le statut d\'une commande spécifique'
- $summary: 'Met à jour le statut d\'une commande'
- $security: [['bearerAuth' => []]]
- $requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(required: ['status'], properties: [new OA\Property(property: 'status', type: 'string', enum: ['En Attente', 'En traitement', 'Terminée', 'Remboursée', 'Annulée'], example: 'En traitement')]))
- $tags: ['Administration']
- $parameters: [new OA\Parameter(name: 'id', description: 'ID de la commande', in: 'path', required: true, schema: new OA\Schema(type: 'integer'))]
- $responses: [new OA\Response(response: 200, description: 'Statut mis à jour avec succès', content: new OA\JsonContent(properties: [new OA\Property(property: 'message', type: 'string', example: 'Statut mis à jour avec succès')])), new OA\Response(response: 404, description: 'Commande non trouvée'), new OA\Response(response: 400, description: 'Statut invalide')]
- #[Route]
- '/orders/{id}/status'
- $name: 'update_order_status'
- $methods: ['PUT']
Return values
JsonResponse —Message de confirmation, ou message d'erreur sous la clé error.
usersList()
Retourne la liste paginée de tous les utilisateurs.
public
usersList(Request $request, UserRepository $userRepository) : JsonResponse
page est ramené à 1 au minimum et limit est borné à l'intervalle [1, 100]
(défaut 20). Le drapeau business_only, lu comme booléen, ajoute un critère
business = true sur le dépôt. Les résultats sont triés par created_at
décroissant. Pour chaque utilisateur, le nombre de commandes et d'employés est
obtenu en comptant les collections associées, ce qui provoque autant de
chargements que d'utilisateurs retournés. La charge utile réelle renvoie name et
email_verified là où le schéma OpenApi déclare firstname, lastname et
created_at.
Route : /api/admin/users (GET), nom api_admin_users_list. Requiert ROLE_ADMIN.
Paramètres de requête : page (optionnel, défaut 1), limit (optionnel, défaut 20,
plafonné à 100), business_only (optionnel, booléen).
Réponses : 200 liste renvoyée, 403 appelant sans ROLE_ADMIN, 401 requête non authentifiée.
Parameters
- $request : Request
-
Requête HTTP portant la pagination et le filtre entreprise.
- $userRepository : UserRepository
-
Dépôt utilisé pour la recherche et le comptage.
Attributes
- #[Get]
- $path: '/api/admin/users'
- $description: 'Récupère la liste de tous les utilisateurs avec pagination'
- $summary: 'Liste tous les utilisateurs'
- $security: [['bearerAuth' => []]]
- $tags: ['Administration']
- $parameters: [new OA\Parameter(name: 'page', description: 'Numéro de page', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 1)), new OA\Parameter(name: 'limit', description: 'Nombre d\'éléments par page', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 20)), new OA\Parameter(name: 'business_only', description: 'Filtrer uniquement les comptes entreprise', in: 'query', required: false, schema: new OA\Schema(type: 'boolean'))]
- $responses: [new OA\Response(response: 200, description: 'Liste des utilisateurs', content: new OA\JsonContent(properties: [new OA\Property(property: 'users', type: 'array', items: new OA\Items(properties: [new OA\Property(property: 'id', type: 'integer', example: 1), new OA\Property(property: 'email', type: 'string', example: 'user@example.com'), new OA\Property(property: 'firstname', type: 'string', example: 'John'), new OA\Property(property: 'lastname', type: 'string', example: 'Doe'), new OA\Property(property: 'business_activated', type: 'boolean', example: true), new OA\Property(property: 'roles', type: 'array', items: new OA\Items(type: 'string')), new OA\Property(property: 'created_at', type: 'string', format: 'date-time'), new OA\Property(property: 'orders_count', type: 'integer', example: 5), new OA\Property(property: 'employees_count', type: 'integer', example: 3)])), new OA\Property(property: 'pagination', type: 'object')]))]
- #[Route]
- '/users'
- $name: 'users_list'
- $methods: ['GET']
Return values
JsonResponse —Objet JSON {users: list<array<string, mixed>>, pagination: array<string, int|float>}.