PlanService
in package
Expose les règles métier liées aux offres commerciales et aux quotas qui en découlent.
Le service résout le plan applicable à un utilisateur (celui de son abonnement actif, à défaut le plan « Free »), vérifie la présence d'une fonctionnalité, calcule le quota de cartes restantes ainsi que les tarifs et remises annuelles. Il lit le contexte de sécurité pour les vérifications portant sur l'utilisateur connecté et interroge le PlanRepository en lecture seule ; il n'écrit jamais en base.
Table of Contents
Properties
- $planRepository : PlanRepository
- $security : Security
Methods
- __construct() : mixed
- calculateYearlyDiscount() : int
- Calcule le pourcentage de remise annuelle
- calculateYearlyPrice() : float
- Calcule le prix avec remise annuelle
- canCreateMoreCards() : bool
- Vérifie si l'utilisateur peut créer plus de cartes
- canUpgrade() : bool
- Vérifie si l'utilisateur peut upgrader vers un plan supérieur
- canUsePremiumFeatures() : bool
- Check if user has access a features premium
- getActivePlans() : array<int, Plan>
- Récupère tous les plans actifs
- getAvailableFeatures() : array<string, string>
- Récupère les fonctionnalités disponibles par plan
- getFreePlan() : Plan|null
- Récupère le plan gratuit (plan par défaut)
- getPopularPlan() : Plan|null
- Récupère le plan le plus populaire
- getRemainingCards() : int
- Récupère le nombre de cartes restantes pour l'utilisateur
- getUserPlan() : Plan|null
- Récupère le plan de l'utilisateur
- hasFeature() : bool
- Vérifie si l'utilisateur actuel a accès à une fonctionnalité
- planHasFeature() : bool
- Vérifie si un plan a une fonctionnalité spécifique
Properties
$planRepository
private
PlanRepository
$planRepository
$security
private
Security
$security
Methods
__construct()
public
__construct(PlanRepository $planRepository, Security $security) : mixed
Parameters
- $planRepository : PlanRepository
-
Accès en lecture aux plans commerciaux.
- $security : Security
-
Contexte de sécurité, utilisé pour résoudre l'utilisateur connecté.
calculateYearlyDiscount()
Calcule le pourcentage de remise annuelle
public
calculateYearlyDiscount(Plan $plan) : int
Compare le prix annuel réel au cumul de douze mensualités et exprime l'écart en
pourcentage arrondi. Deux replis existent : 20 lorsque aucun prix annuel positif
n'est défini, et 0 lorsque le cumul mensuel est nul ou négatif (division
impossible). Le résultat est borné à zéro, un prix annuel plus cher que le mensuel
n'affiche donc pas de remise négative.
Parameters
- $plan : Plan
-
Plan dont la remise est évaluée.
Return values
int —Pourcentage entier de remise, compris entre 0 et 100 en pratique.
calculateYearlyPrice()
Calcule le prix avec remise annuelle
public
calculateYearlyPrice(Plan $plan) : float
Si le plan porte un prix annuel strictement positif, celui-ci est retourné tel quel. Dans le cas contraire, un tarif théorique est calculé à partir du prix mensuel sur douze mois, diminué d'une remise implicite de 20 %.
Parameters
- $plan : Plan
-
Plan dont le tarif annuel est demandé.
Return values
float —Prix annuel effectif ou, à défaut, prix annuel reconstitué avec remise.
canCreateMoreCards()
Vérifie si l'utilisateur peut créer plus de cartes
public
canCreateMoreCards(User $user) : bool
Compare le nombre de cartes déjà détenues au quota cardsIncluded du plan résolu.
Contrairement à SubscriptionService::canUserCreateMoreCards(), un quota nul
n'est pas interprété comme « illimité » mais bloque toute création.
Parameters
- $user : User
-
Utilisateur évalué.
Return values
bool —true si le quota du plan n'est pas atteint ; false si aucun plan n'a pu être résolu.
canUpgrade()
Vérifie si l'utilisateur peut upgrader vers un plan supérieur
public
canUpgrade(User $user, Plan $targetPlan) : bool
La hiérarchie des offres est déduite du seul prix mensuel : la montée en gamme est autorisée si le plan cible est strictement plus cher que le plan courant. Lorsque aucun plan courant n'a pu être résolu, la méthode autorise l'opération.
Parameters
Return values
bool —true si le plan cible est plus cher que le plan courant, ou si aucun plan courant n'existe.
canUsePremiumFeatures()
Check if user has access a features premium
public
canUsePremiumFeatures(User $user) : bool
Le critère retenu est purement nominal : tout plan dont le nom diffère de Free est
considéré comme premium. Ni la liste des fonctionnalités, ni le statut de paiement
de l'abonnement ne sont examinés.
Parameters
- $user : User
-
Utilisateur évalué.
Return values
bool —true si le plan résolu n'est pas le plan « Free » ; false si aucun plan n'a pu être résolu.
getActivePlans()
Récupère tous les plans actifs
public
getActivePlans() : array<int, Plan>
Les plans sont triés par sortOrder croissant, ce qui définit l'ordre d'affichage
de la grille tarifaire.
Return values
array<int, Plan> —Plans dont isActive est vrai, ordonnés pour l'affichage.
getAvailableFeatures()
Récupère les fonctionnalités disponibles par plan
public
getAvailableFeatures() : array<string, string>
Retourne un catalogue statique associant chaque clé technique de fonctionnalité à son libellé français. Cette liste est codée en dur et distincte de celle de PredefinedFeaturesService::FEATURES : les deux référentiels ne couvrent pas exactement les mêmes clés et doivent être maintenus de concert.
Return values
array<string, string> —Correspondance clé technique => libellé affichable.
getFreePlan()
Récupère le plan gratuit (plan par défaut)
public
getFreePlan() : Plan|null
Recherche en base le plan dont le nom vaut exactement Free et dont l'indicateur
isActive est vrai. Ce nom est codé en dur : renommer ou désactiver le plan en
base neutralise silencieusement l'ensemble des replis sur l'offre gratuite.
Return values
Plan|null —Plan gratuit actif, ou null s'il est absent ou désactivé.
getPopularPlan()
Récupère le plan le plus populaire
public
getPopularPlan() : Plan|null
Retourne le premier plan à la fois marqué isPopular et actif ; il s'agit d'une
mise en avant éditoriale, sans lien avec des statistiques d'usage. Si plusieurs
plans portent le marqueur, celui retenu dépend de l'ordre de la base.
Return values
Plan|null —Plan mis en avant, ou null si aucun plan actif ne porte le marqueur.
getRemainingCards()
Récupère le nombre de cartes restantes pour l'utilisateur
public
getRemainingCards(User $user) : int
Calcule la différence entre le quota cardsIncluded du plan résolu et le nombre de
cartes existantes, bornée à zéro pour ne jamais renvoyer de valeur négative en cas
de dépassement de quota.
Parameters
- $user : User
-
Utilisateur évalué.
Return values
int —Nombre de cartes encore créables ; 0 si le quota est atteint ou si aucun plan n'a pu être résolu.
getUserPlan()
Récupère le plan de l'utilisateur
public
getUserPlan(User $user) : Plan|null
Retourne le plan de l'abonnement actif si l'utilisateur en possède un ; sinon, se rabat sur le plan gratuit via self::getFreePlan(). Le statut de l'abonnement n'est pas réexaminé ici : la notion d'« actif » est celle de User::getActiveSubscription().
Parameters
- $user : User
-
Utilisateur dont on cherche le plan applicable.
Return values
Plan|null —Plan applicable, ou null si l'utilisateur n'a pas d'abonnement actif et qu'aucun plan « Free » actif n'existe en base.
hasFeature()
Vérifie si l'utilisateur actuel a accès à une fonctionnalité
public
hasFeature(string $feature) : bool
Porte sur l'utilisateur authentifié issu du contexte de sécurité, et non sur un
utilisateur passé en paramètre. Retourne false par sécurité si personne n'est
connecté, si le jeton ne porte pas une instance de User, ou si aucun plan
(pas même le plan gratuit) n'a pu être résolu.
Parameters
- $feature : string
-
Clé technique de la fonctionnalité recherchée.
Return values
bool —true uniquement si un plan est résolu et qu'il déclare cette fonctionnalité.
planHasFeature()
Vérifie si un plan a une fonctionnalité spécifique
public
planHasFeature(Plan $plan, string $feature) : bool
Recherche la clé dans le tableau de fonctionnalités du plan avec une comparaison stricte : la casse et le type doivent correspondre exactement.
Parameters
- $plan : Plan
-
Plan dont les fonctionnalités sont inspectées.
- $feature : string
-
Clé technique de la fonctionnalité recherchée.
Return values
bool —true si la clé figure dans les fonctionnalités du plan.