CardController
extends AbstractController
in package
Contrôleur des cartes de visite numériques (entité {@see BusinessCardAize}).
Il expose à la fois les pages publiques de consultation d'une carte (accessibles sans
authentification via un publicHash de 64 caractères hexadécimaux) et l'espace privé de
gestion : liste, création, édition, suppression, partage, régénération et téléchargement du
QR Code. Les actions de création tiennent compte du plan d'abonnement de l'utilisateur
(limite de cartes, fonctionnalités premium) et un abonnement gratuit est créé à la volée
lorsque l'utilisateur n'en possède aucun. Les comptes rattachés à une entreprise doivent être
activés par un administrateur pour accéder à la liste et à la création. Les employés
(ROLE_EMPLOYEE) peuvent voir et modifier la carte associée à leur adresse e-mail même si
celle-ci ne leur appartient pas au sens de la relation user.
Aucun préfixe de route ni contrôle d'accès au niveau de la classe : chaque méthode porte ses
propres attributs #[Route] et #[IsGranted].
Table of Contents
Properties
- $auditLogger : AuditLogger
- $entityManager : EntityManagerInterface
- $logger : LoggerInterface
- $logoManagementService : LogoManagementService
- $subscriptionService : SubscriptionService
- $uploaderService : UploaderService
Methods
- __construct() : mixed
- cardsList() : Response
- Affiche la liste des cartes de visite de l'utilisateur connecté.
- createCard() : Response
- Affiche et traite le formulaire de création d'une carte de visite numérique.
- deleteCard() : Response
- Supprime une carte de visite et l'ensemble des fichiers qui lui sont associés.
- downloadQRCode() : Response
- Renvoie le fichier QR Code d'une carte en téléchargement.
- editCard() : Response
- Affiche et traite le formulaire de modification d'une carte de visite existante.
- redirectHashNamed() : Response
- Redirige une URL nommée prénom/nom vers la page canonique de la carte.
- redirectLegacy() : Response
- Point d'entrée hérité d'un ancien format d'URL prénom/nom, aujourd'hui neutralisé.
- regenerateQRCode() : JsonResponse
- Régénère le QR Code d'une carte et retourne le résultat en JSON.
- shareCard() : JsonResponse
- Construit et renvoie en JSON l'URL de partage public d'une carte.
- showInformationACard() : Response
- Affiche publiquement une carte de visite numérique identifiée par son hash public.
- showSimpleCompanyBusinessCard() : Response
- Affiche une carte de visite via une URL « lisible » incluant l'entreprise et le poste.
- checkPhpUploadErrors() : void
- Vérifie les erreurs d'upload PHP et les convertit en messages d'erreur Symfony Cette méthode détecte les erreurs qui se produisent avant la validation Symfony (comme les fichiers trop volumineux rejetés par PHP lui-même)
- createSlug() : string
- Convertit un texte en slug utilisable dans une URL.
- getUploadErrorMessage() : string|null
- Convertit un code d'erreur PHP en message d'erreur lisible
- handleCustomLogoAndColors() : void
- Manage upload custom logo and color for user pro
- MangeCVFile() : void
- Déplace les fichiers uploadés du formulaire vers leurs répertoires de destination.
Properties
$auditLogger read-only
private
AuditLogger
$auditLogger
$entityManager read-only
private
EntityManagerInterface
$entityManager
$logger read-only
private
LoggerInterface
$logger
$logoManagementService read-only
private
LogoManagementService
$logoManagementService
$subscriptionService read-only
private
SubscriptionService
$subscriptionService
$uploaderService read-only
private
UploaderService
$uploaderService
Methods
__construct()
public
__construct(SubscriptionService $subscriptionService, LogoManagementService $logoManagementService, LoggerInterface $logger, UploaderService $uploaderService, EntityManagerInterface $entityManager, AuditLogger $auditLogger) : mixed
Parameters
- $subscriptionService : SubscriptionService
-
Vérifie l'accès aux fonctionnalités premium et crée les abonnements gratuits par défaut.
- $logoManagementService : LogoManagementService
-
Gère l'upload du logo personnalisé et l'application des couleurs de l'entreprise.
- $logger : LoggerInterface
-
Journalisation (injecté, non utilisé actuellement dans cette classe).
- $uploaderService : UploaderService
-
Supprime les fichiers associés à une carte lors de sa suppression.
- $entityManager : EntityManagerInterface
-
Accès aux repositories et persistance Doctrine.
- $auditLogger : AuditLogger
-
Enregistre les évènements d'audit sur les cartes virtuelles (création, modification, suppression).
cardsList()
Affiche la liste des cartes de visite de l'utilisateur connecté.
public
cardsList() : Response
Bloque l'accès (message flash d'erreur puis redirection vers l'accueil) si l'utilisateur est
rattaché à une entreprise et que son compte n'a pas encore été activé par un administrateur.
Crée un abonnement gratuit si aucun abonnement actif n'existe. Les cartes proviennent de la
collection businessCardAizes de l'utilisateur ; en repli, si l'utilisateur possède
ROLE_EMPLOYEE et que cette collection est vide, les cartes sont recherchées par adresse
e-mail. La liste est ensuite triée par date de création décroissante.
Route : /mes-cartes (toutes méthodes), nom app_cards_list. Authentification complète requise (IS_AUTHENTICATED_FULLY).
Attributes
- #[IsGranted]
- 'IS_AUTHENTICATED_FULLY'
- #[Route]
- '/mes-cartes'
- $name: 'app_cards_list'
Return values
Response —Page HTML business_card/cards_list.html.twig (variables businessCards, isEmployee), ou redirection vers app_home si le compte entreprise n'est pas activé.
createCard()
Affiche et traite le formulaire de création d'une carte de visite numérique.
public
createCard(Request $request, EntityManagerInterface $entityManager, QRCodeService $qrCodeService) : Response
Refuse la création si l'utilisateur appartient à une entreprise non activée. Crée un
abonnement gratuit à la volée si nécessaire, puis contrôle le quota du plan : si
cardsIncluded vaut autre chose que -1 (illimité) et que le nombre de cartes existantes
l'atteint, l'utilisateur est redirigé vers la liste avec un message d'information. La
nouvelle carte est rattachée à l'utilisateur et publiée d'emblée
(BusinessCardAize::STATUS_PUBLISHED). Le formulaire reçoit l'option is_pro_user selon
l'accès premium. À la soumission, les erreurs d'upload PHP sont vérifiées via
CardController::checkPhpUploadErrors(), les fichiers sont traités par
CardController::MangeCVFile(), la carte est persistée puis journalisée
(AuditLog::ACTION_VCARD_CREATED). Si le publicHash est absent, il est calculé en
hash_hmac('sha256', id, APP_SECRET). Le QR Code est ensuite généré à partir de l'URL
<schéma+hôte>/bcard ; un échec de génération produit un message d'avertissement mais
n'annule pas la création.
Route : /business-card/create (GET, POST), nom app_business_card_create. Authentification requise (IS_AUTHENTICATED).
Parameters
- $request : Request
-
Requête HTTP courante (données du formulaire, fichiers, schéma et hôte).
- $entityManager : EntityManagerInterface
-
Gestionnaire d'entités utilisé pour persister la carte.
- $qrCodeService : QRCodeService
-
Service de génération du QR Code.
Attributes
- #[IsGranted]
- 'IS_AUTHENTICATED'
- #[Route]
- '/business-card/create'
- $name: 'app_business_card_create'
- $methods: ['GET', 'POST']
Return values
Response —Page HTML business_card/create.html.twig, ou redirection vers app_cards_list en cas de succès, de compte non activé ou de quota atteint.
deleteCard()
Supprime une carte de visite et l'ensemble des fichiers qui lui sont associés.
public
deleteCard(BusinessCardAize $businessCard, EntityManagerInterface $entityManager) : Response
Seul le propriétaire de la carte peut la supprimer ; dans le cas contraire une exception
d'accès refusé est levée. Les fichiers liés (image, CV, brochures…) sont d'abord effacés via
UploaderService::deleteAssociatedFiles(), la suppression est journalisée
(AuditLog::ACTION_VCARD_DELETED), puis l'entité est retirée. Toute exception survenant
pendant l'opération est capturée et transformée en message flash d'erreur : la redirection
finale a lieu dans tous les cas.
Route : /business-card/{id}/delete (POST), nom app_business_card_delete. Rôle requis : ROLE_USER.
Parameters
- $businessCard : BusinessCardAize
-
Carte à supprimer, résolue depuis le paramètre de route
id. - $entityManager : EntityManagerInterface
-
Gestionnaire d'entités utilisé pour la suppression.
Tags
Attributes
- #[IsGranted]
- 'ROLE_USER'
- #[Route]
- '/business-card/{id}/delete'
- $name: 'app_business_card_delete'
- $methods: ['POST']
Return values
Response —Redirection vers app_cards_list, avec un message flash de succès ou d'erreur.
downloadQRCode()
Renvoie le fichier QR Code d'une carte en téléchargement.
public
downloadQRCode(BusinessCardAize $businessCard, Request $request, QRCodeService $qrCodeService) : Response
Refuse l'accès si la carte n'appartient pas à l'utilisateur connecté. Si aucun chemin de QR
Code n'est enregistré sur la carte, un message flash d'erreur est ajouté et l'utilisateur
est redirigé vers la liste des cartes. Le format souhaité est lu dans le paramètre de
requête format (png par défaut) et transmis à QRCodeService::downloadQRCode() ;
si le service ne retourne rien, un second message d'erreur est affiché et la redirection a
lieu.
Route : /business-card/{id}/download-qr (GET), nom app_business_card_download_qr. Rôle requis : ROLE_USER.
Parameters
- $businessCard : BusinessCardAize
-
Carte concernée, résolue depuis le paramètre de route
id. - $request : Request
-
Requête HTTP courante (paramètre
format). - $qrCodeService : QRCodeService
-
Service fournissant la réponse de téléchargement.
Tags
Attributes
- #[IsGranted]
- 'ROLE_USER'
- #[Route]
- '/business-card/{id}/download-qr'
- $name: 'app_business_card_download_qr'
- $methods: ['GET']
Return values
Response —Réponse de téléchargement du fichier, ou redirection vers app_cards_list si aucun QR Code n'est disponible ou introuvable.
editCard()
Affiche et traite le formulaire de modification d'une carte de visite existante.
public
editCard(BusinessCardAize $businessCard, Request $request, EntityManagerInterface $entityManager, QRCodeService $qrCodeService) : Response
L'accès est autorisé au propriétaire de la carte, ou à un utilisateur portant
ROLE_EMPLOYEE dont l'adresse e-mail correspond à celle enregistrée sur la carte ; sinon
une exception d'accès refusé est levée. Le formulaire reçoit les options is_pro_user et
for_employee. À la soumission, les erreurs d'upload PHP sont contrôlées via
CardController::checkPhpUploadErrors() et les fichiers traités par
CardController::MangeCVFile(). Après enregistrement, la modification est journalisée
(AuditLog::ACTION_VCARD_UPDATED), le publicHash est calculé s'il manquait, puis le QR
Code est régénéré ; un échec de régénération donne lieu à un simple avertissement.
Route : /business-card/{id}/edit (GET, POST), nom app_business_card_edit. Authentification complète requise (IS_AUTHENTICATED_FULLY).
Parameters
- $businessCard : BusinessCardAize
-
Carte à modifier, résolue depuis le paramètre de route
id. - $request : Request
-
Requête HTTP courante.
- $entityManager : EntityManagerInterface
-
Gestionnaire d'entités utilisé pour les mises à jour.
- $qrCodeService : QRCodeService
-
Service de (re)génération du QR Code.
Tags
Attributes
- #[IsGranted]
- 'IS_AUTHENTICATED_FULLY'
- #[Route]
- '/business-card/{id}/edit'
- $name: 'app_business_card_edit'
- $methods: ['GET', 'POST']
Return values
Response —Page HTML business_card/edit.html.twig, ou redirection vers app_cards_list après une modification réussie.
redirectHashNamed()
Redirige une URL nommée prénom/nom vers la page canonique de la carte.
public
redirectHashNamed(string $hash, string $firstname, string $lastname) : Response
Vérifie uniquement l'existence d'une carte portant le publicHash fourni : si elle est
introuvable, un message flash est ajouté et l'utilisateur est renvoyé vers l'accueil. La
cohérence entre les segments firstname/lastname et les valeurs réelles de la carte n'est
plus contrôlée (code commenté). Dans tous les autres cas, redirection vers
app_show_business_card.
Route : /bcard/{hash}/{firstname}/{lastname} (toutes méthodes), nom app_show_business_card_named. Accès public.
Parameters
- $hash : string
-
Hash public de la carte, 64 caractères hexadécimaux.
- $firstname : string
-
Slug du prénom (non vérifié).
- $lastname : string
-
Slug du nom (non vérifié).
Attributes
- #[Route]
- '/bcard/{hash}/{firstname}/{lastname}'
- $name: 'app_show_business_card_named'
- $requirements: ['hash' => '[a-f0-9]{64}', 'firstname' => '[a-zA-Z0-9\-]+', 'lastname' => '[a-zA-Z0-9\-]+']
Return values
Response —Redirection vers app_show_business_card, ou vers app_home si la carte est introuvable.
redirectLegacy()
Point d'entrée hérité d'un ancien format d'URL prénom/nom, aujourd'hui neutralisé.
public
redirectLegacy(string $firstname, string $lastname[, BusinessCardAize|null $businessCard = null ]) : Response
Aucune logique n'est exécutée : la méthode lève systématiquement une exception 404. Elle ne
porte plus d'attribut #[Route] et n'est donc plus routable ; elle est conservée pour
compatibilité.
Parameters
- $firstname : string
-
Prénom issu de l'ancienne URL (ignoré).
- $lastname : string
-
Nom issu de l'ancienne URL (ignoré).
- $businessCard : BusinessCardAize|null = null
-
Carte éventuellement résolue par ParamConverter (ignorée).
Tags
Return values
Response —Ne retourne jamais : une exception est toujours levée.
regenerateQRCode()
Régénère le QR Code d'une carte et retourne le résultat en JSON.
public
regenerateQRCode(BusinessCardAize $businessCard, Request $request, EntityManagerInterface $entityManager, QRCodeService $qrCodeService) : JsonResponse
Refuse l'opération si la carte n'appartient pas à l'utilisateur connecté. Les options de
rendu sont lues dans le corps de la requête : size (entier, 300 par défaut), format
(png par défaut) et labelText (SCAN ME par défaut). Si le publicHash est absent, il
est calculé en hash_hmac('sha256', id, APP_SECRET) avant la génération. L'ancien fichier
est transmis au service afin d'être remplacé ; en cas de succès, le nouveau chemin est
enregistré sur la carte. Toute exception est capturée et convertie en réponse JSON d'erreur.
Route : /business-card/{id}/regenerate-qr (toutes méthodes), nom app_business_card_regenerate_qr. Rôle requis : ROLE_USER.
Parameters
- $businessCard : BusinessCardAize
-
Carte concernée, résolue depuis le paramètre de route
id. - $request : Request
-
Requête HTTP courante (options de génération, schéma et hôte).
- $entityManager : EntityManagerInterface
-
Gestionnaire d'entités utilisé pour enregistrer le nouveau chemin.
- $qrCodeService : QRCodeService
-
Service de régénération du QR Code.
Tags
Attributes
- #[IsGranted]
- 'ROLE_USER'
- #[Route]
- '/business-card/{id}/regenerate-qr'
- $name: 'app_business_card_regenerate_qr'
Return values
JsonResponse —array{success: true, message: string, qrCodePath: string} (HTTP 200) en cas de succès, ou array{success: false, message: string} (HTTP 500) si la génération échoue ou lève une exception.
shareCard()
Construit et renvoie en JSON l'URL de partage public d'une carte.
public
shareCard(BusinessCardAize $businessCard) : JsonResponse
Refuse l'accès si la carte n'appartient pas à l'utilisateur connecté. Deux formes d'URL sont
possibles : si le nom d'entreprise et l'intitulé de poste produisent tous deux un slug non
vide (via CardController::createSlug()), l'URL « entreprise/poste »
(app_show_company_business_card) est retournée ; sinon l'URL nommée prénom/nom
(app_show_business_card_named) sert de repli. Les URL sont générées en absolu.
Route : /card/{id}/share (GET), nom app_card_share. Authentification requise (IS_AUTHENTICATED).
Parameters
- $businessCard : BusinessCardAize
-
Carte à partager, résolue depuis le paramètre de route
id.
Tags
Attributes
- #[IsGranted]
- 'IS_AUTHENTICATED'
- #[Route]
- '/card/{id}/share'
- $name: 'app_card_share'
- $methods: ['GET']
Return values
JsonResponse —Objet JSON array{success: bool, shareUrl: string, cardName: string} (HTTP 200).
showInformationACard()
Affiche publiquement une carte de visite numérique identifiée par son hash public.
public
showInformationACard(string $hash) : Response
Recherche la carte par son publicHash. Si aucune carte ne correspond, ajoute un message
flash d'information et redirige vers l'accueil. Si la carte est désactivée
(isDisabled()), affiche un message expliquant la désactivation temporaire par
l'entreprise et redirige également vers l'accueil. Lorsque le visiteur connecté est le
propriétaire de la carte et qu'il n'a aucun abonnement actif, un abonnement gratuit lui est
créé au passage. Le rendu utilise le template business_card/new_design.html.twig.
Route : /bcard/{hash} (toutes méthodes), nom app_show_business_card. Accès public.
Parameters
- $hash : string
-
Hash public de la carte, 64 caractères hexadécimaux minuscules.
Attributes
- #[Route]
- '/bcard/{hash}'
- $name: 'app_show_business_card'
- $requirements: ['hash' => '[a-f0-9]{64}']
Return values
Response —Page HTML de la carte, ou redirection vers app_home si la carte est introuvable ou désactivée.
showSimpleCompanyBusinessCard()
Affiche une carte de visite via une URL « lisible » incluant l'entreprise et le poste.
public
showSimpleCompanyBusinessCard(string $company, string $hash, string $position) : Response
Seul le hash est réellement discriminant : la carte est recherchée par publicHash, et
les segments company et position ne sont plus vérifiés (les contrôles de correspondance
de slug sont commentés dans le code). Comme CardController::showInformationACard(),
la méthode redirige vers l'accueil avec un message flash si la carte est introuvable ou
désactivée, et crée un abonnement gratuit si le visiteur connecté est le propriétaire de la
carte et n'a pas d'abonnement actif.
Route : /card/{company}/{hash}/{position} (toutes méthodes), nom app_show_company_business_card. Accès public.
Parameters
- $company : string
-
Slug du nom d'entreprise (non vérifié).
- $hash : string
-
Hash public de la carte, 64 caractères hexadécimaux.
- $position : string
-
Slug de l'intitulé de poste (non vérifié).
Attributes
- #[Route]
- '/card/{company}/{hash}/{position}'
- $name: 'app_show_company_business_card'
- $requirements: ['company' => '[a-zA-Z0-9\-]+', 'position' => '[a-zA-Z0-9\-]+', 'hash' => '[a-f0-9]{64}']
Return values
Response —Page HTML de la carte, ou redirection vers app_home si la carte est introuvable ou désactivée.
checkPhpUploadErrors()
Vérifie les erreurs d'upload PHP et les convertit en messages d'erreur Symfony Cette méthode détecte les erreurs qui se produisent avant la validation Symfony (comme les fichiers trop volumineux rejetés par PHP lui-même)
private
checkPhpUploadErrors(Request $request) : void
Parcourt les champs de fichier image, cv et brochure lus directement dans
$request->files. Pour chaque fichier dont le code d'erreur diffère de UPLOAD_ERR_OK, le
message correspondant est obtenu via CardController::getUploadErrorMessage() puis
ajouté comme message flash de type error. Aucune exception n'est levée : la méthode
n'interrompt pas le traitement du formulaire.
Parameters
- $request : Request
-
Requête HTTP contenant les fichiers uploadés.
createSlug()
Convertit un texte en slug utilisable dans une URL.
private
createSlug(string $text) : string
Le texte est passé en minuscules (en UTF-8), les caractères accentués français
sont remplacés par leur équivalent ASCII, tout caractère hors [a-z0-9] devient
un tiret, les tirets de bord sont supprimés et les séquences de tirets réduites
à un seul.
Une implémentation antérieure fondée sur iconv('UTF-8', 'ASCII//TRANSLIT')
subsiste juste au-dessus, mise en commentaire.
Parameters
- $text : string
-
Texte source, typiquement un nom ou un titre.
Return values
string —Slug en minuscules, composé de [a-z0-9] séparés par des tirets
simples ; chaîne vide si le texte ne contient aucun caractère retenu.
getUploadErrorMessage()
Convertit un code d'erreur PHP en message d'erreur lisible
private
getUploadErrorMessage(int $errorCode) : string|null
Fait correspondre les constantes UPLOAD_ERR_* (taille dépassée côté serveur ou côté
formulaire, upload partiel, absence de fichier, dossier temporaire manquant, échec
d'écriture, interruption par une extension) à un libellé en français. Malgré son type de
retour nullable, la méthode retourne toujours une chaîne : un code inconnu produit le
message générique « Erreur inconnue lors de l'upload du fichier. ».
Parameters
- $errorCode : int
-
Code d'erreur d'upload PHP (
UploadedFile::getError()).
Return values
string|null —Message en français correspondant au code d'erreur.
handleCustomLogoAndColors()
Manage upload custom logo and color for user pro
private
handleCustomLogoAndColors(FormInterface $form, BusinessCardAize $businessCard) : void
Traite le logo personnalisé (fonctionnalité Pro, conservée pour compatibilité) : si le
formulaire possède un champ customLogo et qu'un fichier y a été fourni, celui-ci est
envoyé via LogoManagementService::uploadCustomLogo() et le chemin résultant est
affecté à la carte. Applique ensuite systématiquement les couleurs de l'entreprise à la
carte via LogoManagementService::setCompanyColors(), en lieu et place de couleurs
personnalisées. Les deux opérations sont protégées : une exception est convertie en message
flash d'erreur sans interrompre l'enregistrement.
Parameters
- $form : FormInterface
-
Formulaire soumis de la carte de visite.
- $businessCard : BusinessCardAize
-
Carte sur laquelle appliquer le logo et les couleurs.
MangeCVFile()
Déplace les fichiers uploadés du formulaire vers leurs répertoires de destination.
private
MangeCVFile(FormInterface $form, BusinessCardAize $businessCard) : void
Traite successivement : le CV (champ cv, déplacé vers le paramètre cv_directory),
l'image de profil (champ image, vers profil_directory), puis les brochures de chaque
sous-formulaire d'activities (vers brochure_directory). Chaque fichier est renommé avec
un uniqid() suivi de l'extension devinée, et le nom généré est enregistré sur l'entité
correspondante. Les échecs de déplacement du CV et de l'image sont capturés et signalés par
un message flash d'erreur ; en revanche, le déplacement des brochures n'est pas protégé et
peut propager une FileException. Entre l'image et les brochures, la méthode délègue à
CardController::handleCustomLogoAndColors().
Parameters
- $form : FormInterface
-
Formulaire soumis contenant les champs
cv,imageetactivities. - $businessCard : BusinessCardAize
-
Carte à mettre à jour avec les noms de fichiers.