From 9e69c972508980ad9092f7cbf65979cfb3d7726c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 26 Sep 2024 14:17:19 +0200 Subject: [PATCH] Add search functionality for user groups Implemented `SearchUserGroupApiProvider` to handle user group search requests. Added `UserGroupRepository` and its interface to support search queries. Updated API specs to include user group as a searchable type. --- .../Repository/UserGroupRepository.php | 68 +++++++++++++++++++ .../UserGroupRepositoryInterface.php | 27 ++++++++ .../Entity/SearchUserGroupApiProvider.php | 59 ++++++++++++++++ .../Repository/UserGroupRepositoryTest.php | 50 ++++++++++++++ .../ChillMainBundle/chill.api.specs.yaml | 1 + 5 files changed, 205 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/Repository/UserGroupRepository.php create mode 100644 src/Bundle/ChillMainBundle/Repository/UserGroupRepositoryInterface.php create mode 100644 src/Bundle/ChillMainBundle/Search/Entity/SearchUserGroupApiProvider.php create mode 100644 src/Bundle/ChillMainBundle/Tests/Repository/UserGroupRepositoryTest.php diff --git a/src/Bundle/ChillMainBundle/Repository/UserGroupRepository.php b/src/Bundle/ChillMainBundle/Repository/UserGroupRepository.php new file mode 100644 index 000000000..aa2d6f5f5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/UserGroupRepository.php @@ -0,0 +1,68 @@ +repository = $em->getRepository(UserGroup::class); + } + + public function find($id): ?UserGroup + { + return $this->repository->find($id); + } + + public function findAll(): array + { + return $this->repository->findAll(); + } + + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?UserGroup + { + return $this->repository->findOneBy($criteria); + } + + public function getClassName(): string + { + return UserGroup::class; + } + + public function provideSearchApiQuery(string $pattern, string $lang, string $selectKey = 'user-group'): SearchApiQuery + { + $query = new SearchApiQuery(); + $query + ->setSelectKey($selectKey) + ->setSelectJsonbMetadata("jsonb_build_object('id', ug.id)") + ->setSelectPertinence('3 + SIMILARITY(LOWER(UNACCENT(?)), ug.label->>?) + CASE WHEN (EXISTS(SELECT 1 FROM unnest(string_to_array(label->>?, \' \')) AS t WHERE LOWER(t) LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\')) THEN 100 ELSE 0 END', [$pattern, $lang, $lang, $pattern]) + ->setFromClause('chill_main_user_group AS ug') + ->setWhereClauses(' + SIMILARITY(LOWER(UNACCENT(?)), ug.label->>?) > 0.15 + OR ug.label->>? LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\' + ', [$pattern, $lang, $pattern, $lang]); + + return $query; + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/UserGroupRepositoryInterface.php b/src/Bundle/ChillMainBundle/Repository/UserGroupRepositoryInterface.php new file mode 100644 index 000000000..9512e7b25 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/UserGroupRepositoryInterface.php @@ -0,0 +1,27 @@ + + */ +interface UserGroupRepositoryInterface extends ObjectRepository +{ + /** + * Provide a SearchApiQuery for searching amongst user groups. + */ + public function provideSearchApiQuery(string $pattern, string $lang, string $selectKey = 'user-group'): SearchApiQuery; +} diff --git a/src/Bundle/ChillMainBundle/Search/Entity/SearchUserGroupApiProvider.php b/src/Bundle/ChillMainBundle/Search/Entity/SearchUserGroupApiProvider.php new file mode 100644 index 000000000..acdd99976 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Search/Entity/SearchUserGroupApiProvider.php @@ -0,0 +1,59 @@ +locale = $locale; + } + + public function getLocale(): string + { + return $this->locale; + } + + public function getResult(string $key, array $metadata, float $pertinence) + { + return $this->userGroupRepository->find($metadata['id']); + } + + public function prepare(array $metadatas): void {} + + public function provideQuery(string $pattern, array $parameters): SearchApiQuery + { + return $this->userGroupRepository->provideSearchApiQuery($pattern, $this->getLocale(), 'user-group'); + } + + public function supportsResult(string $key, array $metadatas): bool + { + return 'user-group' === $key; + } + + public function supportsTypes(string $pattern, array $types, array $parameters): bool + { + return in_array('user-group', $types, true); + } +} diff --git a/src/Bundle/ChillMainBundle/Tests/Repository/UserGroupRepositoryTest.php b/src/Bundle/ChillMainBundle/Tests/Repository/UserGroupRepositoryTest.php new file mode 100644 index 000000000..1ea243541 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Repository/UserGroupRepositoryTest.php @@ -0,0 +1,50 @@ +entityManager = static::getContainer()->get(EntityManagerInterface::class); + + } + + public function testProvideSearchApiQuery(): void + { + $repository = new UserGroupRepository($this->entityManager); + + $apiQuery = $repository->provideSearchApiQuery('trav', 'fr'); + + // test that the query does works + $sql = $apiQuery->buildQuery(); + $params = $apiQuery->buildParameters(); + + $result = $this->entityManager->getConnection()->executeQuery($sql, $params); + $results = $result->fetchAllAssociative(); + + self::assertIsArray($results); + + } +} diff --git a/src/Bundle/ChillMainBundle/chill.api.specs.yaml b/src/Bundle/ChillMainBundle/chill.api.specs.yaml index b31669043..ea1ae10bd 100644 --- a/src/Bundle/ChillMainBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillMainBundle/chill.api.specs.yaml @@ -236,6 +236,7 @@ paths: - thirdparty - user - household + - user-group responses: 200: description: "OK"