mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2026-04-05 04:23:43 +00:00
Add Person's external identifiers to creation and edit form
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Repository\Identifier;
|
||||
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
|
||||
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
class PersonIdentifierRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry, private readonly PersonIdentifierManagerInterface $personIdentifierManager)
|
||||
{
|
||||
parent::__construct($registry, PersonIdentifier::class);
|
||||
}
|
||||
|
||||
public function findByDefinitionAndCanonical(PersonIdentifierDefinition $definition, array|string $valueOrCanonical): array
|
||||
{
|
||||
return $this->createQueryBuilder('p')
|
||||
->where('p.definition = :definition')
|
||||
->andWhere('p.canonical = :canonical')
|
||||
->setParameter('definition', $definition)
|
||||
->setParameter(
|
||||
'canonical',
|
||||
is_string($valueOrCanonical) ?
|
||||
$valueOrCanonical :
|
||||
$this->personIdentifierManager->buildWorkerByPersonIdentifierDefinition($definition)->canonicalizeValue($valueOrCanonical),
|
||||
)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@ use Chill\MainBundle\Search\ParsingException;
|
||||
use Chill\MainBundle\Search\SearchApiQuery;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
|
||||
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierWorker;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
@@ -27,7 +29,13 @@ use Symfony\Component\Security\Core\Security;
|
||||
|
||||
final readonly class PersonACLAwareRepository implements PersonACLAwareRepositoryInterface
|
||||
{
|
||||
public function __construct(private Security $security, private EntityManagerInterface $em, private CountryRepository $countryRepository, private AuthorizationHelperInterface $authorizationHelper) {}
|
||||
public function __construct(
|
||||
private Security $security,
|
||||
private EntityManagerInterface $em,
|
||||
private CountryRepository $countryRepository,
|
||||
private AuthorizationHelperInterface $authorizationHelper,
|
||||
private PersonIdentifierManagerInterface $personIdentifierManager,
|
||||
) {}
|
||||
|
||||
public function buildAuthorizedQuery(
|
||||
?string $default = null,
|
||||
@@ -107,6 +115,15 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
$query
|
||||
->setFromClause('chill_person_person AS person');
|
||||
|
||||
$idDefinitionWorkers = array_map(
|
||||
fn (PersonIdentifierWorker $worker) => $worker->getDefinition()->getId(),
|
||||
array_filter(
|
||||
$this->personIdentifierManager->getWorkers(),
|
||||
fn (PersonIdentifierWorker $worker) => $worker->getDefinition()->isSearchable()
|
||||
)
|
||||
);
|
||||
$idDefinitionWorkerQuestionMarks = implode(', ', array_fill(0, count($idDefinitionWorkers), '?'));
|
||||
|
||||
$pertinence = [];
|
||||
$pertinenceArgs = [];
|
||||
$andWhereSearchClause = [];
|
||||
@@ -124,20 +141,53 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
'(starts_with(LOWER(UNACCENT(lastname)), UNACCENT(LOWER(?))))::int';
|
||||
\array_push($pertinenceArgs, $str, $str, $str, $str);
|
||||
|
||||
$andWhereSearchClause[] =
|
||||
'(LOWER(UNACCENT(?)) <<% person.fullnamecanonical OR '.
|
||||
"person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%' )";
|
||||
\array_push($andWhereSearchClauseArgs, $str, $str);
|
||||
$q = [
|
||||
'LOWER(UNACCENT(?)) <<% person.fullnamecanonical',
|
||||
"person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%' ",
|
||||
];
|
||||
$qArguments = [$str, $str];
|
||||
|
||||
if (count($idDefinitionWorkers) > 0) {
|
||||
$q[] = $mq = "EXISTS (
|
||||
SELECT 1 FROM chill_person_identifier AS identifier
|
||||
WHERE identifier.canonical LIKE LOWER(UNACCENT(?)) || '%' AND identifier.definition_id IN ({$idDefinitionWorkerQuestionMarks})
|
||||
AND person.id = identifier.person_id
|
||||
)";
|
||||
$pertinence[] = "({$mq})::int * 1000000";
|
||||
$qArguments = [...$qArguments, $str, ...$idDefinitionWorkers];
|
||||
$pertinenceArgs = [...$pertinenceArgs, $str, ...$idDefinitionWorkers];
|
||||
}
|
||||
|
||||
$andWhereSearchClause[] = '('.implode(' OR ', $q).')';
|
||||
$andWhereSearchClauseArgs = [...$andWhereSearchClauseArgs, ...$qArguments];
|
||||
}
|
||||
|
||||
$query->andWhereClause(
|
||||
\implode(' AND ', $andWhereSearchClause),
|
||||
$andWhereSearchClauseArgs
|
||||
);
|
||||
} else {
|
||||
$pertinence = ['1'];
|
||||
$pertinenceArgs = [];
|
||||
}
|
||||
|
||||
if (null !== $phonenumber) {
|
||||
$personPhoneClause = "person.phonenumber LIKE '%' || ? || '%' OR person.mobilenumber LIKE '%' || ? || '%' OR EXISTS (SELECT 1 FROM chill_person_phone where person_id = person.id AND phonenumber LIKE '%' || ? || '%')";
|
||||
if (count($andWhereSearchClauseArgs) > 0) {
|
||||
$initialSearchClause = '(('.\implode(' AND ', $andWhereSearchClause).') OR '.$personPhoneClause.')';
|
||||
}
|
||||
$andWhereSearchClauseArgs = [...$andWhereSearchClauseArgs, $phonenumber, $phonenumber, $phonenumber];
|
||||
|
||||
// drastically increase pertinence
|
||||
$pertinence[] = "(person.phonenumber LIKE '%' || ? || '%' OR person.mobilenumber LIKE '%' || ? || '%' OR EXISTS (SELECT 1 FROM chill_person_phone where person_id = person.id AND phonenumber LIKE '%' || ? || '%'))::int * 1000000";
|
||||
$pertinenceArgs = [...$pertinenceArgs, $phonenumber, $phonenumber, $phonenumber];
|
||||
} else {
|
||||
$initialSearchClause = \implode(' AND ', $andWhereSearchClause);
|
||||
}
|
||||
|
||||
if (isset($initialSearchClause)) {
|
||||
$query->andWhereClause(
|
||||
$initialSearchClause,
|
||||
$andWhereSearchClauseArgs
|
||||
);
|
||||
}
|
||||
|
||||
$query
|
||||
->setSelectPertinence(\implode(' + ', $pertinence), $pertinenceArgs);
|
||||
|
||||
@@ -176,14 +226,6 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $phonenumber) {
|
||||
$query->andWhereClause(
|
||||
"person.phonenumber LIKE '%' || ? || '%' OR person.mobilenumber LIKE '%' || ? || '%' OR pp.phonenumber LIKE '%' || ? || '%'",
|
||||
[$phonenumber, $phonenumber, $phonenumber]
|
||||
);
|
||||
$query->setFromClause($query->getFromClause().' LEFT JOIN chill_person_phone pp ON pp.person_id = person.id');
|
||||
}
|
||||
|
||||
if (null !== $city) {
|
||||
$query->setFromClause($query->getFromClause().' '.
|
||||
'JOIN view_chill_person_current_address vcpca ON vcpca.person_id = person.id '.
|
||||
|
||||
Reference in New Issue
Block a user