mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-21 07:03:49 +00:00
cs: Fix code style (safe rules only).
This commit is contained in:
@@ -1,33 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Repository\CountryRepository;
|
||||
use Chill\MainBundle\Search\ParsingException;
|
||||
use Chill\MainBundle\Search\SearchApi;
|
||||
use Chill\MainBundle\Search\SearchApiQuery;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
use function array_fill;
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function array_push;
|
||||
use function explode;
|
||||
use function implode;
|
||||
|
||||
final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterface
|
||||
{
|
||||
private Security $security;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
private AuthorizationHelper $authorizationHelper;
|
||||
|
||||
private CountryRepository $countryRepository;
|
||||
|
||||
private AuthorizationHelper $authorizationHelper;
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
private Security $security;
|
||||
|
||||
public function __construct(
|
||||
Security $security,
|
||||
@@ -41,53 +50,182 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|Person[]
|
||||
* @throws NonUniqueResultException
|
||||
* @throws ParsingException
|
||||
*/
|
||||
public function findBySearchCriteria(
|
||||
int $start,
|
||||
int $limit,
|
||||
bool $simplify = false,
|
||||
string $default = null,
|
||||
string $firstname = null,
|
||||
string $lastname = null,
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
string $gender = null,
|
||||
string $countryCode = null,
|
||||
string $phonenumber = null,
|
||||
string $city = null
|
||||
): array {
|
||||
$query = $this->buildAuthorizedQuery($default, $firstname, $lastname,
|
||||
$birthdate, $birthdateBefore, $birthdateAfter, $gender,
|
||||
$countryCode, $phonenumber, $city);
|
||||
public function buildAuthorizedQuery(
|
||||
?string $default = null,
|
||||
?string $firstname = null,
|
||||
?string $lastname = null,
|
||||
?DateTimeInterface $birthdate = null,
|
||||
?DateTimeInterface $birthdateBefore = null,
|
||||
?DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null
|
||||
): SearchApiQuery {
|
||||
$query = $this->createSearchQuery(
|
||||
$default,
|
||||
$firstname,
|
||||
$lastname,
|
||||
$birthdate,
|
||||
$birthdateBefore,
|
||||
$birthdateAfter,
|
||||
$gender,
|
||||
$countryCode,
|
||||
$phonenumber
|
||||
);
|
||||
|
||||
return $this->fetchQueryPerson($query);
|
||||
return $this->addAuthorizations($query);
|
||||
}
|
||||
|
||||
public function countBySearchCriteria(
|
||||
string $default = null,
|
||||
string $firstname = null,
|
||||
string $lastname = null,
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
string $gender = null,
|
||||
string $countryCode = null,
|
||||
string $phonenumber = null,
|
||||
string $city = null
|
||||
?string $default = null,
|
||||
?string $firstname = null,
|
||||
?string $lastname = null,
|
||||
?DateTimeInterface $birthdate = null,
|
||||
?DateTimeInterface $birthdateBefore = null,
|
||||
?DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null
|
||||
): int {
|
||||
$query = $this->buildAuthorizedQuery($default, $firstname, $lastname,
|
||||
$birthdate, $birthdateBefore, $birthdateAfter, $gender,
|
||||
$countryCode, $phonenumber, $city)
|
||||
;
|
||||
$query = $this->buildAuthorizedQuery(
|
||||
$default,
|
||||
$firstname,
|
||||
$lastname,
|
||||
$birthdate,
|
||||
$birthdateBefore,
|
||||
$birthdateAfter,
|
||||
$gender,
|
||||
$countryCode,
|
||||
$phonenumber,
|
||||
$city
|
||||
);
|
||||
|
||||
return $this->fetchQueryCount($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a search query without ACL.
|
||||
*
|
||||
* @throws NonUniqueResultException
|
||||
* @throws ParsingException
|
||||
*/
|
||||
public function createSearchQuery(
|
||||
?string $default = null,
|
||||
?string $firstname = null,
|
||||
?string $lastname = null,
|
||||
?DateTimeInterface $birthdate = null,
|
||||
?DateTimeInterface $birthdateBefore = null,
|
||||
?DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null
|
||||
): SearchApiQuery {
|
||||
$query = new SearchApiQuery();
|
||||
$query
|
||||
->setFromClause('chill_person_person AS person');
|
||||
|
||||
$pertinence = [];
|
||||
$pertinenceArgs = [];
|
||||
$orWhereSearchClause = [];
|
||||
$orWhereSearchClauseArgs = [];
|
||||
|
||||
if ('' !== $default) {
|
||||
foreach (explode(' ', $default) as $str) {
|
||||
$pertinence[] =
|
||||
'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";
|
||||
array_push($pertinenceArgs, $str, $str, $str);
|
||||
|
||||
$orWhereSearchClause[] =
|
||||
'(LOWER(UNACCENT(?)) <<% person.fullnamecanonical OR ' .
|
||||
"person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%' )";
|
||||
array_push($orWhereSearchClauseArgs, $str, $str);
|
||||
}
|
||||
|
||||
$query->andWhereClause(
|
||||
implode(' OR ', $orWhereSearchClause),
|
||||
$orWhereSearchClauseArgs
|
||||
);
|
||||
} else {
|
||||
$pertinence = ['1'];
|
||||
$pertinenceArgs = [];
|
||||
}
|
||||
$query
|
||||
->setSelectPertinence(implode(' + ', $pertinence), $pertinenceArgs);
|
||||
|
||||
if (null !== $birthdate) {
|
||||
$query->andWhereClause(
|
||||
'person.birthdate = ?::date',
|
||||
[$birthdate->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $firstname) {
|
||||
$query->andWhereClause(
|
||||
"UNACCENT(LOWER(person.firstname)) LIKE '%' || UNACCENT(LOWER(?)) || '%'",
|
||||
[$firstname]
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $lastname) {
|
||||
$query->andWhereClause(
|
||||
"UNACCENT(LOWER(person.lastname)) LIKE '%' || UNACCENT(LOWER(?)) || '%'",
|
||||
[$lastname]
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $birthdateBefore) {
|
||||
$query->andWhereClause(
|
||||
'p.birthdate < ?::date',
|
||||
[$birthdateBefore->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $birthdateAfter) {
|
||||
$query->andWhereClause(
|
||||
'p.birthdate > ?::date',
|
||||
[$birthdateAfter->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
|
||||
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 ' .
|
||||
'JOIN chill_main_address cma ON vcpca.address_id = cma.id ' .
|
||||
'JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id');
|
||||
|
||||
foreach (explode(' ', $city) as $cityStr) {
|
||||
$query->andWhereClause(
|
||||
"(UNACCENT(LOWER(cmpc.label)) LIKE '%' || UNACCENT(LOWER(?)) || '%' OR cmpc.code LIKE '%' || UNACCENT(LOWER(?)) || '%')",
|
||||
[$cityStr, $city]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $countryCode) {
|
||||
$query->setFromClause($query->getFromClause() . ' JOIN country ON person.nationality_id = country.id');
|
||||
$query->andWhereClause('country.countrycode = UPPER(?)', [$countryCode]);
|
||||
}
|
||||
|
||||
if (null !== $gender) {
|
||||
$query->andWhereClause('person.gender = ?', [$gender]);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function fetchQueryCount(SearchApiQuery $query): int
|
||||
{
|
||||
$rsm = new Query\ResultSetMapping();
|
||||
@@ -110,30 +248,48 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
||||
$query->addSelectClause($rsm->generateSelectClause());
|
||||
|
||||
$nql = $this->em->createNativeQuery(
|
||||
$query->buildQuery()." ORDER BY pertinence DESC OFFSET ? LIMIT ?", $rsm
|
||||
)->setParameters(\array_merge($query->buildParameters(), [$start, $limit]));
|
||||
$query->buildQuery() . ' ORDER BY pertinence DESC OFFSET ? LIMIT ?',
|
||||
$rsm
|
||||
)->setParameters(array_merge($query->buildParameters(), [$start, $limit]));
|
||||
|
||||
return $nql->getResult();
|
||||
}
|
||||
|
||||
public function buildAuthorizedQuery(
|
||||
string $default = null,
|
||||
string $firstname = null,
|
||||
string $lastname = null,
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
string $gender = null,
|
||||
string $countryCode = null,
|
||||
string $phonenumber = null,
|
||||
string $city = null
|
||||
): SearchApiQuery {
|
||||
$query = $this->createSearchQuery($default, $firstname, $lastname,
|
||||
$birthdate, $birthdateBefore, $birthdateAfter, $gender,
|
||||
$countryCode, $phonenumber)
|
||||
;
|
||||
/**
|
||||
* @throws NonUniqueResultException
|
||||
* @throws ParsingException
|
||||
*
|
||||
* @return array|Person[]
|
||||
*/
|
||||
public function findBySearchCriteria(
|
||||
int $start,
|
||||
int $limit,
|
||||
bool $simplify = false,
|
||||
?string $default = null,
|
||||
?string $firstname = null,
|
||||
?string $lastname = null,
|
||||
?DateTimeInterface $birthdate = null,
|
||||
?DateTimeInterface $birthdateBefore = null,
|
||||
?DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null
|
||||
): array {
|
||||
$query = $this->buildAuthorizedQuery(
|
||||
$default,
|
||||
$firstname,
|
||||
$lastname,
|
||||
$birthdate,
|
||||
$birthdateBefore,
|
||||
$birthdateAfter,
|
||||
$gender,
|
||||
$countryCode,
|
||||
$phonenumber,
|
||||
$city
|
||||
);
|
||||
|
||||
return $this->addAuthorizations($query);
|
||||
return $this->fetchQueryPerson($query);
|
||||
}
|
||||
|
||||
private function addAuthorizations(SearchApiQuery $query): SearchApiQuery
|
||||
@@ -142,133 +298,21 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
||||
->getReachableCenters($this->security->getUser(), PersonVoter::SEE);
|
||||
|
||||
if ([] === $authorizedCenters) {
|
||||
return $query->andWhereClause("FALSE = TRUE", []);
|
||||
return $query->andWhereClause('FALSE = TRUE', []);
|
||||
}
|
||||
|
||||
return $query
|
||||
->andWhereClause(
|
||||
strtr(
|
||||
"person.center_id IN ({{ center_ids }})",
|
||||
'person.center_id IN ({{ center_ids }})',
|
||||
[
|
||||
'{{ center_ids }}' => \implode(', ',
|
||||
\array_fill(0, count($authorizedCenters), '?')),
|
||||
'{{ center_ids }}' => implode(
|
||||
', ',
|
||||
array_fill(0, count($authorizedCenters), '?')
|
||||
),
|
||||
]
|
||||
),
|
||||
\array_map(function(Center $c) {return $c->getId();}, $authorizedCenters)
|
||||
array_map(function (Center $c) {return $c->getId(); }, $authorizedCenters)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a search query without ACL
|
||||
*
|
||||
* @throws NonUniqueResultException
|
||||
* @throws ParsingException
|
||||
*/
|
||||
public function createSearchQuery(
|
||||
string $default = null,
|
||||
string $firstname = null,
|
||||
string $lastname = null,
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
string $gender = null,
|
||||
string $countryCode = null,
|
||||
string $phonenumber = null,
|
||||
string $city = null
|
||||
): SearchApiQuery {
|
||||
$query = new SearchApiQuery();
|
||||
$query
|
||||
->setFromClause("chill_person_person AS person")
|
||||
;
|
||||
|
||||
$pertinence = [];
|
||||
$pertinenceArgs = [];
|
||||
$orWhereSearchClause = [];
|
||||
$orWhereSearchClauseArgs = [];
|
||||
|
||||
if ("" !== $default) {
|
||||
foreach (\explode(" ", $default) as $str) {
|
||||
$pertinence[] =
|
||||
"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";
|
||||
\array_push($pertinenceArgs, $str, $str, $str);
|
||||
|
||||
$orWhereSearchClause[] =
|
||||
"(LOWER(UNACCENT(?)) <<% person.fullnamecanonical OR ".
|
||||
"person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%' )";
|
||||
\array_push($orWhereSearchClauseArgs, $str, $str);
|
||||
}
|
||||
|
||||
$query->andWhereClause(\implode(' OR ', $orWhereSearchClause),
|
||||
$orWhereSearchClauseArgs);
|
||||
} else {
|
||||
$pertinence = ["1"];
|
||||
$pertinenceArgs = [];
|
||||
}
|
||||
$query
|
||||
->setSelectPertinence(\implode(' + ', $pertinence), $pertinenceArgs)
|
||||
;
|
||||
|
||||
if (NULL !== $birthdate) {
|
||||
$query->andWhereClause(
|
||||
"person.birthdate = ?::date",
|
||||
[$birthdate->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
if (NULL !== $firstname) {
|
||||
$query->andWhereClause(
|
||||
"UNACCENT(LOWER(person.firstname)) LIKE '%' || UNACCENT(LOWER(?)) || '%'",
|
||||
[$firstname]
|
||||
);
|
||||
}
|
||||
if (NULL !== $lastname) {
|
||||
$query->andWhereClause(
|
||||
"UNACCENT(LOWER(person.lastname)) LIKE '%' || UNACCENT(LOWER(?)) || '%'",
|
||||
[$lastname]
|
||||
);
|
||||
}
|
||||
if (NULL !== $birthdateBefore) {
|
||||
$query->andWhereClause(
|
||||
'p.birthdate < ?::date',
|
||||
[$birthdateBefore->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
if (NULL !== $birthdateAfter) {
|
||||
$query->andWhereClause(
|
||||
'p.birthdate > ?::date',
|
||||
[$birthdateAfter->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
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 ".
|
||||
"JOIN chill_main_address cma ON vcpca.address_id = cma.id ".
|
||||
"JOIN chill_main_postal_code cmpc ON cma.postcode_id = cmpc.id");
|
||||
|
||||
foreach (\explode(" ", $city) as $cityStr) {
|
||||
$query->andWhereClause(
|
||||
"(UNACCENT(LOWER(cmpc.label)) LIKE '%' || UNACCENT(LOWER(?)) || '%' OR cmpc.code LIKE '%' || UNACCENT(LOWER(?)) || '%')",
|
||||
[$cityStr, $city]
|
||||
);
|
||||
}
|
||||
}
|
||||
if (null !== $countryCode) {
|
||||
$query->setFromClause($query->getFromClause()." JOIN country ON person.nationality_id = country.id");
|
||||
$query->andWhereClause("country.countrycode = UPPER(?)", [$countryCode]);
|
||||
}
|
||||
if (null !== $gender) {
|
||||
$query->andWhereClause("person.gender = ?", [$gender]);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user