<?php
namespace App\Security\Voter\PredictAi;
use App\Entity\Product;
use App\Entity\User;
use App\Service\Subscription\SubscriptionProvider;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* Voter permettant de vérifier l'accès à la fonctionnalité de Predict AI par le membre connecté.
*/
/**
* @extends Voter<string, mixed>
*/
class PredictAiBetaAccessVoter extends Voter
{
public const PREDICT_AI_BETA_ACCESS = 'predict_ai_beta_access';
private SubscriptionProvider $subscriptionProvider;
public function __construct(
SubscriptionProvider $subscriptionProvider
) {
$this->subscriptionProvider = $subscriptionProvider;
}
protected function supports(string $attribute, $subject): bool
{
return self::PREDICT_AI_BETA_ACCESS === $attribute;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
/** @var User|null $user */
$user = $token->getUser();
if (null === $user) {
return false;
}
$member = $user->getMember();
if (null === $member) {
return false;
}
// On ne donne accès qu'aux membres ayant un premiumm (1, 6, 12 mois), les full en 6/12 mois et IKIGAI+ (premium par défaut)
// (en fait on ne donne simplement pas l'accès aux full en 1 mois)
// D'abord on récupère la dernière souscription active sur un pack IKIGAI
$lastIkigaiSubscription = $this->subscriptionProvider->getLastIkigaiSubscription($member);
// Si c'est un IKIGAI + c'est forcément un pack premium
if (null !== $lastIkigaiSubscription
&& null !== $lastIkigaiSubscription->getProduct()
&& Product::IKIGAI_PLUS_KEY === $lastIkigaiSubscription->getProduct()->getName()
) {
return true;
}
// Ensuite on teste la dernière souscription active sur un pack Futures
$lastFuturesSubscription = $this->subscriptionProvider->getLastFuturesSubscription($member, true);
// Si le membre n'a pas d'abonnement Futures en cours ou que le produit rattaché n'existe pas
if (null === $lastFuturesSubscription || null === $lastFuturesSubscription->getProduct()) {
return false;
}
// Si le membre a un abonnement Futures en cours et que la durée est 6 ou 12 mois
if ($lastFuturesSubscription->getDurationTotal() > 1) {
return true;
}
// Si le membre a un abonnement Futures en cours et que le produit est un premium
if (Product::PREMIUM_KEY === $lastFuturesSubscription->getProduct()->getName()) {
return true;
}
return false;
}
}