<?php
namespace App\Voter;
use App\Entity\Product\Product;
use App\Entity\User as UserEntity;
use App\Model\ProductFactory;
use App\Model\User\User;
use Exception;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class ProductVoter extends Voter
{
public const MANAGE_MERCU = 'manage_mercu';
public const MANAGE_GUEST_PRODUCT = 'manage_guest_product';
public const CREATE_GUEST_PRODUCT = 'create_guest_product';
public const READ_GUEST_PRODUCT = 'read_guest_product';
private $user;
private $productFactory;
public function __construct(Security $security, User $user, ProductFactory $productFactory)
{
$this->user = $user;
$this->productFactory = $productFactory;
}
protected function supports($attribute, $subject): bool
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, [
self::MANAGE_MERCU,
self::MANAGE_GUEST_PRODUCT,
self::READ_GUEST_PRODUCT,
self::CREATE_GUEST_PRODUCT
])) {
return false;
}
// only vote on Product objects inside this voter
if (! $subject instanceof Product) {
return false;
}
return true;
}
/**
* @param string $attribute
* @param Product $entity
*
* @return bool
* @throws Exception
*/
protected function voteOnAttribute($attribute, $entity, TokenInterface $token): bool
{
$userEntity = $token->getUser();
if (! $userEntity instanceof UserEntity) {
// the user must be logged in; if not, deny access
return false;
}
$this->user->setEntity($userEntity);
switch ($attribute) {
case self::MANAGE_MERCU:
return $this->user->canManageCurrentShopMercu();
case self::CREATE_GUEST_PRODUCT:
return $this->user->canManageCurrentShopGuestProducts();
case self::MANAGE_GUEST_PRODUCT:
$product = $this->productFactory->createModel($entity);
return $product->canBeManagedBy($this->user);
case self::READ_GUEST_PRODUCT:
$product = $this->productFactory->createModel($entity);
return $product->canBeSeenBy($this->user);
}
return false;
}
}