From 9e047039d92190f43d210ea3b6081fef141114b9 Mon Sep 17 00:00:00 2001 From: pfleu <fleutotp@gmail.com> Date: Tue, 30 May 2023 18:22:28 +0200 Subject: [PATCH] MErge Labels --- src/Controller/ApiLabelController.php | 8 ++-- src/Controller/LabelController.php | 51 ++++++++++++++++++++------ src/Entity/Label.php | 7 +++- src/Form/LabelType.php | 3 ++ src/Manager/LabelManager.php | 46 +++++++++++++++++++++++ src/Repository/LabelRepository.php | 8 ++++ templates/entry/_chooseLabel.html.twig | 2 + templates/label/edit.html.twig | 38 +++++++++++++++++++ 8 files changed, 146 insertions(+), 17 deletions(-) create mode 100644 templates/label/edit.html.twig diff --git a/src/Controller/ApiLabelController.php b/src/Controller/ApiLabelController.php index a065ce3..41edfdf 100644 --- a/src/Controller/ApiLabelController.php +++ b/src/Controller/ApiLabelController.php @@ -9,6 +9,7 @@ use App\Entity\Headword; use App\Entity\Label; use App\Entity\Lexicon; use App\Entity\User; +use App\Manager\LabelManager; use App\Manager\WiktionaryManager; use App\Repository\LabelRepository; use Doctrine\Persistence\ManagerRegistry; @@ -399,16 +400,13 @@ class ApiLabelController extends AppBaseController * @OA\Tag(name="Labels") * @Security(name="OAuth2") */ - public function merge(Request $request, WiktionaryManager$wiktionaryManager, Label $labelDeleted, Label $labelMerged): Response + public function merge(Request $request, WiktionaryManager$wiktionaryManager, Label $labelDeleted, Label $labelMerged, LabelManager $labelManager): Response { $diffs = $labelDeleted->compareWith($labelMerged); if ($diffs) { return $this->createJsonResponse(401, ['error' => sprintf("Fusion impossible : %s", implode(', ', $diffs))]); } else { - foreach ($labelDeleted->getHeadwords() as $headword) { - $headword->addLabel($labelMerged); - } - $this->doctrine->getManager()->remove($labelDeleted); + $labelManager->mergeLabels($labelDeleted, $labelMerged); $labelDeletedId = $labelDeleted->getId(); $this->doctrine->getManager()->flush(); $this->addSuccessMessage(sprintf("Fusion effectuée: Label %s appliqué aux mots du label %s. Label %s supprimé.", $labelDeletedId, $labelMerged->getId(), $labelDeletedId)); diff --git a/src/Controller/LabelController.php b/src/Controller/LabelController.php index 24de601..3c5dd00 100644 --- a/src/Controller/LabelController.php +++ b/src/Controller/LabelController.php @@ -54,7 +54,7 @@ class LabelController extends AppBaseController * requirements={"category"=App\Entity\Label::REQUIREMENTS_LABEL_CATEGORY, "masterType"=App\Entity\Label::REQUIREMENTS_MASTERS_TYPES}) * @Security("is_granted('ROLE_TEACHER') or category != constant('App\\Entity\\Label::LABEL_CATEGORY_INSTITUTIONAL')") */ - public function new(ManagerRegistry $doctrine, Request $request, $masterType, $category, LabelRepository $labelRepository): Response + public function new(ManagerRegistry $doctrine, Request $request, $masterType, $category, LabelRepository $labelRepository, LabelManager $labelManager): Response { $label = new Label($category); $label->setMaster($masterType); @@ -69,6 +69,7 @@ class LabelController extends AppBaseController } $label->setGroup($group); } + $form = $this->createForm(LabelType::class, $label, [ 'action' => $this->generateUrl('app_label_new', [ 'masterType' => $masterType, @@ -78,10 +79,17 @@ class LabelController extends AppBaseController ]); $form->handleRequest($request); + $identicalLabel = $labelManager->getIdenticalLabel($label); + if ($form->isSubmitted() && $form->isValid()) { - $labelRepository->add($label, true); + if ($identicalLabel) { + $this->addFlash('warning', sprintf("Création impossible. Un label identique existe déjà .")); + } else { + $this->em->flush(); + $this->addFlash('success', "Le label a été ajouté"); - return $this->render('closeModalAndReload.html.twig'); + return $this->render('closeModalAndReload.html.twig'); + } } return $this->render('genericModalForm.html.twig', [ @@ -214,22 +222,45 @@ class LabelController extends AppBaseController * @Route("/{id}/edit", name="app_label_edit", methods={"GET", "POST"}) */ // * @IsGranted("LABEL_EDIT", subject="label") - public function edit(Request $request, Label $label, LabelRepository $labelRepository): Response + public function edit(Request $request, Label $label, LabelManager $labelManager): Response { $form = $this->createForm(LabelType::class, $label, [ 'action' => $this->generateUrl('app_label_edit', ['id' => $label->getId()]) ]); $form->handleRequest($request); + $identicalLabel = $labelManager->getIdenticalLabel($label); + if ($form->isSubmitted() && $form->isValid()) { - $labelRepository->add($label, true); - return $this->render('closeModalAndReload.html.twig'); + if ($identicalLabel) { + // Si on a un identique et qu'on a forcé la validation, on fusionne notre label dans celui existant, $identicalLabel sera apposé sur les mots-vedettes qui possédaient $label + if ($form->get('forceValidation')->isClicked()) { + $labelManager->mergeLabels($identicalLabel, $label); + $this->em->flush(); + $this->addFlash('success', "Le label a été modifié et fusionné avec un label identique"); + + return $this->render('closeModalAndReload.html.twig'); + + // Si on a un identique et qu'on a pas forcé la validation, on refuse de modifier le label et on affiche une demande de confirmation + } else { + $displayForceValidation = true; + $this->addFlash('warning', sprintf("Un label identique existe déjà . Voulez-vous fusionner votre label avec le label existant ?")); + } + + // Si pas de label identique on modifie le label + } else { + $this->em->flush(); + $this->addFlash('success', "Le label a été modifié"); + + return $this->render('closeModalAndReload.html.twig'); + } } - return $this->render('genericModalForm.html.twig', [ - 'title' => "Modifier le label", + return $this->render('label/edit.html.twig', [ + 'label' => $label, 'form' => $form->createView(), + 'displayForceValidation' => $displayForceValidation ?? false, ]); } @@ -264,8 +295,6 @@ class LabelController extends AppBaseController // * @IsGranted("LABEL_EDIT", subject="label") public function addHeadwordDescription(WiktionaryManager $wiktionaryManager, Request $request, Label $label): Response { - $displayForceValidation = false; - $form = $this->createForm(EnterWordType::class, null, [ 'action' => $this->generateUrl('app_label_add_headword', ['id' => $label->getId()]) ]); @@ -308,7 +337,7 @@ class LabelController extends AppBaseController return $this->render('label/addHeadwordToLabel.html.twig', [ 'title' => "Modifier le label", 'form' => $form->createView(), - 'displayForceValidation' => $displayForceValidation, + 'displayForceValidation' => $displayForceValidation ?? false, ]); } diff --git a/src/Entity/Label.php b/src/Entity/Label.php index cadacbc..29de089 100644 --- a/src/Entity/Label.php +++ b/src/Entity/Label.php @@ -145,7 +145,7 @@ class Label private $updateRequests; /** - * @ORM\OneToMany(targetEntity=LabelVisibility::class, mappedBy="label") + * @ORM\OneToMany(targetEntity=LabelVisibility::class, mappedBy="label", cascade={"persist", "remove"}) */ private $labelVisibilities; @@ -172,6 +172,11 @@ class Label // throw new \LogicException("Cannot determine label masters type"); // } + public function isIdenticalTo(Label $label) + { + return empty($this->compareWith($label)); + } + // TODO reprendre ?? public function compareWith(Label $label) { diff --git a/src/Form/LabelType.php b/src/Form/LabelType.php index bb539c0..f1ed381 100644 --- a/src/Form/LabelType.php +++ b/src/Form/LabelType.php @@ -61,6 +61,9 @@ class LabelType extends AbstractType } $builder + ->add('forceValidation', SubmitType::class, [ + 'label' => 'Confirmer', + ]) ->add('submit', SubmitType::class, [ 'label' => 'Enregistrer', ]); diff --git a/src/Manager/LabelManager.php b/src/Manager/LabelManager.php index a07067b..4950a88 100644 --- a/src/Manager/LabelManager.php +++ b/src/Manager/LabelManager.php @@ -37,6 +37,52 @@ class LabelManager $this->searchString = $searchString; } + public function mergeLabels(Label $labelDeleted, Label $labelMerged) + { + foreach ($labelDeleted->getHeadwords() as $headword) { + $headword->addLabel($labelMerged); + } + // pour chaque visibilité liée à labelDeleted, on regarde si on a une visibilité pour le même lexique dans labelMerged + // Si ce n'est pas le cas, on en ajoute une + foreach ($labelDeleted->getLabelVisibilities() as $labelVisibilityDeleted) { + $labelMergedHasSameLexiconVisibility = false; + foreach ($labelMerged->getLabelVisibilities() as $labelVisibilityMerged) { + if ($labelVisibilityDeleted->getLexicon() == $labelVisibilityMerged->getLexicon()) { + $labelMergedHasSameLexiconVisibility = true; break; + } + } + if (false === $labelMergedHasSameLexiconVisibility) { + $labelVisibility = new LabelVisibility(); + $labelVisibility->setLexicon($labelVisibilityDeleted->getLexicon()); + $labelVisibility->setLabel($labelMerged); + $labelVisibility->setUser($labelVisibilityDeleted->getUser()); + $this->doctrine->getManager()->persist($labelVisibility); + } + } + $this->doctrine->getManager()->remove($labelDeleted); + } + + /** + * @param Label $label + * @return Label|null + */ + public function getIdenticalLabel(Label $label) + { + $identicalLabels = $this->doctrine->getRepository(Label::class)->filter([ + 'user' => $label->getUser(), + 'group' => $label->getGroup(), + 'category' => $label->getCategory(), + 'milestone' => $label->getMilestone(), + 'name' => $label->getName(), + 'graphyList' => $label->getGraphyList(), + ]); + + $identicalLabel = $identicalLabels ? $identicalLabels[0] : null; + + // On s'assure que le label identique n'est le label passé en paramètre (ça peut être le cas en edit si on a pas encore modifié label) + return $identicalLabel && $identicalLabel->getId() !== $label->getId() ? $identicalLabel : null; + } + // vrai si le label est visible pour user dans un lexique donné public function isVisible(Label $label, Lexicon $lexicon, User $user) { diff --git a/src/Repository/LabelRepository.php b/src/Repository/LabelRepository.php index bb39428..77b167d 100644 --- a/src/Repository/LabelRepository.php +++ b/src/Repository/LabelRepository.php @@ -67,6 +67,14 @@ class LabelRepository extends ServiceEntityRepository $qb ->andWhere('l.user = :user') ->setParameter('user', $filter['user']); } + if (!empty($filter['graphyList'])) { + $qb ->andWhere('l.graphyList = :graphyList') + ->setParameter('graphyList', $filter['graphyList']); + } + if (!empty($filter['name'])) { + $qb ->andWhere('UPPER(l.name) = UPPER(:name)') + ->setParameter('name', $filter['name']); + } if (!empty($filter['searchString'])) { $qb ->andWhere('l.name LIKE :searchString') diff --git a/templates/entry/_chooseLabel.html.twig b/templates/entry/_chooseLabel.html.twig index eaeaef2..e8a3a52 100644 --- a/templates/entry/_chooseLabel.html.twig +++ b/templates/entry/_chooseLabel.html.twig @@ -14,6 +14,8 @@ <a class="ajax-link" href="#" data-method="DELETE" data-url="{{ path('label_remove', {id: label.id}) }}" data-json="{{ {headwords_ids: [entry.headword.id]}|json_encode }}"> <i class="fa fa-lg fa-times-circle text-danger" style="margin-left: -8px; margin-right: 5px;"></i> </a> + {% else %} + <i>{{ "Aucun label visible dans ce lexique pour cette catégorie"|trans }}</i> {% endfor %} </div> diff --git a/templates/label/edit.html.twig b/templates/label/edit.html.twig new file mode 100644 index 0000000..fba2363 --- /dev/null +++ b/templates/label/edit.html.twig @@ -0,0 +1,38 @@ +{% extends 'modal.html.twig' %} + +{% block modal_title %} + {% if label.id %} + {{ "Modifier un label"|trans }} + {% else %} + {{ "Ajouter un label"|trans }} + {% endif %} +{% endblock %} + +{% block modal_body %} + <div class="row"> + <div class="col-md-12"> + + {% include "flashes.html.twig" %} + + {{ form_start(form) }} + {{ form_errors(form) }} + {% for child in form %} + {% if child.vars.name not in ['submit', 'forceValidation'] %} + {{ form_row(child) }} + {% endif %} + {% endfor %} + <div class="row pt-3"> + <div class="col-sm-4"></div> + <div class="col-sm-8"> + {% if displayForceValidation %} + {{ form_widget(form.forceValidation) }} + {% else %} + {{ form_widget(form.submit) }} + {% endif %} + <button type="button" class="btn btn-light" data-bs-dismiss="modal">{{ 'Annuler'|trans }}</button> + </div> + </div> + {{ form_end(form, {render_rest: false}) }} + </div> + </div> +{% endblock %} \ No newline at end of file -- GitLab