From ccfa66f3ef8f6ef7c924d92b413b783fae4da1be Mon Sep 17 00:00:00 2001
From: pfleu <fleutotp@gmail.com>
Date: Mon, 13 Feb 2023 10:50:49 +0100
Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20messages=20d'erreur=20404.?=
 =?UTF-8?q?=20Ajout=20endpoint=20search=20Lexicons.=20Modif=20endpoint=20e?=
 =?UTF-8?q?xtract=20lexicons=20:=20on=20retourne=20toutes=20les=20graphies?=
 =?UTF-8?q?=20si=20nb=20demand=C3=A9=20=3D=20z=C3=A9ro?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/Controller/ApiLexiconController.php | 75 ++++++++++++++++++++++++-
 src/Controller/ApiTraceController.php   |  6 +-
 src/Entity/Group.php                    |  2 +
 src/Entity/Lexicon.php                  |  8 +++
 src/Normalizer/ApiProblemNormalizer.php |  8 ++-
 src/Repository/LexiconRepository.php    | 35 ++++++++++++
 6 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/src/Controller/ApiLexiconController.php b/src/Controller/ApiLexiconController.php
index a1b6109..68f4110 100644
--- a/src/Controller/ApiLexiconController.php
+++ b/src/Controller/ApiLexiconController.php
@@ -132,7 +132,7 @@ class ApiLexiconController extends ApiBaseController
     /**
      * Récupère un nombre n de graphies d’un lexique
      *
-     * @Route("/extract/{nb}", name="api_lexicon_extract_graphies", methods={"GET"})
+     * @Route("/extract/{nb}", name="api_lexicon_extract_graphies", methods={"GET"}, requirements={"id" = "\d+"})
      * @OA\Parameter(name="nb", in="path", description="nb de graphies retournées", @OA\Schema(type="integer"))
      * @OA\Parameter(name="lexiconId", in="query", required=true, description="id du lexique dans lequel chercher", @OA\Schema(type="string"))
      *
@@ -163,7 +163,7 @@ class ApiLexiconController extends ApiBaseController
             }
         }
         shuffle($graphies);
-        $selectedGraphies = array_slice($graphies, 0, $nb);
+        $selectedGraphies = $nb > 0 ? array_slice($graphies, 0, $nb) : $graphies;
 
         return $this->createJsonResponse(200, $selectedGraphies);
     }
@@ -257,4 +257,75 @@ class ApiLexiconController extends ApiBaseController
 
         return $this->createJsonResponse();
     }
+
+    /**
+     * Recherche de lexiques par catégorie ou id user ou id groupe ou langue
+     *
+     * @Route("/search", name="api_lexicon_search", methods={"GET"})
+     *
+     * @OA\Response(response=200, description="success",
+     *      @OA\JsonContent(type="array",
+     *          @OA\Items(ref=@Model(type=Lexicon::class, groups={"lexicon:read"})))
+     * )
+     * @OA\Response(response=401, description="error", @OA\JsonContent(type="string"))
+     * @OA\Response(response=403, description="error", @OA\JsonContent(type="string"))
+     * @OA\Response(response=500, description="error", @OA\JsonContent(type="string"))
+     *
+     * @OA\Parameter(name="user_id", in="query", @OA\Schema(type="integer", example="4"))
+     * @OA\Parameter(name="group_id", in="query", @OA\Schema(type="integer", example="1"))
+     * @OA\Parameter(name="category", in="query", @OA\Schema(type="string", example="User ou Group ou Zero ou New words"))
+     * @OA\Parameter(name="language", in="query", @OA\Schema(type="string", example="en"))
+     *
+     * @OA\Tag(name="Lexicons")
+     * @Security(name="OAuth2")
+     */
+    public function search(Request $request, SerializerInterface $serializer): Response
+    {
+        $userId    = $request->get('user_id');
+        $groupId   = $request->get('group_id');
+        $category  = $request->get('category');
+        $language  = $request->get('language');
+        if (!$groupId && !$category && !$userId && !$language) {
+            return $this->createJsonResponse(401, ['error' => sprintf("Veuillez spécifier au moins un paramètre de recherche parmi: group_id, category, user_id, language")]);
+        }
+        if ($category && !in_array($category, Lexicon::LEXICON_TYPES)) {
+            return $this->createJsonResponse(401, ['error' => sprintf("La catégorie de lexique %s n'existe pas", $category)]);
+        }
+        if ($language && !in_array($language, $this->getLanguages())) {
+            return $this->createJsonResponse(401, ['error' => sprintf("Pas de langue trouvée pour: %s", $language)]);
+        }
+
+        $filter = [];
+        if ($userId ?? null) {
+            $user = $this->doctrine->getRepository(User::class)->find($userId);
+            if (!$user) {
+                return $this->createJsonResponse(401, ['error' => sprintf("Pas d'utilisateur trouvé pour l'id %s", $userId)]);
+            } else {
+                $filter['user'] = $user;
+            }
+        }
+        if ($groupId ?? null) {
+            $group = $this->doctrine->getRepository(User::class)->find($groupId);
+            if (!$group) {
+                return $this->createJsonResponse(401, ['error' => sprintf("Pas de groupe trouvé pour l'id %s", $groupId)]);
+            } else {
+                $filter['group'] = $group;
+            }
+        }
+        if ($category ?? null) {
+            $filter['category'] = $category;
+        }
+        if ($language ?? null) {
+            $filter['language'] = $language;
+        }
+
+        $lexicons = $this->doctrine->getRepository(Lexicon::class)->search($filter);
+
+        $content = $serializer->serialize($lexicons, 'json', [
+            'groups' => ["lexicon:read", "user:read", "group:read"],
+            'datetime_format' => 'Y-m-d h:i:s.u'
+        ]);
+
+        return new JsonResponse($content, 200, [], true);
+    }
 }
diff --git a/src/Controller/ApiTraceController.php b/src/Controller/ApiTraceController.php
index 5e912e3..043f1bc 100644
--- a/src/Controller/ApiTraceController.php
+++ b/src/Controller/ApiTraceController.php
@@ -163,9 +163,9 @@ class ApiTraceController extends ApiBaseController
      *
      * @OA\Parameter(name="date", in="query", @OA\Schema(type="date", example="2023-01-09"))
      * @OA\Parameter(name="date_client", in="query", @OA\Schema(type="date", example="2023-01-09"))
-     * @OA\Parameter(name="user_id", in="query", @OA\Schema(type="date", example="4"))
-     * @OA\Parameter(name="origin", in="query", @OA\Schema(type="date", example="Prisms"))
-     * @OA\Parameter(name="action", in="query", @OA\Schema(type="date", example="action"))
+     * @OA\Parameter(name="user_id", in="query", @OA\Schema(type="integer", example="4"))
+     * @OA\Parameter(name="origin", in="query", @OA\Schema(type="string", example="Prisms"))
+     * @OA\Parameter(name="action", in="query", @OA\Schema(type="string", example="action"))
      *
      * @OA\Tag(name="Traces")
      * @Security(name="OAuth2")
diff --git a/src/Entity/Group.php b/src/Entity/Group.php
index cc5ce1b..c9506a0 100644
--- a/src/Entity/Group.php
+++ b/src/Entity/Group.php
@@ -20,6 +20,7 @@ class Group
      * @ORM\Id
      * @ORM\GeneratedValue
      * @ORM\Column(type="integer")
+     * @Groups({"group:read"})
      */
     private $id;
 
@@ -43,6 +44,7 @@ class Group
      * @ORM\Column(type="string", length=150)
      * @Assert\Length(max={150})
      * @Assert\NotBlank()
+     * @Groups({"group:read"})
      */
     private $name;
 
diff --git a/src/Entity/Lexicon.php b/src/Entity/Lexicon.php
index 8d4b5e8..ab29022 100644
--- a/src/Entity/Lexicon.php
+++ b/src/Entity/Lexicon.php
@@ -22,6 +22,13 @@ class Lexicon
     const TYPE_ZERO       = 'Zero';
     const TYPE_NEW_WORDS  = 'New words';
 
+    const LEXICON_TYPES = [
+        self::TYPE_USER,
+        self::TYPE_GROUP,
+        self::TYPE_ZERO,
+        self::TYPE_NEW_WORDS,
+    ];
+
     const MERGE_MERGE     = 'merge';
     const MERGE_OVERWRITE = 'overwrite';
     const MERGE_IGNORE    = 'ignore';
@@ -50,6 +57,7 @@ class Lexicon
 
     /**
      * @ORM\Column(type="string", length=100)
+     * @Groups({"lexicon:read"})
      */
     private $language;
 
diff --git a/src/Normalizer/ApiProblemNormalizer.php b/src/Normalizer/ApiProblemNormalizer.php
index ef459c0..d86a768 100644
--- a/src/Normalizer/ApiProblemNormalizer.php
+++ b/src/Normalizer/ApiProblemNormalizer.php
@@ -22,8 +22,14 @@ class ApiProblemNormalizer implements NormalizerInterface
 
     public function normalize($exception, string $format = null, array $context = []): array
     {
+        if ($exception->getStatusCode() === 404) {
+            return [
+                'error' => 'Resource not found. Check uri and parameters.',
+            ];
+        }
+
         return [
-            'error' => 'Something went wrong. Please try again later.',
+            'error' => sprintf('%s : Something went wrong. Please try again later.', $exception->getStatusCode()),
         ];
     }
 
diff --git a/src/Repository/LexiconRepository.php b/src/Repository/LexiconRepository.php
index 64f31f0..4285935 100644
--- a/src/Repository/LexiconRepository.php
+++ b/src/Repository/LexiconRepository.php
@@ -21,6 +21,41 @@ class LexiconRepository extends ServiceEntityRepository
         parent::__construct($registry, Lexicon::class);
     }
 
+    public function search($filter)
+    {
+        $qb = $this->createQueryBuilder('l')
+            ->leftJoin('l.user', 'u')
+            ->leftJoin('l.group', 'g')
+        ;
+
+        if ($filter['user'] ?? null) {
+            $qb->andWhere('u = :user')
+                ->setParameter('user', $filter['user'])
+            ;
+        }
+
+        if ($filter['group'] ?? null) {
+            $qb->andWhere('g = :group')
+                ->setParameter('group', $filter['group'])
+            ;
+        }
+
+        if ($filter['category'] ?? null) {
+            $qb->andWhere('l.category = :category')
+                ->setParameter('category', $filter['category'])
+            ;
+        }
+
+        if ($filter['language'] ?? null) {
+            $qb->andWhere('l.language = :language')
+                ->setParameter('language', $filter['language'])
+            ;
+        }
+
+        return $qb->getQuery()->getResult();
+
+    }
+
     public function add(Lexicon $entity, bool $flush = false): void
     {
         $this->getEntityManager()->persist($entity);
-- 
GitLab