mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
94 lines
3.4 KiB
PHP
94 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace Chill\PersonBundle\Search;
|
|
|
|
use Chill\MainBundle\Entity\Center;
|
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
|
use Chill\PersonBundle\Repository\PersonRepository;
|
|
use Chill\MainBundle\Search\SearchApiQuery;
|
|
use Chill\MainBundle\Search\SearchApiInterface;
|
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
|
use Symfony\Component\Security\Core\Security;
|
|
|
|
class SearchPersonApiProvider implements SearchApiInterface
|
|
{
|
|
private PersonRepository $personRepository;
|
|
private Security $security;
|
|
private AuthorizationHelperInterface $authorizationHelper;
|
|
|
|
public function __construct(PersonRepository $personRepository, Security $security, AuthorizationHelperInterface $authorizationHelper)
|
|
{
|
|
$this->personRepository = $personRepository;
|
|
$this->security = $security;
|
|
$this->authorizationHelper = $authorizationHelper;
|
|
}
|
|
|
|
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
|
|
{
|
|
return $this->addAuthorizations($this->buildBaseQuery($pattern, $parameters));
|
|
}
|
|
|
|
public function buildBaseQuery(string $pattern, array $parameters): SearchApiQuery
|
|
{
|
|
$query = new SearchApiQuery();
|
|
$query
|
|
->setSelectKey("person")
|
|
->setSelectJsonbMetadata("jsonb_build_object('id', person.id)")
|
|
->setSelectPertinence("".
|
|
"STRICT_WORD_SIMILARITY(LOWER(UNACCENT(?)), person.fullnamecanonical) + ".
|
|
"(person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%')::int + ".
|
|
"(EXISTS (SELECT 1 FROM unnest(string_to_array(fullnamecanonical, ' ')) AS t WHERE starts_with(t, UNACCENT(LOWER(?)))))::int"
|
|
, [ $pattern, $pattern, $pattern ])
|
|
->setFromClause("chill_person_person AS person")
|
|
->setWhereClauses("LOWER(UNACCENT(?)) <<% person.fullnamecanonical OR ".
|
|
"person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%' ", [ $pattern, $pattern ])
|
|
;
|
|
|
|
return $query;
|
|
}
|
|
|
|
private function addAuthorizations(SearchApiQuery $query): SearchApiQuery
|
|
{
|
|
$authorizedCenters = $this->authorizationHelper
|
|
->getReachableCenters($this->security->getUser(), PersonVoter::SEE);
|
|
|
|
if ([] === $authorizedCenters) {
|
|
return $query->andWhereClause("FALSE = TRUE", []);
|
|
}
|
|
|
|
return $query
|
|
->andWhereClause(
|
|
strtr(
|
|
"person.center_id IN ({{ center_ids }})",
|
|
[
|
|
'{{ center_ids }}' => \implode(', ',
|
|
\array_fill(0, count($authorizedCenters), '?')),
|
|
]
|
|
),
|
|
\array_map(function(Center $c) {return $c->getId();}, $authorizedCenters)
|
|
);
|
|
}
|
|
|
|
public function supportsTypes(string $pattern, array $types, array $parameters): bool
|
|
{
|
|
return \in_array('person', $types);
|
|
}
|
|
|
|
public function prepare(array $metadatas): void
|
|
{
|
|
$ids = \array_map(fn($m) => $m['id'], $metadatas);
|
|
|
|
$this->personRepository->findByIds($ids);
|
|
}
|
|
|
|
public function supportsResult(string $key, array $metadatas): bool
|
|
{
|
|
return $key === 'person';
|
|
}
|
|
|
|
public function getResult(string $key, array $metadata, float $pertinence)
|
|
{
|
|
return $this->personRepository->find($metadata['id']);
|
|
}
|
|
}
|