delegate person matching detection to service SimilarPersonMatcher

This commit is contained in:
Julien Fastré 2018-05-14 17:58:00 +02:00
parent db00a0d265
commit 983ed7a50d
6 changed files with 128 additions and 40 deletions

View File

@ -30,9 +30,21 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
class PersonController extends Controller
{
/**
*
* @var SimilarPersonMatcher
*/
protected $similarPersonMatcher;
public function __construct(SimilarPersonMatcher $similarPersonMatcher)
{
$this->similarPersonMatcher = $similarPersonMatcher;
}
public function getCFGroup()
{
$cFGroup = null;
@ -266,35 +278,8 @@ class PersonController extends Controller
$this->get('logger')->info('Person created without errors');
}
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery();
$dql = 'SELECT p from ChillPersonBundle:Person p WHERE '
. 'LOWER(p.firstName) LIKE LOWER(:firstName)'
. ' OR LOWER(p.lastName) LIKE LOWER(:lastName)'
. ' OR LOWER(p.firstName) LIKE LOWER(:lastName)'
. ' OR LOWER(p.lastName) LIKE LOWER(:firstName)';
$query->setParameter('firstName', $form['firstName']->getData())
->setParameter('lastName', $form['lastName']->getData());
if ($this->container
->getParameter('cl_chill_person.search.use_double_metaphone')) {
$dql .= ' OR DOUBLEMETAPHONE(p.lastName) LIKE DOUBLEMETAPHONE(:lastName) ';
}
// add authorized centers
$centers = $this->get('chill.main.security.authorization.helper')
->getReachableCenters($this->getUser(), new Role(PersonVoter::SEE));
$dql.=' and p.center IN (:centers) ';
$query->setParameter('centers', $centers);
// run query
$query->setDql($dql);
$alternatePersons = $query->getResult();
$alternatePersons = $this->similarPersonMatcher
->matchPerson($person);
if (count($alternatePersons) === 0) {
return $this->forward('ChillPersonBundle:Person:create');

View File

@ -58,6 +58,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$loader->load('services/widgets.yml');
$loader->load('services/exports.yml');
$loader->load('services/fixtures.yml');
$loader->load('services/controller.yml');
$loader->load('services/search.yml');
}
private function handlePersonFieldsParameters(ContainerBuilder $container, $config)

View File

@ -16,17 +16,6 @@ services:
tags:
- { name: form.type, alias: closing_motive }
chill.person.search_person:
class: Chill\PersonBundle\Search\PersonSearch
arguments:
- "@doctrine.orm.entity_manager"
- "@security.token_storage"
- "@chill.main.security.authorization.helper"
- "@chill_main.paginator_factory"
calls:
- ['setContainer', ["@service_container"]]
tags:
- { name: chill.search, alias: 'person_regular' }
chill.person.form.type.select2maritalstatus:
class: Chill\PersonBundle\Form\Type\Select2MaritalStatusType
arguments:

View File

@ -0,0 +1,5 @@
services:
Chill\PersonBundle\Controller\PersonController:
arguments:
$similarPersonMatcher: '@Chill\PersonBundle\Search\SimilarPersonMatcher'
tags: ['controller.service_arguments']

View File

@ -0,0 +1,18 @@
services:
chill.person.search_person:
class: Chill\PersonBundle\Search\PersonSearch
arguments:
- "@doctrine.orm.entity_manager"
- "@security.token_storage"
- "@chill.main.security.authorization.helper"
- "@chill_main.paginator_factory"
calls:
- ['setContainer', ["@service_container"]]
tags:
- { name: chill.search, alias: 'person_regular' }
Chill\PersonBundle\Search\SimilarPersonMatcher:
arguments:
$em: '@Doctrine\ORM\EntityManagerInterface'
$tokenStorage: '@Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'

View File

@ -0,0 +1,89 @@
<?php
/*
*
* Copyright (C) 2018, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\Search;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class SimilarPersonMatcher
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
*
* @var TokenStorageInterface
*/
protected $tokenStorage;
public function __construct(
EntityManagerInterface $em,
AuthorizationHelper $authorizationHelper,
TokenStorageInterface $tokenStorage
) {
$this->em = $em;
$this->authorizationHelper = $authorizationHelper;
$this->tokenStorage = $tokenStorage;
}
public function matchPerson(Person $person)
{
$centers = $this->authorizationHelper
->getReachableCenters(
$this->tokenStorage->getToken()->getUser(),
new Role(PersonVoter::SEE)
);
$dql = 'SELECT p from ChillPersonBundle:Person p WHERE'
. ' UNACCENT(LOWER(p.firstName)) LIKE UNACCENT(LOWER(:firstName))'
. ' OR UNACCENT(LOWER(p.lastName)) LIKE UNACCENT(LOWER(:lastName))'
. ' OR UNACCENT(LOWER(p.firstName)) LIKE UNACCENT(LOWER(:lastName))'
. ' OR UNACCENT(LOWER(p.lastName)) LIKE UNACCENT(LOWER(:firstName))'
. ' AND p.center IN (:centers)';
$query =
$this->em
->createQuery($dql)
->setParameter('firstName', $person->getFirstName())
->setParameter('lastName', $person->getLastName())
->setParameter('centers', $centers)
;
return $query->getResult();
}
}