<?php
declare(strict_types=1);
namespace App\Security\Voter;
use App\Entity\Admin;
use App\Entity\Area;
use App\Entity\Company;
use App\Entity\Order;
use App\Entity\Page;
use App\Entity\Page\StaticPage;
use App\Entity\PromotionalCode;
use App\Entity\Quotation;
use App\Entity\Reservation\Row;
use App\Entity\Show;
use App\Entity\Sibil\Declaration;
use App\Repository\AreaRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class CompanyVoter extends Voter
{
public function __construct(
private readonly AreaRepository $areaRepository,
) {
}
protected function supports(string $attribute, $subject): bool
{
return ($attribute === 'COMPANY_ACCESS'
&& (
$subject instanceof Company
|| $subject instanceof Show\Theater
|| $subject instanceof Show\Session
|| $subject instanceof PromotionalCode
|| $subject instanceof Show\Session\SittingPlacePrice
|| $subject instanceof Row
|| $subject instanceof Page
|| $subject instanceof Page\Section
|| $subject instanceof StaticPage
|| $subject instanceof Order
|| $subject instanceof Quotation
|| $subject instanceof Declaration
)
);
}
/**
* @param string $attribute
* @param Show $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof Admin || !$user->getCompany()) {
return true;
}
/** @var Company $company */
$company = $user->getCompany();
try {
if ($subject instanceof Company) {
return $company->getId() === $subject->getId();
}
if ($subject instanceof Show\Theater || $subject instanceof PromotionalCode || $subject instanceof Order || $subject instanceof Quotation) {
return $company->getId() === $subject->getCompany()->getId();
}
if ($subject instanceof Show\Session) {
return $company->getId() === $subject->getTheater()->getCompany()->getId();
}
if ($subject instanceof Show\Session\SittingPlacePrice || $subject instanceof Declaration || $subject instanceof Row) {
return $company->getId() === $subject->getSession()->getTheater()->getCompany()->getId();
}
if ($subject instanceof Page || $subject instanceof Page\Section || $subject instanceof StaticPage) {
$areas = $this->areaRepository->getAreasByCompany((string)$company->getId());
if (empty($areas)) {
return false;
}
if ($subject instanceof Page || $subject instanceof StaticPage) {
$areaId = $subject->getArea()->getId();
} elseif ($subject instanceof Page\Section) {
$areaId = $subject->getPage()->getArea()->getId();
}
$found = array_filter($areas, static function (Area $area) use ($areaId) {
return $areaId === $area->getId();
});
return count($found) > 0;
}
} catch (\Exception $e) {
}
return false;
}
}