<?php
namespace App\LawFirm\Security;
use AppBundle\Entity\LawFirm;
use AppBundle\Entity\User;
use CRMBundle\Entity\ContactQuality;
use CRMBundle\Enum\ContactQualityEnum;
use CRMBundle\Repository\ContactRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use InvalidArgumentException;
class ContactQualityVoter extends Voter
{
public const EDIT = 'edit';
public const REMOVE = 'remove';
private ContactRepository $contactRepository;
public function __construct(ContactRepository $contactRepository)
{
$this->contactRepository = $contactRepository;
}
/**
* @inheritDoc
*/
protected function supports($attribute, $subject)
{
if (!in_array(
$attribute,
[
self::EDIT,
self::REMOVE,
]
)) {
return false;
}
if (!$subject instanceof ContactQuality) {
return false;
}
return true;
}
/**
* {@inheritdoc}
* @param ContactQuality $subject
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
/** @var LawFirm $lawFirm */
$lawFirm = $user->getLawFirm();
$isLockedQuality = in_array($subject->getQualityRelated(), [
ContactQualityEnum::NONE,
ContactQualityEnum::JURISDICTION,
ContactQualityEnum::CUSTOMER,
]);
switch ($attribute) {
case self::EDIT:
return !$isLockedQuality;
case self::REMOVE:
return !$isLockedQuality && !$this->usedByContact($subject, $lawFirm);
default:
throw new InvalidArgumentException('Invalid attribute');
}
}
private function usedByContact(ContactQuality $contactQuality, LawFirm $lawFirm): bool
{
return $this->contactRepository->count([
'lawFirm' => $lawFirm,
'qualityNew' => $contactQuality,
]) > 0;
}
}