From 92541e2e8be5b90debca0030fe45cac3604103e7 Mon Sep 17 00:00:00 2001 From: Baptiste Leduc Date: Mon, 21 Sep 2026 19:14:13 +0000 Subject: [PATCH] =?UTF-8?q?Migre=20l'entit=C3=A9=20Ting=20EventTheme=20ver?= =?UTF-8?q?s=20Doctrine=20(#2383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Event/EventEditorializationAction.php | 12 +-- .../Admin/Event/EventThemeAction.php | 10 +-- .../Admin/Event/EventThemeAddEditAction.php | 14 +-- .../Controller/Event/Blog/ProgramAction.php | 8 +- sources/AppBundle/Event/Entity/EventTheme.php | 30 +++++++ .../Repository/EventThemeRepository.php | 28 ++++++ .../AppBundle/Event/Form/EventThemeType.php | 2 +- sources/AppBundle/Event/Model/EventTheme.php | 86 ------------------- .../Model/Repository/EventThemeRepository.php | 26 ------ .../Repository/EventThemeRepositoryTest.php | 57 ++++++++++++ 10 files changed, 138 insertions(+), 135 deletions(-) create mode 100644 sources/AppBundle/Event/Entity/EventTheme.php create mode 100644 sources/AppBundle/Event/Entity/Repository/EventThemeRepository.php delete mode 100644 sources/AppBundle/Event/Model/EventTheme.php delete mode 100644 sources/AppBundle/Event/Model/Repository/EventThemeRepository.php create mode 100644 tests/integration/AppBundle/Event/Entity/Repository/EventThemeRepositoryTest.php diff --git a/sources/AppBundle/Controller/Admin/Event/EventEditorializationAction.php b/sources/AppBundle/Controller/Admin/Event/EventEditorializationAction.php index ad03ddcf1..937ebe31e 100644 --- a/sources/AppBundle/Controller/Admin/Event/EventEditorializationAction.php +++ b/sources/AppBundle/Controller/Admin/Event/EventEditorializationAction.php @@ -5,8 +5,8 @@ namespace AppBundle\Controller\Admin\Event; use AppBundle\Event\AdminEventSelection; +use AppBundle\Event\Entity\Repository\EventThemeRepository; use AppBundle\Event\Model\Event; -use AppBundle\Event\Model\Repository\EventThemeRepository; use AppBundle\Event\Model\Repository\TalkRepository; use AppBundle\Event\Model\Talk; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -31,7 +31,7 @@ public function __invoke(Request $request, AdminEventSelection $eventSelection): $eventId = $event->getId() ?? 0; $hasThemes = $event->getHasThemes(); - $themes = $hasThemes ? iterator_to_array($this->eventThemeRepository->getByThemesOrderedByPriority($eventId)) : []; + $themes = $hasThemes ? $this->eventThemeRepository->getByThemesOrderedByPriority($eventId) : []; $scheduledTalks = iterator_to_array($this->talkRepository->getScheduledTalksByEvent($eventId)); $talkGroups = $this->groupTalks($scheduledTalks, $themes, $hasThemes); @@ -47,8 +47,8 @@ public function __invoke(Request $request, AdminEventSelection $eventSelection): /** * @param array $scheduledTalks - * @param array<\AppBundle\Event\Model\EventTheme> $themes - * @return array}> + * @param array<\AppBundle\Event\Entity\EventTheme> $themes + * @return array}> */ private function groupTalks(array $scheduledTalks, array $themes, bool $hasThemes): array { @@ -61,7 +61,7 @@ private function groupTalks(array $scheduledTalks, array $themes, bool $hasTheme $talksByThemeId = []; foreach ($themes as $theme) { - $talksByThemeId[(int) $theme->getId()] = []; + $talksByThemeId[(int) $theme->id] = []; } $noThemeTalks = []; @@ -78,7 +78,7 @@ private function groupTalks(array $scheduledTalks, array $themes, bool $hasTheme $groups = [['theme' => null, 'talks' => $noThemeTalks]]; foreach ($themes as $theme) { - $talks = $talksByThemeId[(int) $theme->getId()]; + $talks = $talksByThemeId[(int) $theme->id]; usort($talks, $this->compareTalks(...)); $groups[] = ['theme' => $theme, 'talks' => $talks]; } diff --git a/sources/AppBundle/Controller/Admin/Event/EventThemeAction.php b/sources/AppBundle/Controller/Admin/Event/EventThemeAction.php index 34f244015..10431d338 100644 --- a/sources/AppBundle/Controller/Admin/Event/EventThemeAction.php +++ b/sources/AppBundle/Controller/Admin/Event/EventThemeAction.php @@ -5,8 +5,8 @@ namespace AppBundle\Controller\Admin\Event; use AppBundle\Event\AdminEventSelection; +use AppBundle\Event\Entity\Repository\EventThemeRepository; use AppBundle\Event\Model\Event; -use AppBundle\Event\Model\Repository\EventThemeRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -25,11 +25,11 @@ public function __invoke(Request $request, AdminEventSelection $eventSelection): return $this->handleAjaxRequest($request, $event); } if ($request->getMethod() === 'POST' && $request->request->has('delete')) { - $theme = $this->eventThemeRepository->get($request->request->getInt('theme_id')); + $theme = $this->eventThemeRepository->find($request->request->getInt('theme_id')); if ($theme === null) { $this->addFlash('error', 'Thème introuvable.'); } else { - $name = $theme->getName(); + $name = $theme->name; $this->eventThemeRepository->delete($theme); $this->addFlash('notice', sprintf('Le thème "%s" a été supprimé.', $name)); } @@ -61,12 +61,12 @@ private function updateThemePriority(Request $request): JsonResponse $themeId = $request->request->getInt('theme_id'); $priority = $request->request->getInt('priority'); - $theme = $this->eventThemeRepository->get($themeId); + $theme = $this->eventThemeRepository->find($themeId); if (!$theme) { return new JsonResponse(['error' => 'Thème non trouvé'], 404); } - $theme->setPriority($priority); + $theme->priority = $priority; $this->eventThemeRepository->save($theme); return new JsonResponse(['success' => true]); diff --git a/sources/AppBundle/Controller/Admin/Event/EventThemeAddEditAction.php b/sources/AppBundle/Controller/Admin/Event/EventThemeAddEditAction.php index dac4cf641..0f98ef46e 100644 --- a/sources/AppBundle/Controller/Admin/Event/EventThemeAddEditAction.php +++ b/sources/AppBundle/Controller/Admin/Event/EventThemeAddEditAction.php @@ -4,12 +4,12 @@ namespace AppBundle\Controller\Admin\Event; +use AppBundle\Event\Entity\EventTheme; +use AppBundle\Event\Entity\Repository\EventThemeRepository; use AppBundle\Event\Form\EventThemeType; -use AppBundle\Event\Model\EventTheme; use AppBundle\Event\Model\Repository\EventRepository; -use AppBundle\Event\Model\Repository\EventThemeRepository; use AppBundle\Event\Model\Repository\TalkRepository; -use CCMBenchmark\TingBundle\Attribute\MapEntity; +use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -29,12 +29,12 @@ public function __invoke(Request $request, #[MapEntity] ?EventTheme $eventTheme $new = true; $eventTheme = new EventTheme(); if ($request->query->has('idForum')) { - $eventTheme->setIdForum($request->query->getInt('idForum')); + $eventTheme->idForum = $request->query->getInt('idForum'); } } else { - $event = $this->eventRepository->get($eventTheme->getIdForum()); + $event = $this->eventRepository->get($eventTheme->idForum); if ($event !== null) { - $talks = $this->talkRepository->getByEventWithSpeakers($event, false, false, $eventTheme->getId()); + $talks = $this->talkRepository->getByEventWithSpeakers($event, false, false, $eventTheme->id); } } @@ -45,7 +45,7 @@ public function __invoke(Request $request, #[MapEntity] ?EventTheme $eventTheme $this->eventThemeRepository->save($eventTheme); $this->addFlash('notice', 'Thème ' . ($new ? 'ajouté' : 'modifié')); - return $this->redirectToRoute('admin_event_themes_list', ['id' => $eventTheme->getIdForum()]); + return $this->redirectToRoute('admin_event_themes_list', ['id' => $eventTheme->idForum]); } return $this->render('admin/event/theme_add_edit.html.twig', [ diff --git a/sources/AppBundle/Controller/Event/Blog/ProgramAction.php b/sources/AppBundle/Controller/Event/Blog/ProgramAction.php index 7892574df..0f49fc972 100644 --- a/sources/AppBundle/Controller/Event/Blog/ProgramAction.php +++ b/sources/AppBundle/Controller/Event/Blog/ProgramAction.php @@ -5,8 +5,8 @@ namespace AppBundle\Controller\Event\Blog; use AppBundle\Controller\Event\EventActionHelper; +use AppBundle\Event\Entity\Repository\EventThemeRepository; use AppBundle\Event\JsonLd; -use AppBundle\Event\Model\Repository\EventThemeRepository; use AppBundle\Event\Model\Repository\TalkRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -28,9 +28,9 @@ public function __invoke(Request $request, $eventSlug): Response $talkAggregates = $this->talkRepository->getByEventWithSpeakers($event, $request->query->getBoolean('apply-publication-date-filters', true), $event->getHasThemes()); $themes = null; if ($event->getHasThemes()) { - $themes = iterator_to_array($this->eventThemeRepository->getBy(['idForum' => $event->getId()])); - usort($themes, fn($a, $b): int => $a->getPriority() === $b->getPriority() ? $a->getName() <=> $b->getName() : $a->getPriority() <=> $b->getPriority()); - $themes = array_combine(array_map(fn($theme): int => (int) $theme->getId(), $themes), $themes); + $themes = $this->eventThemeRepository->findBy(['idForum' => $event->getId()]); + usort($themes, fn($a, $b): int => $a->priority === $b->priority ? $a->name <=> $b->name : $a->priority <=> $b->priority); + $themes = array_combine(array_map(fn($theme): int => (int) $theme->id, $themes), $themes); } $now = new \DateTime(); diff --git a/sources/AppBundle/Event/Entity/EventTheme.php b/sources/AppBundle/Event/Entity/EventTheme.php new file mode 100644 index 000000000..0066a2d84 --- /dev/null +++ b/sources/AppBundle/Event/Entity/EventTheme.php @@ -0,0 +1,30 @@ + 0])] + public int $priority = 0; +} diff --git a/sources/AppBundle/Event/Entity/Repository/EventThemeRepository.php b/sources/AppBundle/Event/Entity/Repository/EventThemeRepository.php new file mode 100644 index 000000000..37e1d45a4 --- /dev/null +++ b/sources/AppBundle/Event/Entity/Repository/EventThemeRepository.php @@ -0,0 +1,28 @@ + + */ +final class EventThemeRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, EventTheme::class); + } + + /** + * @return array + */ + public function getByThemesOrderedByPriority(int $eventId): array + { + return $this->findBy(['idForum' => $eventId], ['priority' => 'ASC', 'name' => 'ASC']); + } +} diff --git a/sources/AppBundle/Event/Form/EventThemeType.php b/sources/AppBundle/Event/Form/EventThemeType.php index b4f6720e1..0209c7a64 100644 --- a/sources/AppBundle/Event/Form/EventThemeType.php +++ b/sources/AppBundle/Event/Form/EventThemeType.php @@ -4,9 +4,9 @@ namespace AppBundle\Event\Form; +use AppBundle\Event\Entity\EventTheme; use AppBundle\Event\Form\Support\EventHelper; use AppBundle\Event\Model\Event; -use AppBundle\Event\Model\EventTheme; use AppBundle\Event\Model\Repository\EventRepository; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\CallbackTransformer; diff --git a/sources/AppBundle/Event/Model/EventTheme.php b/sources/AppBundle/Event/Model/EventTheme.php deleted file mode 100644 index fb88ddab7..000000000 --- a/sources/AppBundle/Event/Model/EventTheme.php +++ /dev/null @@ -1,86 +0,0 @@ -id; - } - - public function setId(?int $id): void - { - $this->propertyChanged('id', $this->id ?? null, $id); - $this->id = $id; - } - - public function getIdForum(): ?int - { - return $this->idForum; - } - - public function setIdForum(?int $idForum): void - { - $this->propertyChanged('idForum', $this->idForum ?? null, $idForum); - $this->idForum = $idForum; - } - - public function getName(): string - { - return $this->name; - } - - public function setName(string $name): void - { - $this->propertyChanged('name', $this->name ?? '', $name); - $this->name = $name; - } - - public function getDescription(): string - { - return $this->description; - } - - public function setDescription(string $description): void - { - $this->propertyChanged('description', $this->description ?? '', $description); - $this->description = $description; - } - - public function getPriority(): int - { - return $this->priority; - } - - public function setPriority(int $priority): void - { - $this->propertyChanged('priority', $this->priority, $priority); - $this->priority = $priority; - } -} diff --git a/sources/AppBundle/Event/Model/Repository/EventThemeRepository.php b/sources/AppBundle/Event/Model/Repository/EventThemeRepository.php deleted file mode 100644 index 8c1cb1ea9..000000000 --- a/sources/AppBundle/Event/Model/Repository/EventThemeRepository.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ -class EventThemeRepository extends Repository -{ - /** - * @return CollectionInterface - */ - public function getByThemesOrderedByPriority(int $eventId): CollectionInterface - { - return $this->getPreparedQuery( - 'SELECT * FROM afup_conference_theme WHERE id_forum = :idForum ORDER BY priority ASC, name ASC', - )->setParams(['idForum' => $eventId])->query($this->getCollection(new HydratorSingleObject())); - } -} diff --git a/tests/integration/AppBundle/Event/Entity/Repository/EventThemeRepositoryTest.php b/tests/integration/AppBundle/Event/Entity/Repository/EventThemeRepositoryTest.php new file mode 100644 index 000000000..bacb4cf83 --- /dev/null +++ b/tests/integration/AppBundle/Event/Entity/Repository/EventThemeRepositoryTest.php @@ -0,0 +1,57 @@ +get(EventThemeRepository::class); + + $themeAtelier = $this->buildEventTheme(42, 'Atelier', 2, 'Description de l\'atelier'); + $themeConference = $this->buildEventTheme(42, 'Conference', 1, null); + $themeLightning = $this->buildEventTheme(42, 'Lightning talks', 1, null); + $themeAutreEvenement = $this->buildEventTheme(43, 'Autre evenement', 3, null); + + $eventThemeRepository->save($themeAtelier); + $eventThemeRepository->save($themeConference); + $eventThemeRepository->save($themeLightning); + $eventThemeRepository->save($themeAutreEvenement); + + $loaded = $eventThemeRepository->find($themeAtelier->id); + self::assertInstanceOf(EventTheme::class, $loaded); + self::assertSame('Atelier', $loaded->name); + self::assertSame(42, $loaded->idForum); + self::assertSame('Description de l\'atelier', $loaded->description); + self::assertSame(2, $loaded->priority); + self::assertNull($themeConference->description); + + // Tri attendu : priorité croissante puis nom alphabétique, filtré par évènement + $themes = $eventThemeRepository->getByThemesOrderedByPriority(42); + self::assertSame(['Conference', 'Lightning talks', 'Atelier'], array_map(fn(EventTheme $theme): string => $theme->name, $themes)); + self::assertCount(0, $eventThemeRepository->getByThemesOrderedByPriority(99)); + + // L'identifiant est réinitialisé par Doctrine après la suppression, on le récupère avant + $lightningThemeId = $themeLightning->id; + $eventThemeRepository->delete($themeLightning); + self::assertNull($eventThemeRepository->find($lightningThemeId)); + self::assertCount(2, $eventThemeRepository->getByThemesOrderedByPriority(42)); + } + + private function buildEventTheme(int $idForum, string $name, int $priority, ?string $description): EventTheme + { + $eventTheme = new EventTheme(); + $eventTheme->idForum = $idForum; + $eventTheme->name = $name; + $eventTheme->description = $description; + $eventTheme->priority = $priority; + + return $eventTheme; + } +}