diff --git a/.gitignore b/.gitignore index bc4051933364022b4ed91f9c8dae00871d6e3093..5353ef76120c7f631738534ce0e406af3c6800a6 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 2e1f604f0218824ac26a171e489148ad3f6f7784..bb7980feb353054d28597d94c2dc97c1a20fcfd4 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 d7f8ffcbedd7072c87601b70ef10c4235968ecfa..f2ba84256ddac5f49e4bceef2468f663401bd828 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 99749e505f583fbfc212836bb34b1913b1774d98..8955781c994dcfbdf67bacd783b13a5e0e11e453 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 7b11e81fdbc14f02fa92830e1e0917036b77225f..5b308df16b24a77c78b30fb0556c6fb60b9c42c9 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 49d1015f9aefe8f5e1bd885cfd4d0da63109ba7e..f8aa3eea9915fef3234f4ab9ec12028f3bedf57c 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 a04750d501a69ff4fd3296b98580a456b52b9344..8df1b1480ee585828f62bbeeff1272a1bc656b93 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 fec1efb131518ec026be156fa3cdd4f42538cf62..8fa0ff7f6e4fa8275292f8673462760669f1da27 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 cf119190494db4a8fb68f431200faf03b479abf9..01f58a0dcad5d4a02b2d86aaee00da1bff635678 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 0000000000000000000000000000000000000000..0657ba7073a6c7c18a7b1bfbccecbc9d16d95ec9 --- /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 0000000000000000000000000000000000000000..69601c9de63f45584afccee477d396f09ec51cde --- /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 0000000000000000000000000000000000000000..64d519f264863fe3356f6655fec10c2f4ee1154c --- /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 ebefbdf180a88be3d814d63c471a0f95adba1ca3..4e9110d7cdac20a650272f0d307da5d3cc61c7e6 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 cb5ed87dd5c656a5d6fc24f2601334f6c4847e67..2033cf185404c262dfd7c608b0ee6ddbfdbbcd88 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 0000000000000000000000000000000000000000..bac7d4ee268860588f3a48b00186eb5a64b57d09 --- /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 d9f1452531e774c5f9f7e436389d73c484ff609b..4f5bffa9cd6761d159133ee7ca12c1537db3df7d 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 e1369a5c576bb7c586671a1017c74d4f9a896a58..593ccaff232783afbc184de51ab731c6494d9425 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