<?php
namespace App\Voters;
use App\Entity\Clinic\Person\ClinicUser;
use App\Entity\Message\TableConversation;
use App\Entity\Message\UserConversation;
use App\Entity\Person\Patient;
use App\Entity\Person\SuperClinicAdmin;
use App\Entity\Person\User;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
class ApiVoter extends AppVoter
{
public const IPAD = 'ipad';
public const IPAD_BY_PATIENT = 'ipad_by_patient';
public const IPAD_LIMITED_ACCESS = 'ipad_limited_access';
public const IPAD_LIMITED_ACCESS_CHAT = 'ipad_limited_access_chat';
public const IPHONE = 'iphone';
/**
* @var ManagerRegistry
*/
private $doctrine;
public function __construct(AccessDecisionManagerInterface $decisionManager, ManagerRegistry $registry)
{
parent::__construct($decisionManager);
$this->doctrine = $registry;
}
protected function supports($attribute, $subject)
{
return in_array($attribute,
[
self::IPAD,
self::IPHONE,
self::IPAD_BY_PATIENT,
self::IPAD_LIMITED_ACCESS,
self::IPAD_LIMITED_ACCESS_CHAT
],
true
);
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
/** @var ClinicUser|Patient|SuperClinicAdmin $user */
$user = $token->getUser();
if ($this->decisionManager->decide($token, [User::ROLE_PATIENT]) && self::IPHONE == $attribute) {
return $user->getId() == $subject;
}
if ($this->decisionManager->decide($token, [User::ROLE_PRACTITIONER, User::ROLE_SCHEDULER, User::ROLE_SUPER_CLINIC_ADMIN])
&& in_array($attribute, [self::IPAD, self::IPHONE, self::IPAD_BY_PATIENT])) {
if ($subject && in_array($attribute, [self::IPAD_BY_PATIENT, self::IPHONE])) {
/** @var Patient $patient */
$patient = $this->doctrine->getRepository(Patient::class)->find((int) $subject);
if ($user instanceof SuperClinicAdmin) {
$clinic = $user->getCurrentClinic();
} else {
$clinic = $user->getClinic();
}
return $patient && ($clinic->getId() == $patient->getClinic()->getId() || $patient->getAllowedClinics()->contains($clinic));
}
return true;
}
if ($this->decisionManager->decide($token,
[
User::ROLE_PRACTITIONER,
User::ROLE_SCHEDULER,
User::ROLE_CLINIC_ADMIN,
User::ROLE_SUPER_CLINIC_ADMIN,
User::ROLE_RECEPTIONIST,
User::ROLE_BOOKER
]
)
&& self::IPAD_LIMITED_ACCESS == $attribute) {
if ($subject) {
/** @var Patient $patient */
$patient = $this->doctrine->getRepository(Patient::class)->find($subject);
if ($user instanceof SuperClinicAdmin) {
if ($user->getCurrentClinic()) {
return $patient && ($user->getCurrentClinic()->getId() == $patient->getClinic()->getId() || $patient->getAllowedClinics()->contains($user->getCurrentClinic()));
}
return false;
}
return $patient && ($user->getClinic()->getId() == $patient->getClinic()->getId() || $patient->getAllowedClinics()->contains($user->getClinic()));
// return $patient && $user->getClinic()->getId() == $patient->getClinic()->getId();
}
return true;
}
if ($this->decisionManager->decide($token,
[
User::ROLE_PRACTITIONER,
User::ROLE_SCHEDULER,
User::ROLE_CLINIC_ADMIN,
User::ROLE_SUPER_CLINIC_ADMIN,
User::ROLE_RECEPTIONIST,
User::ROLE_BOOKER
]
)
&& self::IPAD_LIMITED_ACCESS_CHAT == $attribute) {
if ($subject) {
/** @var TableConversation $conversation */
$conversation = $this->doctrine->getRepository(TableConversation::class)->find($subject);
return $conversation &&
$conversation->getUserConversations()->filter(function (UserConversation $userConversation) use ($user) {
return $userConversation->getUser()->getId() == $user->getId();
})->count() > 0;
}
return false;
}
return false;
}
}