From bbb0ab22037d76ca15c67268ed65ffd34ed3c3a3 Mon Sep 17 00:00:00 2001
From: pfleu <fleutotp@gmail.com>
Date: Mon, 29 May 2023 17:04:38 +0200
Subject: [PATCH] =?UTF-8?q?Ajout=20pages=20d'erreur=20persos.=20Ajout=20lo?=
 =?UTF-8?q?g=20de=20lexique=20add/delete=20entries.=20On=20affiche=20ces?=
 =?UTF-8?q?=20logs=20dans=20un=20bloc=20Historique=20sur=20page=20lexique.?=
 =?UTF-8?q?=20Mise=20=C3=A0=20jour=20Wikstraktor?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |  3 +-
 src/Controller/ApiEntryController.php         |  5 +++
 src/Controller/AppBaseController.php          | 13 ++++++
 src/Controller/EntryController.php            | 13 +++---
 src/Controller/LexiconController.php          |  1 +
 src/Entity/Log.php                            |  4 +-
 src/Manager/LogManager.php                    | 15 +++++--
 src/Wikstraktor/wikstraktor.py                | 11 +++--
 templates/base.html.twig                      |  5 ++-
 .../TwigBundle/Exception/error.html.twig      | 10 +++++
 .../TwigBundle/Exception/error403.html.twig   | 10 +++++
 .../TwigBundle/Exception/error404.html.twig   | 10 +++++
 templates/entry/_lexiconsTabs.html.twig       |  2 +-
 templates/entry/show.html.twig                | 42 +++++++++++--------
 templates/errorLayout.html.twig               |  9 ++++
 templates/lexicon/show.html.twig              | 13 +++++-
 templates/log/_formattedLog.html.twig         | 10 ++++-
 17 files changed, 139 insertions(+), 37 deletions(-)
 create mode 100644 templates/bundles/TwigBundle/Exception/error.html.twig
 create mode 100644 templates/bundles/TwigBundle/Exception/error403.html.twig
 create mode 100644 templates/bundles/TwigBundle/Exception/error404.html.twig
 create mode 100644 templates/errorLayout.html.twig

diff --git a/.gitignore b/.gitignore
index bc40519..5353ef7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,9 @@ public/.htaccess
 ###    PYTHON   ###
 public/pywikibot.lwp
 public/throttle.ctrl
-public//wikstraktor.sqlite
+public/wikstraktor.sqlite
 public/apicache*
+src/Wikstraktor/wikstraktor.sqlite
 src/Wikstraktor/pywikibot.lwp
 src/Wikstraktor/throttle.ctrl
 src/Wikstraktor/apicache*
diff --git a/src/Controller/ApiEntryController.php b/src/Controller/ApiEntryController.php
index 2e1f604..bb7980f 100644
--- a/src/Controller/ApiEntryController.php
+++ b/src/Controller/ApiEntryController.php
@@ -6,6 +6,7 @@ use App\Entity\Entry;
 use App\Entity\Graphy;
 use App\Entity\Headword;
 use App\Entity\Lexicon;
+use App\Entity\Log;
 use App\Entity\User;
 use App\Manager\WiktionaryManager;
 use Doctrine\Persistence\ManagerRegistry;
@@ -282,6 +283,9 @@ class ApiEntryController extends AppBaseController
                     $newEntry->setCreatedAt(new \DateTimeImmutable());
                     $newEntry->setUpdatedAt(null);
                     $this->doctrine->getManager()->persist($newEntry);
+
+                    $this->addLexiconLog($newEntry, Log::CATEGORY_ADD_ENTRY);
+
                     $this->doctrine->getManager()->flush();
                     $added[] = $newEntry->getId();
                 }
@@ -538,6 +542,7 @@ class ApiEntryController extends AppBaseController
 
         if ($entry) {
             $this->doctrine->getManager()->remove($entry);
+            $this->addLexiconLog($entry, Log::CATEGORY_DELETE_ENTRY);
             $this->doctrine->getManager()->flush();
         } else {
             return $this->createJsonResponse(401, ['error' => sprintf("Pas d'entrée trouvée pour cette graphie et ce lexique")]);
diff --git a/src/Controller/AppBaseController.php b/src/Controller/AppBaseController.php
index d7f8ffc..f2ba842 100644
--- a/src/Controller/AppBaseController.php
+++ b/src/Controller/AppBaseController.php
@@ -8,6 +8,7 @@ use App\Entity\Headword;
 use App\Entity\HeadwordUserInfo;
 use App\Entity\Label;
 use App\Entity\Lexicon;
+use App\Entity\Log;
 use App\Entity\User;
 use App\Languages\LanguagesIso;
 use App\Manager\LexiconManager;
@@ -335,6 +336,7 @@ class AppBaseController extends AbstractController
         foreach ($lexicon->getGraphyLists() as $graphyList) {
             $headword->addLabel($graphyList->getLabel());
         }
+        $this->addLexiconLog($entry, Log::CATEGORY_ADD_ENTRY);
 
         return $entry;
     }
@@ -434,6 +436,7 @@ class AppBaseController extends AbstractController
         $entry->setLanguage($headword->getLanguage());
         $entry->setLexicon($newWordsLexicon);
         $this->initializeWithBasicAttributes($entry);
+        $this->addLexiconLog($entry, Log::CATEGORY_ADD_ENTRY);
 
         return $entry;
     }
@@ -488,4 +491,14 @@ class AppBaseController extends AbstractController
             $headwordUserInfo->setKnown($status);
         }
     }
+
+    public function addLexiconLog(Entry $entry, $category)
+    {
+        $log = new Log();
+        $log->setCategory($category);
+        $log->setCreatedBy($this->getUser());
+        $log->setContent((string) $entry);
+        $log->setLexicon($entry->getLexicon());
+        $this->em->persist($log);
+    }
 }
diff --git a/src/Controller/EntryController.php b/src/Controller/EntryController.php
index 99749e5..8955781 100644
--- a/src/Controller/EntryController.php
+++ b/src/Controller/EntryController.php
@@ -75,7 +75,7 @@ class EntryController extends AppBaseController
 //            '_route' => $request->attributes->get('_route'),
 //            '_route_params' => $request->attributes->get('_route_params'),
         ));
-
+//dump($response);die();
         if ($response->getStatusCode() == 200) {
             $this->addFlash('success', "Copie effectuée");
         } else {
@@ -92,6 +92,7 @@ class EntryController extends AppBaseController
     public function deleteEntry(Request $request, Entry $entry)
     {
         $this->em->remove($entry);
+        $this->addLexiconLog($entry, Log::CATEGORY_DELETE_ENTRY);
         $this->em->flush();
         $this->addFlash('success', sprintf("L'entrée a été supprimée du lexique %s", $entry->getLexicon()));
 
@@ -188,7 +189,7 @@ class EntryController extends AppBaseController
         if ($form->isSubmitted() && $form->isValid()) {
             $propertyAccessor->setValue($attributes, $blockId, $form->getData());
             $entry->setAttributes($attributes);
-            $this->addLog($entry, 'edit', $blockCategory);
+            $this->addBlockLog($entry, 'edit', $blockCategory);
             $this->em->flush();
 
             return $this->render('closeModalAndReload.html.twig');
@@ -223,7 +224,7 @@ class EntryController extends AppBaseController
             $parentBlock[$blockCategory][] = $form->getData();
             $propertyAccessor->setValue($attributes, $blockId, $parentBlock);
             $entry->setAttributes($attributes);
-            $this->addLog($entry, 'add', $blockCategory);
+            $this->addBlockLog($entry, 'add', $blockCategory);
             $this->em->flush();
 
             return $this->render('closeModalAndReload.html.twig');
@@ -271,7 +272,7 @@ class EntryController extends AppBaseController
                 ]
             ];
             $entry->setAttributes($attributes);
-            $this->addLog($entry, 'add', Entry::ATTR_PART_OF_SPEECH);
+            $this->addBlockLog($entry, 'add', Entry::ATTR_PART_OF_SPEECH);
             $this->em->flush();
 
             return $this->render('closeModalAndReload.html.twig');
@@ -301,13 +302,13 @@ class EntryController extends AppBaseController
         unset($parentBlock[$childId]);
         $propertyAccessor->setValue($attributes, $parentId, $parentBlock);
         $entry->setAttributes($attributes);
-        $this->addLog($entry, 'delete', $blockCategory);
+        $this->addBlockLog($entry, 'delete', $blockCategory);
         $this->em->flush();
 
         return $this->redirectToRoute('app_entry_show', ['id' => $entry->getId()]);
     }
 
-    public function addLog(Entry $entry, $type, $blockCategory)
+    public function addBlockLog(Entry $entry, $type, $blockCategory)
     {
         if (in_array($blockCategory, [
             Entry::ATTR_DEFINITION,
diff --git a/src/Controller/LexiconController.php b/src/Controller/LexiconController.php
index 7b11e81..5b308df 100644
--- a/src/Controller/LexiconController.php
+++ b/src/Controller/LexiconController.php
@@ -130,6 +130,7 @@ class LexiconController extends AppBaseController
                 foreach ($selectedIds as $selectedId) {
                     $entry = $entryRepository->find($selectedId);
                     $entryRepository->remove($entry);
+                    $this->addLexiconLog($entry, Log::CATEGORY_DELETE_ENTRY);
                 }
                 $this->em->flush();
             }
diff --git a/src/Entity/Log.php b/src/Entity/Log.php
index 49d1015..f8aa3ee 100644
--- a/src/Entity/Log.php
+++ b/src/Entity/Log.php
@@ -17,6 +17,8 @@ class Log
     const CATEGORY_UPDATE_COMMENT    = 'update_comment';
     const CATEGORY_UPDATE_DISCUSSION = 'update_discussion';
     const CATEGORY_UPDATE_ENTRY      = 'update_entry';
+    const CATEGORY_ADD_ENTRY      = 'add_entry';
+    const CATEGORY_DELETE_ENTRY      = 'delete_entry';
 
     const LOG_LIST_CATEGORIES = [
         self::CATEGORY_UPDATE_COMMENT, self::CATEGORY_UPDATE_DISCUSSION
@@ -48,7 +50,7 @@ class Log
     private $category;
 
     /**
-     * @ORM\Column(type="string", length=80)
+     * @ORM\Column(type="string", length=80, nullable=true)
      * @Groups({"log:read"})
      */
     private $blockCategory;
diff --git a/src/Manager/LogManager.php b/src/Manager/LogManager.php
index a04750d..8df1b14 100644
--- a/src/Manager/LogManager.php
+++ b/src/Manager/LogManager.php
@@ -32,16 +32,25 @@ class LogManager
     }
 
 
-    // Retourne les 5 derniers logs visibles par un user classés par date de création DESC
-    public function getLastLogsForEntry(Entry $entry, User $user)
+    // Retourne les 5 derniers logs d'une entrée classés par date de création DESC
+    public function getLastLogsForEntry(Entry $entry)
     {
         return $this->doctrine->getRepository(Log::class)->search([
-            'user' => $user,
             'entry' => $entry,
             'limit' => 5,
         ]);
     }
 
+
+    // Retourne les 5 derniers logs d'une entrée classés par date de création DESC
+    public function getLastLogsForLexicon(Lexicon $lexicon)
+    {
+        return $this->doctrine->getRepository(Log::class)->search([
+            'lexicon' => $lexicon,
+            'limit' => 5,
+        ]);
+    }
+
     // Retourne les logs visibles dans un lexique pour un user (pour une catégorie si renseignée)
     public function getVisibleLabelsInLexicon(Lexicon $lexicon, User $user, $category = null)
     {
diff --git a/src/Wikstraktor/wikstraktor.py b/src/Wikstraktor/wikstraktor.py
index fec1efb..8fa0ff7 100644
--- a/src/Wikstraktor/wikstraktor.py
+++ b/src/Wikstraktor/wikstraktor.py
@@ -599,16 +599,21 @@ class Wikstraktor:
 			pattern_ex = self.constants['sense_pattern'][0]["add_subdef"] + self.constants['sense_pattern'][0]["ex"]
 		#Process examples
 		a = 0
-		#print(newSense, sub_items)# DEBUG:
 		for item_list in sub_items:
 			if item_list.pattern == pattern_ex:
 				for item in item_list.items:
 					newSense.add_example(self.process_example(item))
 					#Si on veut traiter les sous items (ex traductions), on peut utiliser
-					#item_list.sublists(a)
 			if def_level and item_list.pattern == pattern_subdef:
+				b = 0
 				for item in item_list.items:
-					newSense.add_subsense(self.process_definition(item, item_list.sublists(a), False))
+					try:
+						sub_sub = item_list.sublists(b)
+					except IndexError as err:
+						sub_sub = []
+						print(f"There is an error in the selection of subitems:\n\t{b}th item of\n\t{itm_list.sublists()}\ntriggered {err}")
+					newSense.add_subsense(self.process_definition(item, sub_sub, False))
+					b += 1
 			a += 1
 		return newSense
 
diff --git a/templates/base.html.twig b/templates/base.html.twig
index cf11919..01f58a0 100644
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -20,8 +20,9 @@
         <script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script></head>
         <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
         {% include "js_translations.html.twig" %}
-<script src="{{ asset('assets/js/app.js') }}"></script>
-{% endblock %}
+        <script src="{{ asset('assets/js/app.js') }}"></script>
+    {% endblock %}
+
 <body {% if app.environment|upper == 'DEV' %}class="bg-dark-gray"{% endif %}>
 
 {% block nav %}
diff --git a/templates/bundles/TwigBundle/Exception/error.html.twig b/templates/bundles/TwigBundle/Exception/error.html.twig
new file mode 100644
index 0000000..0657ba7
--- /dev/null
+++ b/templates/bundles/TwigBundle/Exception/error.html.twig
@@ -0,0 +1,10 @@
+{% extends "errorLayout.html.twig" %}
+
+{% block title %}
+    Une erreur s'est produite
+{% endblock title %}
+
+{% block body %}
+        <br><br>
+        <h2>{{"Un problème est survenu. Nous sommes désolés pour le désagrément."|trans}}</h2>
+{% endblock %}
\ No newline at end of file
diff --git a/templates/bundles/TwigBundle/Exception/error403.html.twig b/templates/bundles/TwigBundle/Exception/error403.html.twig
new file mode 100644
index 0000000..69601c9
--- /dev/null
+++ b/templates/bundles/TwigBundle/Exception/error403.html.twig
@@ -0,0 +1,10 @@
+{% extends "errorLayout.html.twig" %}
+
+{% block title %}
+    Une erreur s'est produite
+{% endblock title %}
+
+{% block body %}
+        <br><br>
+        <h2>{{"Nous sommes désolés mais vous n'avez pas accès à cette page."|trans}}</h2>
+{% endblock %}
\ No newline at end of file
diff --git a/templates/bundles/TwigBundle/Exception/error404.html.twig b/templates/bundles/TwigBundle/Exception/error404.html.twig
new file mode 100644
index 0000000..64d519f
--- /dev/null
+++ b/templates/bundles/TwigBundle/Exception/error404.html.twig
@@ -0,0 +1,10 @@
+{% extends "errorLayout.html.twig" %}
+
+{% block title %}
+    Une erreur s'est produite
+{% endblock title %}
+
+{% block body %}
+        <br><br>
+        <h2>{{"Nous sommes désolés, la page que vous avez demandée n'existe pas."|trans}}</h2>
+{% endblock %}
\ No newline at end of file
diff --git a/templates/entry/_lexiconsTabs.html.twig b/templates/entry/_lexiconsTabs.html.twig
index ebefbdf..4e9110d 100644
--- a/templates/entry/_lexiconsTabs.html.twig
+++ b/templates/entry/_lexiconsTabs.html.twig
@@ -1,4 +1,4 @@
-<ul class="nav nav-tabs mt-3 justify-content-end">
+<ul class="nav nav-tabs justify-content-end">
     {% for lexicon in app.user.myLexicons %}
         {% set entryWithSameHeadwordInThisLexicon = lexicon.getEntryForHeadword(entry.headword) %}
 
diff --git a/templates/entry/show.html.twig b/templates/entry/show.html.twig
index cb5ed87..2033cf1 100644
--- a/templates/entry/show.html.twig
+++ b/templates/entry/show.html.twig
@@ -7,8 +7,7 @@
 {% block body %}
 
     <div class="row justify-content-center m-lg-5 m-sm-3">
-
-        <div class="col">
+        <div class="col-md-12">
 
             {% if entry.lexicon.newWords %}
                 <h1>
@@ -33,29 +32,33 @@
                 </h1>
             {% endif %}
 
-            {% if not entry.lexicon.newWords %}
-                {% include "entry/_lexiconsTabs.html.twig" %}
+            <div class="row">
 
-                <div id="tabContent" class="{{ entry.lexicon.zero ? 'tab-wiktionnary' }}">
+                <div class="col">
 
-                    <div class="row">
-                        <div class="col-sm-6 col-xl-4">
-                            {% include "entry/_entryLabels.html.twig" %}
-                        </div>
-                    </div>
+                    {% if not entry.lexicon.newWords %}
+                        {% include "entry/_lexiconsTabs.html.twig" %}
+
+                        <div id="tabContent" class="{{ entry.lexicon.zero ? 'tab-wiktionnary' }}">
+
+                            <div class="row">
+                                <div class="col-sm-6 col-xl-4">
+                                    {% include "entry/_entryLabels.html.twig" %}
+                                </div>
+                            </div>
+
+                            <div class="row">
+                                <div class="col-sm-9">
+                                    {% include "entry/_entryAttributes.html.twig" %}
+                                </div>
+                            </div>
 
-                    <div class="row">
-                        <div class="col-sm-9">
-                            {% include "entry/_entryAttributes.html.twig" %}
                         </div>
-                    </div>
+                    {% endif %}
 
                 </div>
-            {% endif %}
-
-        </div>
 
-        <div class="col-3 align-self-end">
+                <div class="col col-md-3 col-sm-12">
             <div id="history" class="grey-panel">
                 <h5>{{ "Historique des modifications"|trans }}</h5>
                 {% for log in log_manager.lastLogsForEntry(entry, app.user) %}
@@ -64,6 +67,9 @@
             </div>
         </div>
 
+            </div>
+
+        </div>
     </div>
 
 {% endblock %}
diff --git a/templates/errorLayout.html.twig b/templates/errorLayout.html.twig
new file mode 100644
index 0000000..bac7d4e
--- /dev/null
+++ b/templates/errorLayout.html.twig
@@ -0,0 +1,9 @@
+{% extends "base.html.twig" %}
+
+{% block nav %}
+<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
+    <div class="container-fluid">
+        <a class="navbar-brand" href="{{ path('app_login') }}">BALEX</a>
+    </div>
+</nav>
+{% endblock %}
diff --git a/templates/lexicon/show.html.twig b/templates/lexicon/show.html.twig
index d9f1452..4f5bffa 100644
--- a/templates/lexicon/show.html.twig
+++ b/templates/lexicon/show.html.twig
@@ -29,7 +29,8 @@
             </div>
 
             <div class="row mt-4">
-                <div class="col-md-12">
+
+                <div class="col">
 
                     <form name="entries_selection" id="entriesSelection" action="{{ path('app_lexicon_process_selected_entries', {id: lexicon.id}) }}" method="post" novalidate="novalidate" autocomplete="off">
 
@@ -121,6 +122,16 @@
                     </form>
 
                 </div>
+
+                <div class="col col-md-3">
+                    <div id="history" class="grey-panel">
+                        <h5>{{ "Historique des modifications"|trans }}</h5>
+                        {% for log in log_manager.lastLogsForLexicon(lexicon, app.user) %}
+                            <p>{% include "log/_formattedLog.html.twig" %}</p>
+                        {% endfor %}
+                    </div>
+                </div>
+
             </div>
 
         </div>
diff --git a/templates/log/_formattedLog.html.twig b/templates/log/_formattedLog.html.twig
index e1369a5..593ccaf 100644
--- a/templates/log/_formattedLog.html.twig
+++ b/templates/log/_formattedLog.html.twig
@@ -4,8 +4,16 @@
     {{ log.createdBy }}
     {% if log.content == 'add' %}{{ 'a ajouté'|trans }}{% endif %}
     {% if log.content == 'edit' %}{{ 'a modifié'|trans }}{% endif %}
-    {% if log.content == 'add' %}{{ 'a supprimé'|trans }}{% endif %}
+    {% if log.content == 'delete' %}{{ 'a supprimé'|trans }}{% endif %}
     {{ 'un bloc de type'|trans }}
     {{ log.blockCategory }}
 
+{% elseif log.category in [constant('App\\Entity\\Log::CATEGORY_ADD_ENTRY'), constant('App\\Entity\\Log::CATEGORY_DELETE_ENTRY')] %}
+
+    {{ log.createdAt|date('d/m/Y') }} :
+    {{ log.createdBy }}
+    {% if log.category == constant('App\\Entity\\Log::CATEGORY_ADD_ENTRY') %}{{ "a ajouté l'entrée"|trans }}{% endif %}
+    {% if log.category == constant('App\\Entity\\Log::CATEGORY_DELETE_ENTRY') %}{{ "a supprimé l'entrée"|trans }}{% endif %}
+    « {{ log.content }} »
+
 {% endif %}
\ No newline at end of file
-- 
GitLab