From 16b232e96a6bab52928de095c0a2155b32760fcd Mon Sep 17 00:00:00 2001 From: pfleu <fleutotp@gmail.com> Date: Fri, 16 Dec 2022 19:09:17 +0100 Subject: [PATCH] =?UTF-8?q?API:=20requ=C3=AAtes=20pour=20recherche=20de=20?= =?UTF-8?q?traces,=20recherche=20de=20logs=20avec=20divers=20filtres.=20re?= =?UTF-8?q?qu=C3=AAtes=20de=20modification=20des=20commentaires=20ou=20de?= =?UTF-8?q?=20la=20discussion=20pour=20les=20entr=C3=A9es=20te=20pour=20le?= =?UTF-8?q?s=20lexiques.=20Ajout=20fonction=20SQL=20Date=20pour=20recherch?= =?UTF-8?q?e=20des=20logs/traces=20par=20date.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/packages/doctrine.yaml | 4 + src/Controller/ApiEntryController.php | 92 +++++++++++++- src/Controller/ApiLabelController.php | 2 +- src/Controller/ApiLexiconController.php | 92 +++++++++++++- src/Controller/ApiLogController.php | 155 ++++++++++++++++++++++++ src/Controller/ApiTraceController.php | 63 ++++++++++ src/Controller/LexiconController.php | 3 +- src/Doctrine/DQL/Date.php | 25 ++++ src/Doctrine/DQL/Year.php | 25 ++++ src/Entity/Entry.php | 8 +- src/Entity/Log.php | 11 +- src/Entity/LoggableTrait.php | 10 +- src/Entity/Trace.php | 4 +- src/Repository/LogRepository.php | 104 ++++++++++++++++ src/Repository/TraceRepository.php | 98 +++++++++++++++ 15 files changed, 680 insertions(+), 16 deletions(-) create mode 100644 src/Controller/ApiLogController.php create mode 100644 src/Doctrine/DQL/Date.php create mode 100644 src/Doctrine/DQL/Year.php create mode 100644 src/Repository/LogRepository.php create mode 100644 src/Repository/TraceRepository.php diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index 8fe1dd4..95228da 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -15,6 +15,10 @@ doctrine: dir: '%kernel.project_dir%/src/Entity' prefix: 'App\Entity' alias: App + dql: + datetime_functions: + date: App\Doctrine\DQL\Date + year: App\Doctrine\DQL\Year when@test: doctrine: diff --git a/src/Controller/ApiEntryController.php b/src/Controller/ApiEntryController.php index 00c6593..71f78c8 100644 --- a/src/Controller/ApiEntryController.php +++ b/src/Controller/ApiEntryController.php @@ -62,7 +62,7 @@ class ApiEntryController extends ApiBaseController /** * Recherche d'une entrée par graphie et par langue, dans un ensemble de lexiques * - * @Route("/search", name="api_search", methods={"POST"}) + * @Route("/search", name="api_entry_search", methods={"POST"}) * * @OA\Response(response=200, description="success", * @OA\JsonContent(type="array", @@ -405,6 +405,96 @@ class ApiEntryController extends ApiBaseController return new JsonResponse($updatedEntryData, 200, [], true); } + /** + * @Route("/edit-comment/{id}", name="api_edit_comment_entry", methods={"PUT"}) + * + * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) + * @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="id", + * in="path", + * description="id of the entry to edit", + * @OA\Schema(type="string") + * ) + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"comment"}, + * @OA\Property(property="comment", type="string", example="bloc de commentaires dans sa totalité"), + * ) + * ) + * @OA\Tag(name="Entries") + * @Security(name="OAuth2") + */ + public function editCommentEntry(Request $request, SerializerInterface $serializer, Entry $entry = null) + { + if ($entry === null) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas d'entrée trouvée pour cette Id")]); + } + $data = json_decode($request->getContent(), true); + if (!$data) { + return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); + } + if ($missingFields = $this->getMissingFields($data, ['comment'])) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une valeur pour: %s", implode(', ', $missingFields))]); + } + + $entry->setCommentsBy($data['comment'], $this->getUser()); + $this->doctrine->getManager()->flush(); + + $this->addSuccessMessage(sprintf("Commentaires de l'entrée %s modifiés", $entry->getId())); + + return $this->createJsonResponse(); + } + + /** + * @Route("/edit-discussion/{id}", name="api_edit_discussion_entry", methods={"PUT"}) + * + * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) + * @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="id", + * in="path", + * description="id of the entry to edit", + * @OA\Schema(type="string") + * ) + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"discussion"}, + * @OA\Property(property="discussion", type="string", example="bloc de discussion dans sa totalité"), + * ) + * ) + * @OA\Tag(name="Entries") + * @Security(name="OAuth2") + */ + public function editDiscussionEntry(Request $request, SerializerInterface $serializer, Entry $entry = null) + { + if ($entry === null) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas d'entrée trouvée pour cette Id")]); + } + $data = json_decode($request->getContent(), true); + if (!$data) { + return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); + } + if ($missingFields = $this->getMissingFields($data, ['discussion'])) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une valeur pour: %s", implode(', ', $missingFields))]); + } + + $entry->setDiscussionBy($data['discussion'], $this->getUser()); + $this->doctrine->getManager()->flush(); + + $this->addSuccessMessage(sprintf("Discussion de l'entrée %s modifiée", $entry->getId())); + + return $this->createJsonResponse(); + } + /** * @Route("/delete", name="api_entry_delete", methods={"DELETE"}) * diff --git a/src/Controller/ApiLabelController.php b/src/Controller/ApiLabelController.php index 509e906..a6f9e3b 100644 --- a/src/Controller/ApiLabelController.php +++ b/src/Controller/ApiLabelController.php @@ -331,7 +331,7 @@ class ApiLabelController extends ApiBaseController { // $labelId = $request->get('labelId'); // if (!$labelId) { -// return $this->createJsonResponse(401, ['error' => sprintf("Le paramètre labelId ets obligatoire")]); +// return $this->createJsonResponse(401, ['error' => sprintf("Le paramètre labelId est obligatoire")]); // } // $label = $this->doctrine->getRepository(Label::class)->find($labelId); // if (!$label) { diff --git a/src/Controller/ApiLexiconController.php b/src/Controller/ApiLexiconController.php index e2e2def..a1b6109 100644 --- a/src/Controller/ApiLexiconController.php +++ b/src/Controller/ApiLexiconController.php @@ -148,7 +148,7 @@ class ApiLexiconController extends ApiBaseController { $lexiconId = $request->get('lexiconId'); if (!$lexiconId) { - return $this->createJsonResponse(401, ['error' => sprintf("Le paramètre lexiconId ets obligatoire")]); + return $this->createJsonResponse(401, ['error' => sprintf("Le paramètre lexiconId est obligatoire")]); } $lexicon = $this->doctrine->getRepository(Lexicon::class)->find($lexiconId); if (!$lexicon) { @@ -167,4 +167,94 @@ class ApiLexiconController extends ApiBaseController return $this->createJsonResponse(200, $selectedGraphies); } + + /** + * @Route("/edit-comment/{id}", name="api_edit_comment_lexicon", methods={"PUT"}) + * + * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) + * @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="id", + * in="path", + * description="id of the lexicon to edit", + * @OA\Schema(type="string") + * ) + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"comment"}, + * @OA\Property(property="comment", type="string", example="bloc de commentaires dans sa totalité"), + * ) + * ) + * @OA\Tag(name="Lexicons") + * @Security(name="OAuth2") + */ + public function editCommentLexicon(Request $request, SerializerInterface $serializer, Lexicon $lexicon = null) + { + if ($lexicon === null) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas de lexique trouvé pour cette Id")]); + } + $data = json_decode($request->getContent(), true); + if (!$data) { + return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); + } + if ($missingFields = $this->getMissingFields($data, ['comment'])) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une valeur pour: %s", implode(', ', $missingFields))]); + } + + $lexicon->setCommentsBy($data['comment'], $this->getUser()); + $this->doctrine->getManager()->flush(); + + $this->addSuccessMessage(sprintf("Commentaires du lexique %s modifiés", $lexicon->getId())); + + return $this->createJsonResponse(); + } + + /** + * @Route("/edit-discussion/{id}", name="api_edit_discussion_lexicon", methods={"PUT"}) + * + * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) + * @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="id", + * in="path", + * description="id of the lexicon to edit", + * @OA\Schema(type="string") + * ) + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"discussion"}, + * @OA\Property(property="discussion", type="string", example="bloc de discussion dans sa totalité"), + * ) + * ) + * @OA\Tag(name="Lexicons") + * @Security(name="OAuth2") + */ + public function editDiscussionLexicon(Request $request, SerializerInterface $serializer, Lexicon $lexicon = null) + { + if ($lexicon === null) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas de lexique trouvée pour cette Id")]); + } + $data = json_decode($request->getContent(), true); + if (!$data) { + return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); + } + if ($missingFields = $this->getMissingFields($data, ['discussion'])) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une valeur pour: %s", implode(', ', $missingFields))]); + } + + $lexicon->setDiscussionBy($data['discussion'], $this->getUser()); + $this->doctrine->getManager()->flush(); + + $this->addSuccessMessage(sprintf("Discussion du lexique %s modifiée", $lexicon->getId())); + + return $this->createJsonResponse(); + } } diff --git a/src/Controller/ApiLogController.php b/src/Controller/ApiLogController.php new file mode 100644 index 0000000..63be464 --- /dev/null +++ b/src/Controller/ApiLogController.php @@ -0,0 +1,155 @@ +<?php + +namespace App\Controller; + +use App\Entity\Entry; +use App\Entity\Graphy; +use App\Entity\Headword; +use App\Entity\Label; +use App\Entity\Lexicon; +use App\Entity\Log; +use App\Entity\User; +use App\Manager\WiktionaryManager; +use App\Repository\LabelRepository; +use Doctrine\Persistence\ManagerRegistry; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; +use Nelmio\ApiDocBundle\Annotation\Security; +use OpenApi\Annotations as OA; +use Nelmio\ApiDocBundle\Annotation\Model; +use Symfony\Component\Serializer\SerializerInterface; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; + +/** + * @Route("/api/log") + */ +class ApiLogController extends ApiBaseController +{ +// /** +// * +// * @Route("/create", name="api_log_create", methods={"POST"}) +// * +// * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) +// * @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\RequestBody( +// * required=true, +// * @OA\JsonContent( +// * required={"origin", "action"}, +// * @OA\Property(property="origin", type="string", example="Prisms"), +// * @OA\Property(property="action", type="string", example="partie annulée"), +// * @OA\Property(property="additional_info", type="object"), +// * ) +// * ) +// * @OA\Tag(name="Logs") +// * @Security(name="OAuth2") +// */ +// public function createLog(Request $request): Response +// { +// $data = json_decode($request->getContent(), true); +// if (!$data) { +// return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); +// } +// if ($missingFields = $this->getMissingFields($data, ['origin', 'action'])) { +// return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une valeur pour: %s", implode(', ', $missingFields))]); +// } +// +// $log = new Log(); +// $log->setCreatedBy($this->getUser()); +// $log->setAction($data['action']); +// $log->setOrigin($data['origin']); +// if ($data['additional_info'] ?? null) { +// $log->setAdditionalInfo($data['additional_info']); +// } +// $this->doctrine->getManager()->persist($log); +// $this->doctrine->getManager()->flush(); +// +// $this->success[] = sprintf("Log id %s créée.", $log->getId()); +// +// return $this->createJsonResponse(200); +// } + + /** + * Recherche de logs par date ou user + * + * @Route("/search", name="api_log_search", methods={"POST"}) + * + * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) + * @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\RequestBody( + * required=true, + * @OA\JsonContent( + * @OA\Property(property="date", type="date"), + * @OA\Property(property="category", type="string", example="update_comment OU update_discussion"), + * @OA\Property(property="user_id", type="integer", example="4"), + * @OA\Property(property="lexicon_id", type="integer", example="4"), + * @OA\Property(property="entry_id", type="integer", example="4"), + * ) + * ) + * @OA\Tag(name="Logs") + * @Security(name="OAuth2") + */ + public function search(Request $request, SerializerInterface $serializer): Response + { + $data = json_decode($request->getContent(), true); + if (!$data) { + return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); + } + if (!isset($data['date']) && !isset($data['user_id']) && !isset($data['lexicon_id']) && !isset($data['entry_id'])) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez spécifier au moins un paramètre de recherche parmi: date, user_id, lexicon_id, entry_id")]); + } + if (($data['category'] ?? null) && !in_array($data['category'], Log::LOG_LIST_CATEGORIES)) { + return $this->createJsonResponse(401, ['error' => sprintf("La catégorie de log %s n'existe pas", $data['category'])]); + } + + $filter = []; + if ($data["lexicon_id"] ?? null) { + $lexicon = $this->doctrine->getRepository(Lexicon::class)->find($data['lexicon_id']); + if (!$lexicon) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas de lexique trouvé pour l'id %s", $data['lexicon_id'])]); + } else { + $filter['lexicon'] = $lexicon; + } + } + if ($data["entry_id"] ?? null) { + $entry = $this->doctrine->getRepository(Entry::class)->find($data['entry_id']); + if (!$entry) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas d'entrée trouvée pour l'id %s", $data['entry_id'])]); + } else { + $filter['entry'] = $entry; + } + } + if ($data['date'] ?? null) { + $date = date_create_from_format('Y-m-d', $data['date']); + if ($date === false) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une date au format aaaa-mm-jj pour le paramètre «date»")]); + } else { + $filter['date'] = $date; + } + } + if ($data["user_id"] ?? null) { + $user = $this->doctrine->getRepository(User::class)->find($data['user_id']); + if (!$user) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas d'utilisateur trouvé pour l'id %s", $data['user_id'])]); + } else { + $filter['user'] = $user; + } + } + if ($data["category"] ?? null) { + $filter['category'] = $data["category"]; + } + + $logs = $this->doctrine->getRepository(Log::class)->search($filter); + + $content = $serializer->serialize($logs, 'json', ['groups' => ["log:read"]]); + + return new JsonResponse($content, 200, [], true); + } +} diff --git a/src/Controller/ApiTraceController.php b/src/Controller/ApiTraceController.php index 7e23ec5..049767c 100644 --- a/src/Controller/ApiTraceController.php +++ b/src/Controller/ApiTraceController.php @@ -8,6 +8,7 @@ use App\Entity\Headword; use App\Entity\Label; use App\Entity\Lexicon; use App\Entity\Trace; +use App\Entity\User; use App\Manager\WiktionaryManager; use App\Repository\LabelRepository; use Doctrine\Persistence\ManagerRegistry; @@ -72,4 +73,66 @@ class ApiTraceController extends ApiBaseController return $this->createJsonResponse(200); } + + /** + * Recherche de traces par date ou user ou action ou origin + * + * @Route("/search", name="api_trace_search", methods={"POST"}) + * + * @OA\Response(response=200, description="success", @OA\JsonContent(type="string")) + * @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\RequestBody( + * required=true, + * @OA\JsonContent( + * @OA\Property(property="date", type="date"), + * @OA\Property(property="user_id", type="integer", example="4"), + * @OA\Property(property="origin", type="string", example="Prisms"), + * @OA\Property(property="action", type="string", example="action"), + * ) + * ) + * @OA\Tag(name="Traces") + * @Security(name="OAuth2") + */ + public function search(Request $request, SerializerInterface $serializer): Response + { + $data = json_decode($request->getContent(), true); + if (!$data) { + return $this->createJsonResponse(401, ['error' => sprintf("Json non valide")]); + } + if (!isset($data['date']) && !isset($data['user_id']) && !isset($data['origin']) && !isset($data['action'])) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez spécifier au moins un paramètre de recherche parmi: date, user_id, action, origin")]); + } + + $filter = []; + if ($data['date'] ?? null) { + $date = date_create_from_format('Y-m-d', $data['date']); + if ($date === false) { + return $this->createJsonResponse(401, ['error' => sprintf("Veuillez fournir une date au format aaaa-mm-jj pour le paramètre «date»")]); + } else { + $filter['date'] = $date; + } + } + if ($data["user_id"] ?? null) { + $user = $this->doctrine->getRepository(User::class)->find($data['user_id']); + if (!$user) { + return $this->createJsonResponse(401, ['error' => sprintf("Pas d'utilisateur trouvé pour l'id %s", $data['user_id'])]); + } else { + $filter['user'] = $user; + } + } + if ($data['origin'] ?? null) { + $filter['origin'] = $data['origin']; + } + if ($data['action'] ?? null) { + $filter['action'] = $data['action']; + } + + $traces = $this->doctrine->getRepository(Trace::class)->search($filter); + + $content = $serializer->serialize($traces, 'json', ['groups' => ["trace:read"]]); + + return new JsonResponse($content, 200, [], true); + } } diff --git a/src/Controller/LexiconController.php b/src/Controller/LexiconController.php index e6e544f..ab248f9 100644 --- a/src/Controller/LexiconController.php +++ b/src/Controller/LexiconController.php @@ -4,6 +4,7 @@ namespace App\Controller; use App\Entity\Entry; use App\Entity\Lexicon; +use App\Entity\Log; use App\Repository\LexiconRepository; use Doctrine\Persistence\ManagerRegistry; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; @@ -23,7 +24,7 @@ class LexiconController extends AbstractController */ public function index(LexiconRepository $lexiconRepository): Response { -// $entry1 = $this->getDoctrine()->getRepository(Entry::class)->find(1); + dump(in_array('update_comment', Log::LOG_LIST_CATEGORIES));die(); // $entry2 = $this->getDoctrine()->getRepository(Entry::class)->find(9); // // diff --git a/src/Doctrine/DQL/Date.php b/src/Doctrine/DQL/Date.php new file mode 100644 index 0000000..24d2137 --- /dev/null +++ b/src/Doctrine/DQL/Date.php @@ -0,0 +1,25 @@ +<?php + +namespace App\Doctrine\DQL; + +use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\AST\Functions\FunctionNode; + +class Date extends FunctionNode +{ + public $date; + + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return "DATE(" . $sqlWalker->walkArithmeticPrimary($this->date) . ")"; + } + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->date = $parser->ArithmeticPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} diff --git a/src/Doctrine/DQL/Year.php b/src/Doctrine/DQL/Year.php new file mode 100644 index 0000000..c6f158f --- /dev/null +++ b/src/Doctrine/DQL/Year.php @@ -0,0 +1,25 @@ +<?php + +namespace App\Doctrine\DQL; + +use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\AST\Functions\FunctionNode; + +class Year extends FunctionNode +{ + public $year; + + public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + { + return "YEAR(" . $sqlWalker->walkArithmeticPrimary($this->year) . ")"; + } + public function parse(\Doctrine\ORM\Query\Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $this->year = $parser->ArithmeticPrimary(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } +} diff --git a/src/Entity/Entry.php b/src/Entity/Entry.php index 945fcf5..ba7eff9 100644 --- a/src/Entity/Entry.php +++ b/src/Entity/Entry.php @@ -80,7 +80,7 @@ class Entry private $lexicon; /** - * @ORM\OneToMany(targetEntity=Log::class, mappedBy="lexicon", cascade={"remove", "persist"}) + * @ORM\OneToMany(targetEntity=Log::class, mappedBy="entry", cascade={"remove", "persist"}) */ private $logs; @@ -231,7 +231,7 @@ class Entry { if (!$this->logs->contains($log)) { $this->logs[] = $log; - $log->setLexicon($this); + $log->setEntry($this); } return $this; @@ -241,8 +241,8 @@ class Entry { if ($this->logs->removeElement($log)) { // set the owning side to null (unless already changed) - if ($log->getLexicon() === $this) { - $log->setLexicon(null); + if ($log->getEntry() === $this) { + $log->setEntry(null); } } diff --git a/src/Entity/Log.php b/src/Entity/Log.php index 32cc159..6ca7020 100644 --- a/src/Entity/Log.php +++ b/src/Entity/Log.php @@ -2,19 +2,24 @@ namespace App\Entity; -use App\Repository\LexiconRepository; +use App\Repository\LogRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation\Groups; /** - * @ORM\Entity(repositoryClass=LexiconRepository::class) + * @ORM\Entity(repositoryClass=LogRepository::class) * @ORM\HasLifecycleCallbacks */ class Log { - const CATEGORY_UPDATE = 'Update'; + const CATEGORY_UPDATE_COMMENT = 'update_comment'; + const CATEGORY_UPDATE_DISCUSSION = 'update_discussion'; + + const LOG_LIST_CATEGORIES = [ + self::CATEGORY_UPDATE_COMMENT, self::CATEGORY_UPDATE_DISCUSSION + ]; /** * @ORM\Id diff --git a/src/Entity/LoggableTrait.php b/src/Entity/LoggableTrait.php index cfa4267..a7df36c 100644 --- a/src/Entity/LoggableTrait.php +++ b/src/Entity/LoggableTrait.php @@ -8,20 +8,24 @@ trait LoggableTrait { public function setCommentsBy($comments, User $user) { + $this->setComments($comments); $log = new Log(); + $log->setCategory(Log::CATEGORY_UPDATE_COMMENT); $log->setCreatedBy($user); $log->setContent($this->getComments()); - $this->setComments($comments); + $this->addLog($log); return $this; } public function setDiscussionBy($discussions, User $user) { + $this->setDiscussion($discussions); $log = new Log(); + $log->setCategory(Log::CATEGORY_UPDATE_DISCUSSION); $log->setCreatedBy($user); - $log->setContent($this->getDiscussions()); - $this->setDiscussions($discussions); + $log->setContent($this->getDiscussion()); + $this->addLog($log); return $this; } diff --git a/src/Entity/Trace.php b/src/Entity/Trace.php index e866f9d..90f02be 100644 --- a/src/Entity/Trace.php +++ b/src/Entity/Trace.php @@ -2,7 +2,7 @@ namespace App\Entity; -use App\Repository\LexiconRepository; +use App\Repository\TraceRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -10,7 +10,7 @@ use Symfony\Component\Serializer\Annotation\Groups; use OpenApi\Annotations as OA; /** - * @ORM\Entity(repositoryClass=LexiconRepository::class) + * @ORM\Entity(repositoryClass=TraceRepository::class) * @ORM\HasLifecycleCallbacks */ class Trace diff --git a/src/Repository/LogRepository.php b/src/Repository/LogRepository.php new file mode 100644 index 0000000..9b2b564 --- /dev/null +++ b/src/Repository/LogRepository.php @@ -0,0 +1,104 @@ +<?php + +namespace App\Repository; + +use App\Entity\Log; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; + +/** + * @extends ServiceEntityRepository<Log> + * + * @method Log|null find($id, $lockMode = null, $lockVersion = null) + * @method Log|null findOneBy(array $criteria, array $orderBy = null) + * @method Log[] findAll() + * @method Log[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class LogRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Log::class); + } + + public function search($filter) + { + $qb = $this->createQueryBuilder('l'); + + if ($filter['date'] ?? null) { + $qb->andWhere('DATE(l.createdAt) = DATE(:date)') + ->setParameter('date', $filter['date']) + ; + } + + if ($filter['user'] ?? null) { + $qb->andWhere('l.createdBy = :user') + ->setParameter('user', $filter['user']) + ; + } + + if ($filter['lexicon'] ?? null) { + $qb->andWhere('l.lexicon = :lexicon') + ->setParameter('lexicon', $filter['lexicon']) + ; + } + + if ($filter['entry'] ?? null) { + $qb->andWhere('l.entry = :entry') + ->setParameter('entry', $filter['entry']) + ; + } + + if ($filter['category'] ?? null) { + $qb->andWhere('l.category = :category') + ->setParameter('category', $filter['category']) + ; + } + + return $qb->getQuery()->getResult(); + + } + + public function add(Log $entity, bool $flush = false): void + { + $this->getEntityManager()->persist($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + public function remove(Log $entity, bool $flush = false): void + { + $this->getEntityManager()->remove($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + +// /** +// * @return Log[] Returns an array of Log objects +// */ +// public function findByExampleField($value): array +// { +// return $this->createQueryBuilder('e') +// ->andWhere('e.exampleField = :val') +// ->setParameter('val', $value) +// ->orderBy('e.id', 'ASC') +// ->setMaxResults(10) +// ->getQuery() +// ->getResult() +// ; +// } + +// public function findOneBySomeField($value): ?Log +// { +// return $this->createQueryBuilder('e') +// ->andWhere('e.exampleField = :val') +// ->setParameter('val', $value) +// ->getQuery() +// ->getOneOrNullResult() +// ; +// } +} diff --git a/src/Repository/TraceRepository.php b/src/Repository/TraceRepository.php new file mode 100644 index 0000000..fcb0e3b --- /dev/null +++ b/src/Repository/TraceRepository.php @@ -0,0 +1,98 @@ +<?php + +namespace App\Repository; + +use App\Entity\Trace; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; + +/** + * @extends ServiceEntityRepository<Trace> + * + * @method Trace|null find($id, $lockMode = null, $lockVersion = null) + * @method Trace|null findOneBy(array $criteria, array $orderBy = null) + * @method Trace[] findAll() + * @method Trace[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class TraceRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Trace::class); + } + + public function search($filter) + { + $qb = $this->createQueryBuilder('t'); + + if ($filter['date'] ?? null) { + $qb->andWhere('DATE(t.createdAt) = DATE(:date)') + ->setParameter('date', $filter['date']) + ; + } + + if ($filter['user'] ?? null) { + $qb->andWhere('t.createdBy = :user') + ->setParameter('user', $filter['user']) + ; + } + + if ($filter['action'] ?? null) { + $qb->andWhere('t.action = :action') + ->setParameter('action', $filter['action']) + ; + } + + if ($filter['origin'] ?? null) { + $qb->andWhere('t.origin = :origin') + ->setParameter('origin', $filter['origin']) + ; + } + + return $qb->getQuery()->getResult(); + + } + + public function add(Trace $entity, bool $flush = false): void + { + $this->getEntityManager()->persist($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + public function remove(Trace $entity, bool $flush = false): void + { + $this->getEntityManager()->remove($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + +// /** +// * @return Trace[] Returns an array of Trace objects +// */ +// public function findByExampleField($value): array +// { +// return $this->createQueryBuilder('e') +// ->andWhere('e.exampleField = :val') +// ->setParameter('val', $value) +// ->orderBy('e.id', 'ASC') +// ->setMaxResults(10) +// ->getQuery() +// ->getResult() +// ; +// } + +// public function findOneBySomeField($value): ?Trace +// { +// return $this->createQueryBuilder('e') +// ->andWhere('e.exampleField = :val') +// ->setParameter('val', $value) +// ->getQuery() +// ->getOneOrNullResult() +// ; +// } +} -- GitLab