Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/config/packages/backoffice_menu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,14 @@ parameters:
forum_facturation:
nom: "Factures d'évènement"
niveau: 'ROLE_ADMIN'
forum_sessions:
talks:
nom: 'Conférences'
niveau: 'ROLE_FORUM'
url: '/admin/talk/'
extra_routes:
- admin_talk_list
- admin_talk_add
- admin_talk_edit
forum_vote_github:
nom: 'Votes visiteurs'
niveau: 'ROLE_FORUM'
Expand Down
16 changes: 16 additions & 0 deletions app/config/routing/admin_talk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@ admin_talk_list:
path: /
defaults: {_controller: AppBundle\Controller\Admin\Talk\IndexAction}

admin_talk_add:
path: /add
defaults: {_controller: AppBundle\Controller\Admin\Talk\AddAction}

admin_talk_edit:
path: /edit/{id}
defaults: {_controller: AppBundle\Controller\Admin\Talk\EditAction}
requirements:
id: \d+

admin_talk_delete:
path: /delete/{id}
defaults: {_controller: AppBundle\Controller\Admin\Talk\DeleteAction}
requirements:
id: \d+

admin_talk_export_joind_in:
path: /export/joind-in/{eventId}/
defaults: {_controller: AppBundle\Controller\Admin\Talk\ExportJoindInAction}
Expand Down
4 changes: 3 additions & 1 deletion sources/AppBundle/Controller/Admin/HomeAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Psr\Clock\ClockInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class HomeAction extends AbstractController
{
Expand All @@ -27,6 +28,7 @@ public function __construct(
private readonly StatisticsComputer $statisticsComputer,
private readonly ClockInterface $clock,
private readonly Authentication $authentication,
private readonly UrlGeneratorInterface $urlGenerator,
) {}

public function __invoke(): Response
Expand All @@ -37,7 +39,7 @@ public function __invoke(): Response
$cfp = [
'title' => 'CFP',
'subtitle' => 'Talks et speakers',
'url' => '/pages/administration/index.php?page=forum_sessions',
'url' => $this->urlGenerator->generate('admin_talk_list'),
'statistics' => [],
];

Expand Down
51 changes: 51 additions & 0 deletions sources/AppBundle/Controller/Admin/Talk/AddAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace AppBundle\Controller\Admin\Talk;

use AppBundle\AuditLog\Audit;
use AppBundle\Event\AdminEventSelection;
use AppBundle\Event\Form\TalkAdminType;
use AppBundle\Event\Model\Repository\TalkRepository;
use AppBundle\Event\Model\Repository\TalkToSpeakersRepository;
use AppBundle\Event\Model\Talk;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class AddAction extends AbstractController
{
public function __construct(
private readonly TalkRepository $talkRepository,
private readonly TalkToSpeakersRepository $talkToSpeakersRepository,
private readonly Audit $audit,
) {}

public function __invoke(Request $request, AdminEventSelection $eventSelection): Response
{
$talk = new Talk();
$talk->setForumId($eventSelection->event->getId());

$form = $this->createForm(TalkAdminType::class, $talk, [
'event' => $eventSelection->event,
]);

$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->talkRepository->save($talk);
$this->talkToSpeakersRepository->replaceSpeakers($talk, $form->get('speakers')->getData());

$this->audit->log(sprintf('Ajout de la session de %s', $talk->getTitle()));
$this->addFlash('notice', 'La conférence a été ajoutée.');

return $this->redirectToRoute('admin_talk_list');
}

return $this->render('admin/talk/add.html.twig', [
'event' => $eventSelection->event,
'form' => $form,
]);
}

}
35 changes: 35 additions & 0 deletions sources/AppBundle/Controller/Admin/Talk/DeleteAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace AppBundle\Controller\Admin\Talk;

use AppBundle\AuditLog\Audit;
use AppBundle\Event\Model\Repository\TalkRepository;
use AppBundle\Event\Model\Talk;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DeleteAction extends AbstractController
{
public function __construct(
private readonly TalkRepository $talkRepository,
private readonly Audit $audit,
) {}

public function __invoke(int $id, Request $request): Response
{
$talk = $this->talkRepository->get($id);
if (!$talk instanceof Talk) {
throw $this->createNotFoundException(sprintf('Talk not found with id "%s"', $id));
}
$this->talkRepository->delete($talk);

$this->audit->log(sprintf('Suppression de la session de %s (%d)', $talk->getTitle(), $talk->getId()));
$this->addFlash('notice', 'La conférence a été supprimée.');

return $this->redirectToRoute('admin_talk_list');
}

}
62 changes: 62 additions & 0 deletions sources/AppBundle/Controller/Admin/Talk/EditAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace AppBundle\Controller\Admin\Talk;

use AppBundle\AuditLog\Audit;
use AppBundle\Event\Form\TalkAdminType;
use AppBundle\Event\Form\TalkType;
use AppBundle\Event\Model\Event;
use AppBundle\Event\Model\Repository\EventRepository;
use AppBundle\Event\Model\Repository\TalkRepository;
use AppBundle\Event\Model\Repository\TalkToSpeakersRepository;
use AppBundle\Event\Model\Talk;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class EditAction extends AbstractController
{
public function __construct(
private readonly EventRepository $eventRepository,
private readonly TalkRepository $talkRepository,
private readonly TalkToSpeakersRepository $talkToSpeakersRepository,
private readonly Audit $audit,
) {}

public function __invoke(int $id, Request $request): Response
{
$talk = $this->talkRepository->get($id);
if (!$talk instanceof Talk) {
throw $this->createNotFoundException(sprintf('Talk not found with id "%s"', $id));
}
$event = $this->eventRepository->get($talk->getForumId());
if (!$event instanceof Event) {
throw $this->createNotFoundException(sprintf('Event not found with id "%s"', $talk->getForumId()));
}

$form = $this->createForm(TalkAdminType::class, $talk, [
'event' => $event,
TalkType::OPT_COC_CHECKED => true,
]);

$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->talkRepository->save($talk);
$this->talkToSpeakersRepository->replaceSpeakers($talk, $form->get('speakers')->getData());

$this->audit->log(sprintf('Modification de la session de %s (%d)', $talk->getTitle(), $talk->getId()));
$this->addFlash('notice', 'La conférence a été modifiée.');

return $this->redirectToRoute('admin_talk_list');
}

return $this->render('admin/talk/edit.html.twig', [
'event' => $event,
'form' => $form,
'talk' => $talk,
]);
}

}
9 changes: 0 additions & 9 deletions sources/AppBundle/Controller/Admin/Talk/IndexAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,6 @@ public function __construct(

public function __invoke(Request $request, AdminEventSelection $eventSelection): Response
{
//TODO : à supprimer quand les actions via le formulaire auront été migrées
if (isset($_SESSION['flash']['message'])) {
$this->addFlash('notice', $_SESSION['flash']['message']);
}
if (isset($_SESSION['flash']['erreur'])) {
$this->addFlash('error', $_SESSION['flash']['erreur']);
}
unset($_SESSION['flash']);

$event = $eventSelection->event;

$data = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public function __invoke(Request $request): RedirectResponse

$this->addFlash('notice', 'Indexation effectuée');

return $this->redirect($request->headers->get('referer', '/pages/administration/index.php?page=forum_sessions'));
return $this->redirect($request->headers->get('referer', $this->generateUrl('admin_talk_list')));
}
}
112 changes: 112 additions & 0 deletions sources/AppBundle/Event/Form/TalkAdminType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace AppBundle\Event\Form;

use AppBundle\Event\Model\Repository\SpeakerRepository;
use AppBundle\Event\Model\Speaker;
use AppBundle\Event\Model\Talk;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TalkAdminType extends TalkType
{
public function __construct(private readonly SpeakerRepository $speakerRepository) {}

public function buildForm(FormBuilderInterface $builder, array $options): void
{
parent::buildForm($builder, $options);

$allSpeakers = $this->speakerRepository->searchSpeakers($options['event']);
$speakers = $this->speakerRepository->getSpeakersByTalk($builder->getData());
$speakers = iterator_to_array($speakers->getIterator());

$builder->remove('hasAllowedToSharingWithLocalOffices');
$builder
->add('hasAllowedToSharingWithLocalOffices', CheckboxType::class, [
'label' => 'Autoriser l’AFUP à transmettre ma proposition de conférence à ses antennes locales ?',
'required' => false,
])
->add('joindinId', TextType::class, [
'label' => 'joind.in ID',
'required' => false,
'attr' => ['placeholder' => '4639e'],
])
->add('youtubeId', TextType::class, [
'label' => 'Youtube ID',
'required' => false,
'attr' => ['placeholder' => '9P7K3sdg6s4'],
])
->add('slidesUrl', UrlType::class, [
'label' => 'URL des slides',
'required' => false,
'default_protocol' => 'https',
'attr' => ['placeholder' => 'https://'],
])
->add('openfeedbackPath', TextType::class, [
'label' => 'Open Feedback (path)',
'required' => false,
'attr' => ['placeholder' => 'forumphp2025/2025-10-09/5394'],
])
->add('blogPostUrl', UrlType::class, [
'label' => 'URL du blog',
'required' => false,
'default_protocol' => 'https',
'attr' => ['placeholder' => 'https://'],
])
->add('interviewUrl', UrlType::class, [
'label' => 'URL de l\'interview',
'required' => false,
'default_protocol' => 'https',
'attr' => ['placeholder' => 'https://'],
])
->add('languageCode', ChoiceType::class, [
'label' => 'Langue',
'required' => false,
'choices' => array_flip(Talk::getLanguageLabelsByKey()),
])
->add('tweets', TextareaType::class, [
'label' => 'Tweets',
'required' => false,
])
->add('submittedOn', DateTimeType::class, [
'label' => 'Date de soumission',
])
->add('publishedOn', DateTimeType::class, [
'label' => 'Date de publication',
'required' => false,
])
->add('speakers', ChoiceType::class, [
'mapped' => false,
'multiple' => true,
'choices' => $allSpeakers,
'required' => false,
'data' => $speakers,
'choice_label' => fn(Speaker $speaker) => $speaker->getLabel(),
'choice_value' => fn(?Speaker $speaker) => $speaker?->getId(),
'choice_name' => 'id',
])
->add('verbatim', TextareaType::class, [
'label' => 'Verbatim',
'required' => false,
])
->add('save', SubmitType::class)
;
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefault('data_class', Talk::class);
$resolver->setDefault('event', EventType::class);

parent::configureOptions($resolver);
}
}
8 changes: 8 additions & 0 deletions sources/AppBundle/Event/Model/Repository/TalkRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,14 @@ public static function initMetadata(SerializerFactoryInterface $serializerFactor
'unserialize' => ['unSerializeUseFormat' => false],
],
])
->addField([
'columnName' => 'date_publication',
'fieldName' => 'publishedOn',
'type' => 'datetime',
'serializer_options' => [
'unserialize' => ['unSerializeUseFormat' => false],
],
])
->addField([
'columnName' => 'titre',
'fieldName' => 'title',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function replaceSpeakers(Talk $talk, array $speakers): void
{
$this->startTransaction();
try {
$delete = $this->getPreparedQuery('DELETE FROM afup_conferenciers_sessions WHERE talk_id = :talk');
$delete = $this->getPreparedQuery('DELETE FROM afup_conferenciers_sessions WHERE session_id = :talk');
$delete->setParams(['talk' => $talk->getId()])->execute();

$insert = $this->getPreparedQuery('INSERT INTO afup_conferenciers_sessions (conferencier_id, session_id) VALUES (:speaker, :talk)');
Expand Down
Loading