<?php
declare(strict_types=1);
namespace App\Bundles\PatientBundle\Security;
use App\Bundles\AnalyticBundle\Provider\IndexNameProvider;
use App\Bundles\PatientBundle\DataTable\Filters\AnalyticFilterableFieldsEnum;
use App\Bundles\PatientBundle\Entity\Patient;
use App\Bundles\PatientBundle\Repository\QueryBuilder\PatientElasticsearchQueryBuilder;
use App\Bundles\UserBundle\Enum\SystemPermissionEnum;
use App\Platform\Service\ElasticsearchProvider;
use Elastica\Query;
use Elastica\Query\BoolQuery;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ViewPatientVoter extends Voter
{
public function __construct(
private readonly PatientElasticsearchQueryBuilder $queryBuilder,
private readonly ElasticsearchProvider $elasticsearchProvider,
private readonly IndexNameProvider $indexNameProvider,
) {
}
protected function supports(string $attribute, $subject): bool
{
return $attribute == SystemPermissionEnum::SPECIFIC_PATIENT_VIEW->value;
}
/** @param Patient|null $subject */
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
if (!$subject) {
return false;
}
$client = $this->elasticsearchProvider->provideElastica();
$index = $client->getIndex($this->indexNameProvider->patient());
$query = new Query();
$query->setSource([AnalyticFilterableFieldsEnum::ID->value]);
$boolQuery = new BoolQuery();
$boolQuery->addMust($this->queryBuilder->getAccessQuery());
$boolQuery->addMust(new Query\Term([AnalyticFilterableFieldsEnum::ID->value => $subject->getId()]));
$query->setQuery($boolQuery);
return $index->search($query)->count() > 0;
}
}