From 2b6b59934c51bdc88161ad05855bcd565a8565e5 Mon Sep 17 00:00:00 2001 From: pfleu <fleutotp@gmail.com> Date: Mon, 12 Jun 2023 09:23:05 +0200 Subject: [PATCH] =?UTF-8?q?Notifications=20permanentes=20:=20affichage=20d?= =?UTF-8?q?es=20modifs=20depuis=20derni=C3=A8re=20connexion=20:=20mots=20a?= =?UTF-8?q?jout=C3=A9s=20/modifi=C3=A9s=20dans=20les=20groupes=20et=20dans?= =?UTF-8?q?=20l'agora.=20Ajout=20date=20login=20sur=20entit=C3=A9=20User.?= =?UTF-8?q?=20Ajout=20listener=20pour=20stocker=20cette=20date=20automatiq?= =?UTF-8?q?uement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Entity/User.php | 34 +++++++++++++++- src/EventListener/SecuritySubscriber.php | 49 ++++++++++++++++++++++++ src/Manager/LexiconManager.php | 20 ++++++++++ src/Repository/EntryRepository.php | 30 +++++++++++++++ templates/notifications.html.twig | 35 +++++++++++++++-- 5 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 src/EventListener/SecuritySubscriber.php diff --git a/src/Entity/User.php b/src/Entity/User.php index 76075f3..fb166b6 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -92,6 +92,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface */ private $updatedAt; + /** + * @ORM\Column(type="datetime_immutable", nullable=true) + */ + private $loggedAt; + /** * @var boolean * @ORM\Column(type="boolean") @@ -331,8 +336,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface } /** - * @return Lexicon[] - */ + * @return Lexicon[] + */ public function getMyLexicons() { $result = []; @@ -344,6 +349,19 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $result; } + /** + * @return Lexicon[] + */ + public function getMyGroupLexicons() + { + $result = []; + foreach ($this->getMyGroups() as $group) { // Ajout des lexiques de groupes + $result[] = $group->getLexicon(); + } + + return $result; + } + /** * @return Group[] */ @@ -1230,4 +1248,16 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $this; } + public function getLoggedAt(): ?\DateTimeImmutable + { + return $this->loggedAt; + } + + public function setLoggedAt(?\DateTimeImmutable $loggedAt): self + { + $this->loggedAt = $loggedAt; + + return $this; + } + } diff --git a/src/EventListener/SecuritySubscriber.php b/src/EventListener/SecuritySubscriber.php new file mode 100644 index 0000000..d8f20c1 --- /dev/null +++ b/src/EventListener/SecuritySubscriber.php @@ -0,0 +1,49 @@ +<?php + +namespace App\EventListener; + +use App\Entity\User; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; +use Symfony\Component\Security\Http\SecurityEvents; + +/** + * @package App\EventListener + */ +class SecuritySubscriber implements EventSubscriberInterface +{ + /** + * @var EntityManagerInterface + */ + private $em; + + /** + * @param EntityManagerInterface $em + */ + public function __construct(EntityManagerInterface $em) + { + $this->em = $em; + } + + /** + * @return array + */ + public static function getSubscribedEvents(): array + { + return [ + SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin', + ]; + } + + public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void + { + $user = $event->getAuthenticationToken()->getUser(); + if ($user instanceof User) { + $user->setLoginDate(new \DateTime()); + + $this->em->persist($user); + $this->em->flush(); + } + } +} \ No newline at end of file diff --git a/src/Manager/LexiconManager.php b/src/Manager/LexiconManager.php index c816da9..7a9c5f7 100644 --- a/src/Manager/LexiconManager.php +++ b/src/Manager/LexiconManager.php @@ -89,4 +89,24 @@ class LexiconManager return $this->doctrine->getRepository(Entry::class)->getLastEntries($newWordsLexicon); } + + /** + * @param $language + * @return integer + */ + public function getEntriesAddedNbSinceLastLogging(Lexicon $lexicon, User $user) + { + $date = $user->getLoggedAt(); + return count($this->doctrine->getRepository(Entry::class)->getEntriesAddedSince($lexicon, $date)); + } + + /** + * @param $language + * @return integer + */ + public function getEntriesUpdatedNbSinceLastLogging(Lexicon $lexicon, User $user) + { + $date = $user->getLoggedAt(); + return count($this->doctrine->getRepository(Entry::class)->getEntriesUpdatedSince($lexicon, $date)); + } } diff --git a/src/Repository/EntryRepository.php b/src/Repository/EntryRepository.php index 2d2cef6..309ca7f 100644 --- a/src/Repository/EntryRepository.php +++ b/src/Repository/EntryRepository.php @@ -106,6 +106,36 @@ class EntryRepository extends ServiceEntityRepository ; } + /** + * @return integer + */ + public function getEntriesAddedSince(Lexicon $lexicon, $date): array + { + return $this->createQueryBuilder('e') + ->andWhere('e.lexicon = :lexicon') + ->setParameter('lexicon', $lexicon) + ->andWhere('e.createdAt >= :date') + ->setParameter('date', $date) + ->getQuery() + ->getResult() + ; + } + + /** + * @return integer + */ + public function getEntriesUpdatedSince(Lexicon $lexicon, $date): array + { + return $this->createQueryBuilder('e') + ->andWhere('e.lexicon = :lexicon') + ->setParameter('lexicon', $lexicon) + ->andWhere('e.updatedAt >= :date') + ->setParameter('date', $date) + ->getQuery() + ->getResult() + ; + } + /** * @return Entry[] Returns an array of Entry objects */ diff --git a/templates/notifications.html.twig b/templates/notifications.html.twig index c3f0d30..691035a 100644 --- a/templates/notifications.html.twig +++ b/templates/notifications.html.twig @@ -28,12 +28,39 @@ {% endif %} <h2>{{ "Notifications permanentes"|trans }}</h2> - <div class="notifications-item"> <img src="https://img.icons8.com/flat_round/64/000000/vote-badge.png" alt="img"> - <div class="text"> - <h4>John Silvester</h4> - <p>+20 vista badge earned</p> + + {% for lexicon in app.user.myGroupLexicons %} + <div class="notifications-item d-flex justify-content-between align-items-center"> + <a href="{{ path('app_lexicon_show', {id: lexicon.id}) }}"> + <div class="d-flex justify-content-start align-items-center"> + {{ lexicon|badge }} + <div class="text ps-3"> + <h4>{{ lexicon }}</h4> + <p> + {{ "Entrées ajoutées:" }} {{ lexicon_manager.entriesAddedNbSinceLastLogging(lexicon, app.user) }} + {{ "Entrées modifiées:" }} {{ lexicon_manager.entriesUpdatedNbSinceLastLogging(lexicon, app.user) }} + </p> + </div> + </div> + </a> </div> + {% endfor %} + + <div class="notifications-item d-flex justify-content-between align-items-center"> + {% set newWordsLexicon = lexicon_manager.newWordsLexicon %} + <a href="{{ path('app_lexicon_show', {id: newWordsLexicon.id}) }}"> + <div class="d-flex justify-content-start align-items-center"> + {{ newWordsLexicon|badge }} + <div class="text ps-3"> + <h4>{{ "Propositions de mots dans l'agora" }}</h4> + <p> + {{ "Nombre:" }} {{ lexicon_manager.entriesAddedNbSinceLastLogging(newWordsLexicon, app.user) }} + </p> + </div> + </div> + </a> </div> + </div> {#{% macro actions(notification) %}#} -- GitLab