<?php
namespace App\Voter;
use App\Entity\Boutique\Produit;
use App\Entity\Boutique\ProduitCouponReductionHistorique;
use App\Entity\User\User;
use App\Manager\Boutique\ProduitStockBalanceManager;
use App\Repository\Boutique\ProduitCouponReductionHistoriqueRepository;
use App\Repository\Boutique\ProduitRepository;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class ProduitVoter extends Voter
{
// these strings are just invented: you can use anything
const VIEW = 'view';
const BUY = 'buy';
private $security;
/**
* @var ProduitStockBalanceManager
*/
private $produitStockBalanceManager;
/**
* @var ProduitCouponReductionHistoriqueRepository
*/
private $produitCouponReductionHistoriqueRepository;
public function __construct(
Security $security,
ProduitStockBalanceManager $produitStockBalanceManager,
ProduitCouponReductionHistoriqueRepository $produitCouponReductionHistoriqueRepository
)
{
$this->security = $security;
$this->produitStockBalanceManager = $produitStockBalanceManager;
$this->produitCouponReductionHistoriqueRepository = $produitCouponReductionHistoriqueRepository;
}
protected function supports($attribute, $subject)
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, array(self::VIEW, self::BUY))) {
return false;
}
if (!$subject instanceof Produit) {
return false;
}
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
switch ($attribute) {
case self::VIEW:
return $this->canView($subject, $user);
case self::BUY:
return $this->canBuy($subject, $user);
}
throw new \LogicException('This code should not be reached!');
}
private function canView(Produit $produit, User $user)
{
if ($this->security->isGranted(['ROLE_ADMIN','ROLE_PREVIOUS_ADMIN'])) {
return true;
}
if (
false === $produit->getGroups()->isEmpty() &&
false === $user->getGroups()->isEmpty() &&
!in_array($user->getGroups()->first()->getId(), $produit->getUserGroupIds())
) {
return false;
}
if (false === $produit->getActive()) {
return false;
}
if (true === $produit->getVisible()) {
$dateActuelle = new \DateTime();
// Check si l'utilisateur a consommé tous les coupons de réduction
if ($produit->isCouponReduction()) {
// Récupération de l'histoire d'utilisation du coupon actuel et de l'utilisateur
$produitCouponUserHistorique = $this->produitCouponReductionHistoriqueRepository->findByUserAndCoupon($user, $produit);
$couponReductionUtilisationRestante = $produit->getCouponReductionUtilisationNombre() - $produitCouponUserHistorique;
if ($couponReductionUtilisationRestante <= 0) {
return false;
}
}
if (
$produit->getPublishedAt() <= $dateActuelle &&
($produit->getExpiredAt() >= $dateActuelle || is_null($produit->getExpiredAt()))
) {
return true;
}
}
return false;
}
private function canBuy(Produit $produit, $user)
{
if (!($user instanceof UserInterface)) {
return false;
}
if (true === $produit->isCouponReduction()) {
return false;
}
if (
false === $produit->getGroups()->isEmpty() &&
false === $user->getGroups()->isEmpty() &&
!in_array($user->getGroups()->first()->getId(), $produit->getUserGroupIds())
) {
return false;
}
if (
false === $user->getGroups()->isEmpty() &&
true === $user->getGroups()->first()->getRestrictionAchat() &&
false === $this->security->isGranted(['ROLE_ADMIN','ROLE_DELEGUE'])
) {
return false;
}
if (false === $produit->getActive()) {
return false;
}
if (false === $produit->getDispoVente()) {
return false;
}
if (true === $produit->getGestionStock() && $this->produitStockBalanceManager->getStock($produit) <= 0 && is_null($produit->getDefaultDeclinaison())) {
return false;
}
// if (false === $produit->getVisible()) {
// return false;
// }
if (!is_null($produit->getProduitReducCe()) && false === $produit->getProduitReducCe()->seanceDisponibleVente()) {
return false;
}
if (
true === $produit->getVisible() ||
(
false === $produit->getVisible() &&
false === $produit->getIsReducCe() &&
$this->security->isGranted(['ROLE_ADMIN','ROLE_PREVIOUS_ADMIN'])
)
) {
$dateActuelle = new \DateTime();
if (
$produit->getPublishedAt() <= $dateActuelle &&
($produit->getExpiredAt() >= $dateActuelle || is_null($produit->getExpiredAt()))
) {
return true;
}
}
return false;
}
}