diff --git a/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php b/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php index 2fcea304d..57193a96d 100644 --- a/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php +++ b/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php @@ -22,6 +22,10 @@ class SearchApiQuery private array $fromClauseParams = []; + private bool $isDistinct = false; + + private ?string $isDistinctKey = null; + private ?string $jsonbMetadata = null; private array $jsonbMetadataParams = []; @@ -105,6 +109,11 @@ class SearchApiQuery ]); } + public function getDistinct(): bool + { + return $this->isDistinct; + } + public function getFromClause(): string { return $this->fromClause; @@ -139,6 +148,14 @@ class SearchApiQuery 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 { $this->fromClause = $fromClause; @@ -185,7 +202,11 @@ class SearchApiQuery private function buildSelectClause(bool $countOnly = false): string { if ($countOnly) { - return 'count(*) AS c'; + if (!$this->isDistinct) { + return 'count(*) AS c'; + } + + return 'count(distinct ' . $this->isDistinctKey . ') AS c'; } $selects = $this->getSelectClauses(); @@ -202,7 +223,7 @@ class SearchApiQuery $selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]); } - return implode(', ', $selects); + return ($this->isDistinct ? 'DISTINCT ' : '') . implode(', ', $selects); } private function buildSelectParams(bool $count = false): array diff --git a/src/Bundle/ChillMainBundle/chill.api.specs.yaml b/src/Bundle/ChillMainBundle/chill.api.specs.yaml index 4f2e3648e..034dfe74b 100644 --- a/src/Bundle/ChillMainBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillMainBundle/chill.api.specs.yaml @@ -134,6 +134,7 @@ paths: - search - person - thirdparty + - household description: > The search is performed across multiple entities. The entities must be listed into `type` parameters. @@ -159,6 +160,7 @@ paths: - person - thirdparty - user + - household responses: 200: description: "OK" diff --git a/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php b/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php new file mode 100644 index 000000000..bc2cf23f8 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php @@ -0,0 +1,108 @@ +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); + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/search.yaml b/src/Bundle/ChillPersonBundle/config/services/search.yaml index 5428c8105..d700eef19 100644 --- a/src/Bundle/ChillPersonBundle/config/services/search.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/search.yaml @@ -11,3 +11,7 @@ services: Chill\PersonBundle\Search\SearchPersonApiProvider: autowire: true autoconfigure: true + + Chill\PersonBundle\Search\SearchHouseholdApiProvider: + autowire: true + autoconfigure: true