<?php
/**
*
* (c) BonBonSlick
*
*/
declare(strict_types=1);
/*
* Created by BonBonSlick
* Contacts: google it
* Date: 9/14/18
* Time: 12:00 AM
*/
namespace App\Voters;
use App\Entity\Order\Order;
use App\Entity\Role\Role;
use App\Entity\User\User;
use function get_class;
use function in_array;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class self
*/
final class OrderVoter extends Voter
{
public const ADMIN_VIEW_SINGLE = 1;
public const ADMIN_VIEW_PAID_LIST = 3;
public const ADMIN_VIEW_UNPAID_LIST = 7;
public const ADMIN_EDIT = 5;
/**
* string[]
*/
public const ADMIN_PERMS = [
self::ADMIN_VIEW_SINGLE => 'admin.view.single',
self::ADMIN_VIEW_PAID_LIST => 'admin.view.paid.list',
self::ADMIN_VIEW_UNPAID_LIST => 'admin.view.un.paid.list',
self::ADMIN_EDIT => 'admin.edit',
];
/**
* @var AccessDecisionManagerInterface
*/
private $decisionManager;
/**
* self constructor.
*
* @param AccessDecisionManagerInterface $decisionManager
*/
public function __construct(AccessDecisionManagerInterface $decisionManager)
{
$this->decisionManager = $decisionManager;
}
/**
* {@inheritdoc}
*/
protected function supports($attribute, $subject): bool
{
// if the attribute isn't one we support, return false
if (false === in_array($attribute, self::ADMIN_PERMS, true)) {
return false;
}
// only vote on Post objects inside this voter
if (get_class($subject) === Order::class) {
return true;
}
return false;
}
/**
* {@inheritdoc}
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
/** @var User $user */
$user = $token->getUser();
$response = false;
$isGranted = false === $user instanceof UserInterface ||
$this->decisionManager->decide($token, [
User::ROLE_ADMIN,
User::ROLE_WRITER,
User::ROLE_PREMIUM_WRITER,
User::ROLE_EXPRESS_WRITER,
]);
if (false === $isGranted) {
return $response;
}
switch ($attribute) {
case self::ADMIN_PERMS[self::ADMIN_VIEW_SINGLE]:
$response = $this->isAdminCanViewSingle($user);
break;
case self::ADMIN_PERMS[self::ADMIN_VIEW_PAID_LIST]:
$response = $this->adminViewPaidOrderList($user);
break;
case self::ADMIN_PERMS[self::ADMIN_VIEW_UNPAID_LIST]:
$response = $this->isAdminCanViewUnPadiOrderList($user);
break;
case self::ADMIN_PERMS[self::ADMIN_EDIT]:
$response = $this->isAdminCanEdit($user);
break;
default:
return $response;
}
return $response;
}
/**
* @param User $user
*
* @return bool
*/
private function isAdminCanViewSingle(User $user): bool
{
// if they can edit, they can view
if ($this->isAdminCanEdit($user)) {
return true;
}
if ($this->isUserInRole($user, [
User::ROLE_ADMIN,
User::ROLE_WRITER,
User::ROLE_PREMIUM_WRITER,
User::ROLE_EXPRESS_WRITER,
])) {
return true;
}
return false;
}
/**
* @param User $user
*
* @return bool
*/
private function adminViewPaidOrderList(User $user): bool
{
// if they can edit, they can view
if ($this->isAdminCanViewUnPadiOrderList($user)) {
return true;
}
if ($this->isUserInRole($user, [
User::ROLE_WRITER,
User::ROLE_PREMIUM_WRITER,
User::ROLE_EXPRESS_WRITER
])) {
return true;
}
return false;
}
/**
* @param User $user
*
* @return bool
*/
private function isAdminCanViewUnPadiOrderList(User $user): bool
{
if ($this->isUserInRole($user, [
User::ROLE_ADMIN,
])) {
return true;
}
return false;
}
/**
* @param User $user
*
* @return bool
*/
private function isAdminCanEdit(User $user): bool
{
if ($this->isUserInRole($user, [
User::ROLE_ADMIN,
User::ROLE_WRITER,
User::ROLE_PREMIUM_WRITER,
User::ROLE_EXPRESS_WRITER,
])) {
return true;
}
return false;
}
/**
* @param User $user
*
* @param string[] $roles
*
* @return bool
*/
private function isUserInRole(User $user, array $roles): bool
{
/** @var Role $item */
foreach ($user->rolesCollection() as $item) {
if (in_array($item->constantKey(), $roles, true)) {
return true;
}
}
return false;
}
}