<?php
declare(strict_types=1);
namespace App\Security\Voter;
use App\Entity\ToolApplication;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ToolApplicationVoter extends Voter
{
public const DETAILS = 'details';
public const EDIT = 'edit';
public const ARCHIVE = 'archive';
public const DELETE = 'delete';
public const SHOW_TECHNOLOGY = 'show-technology';
public const ADD_TECHNOLOGY = 'add-technology';
public const EDIT_TECHNOLOGY = 'edit-technology';
public const CAN_CHANGE_STATE = 'can-change-state';
public const EXPORT_DATA_TO_CAM = 'export-data-to-cam';
/**
* @param string $attribute
* @param mixed $subject
*
* @return bool
*/
protected function supports($attribute, $subject): bool
{
if (!\in_array($attribute, [
self::DETAILS,
self::SHOW_TECHNOLOGY,
self::ADD_TECHNOLOGY,
self::EDIT_TECHNOLOGY,
self::CAN_CHANGE_STATE,
self::EDIT,
self::ARCHIVE,
self::DELETE,
self::EXPORT_DATA_TO_CAM
], true)) {
return false;
}
if (!$subject instanceof ToolApplication) {
return false;
}
return true;
}
/**
* @param string $attribute
* @param mixed $subject
* @param TokenInterface $token
*
* @return bool
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
/** @var ToolApplication $toolApplication */
$toolApplication = $subject;
$hasVotePassed = false;
switch ($attribute) {
case self::DETAILS:
case self::SHOW_TECHNOLOGY:
case self::ADD_TECHNOLOGY:
case self::EDIT_TECHNOLOGY:
$hasVotePassed = $this->canDetails($toolApplication, $user);
break;
case self::CAN_CHANGE_STATE:
$hasVotePassed = $this->canChangeState($toolApplication, $user);
break;
case self::EDIT:
case self::DELETE:
$hasVotePassed = $this->canEdit($toolApplication, $user);
break;
case self::ARCHIVE:
$hasVotePassed = $this->canArchive($toolApplication, $user);
break;
case self::EXPORT_DATA_TO_CAM:
$hasVotePassed = $this->canExportDataToCam($toolApplication, $user);
break;
}
return $hasVotePassed;
}
/**
* @param ToolApplication $toolApplication
* @param User $user
*
* @return bool
*/
private function canDetails(ToolApplication $toolApplication, User $user): bool
{
return ($user->getOrganization()->getId() === $toolApplication->getCreatedBy()->getOrganization()->getId())
&& $toolApplication->isActive();
}
/**
* @param ToolApplication $toolApplication
* @param User $user
*
* @return bool
*/
private function canChangeState(ToolApplication $toolApplication, User $user): bool
{
return ($user->getOrganization()->getId() === $toolApplication->getCreatedBy()->getOrganization()->getId())
&& $toolApplication->isActive();
}
/**
* @param ToolApplication $toolApplication
* @param User $user
*
* @return bool
*/
private function canEdit(ToolApplication $toolApplication, User $user): bool
{
return ($user->getOrganization()->getId() === $toolApplication->getCreatedBy()->getOrganization()->getId())
&& (!$toolApplication->isDeleted());
}
/**
* @param ToolApplication $toolApplication
* @param User $user
*
* @return bool
*/
private function canArchive(ToolApplication $toolApplication, User $user): bool
{
return $this->canEdit($toolApplication, $user) && $toolApplication->isActive();
}
/**
* @param ToolApplication $toolApplication
* @param User $user
*
* @return bool
*/
private function canExportDataToCam(ToolApplication $toolApplication, User $user): bool
{
return $this->canEdit($toolApplication, $user);
}
}