Add shortcut person <-> current address, and update api for

re-implements searching

* add geographic function ST_CONTAINS
* add a link between the current valid address and person, optimized on
database side;
* update PersonACLAwareRepository for re-using methods elsewhere.
This commit is contained in:
2021-09-16 16:43:38 +02:00
parent 50b7554aea
commit ebb2f5d243
5 changed files with 122 additions and 41 deletions

View File

@@ -60,17 +60,32 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$countryCode);
$this->addACLClauses($qb, 'p');
return $this->getQueryResult($qb, $simplify, $limit, $start);
}
/**
* Helper method to prepare and return the search query for PersonACL.
*
* This method replace the select clause with required parameters, depending on the
* "simplify" parameter. It also add query limits.
*
* The given alias must represent the person alias.
*
* @return array|Person[]
*/
public function getQueryResult(QueryBuilder $qb, string $alias, bool $simplify, int $limit, int $start): array
{
if ($simplify) {
$qb->select(
'p.id',
$alias.'.id',
$qb->expr()->concat(
'p.firstName',
$alias.'.firstName',
$qb->expr()->literal(' '),
'p.lastName'
$alias.'.lastName'
).'AS text'
);
} else {
$qb->select('p');
$qb->select($alias);
}
$qb
@@ -79,8 +94,8 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
//order by firstname, lastname
$qb
->orderBy('p.firstName')
->addOrderBy('p.lastName');
->orderBy($alias.'.firstName')
->addOrderBy($alias.'.lastName');
if ($simplify) {
return $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
@@ -104,7 +119,20 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$countryCode);
$this->addACLClauses($qb, 'p');
$qb->select('COUNT(p.id)');
return $this->getCountQueryResult($qb);
}
/**
* Helper method to prepare and return the count for search query
*
* This method replace the select clause with required parameters, depending on the
* "simplify" parameter.
*
* The given alias must represent the person alias in the query builder.
*/
public function getCountQueryResult(QueryBuilder $qb, $alias): int
{
$qb->select('COUNT('.$alias.'.id)');
return $qb->getQuery()->getSingleScalarResult();
}
@@ -115,33 +143,7 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$qb = $this->createSimilarityQuery($pattern);
$this->addACLClauses($qb, 'sp');
if ($simplify) {
$qb->select(
'sp.id',
$qb->expr()->concat(
'sp.firstName',
$qb->expr()->literal(' '),
'sp.lastName'
).'AS text'
);
} else {
$qb->select('sp');
}
$qb
->setMaxResults($maxResult)
->setFirstResult($firstResult);
//order by firstname, lastname
$qb
->orderBy('sp.firstName')
->addOrderBy('sp.lastName');
if ($simplify) {
return $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
} else {
return $qb->getQuery()->getResult();
}
return $this->getQueryResult($qb, 'sp', $simplify, $maxResult, $firstResult);
}
public function countBySimilaritySearch(string $pattern)
@@ -149,12 +151,27 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$qb = $this->createSimilarityQuery($pattern);
$this->addACLClauses($qb, 'sp');
$qb->select('COUNT(sp.id)');
return $qb->getQuery()->getSingleScalarResult();
return $this->getCountQueryResult($qb, 'sp');
}
private function createSearchQuery(
/**
* Create a search query without ACL
*
* The person alias is a "p"
*
* @param string|null $default
* @param string|null $firstname
* @param string|null $lastname
* @param \DateTime|null $birthdate
* @param \DateTime|null $birthdateBefore
* @param \DateTime|null $birthdateAfter
* @param string|null $gender
* @param string|null $countryCode
* @return QueryBuilder
* @throws NonUniqueResultException
* @throws ParsingException
*/
public function createSearchQuery(
string $default = null,
string $firstname = null,
string $lastname = null,
@@ -244,7 +261,15 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$qb->setParameter('centers', $reachableCenters);
}
private function createSimilarityQuery($pattern): QueryBuilder
/**
* Create a query for searching by similarity.
*
* The person alias is "sp".
*
* @param $pattern
* @return QueryBuilder
*/
public function createSimilarityQuery($pattern): QueryBuilder
{
$qb = $this->em->createQueryBuilder();