api endpoint for search household

This commit is contained in:
Julien Fastré 2022-01-29 01:14:30 +01:00
parent efff496f7a
commit bc90664480
4 changed files with 137 additions and 2 deletions

View File

@ -22,6 +22,10 @@ class SearchApiQuery
private array $fromClauseParams = []; private array $fromClauseParams = [];
private bool $isDistinct = false;
private ?string $isDistinctKey = null;
private ?string $jsonbMetadata = null; private ?string $jsonbMetadata = null;
private array $jsonbMetadataParams = []; private array $jsonbMetadataParams = [];
@ -105,6 +109,11 @@ class SearchApiQuery
]); ]);
} }
public function getDistinct(): bool
{
return $this->isDistinct;
}
public function getFromClause(): string public function getFromClause(): string
{ {
return $this->fromClause; return $this->fromClause;
@ -139,6 +148,14 @@ class SearchApiQuery
return $this; return $this;
} }
public function setDistinct(bool $distinct, string $distinctKey): self
{
$this->isDistinct = $distinct;
$this->isDistinctKey = $distinctKey;
return $this;
}
public function setFromClause(string $fromClause, array $params = []): self public function setFromClause(string $fromClause, array $params = []): self
{ {
$this->fromClause = $fromClause; $this->fromClause = $fromClause;
@ -185,7 +202,11 @@ class SearchApiQuery
private function buildSelectClause(bool $countOnly = false): string private function buildSelectClause(bool $countOnly = false): string
{ {
if ($countOnly) { if ($countOnly) {
return 'count(*) AS c'; if (!$this->isDistinct) {
return 'count(*) AS c';
}
return 'count(distinct ' . $this->isDistinctKey . ') AS c';
} }
$selects = $this->getSelectClauses(); $selects = $this->getSelectClauses();
@ -202,7 +223,7 @@ class SearchApiQuery
$selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]); $selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]);
} }
return implode(', ', $selects); return ($this->isDistinct ? 'DISTINCT ' : '') . implode(', ', $selects);
} }
private function buildSelectParams(bool $count = false): array private function buildSelectParams(bool $count = false): array

View File

@ -134,6 +134,7 @@ paths:
- search - search
- person - person
- thirdparty - thirdparty
- household
description: > description: >
The search is performed across multiple entities. The entities must be listed into The search is performed across multiple entities. The entities must be listed into
`type` parameters. `type` parameters.
@ -159,6 +160,7 @@ paths:
- person - person
- thirdparty - thirdparty
- user - user
- household
responses: responses:
200: 200:
description: "OK" description: "OK"

View File

@ -0,0 +1,108 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Search;
use Chill\MainBundle\Search\SearchApiInterface;
use Chill\MainBundle\Search\SearchApiQuery;
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
use Symfony\Component\Security\Core\Security;
use function array_map;
use function count;
use function in_array;
class SearchHouseholdApiProvider implements SearchApiInterface
{
private AuthorizationHelperInterface $authorizationHelper;
private ExtractDateFromPattern $extractDateFromPattern;
private ExtractPhonenumberFromPattern $extractPhonenumberFromPattern;
private HouseholdRepository $householdRepository;
private PersonACLAwareRepositoryInterface $personACLAwareRepository;
private Security $security;
public function __construct(
HouseholdRepository $householdRepository,
PersonACLAwareRepositoryInterface $personACLAwareRepository,
Security $security,
AuthorizationHelperInterface $authorizationHelper,
ExtractDateFromPattern $extractDateFromPattern,
ExtractPhonenumberFromPattern $extractPhonenumberFromPattern
) {
$this->householdRepository = $householdRepository;
$this->personACLAwareRepository = $personACLAwareRepository;
$this->security = $security;
$this->authorizationHelper = $authorizationHelper;
$this->extractDateFromPattern = $extractDateFromPattern;
$this->extractPhonenumberFromPattern = $extractPhonenumberFromPattern;
}
public function getResult(string $key, array $metadata, float $pertinence)
{
return $this->householdRepository->find($metadata['id']);
}
public function prepare(array $metadatas): void
{
$ids = array_map(static fn ($m) => $m['id'], $metadatas);
$this->householdRepository->findBy(['id' => $ids]);
}
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
{
$datesResult = $this->extractDateFromPattern->extractDates($pattern);
$phoneResult = $this->extractPhonenumberFromPattern->extractPhonenumber($datesResult->getFilteredSubject());
$filtered = $phoneResult->getFilteredSubject();
$query = $this->personACLAwareRepository->buildAuthorizedQuery(
$filtered,
null,
null,
count($datesResult->getFound()) > 0 ? $datesResult->getFound()[0] : null,
null,
null,
null,
null,
count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
);
$query
->setDistinct(true, 'household_id')
->setFromClause(
'view_chill_person_household_address AS vcpha ' .
'JOIN chill_person_person AS person ON vcpha.person_id = person.id'
)
->setSelectKey('household')
->setSelectJsonbMetadata("jsonb_build_object('id', vcpha.household_id)");
return $query;
}
public function supportsResult(string $key, array $metadatas): bool
{
return 'household' === $key;
}
public function supportsTypes(string $pattern, array $types, array $parameters): bool
{
return in_array('household', $types, true);
}
}

View File

@ -11,3 +11,7 @@ services:
Chill\PersonBundle\Search\SearchPersonApiProvider: Chill\PersonBundle\Search\SearchPersonApiProvider:
autowire: true autowire: true
autoconfigure: true autoconfigure: true
Chill\PersonBundle\Search\SearchHouseholdApiProvider:
autowire: true
autoconfigure: true