Duplicate module

Signed-off-by: Mathieu Jaumotte <mathieu.jaumotte@champs-libres.coop>
This commit is contained in:
2021-03-21 14:06:37 +01:00
parent 728ea73bdf
commit 0149457fba
12 changed files with 292 additions and 111 deletions

View File

@@ -18,6 +18,7 @@
*/
namespace Chill\PersonBundle\Search;
use Chill\PersonBundle\Entity\PersonNotDuplicate;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
@@ -32,6 +33,10 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter;
*/
class SimilarPersonMatcher
{
CONST SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL = 'alphabetical';
CONST SIMILAR_SEARCH_ORDER_BY_SIMILARITY = 'similarity';
/**
*
* @var EntityManagerInterface
@@ -61,32 +66,50 @@ class SimilarPersonMatcher
}
public function matchPerson(Person $person, $precision = 0.15)
public function matchPerson(Person $person, $precision = 0.15, $orderBy = self::SIMILAR_SEARCH_ORDER_BY_SIMILARITY)
{
$centers = $this->authorizationHelper->getReachableCenters(
$this->tokenStorage->getToken()->getUser(),
new Role(PersonVoter::SEE)
);
$dql = 'SELECT p from ChillPersonBundle:Person p '
. ' WHERE ('
. ' SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) >= :precision '
. ' OR SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullNameInverted))) >= :precision '
. ' ) '
. ' AND p.center IN (:centers)'
. ' AND p.id != :personId'
. ' ORDER BY SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) DESC '
. ' AND p.id != :personId '
;
$notDuplicatePersons = $this->em->getRepository(PersonNotDuplicate::class)
->findNotDuplicatePerson($person);
if (count($notDuplicatePersons)) {
$dql .= ' AND p.id not in (:notDuplicatePersons)';
}
switch ($orderBy) {
case self::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL:
$dql .= ' ORDER BY p.fullnameCanonical ASC ';
break;
case self::SIMILAR_SEARCH_ORDER_BY_SIMILARITY:
default :
$dql .= ' ORDER BY SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) DESC ';
}
$query = $this->em
->createQuery($dql)
->setParameter('fullName', $person->getFirstName() . ' ' . $person->getLastName())
->setParameter('fullNameInverted', $person->getLastName() . ' ' . $person->getFirstName())
->setParameter('centers', $centers)
->setParameter('personId', $person->getId())
->setParameter('precision', $precision)
;
if (count($notDuplicatePersons)) {
$query->setParameter('notDuplicatePersons', $notDuplicatePersons);
}
return $query->getResult();
}
}