<?php
namespace App\Security\Voter;
use App\Entity\AccountingFirm;
use App\Entity\Survey;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class SurveyVoter extends Voter
{
const ACCESS = 'SURVEY_ACCESS';
const EDIT = 'SURVEY_EDIT';
const DELETE = 'SURVEY_DELETE';
const NEW = 'SURVEY_NEW';
protected function supports(string $attribute, mixed $subject): bool
{
return in_array($attribute, [self::ACCESS, self::EDIT, self::DELETE, self::NEW])
&& ($subject === null || $subject instanceof Survey);
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
if (in_array('ROLE_ADMIN', $user->getRoles())) {
return true;
}
switch ($attribute) {
case self::ACCESS:
return $this->canAccessSurvey($user);
case self::EDIT:
case self::DELETE:
return $this->canEditSurvey($user, $subject);
case self::NEW:
return $this->canNewSurvey($user);
}
return false;
}
private function canAccessSurvey(User $user): bool
{
$accountingFirm = $user->getAccountingFirm();
if (!$accountingFirm) {
return false;
}
return $this->canAccessSurveyModule($accountingFirm);
}
private function canEditSurvey(User $user, ?Survey $survey): bool
{
if (!$this->canAccessSurvey($user)) {
return false;
}
if (!$survey) {
return false;
}
$accountingFirm = $survey->getAccountingFirm();
if (!$this->canAccessSurveyClient($accountingFirm)) {
return false;
}
return $survey->getAccountingFirm() === $user->getAccountingFirm();
}
private function canAccessSurveyModule(AccountingFirm $accountingFirm): bool
{
return $accountingFirm->getSurveyClientActivate() === true || $accountingFirm->getWebsiteCreatedAt() !== null;
}
private function canNewSurvey(User $user): bool
{
$accountingFirm = $user->getAccountingFirm();
if (!$accountingFirm) {
return false;
}
if (!$this->canAccessSurveyClient($accountingFirm)) {
return false;
}
return $accountingFirm->getSurveyClientActivate() === true;
}
//verify if token survey and widget url are not null
private function canAccessSurveyClient(AccountingFirm $accountingFirm): bool
{
return $accountingFirm->getSurveyToken() !== null && $accountingFirm->getSurveyWidgetUrl() !== null;
}
}