src/Controller/Admin/ForumReponseCrudController.php line 312

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Admin;
  3. use App\Entity\ForumReponse;
  4. use App\Entity\Sujetforum;
  5. use App\Entity\User;
  6. use App\Form\CommentResponseForumType;
  7. use App\Repository\ForumReponseRepository;
  8. use App\Service\NotificationManager;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  11. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  12. use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
  13. use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
  14. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent;
  15. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityPersistedEvent;
  16. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent;
  17. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityPersistedEvent;
  18. use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException;
  19. use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException;
  20. use EasyCorp\Bundle\EasyAdminBundle\Factory\EntityFactory;
  21. use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
  22. use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
  23. use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
  24. use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
  25. use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
  26. use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
  27. use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
  28. use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
  29. use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
  30. use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
  31. use Symfony\Component\HttpFoundation\Request;
  32. use Symfony\Component\HttpFoundation\Response;
  33. use Symfony\Component\Routing\Annotation\Route;
  34. use Knp\Component\Pager\PaginatorInterface;
  35. use Symfony\Component\Security\Core\Security;
  36. use Symfony\Component\HttpFoundation\JsonResponse;
  37. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  38. use Symfony\Component\Validator\Constraints\DateTime;
  39. use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
  40. use EasyCorp\Bundle\EasyAdminBundle\Field\CollectionField;
  41. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  42. use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
  43. use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
  44. use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
  45. use Doctrine\ORM\QueryBuilder;
  46. class ForumReponseCrudController extends AbstractBaseCrudController
  47. {
  48.     private $tokenStorage;
  49.     private $adminUrlGenerator;
  50.     private $notificationManager;
  51.         public function __construct(TokenStorageInterface $tokenStorage,
  52.         AdminUrlGenerator $adminUrlGeneratorNotificationManager $notificationManager)
  53.         {
  54.             $this->tokenStorage $tokenStorage;
  55.             $this->adminUrlGenerator $adminUrlGenerator;
  56.             $this->notificationManager $notificationManager;
  57.         }
  58.     public static function getEntityFqcn(): string
  59.     {
  60.         return ForumReponse::class;
  61.     }
  62.     public function configureCrud(Crud $crud): Crud
  63.     {
  64.         return $crud ->setPageTitle('index''Liste des Réponses')
  65.             ->setPageTitle('detail''Détails des Réponses')
  66.             ->setPageTitle('new''Créer une réponse');
  67.     }
  68.     public function configureActions(Actions $actions): Actions
  69.     {
  70.         $actions->add(Crud::PAGE_INDEXAction::DETAIL)
  71.         ->update(Crud::PAGE_INDEX,Action::NEW, function (Action $action) {
  72.             return $action->setLabel('Créer une reponse');
  73.         })
  74.         ->update(Crud::PAGE_NEWAction::SAVE_AND_RETURN, function (Action $action) {
  75.             return $action->setLabel('Enregistrer');
  76.         })
  77.         ->remove(Crud::PAGE_INDEXAction::DETAIL)
  78.         // ->remove(Crud::PAGE_INDEX, Action::NEW)
  79.         //->remove(Crud::PAGE_DETAIL, Action::EDIT)
  80.         ;
  81.         return $actions;
  82.     }
  83.     /**
  84.      * @param SearchDto $searchDto
  85.      * @param EntityDto $entityDto
  86.      * @param FieldCollection $fields
  87.      * @param FilterCollection $filters
  88.      * @return QueryBuilder
  89.      */
  90.     public function createIndexQueryBuilder(SearchDto $searchDtoEntityDto $entityDtoFieldCollection $fieldsFilterCollection $filters): QueryBuilder
  91.     {
  92.         $response parent::createIndexQueryBuilder($searchDto$entityDto$fields$filters); // TODO: Change the autogenerated stub
  93.         $response->andWhere('entity.parent IS NULL ');
  94.         $response->andWhere('entity.reponse IS NOT  NULL ');
  95.         $response->andWhere('entity.user IS NOT  NULL ');
  96.         return $response;
  97.     }
  98.     public function configureFields(string $pageName): iterable
  99.     {
  100.         return [
  101.             FormField::addTab('Détail Réponse')
  102.             ->setIcon('map')->addCssClass('optional'),
  103.             IdField::new('id')->hideOnForm(),
  104.             //TextField::new('nom','Nom')->formatValue(function ($value) { return $value ; }),
  105.             DateField::new('date''Date de la réponse')->formatValue(function ($value) {
  106.                 return $value ;
  107.             })->hideOnForm(),
  108.             AssociationField::new('user''utilisateur')->hideOnForm(),
  109.             AssociationField::new('sujetforum''Sujet'),
  110.             TextareaField::new('reponse''Réponse')->formatValue(function ($value) {
  111.                 return $value ;
  112.             }),
  113.      
  114.                
  115.             BooleanField::new('etat''Publier ?')
  116.                 // ->onlyOnForms() // Ne s'affiche que dans le formulaire
  117.                 ->setFormTypeOption('attr', ['class' => 'enable-in-form'])->setDisabled$pageName == Crud::PAGE_INDEX,true), // Ajout d'une classe CSS personnalisée
  118.   
  119.              FormField::addTab('Commentaires')
  120.              ->setIcon('map')->addCssClass('optional'),
  121.     
  122.              CollectionField::new('children')
  123.              ->allowAdd(true)
  124.              ->allowDelete(true)
  125.              ->setEntryIsComplex(true)
  126.              ->setLabel('comment')
  127.              ->setEntryType(CommentResponseForumType::class)
  128.             
  129.             
  130.              ->setFormTypeOptions(
  131.                  [
  132.                      'allow_add' => true,
  133.                      'allow_delete' => true,
  134.                      'form_attr' => 'ok',
  135.                      'label' => false,
  136.                      'auto_initialize' => false,
  137.                      'block_name' => null,
  138.                      'compound' => true,
  139.                      'by_reference' => false,
  140.              ]
  141.              )->hideOnIndex(false)->setLabel('Liste Commentaire')
  142.         
  143.         ];
  144.         DateField::new('date''Date de la réponse')->formatValue(function ($value) {
  145.             return $value ;
  146.         })->hideOnForm();
  147.     }
  148.     public function persistEntity(EntityManagerInterface $entityManager$entityInstance): void
  149.     {
  150.         $user $this->tokenStorage->getToken()->getUser();
  151.         $entityInstance->setUser($user);
  152.         $entityInstance->setDate(new \DateTime());
  153.         if ($entityInstance->getChildren()) {
  154.             foreach ($entityInstance->getChildren() as $child) {
  155.                 $child->setUser($user);
  156.                 $child->setDate(new \DateTime());
  157.                 $child->setEtat(true);
  158.                 $child->setParent($entityInstance);
  159.                 // Les commentaires (enfants) héritaient rarement du sujet → null à la publication
  160.                 if (!$child->getSujetforum() && $entityInstance->getSujetforum()) {
  161.                     $child->setSujetforum($entityInstance->getSujetforum());
  162.                 }
  163.                 $entityManager->persist($child);
  164.             }
  165.         }
  166.         $entityManager->persist($entityInstance);
  167.         $entityManager->flush();
  168.     }
  169.     public function updateEntity(EntityManagerInterface $entityManager$entityInstance): void
  170.     {
  171.         $conn $entityManager->getConnection();
  172.         $currentUser $this->tokenStorage->getToken()->getUser();
  173.         $oldChildren = [];
  174.         $parentSujet $entityInstance->getSujetforum();
  175.         $pendingNotifications = [];
  176.         /** check if children was updated */
  177.         foreach ($entityInstance->getChildren()->getSnapshot() as $child) {
  178.             /** check if there are children was removed */
  179.             if (!$entityInstance->getChildren()->contains($child)) {
  180.                 $entityManager->remove($child);
  181.                 continue;
  182.             }
  183.             if (!$child->getId()) {
  184.                 continue;
  185.             }
  186.             $sql 'SELECT * FROM forum_reponse f WHERE f.id = :id';
  187.             $resultSet $conn->executeQuery($sql, ['id' => $child->getId()]);
  188.             $oldChildren[$child->getId()] = $resultSet->fetchAssociative();
  189.         }
  190.         foreach ($entityInstance->getChildren() as $child) {
  191.             $child->setParent($entityInstance);
  192.             // Toujours rattacher le sujet du parent (sinon crash getSujetforum()->getId())
  193.             if (!$child->getSujetforum() && $parentSujet) {
  194.                 $child->setSujetforum($parentSujet);
  195.             }
  196.             if ($child->getId() && array_key_exists($child->getId(), $oldChildren) && $oldChildren[$child->getId()]) {
  197.                 $previous $oldChildren[$child->getId()];
  198.                 if (!empty($previous['user_id'])) {
  199.                     $child->setUser($entityManager->getRepository(User::class)->find($previous['user_id']));
  200.                 }
  201.                 if (!empty($previous['date'])) {
  202.                     $child->setDate(new \DateTime($previous['date']));
  203.                 }
  204.             } else {
  205.                 if (!$child->getUser()) {
  206.                     $child->setUser($currentUser);
  207.                 }
  208.             }
  209.             // date est NOT NULL en base : toujours garantir une valeur avant flush
  210.             if (!$child->getDate()) {
  211.                 $child->setDate(new \DateTime());
  212.             }
  213.             $entityManager->persist($child);
  214.             if ($child->isEtat()) {
  215.                 $pendingNotifications[] = [
  216.                     'reponse' => $child,
  217.                     'title' => 'Votre commentaire a été validé !',
  218.                     'message' => 'Votre commentaire a été validé ! ',
  219.                 ];
  220.             }
  221.         }
  222.         if ($entityInstance->isEtat()) {
  223.             $pendingNotifications[] = [
  224.                 'reponse' => $entityInstance,
  225.                 'title' => 'Votre réponse/commentaire a été validé !',
  226.                 'message' => 'Votre réponse/commentaire a été validé ! ',
  227.             ];
  228.         }
  229.         // Flush d'abord les réponses/commentaires, puis les notifications
  230.         // (évite qu'un flush dans NotificationManager persiste une date null)
  231.         $entityManager->flush();
  232.         foreach ($pendingNotifications as $notif) {
  233.             $this->notifyForumPublication(
  234.                 $entityManager,
  235.                 $notif['reponse'],
  236.                 $notif['title'],
  237.                 $notif['message']
  238.             );
  239.         }
  240.     }
  241.     /**
  242.      * Notifie l'auteur qu'une réponse/commentaire a été publié.
  243.      * Ne plante jamais si sujet ou utilisateur est absent.
  244.      */
  245.     private function notifyForumPublication(
  246.         EntityManagerInterface $entityManager,
  247.         ForumReponse $reponse,
  248.         string $title,
  249.         string $message
  250.     ): void {
  251.         $sujet $reponse->getSujetforum();
  252.         if (!$sujet && $reponse->getParent()) {
  253.             $sujet $reponse->getParent()->getSujetforum();
  254.             if ($sujet) {
  255.                 $reponse->setSujetforum($sujet);
  256.             }
  257.         }
  258.         $auteur $reponse->getUser();
  259.         if (!$sujet || !$auteur) {
  260.             return;
  261.         }
  262.         $urlSujet '/show/forum/detail/' $sujet->getId();
  263.         $this->notificationManager->pushMessage($title$message$auteur$urlSujet);
  264.     }
  265.     #[Route('/show/forum/detail/{id}'name'show_forum_detail')]
  266.     public function listServices(Sujetforum $sujetRequest $requestEntityManagerInterface $entityManagerPaginatorInterface $paginatorSecurity $security): Response
  267.     {
  268.         if ($security->getUser()) {
  269.             $donnees $entityManager->getRepository(ForumReponse::class)->finResponsesdWithUser($sujet->getId(), $security->getUser()->getId(), 0);
  270.         } else {
  271.             
  272.             $donnees $entityManager->getRepository(ForumReponse::class)->finResponsesdWithUser($sujet->getId(), null 0);
  273.         }
  274.         $reponseForums $donnees;
  275.         return $this->render('forum/detail.html.twig', [
  276.              'sujetForum'=>$sujet,
  277.              'reponsesForums'=>$reponseForums
  278.           
  279.          ]);
  280.     }
  281.     
  282.     #[Route('/make/forum/response/{id}'name'make_forum_response')]
  283.     public function responseForum(Sujetforum $sujetRequest $request,
  284.      EntityManagerInterface $entityManagerSecurity $security,
  285.      NotificationManager $notificationManager
  286.      ): Response
  287.     
  288.         
  289.         if($this->getUser()){
  290.         $reponse= new ForumReponse();
  291.         $reponse->setReponse($request->request->get('message'));
  292.         $reponse->setUser($security->getUser());
  293.         $reponse->setDate(new \DateTime());
  294.         $reponse->setEtat(false);
  295.         $reponse->setSujetforum($sujet);
  296.         $entityManager->persist($reponse);
  297.         $entityManager->flush();
  298.            // Send Comment
  299.            $edit_demande_url =  $this->adminUrlGenerator
  300.            ->setController(ForumReponseCrudController::class)
  301.            ->setAction(Action::EDIT)
  302.            ->setEntityId($reponse->getId())
  303.            ->generateUrl();
  304.            $notification_message 'Nouvelle Réponse au Sujet ! ';
  305.            $admins $entityManager->getRepository(User::class)->findByRole('ROLE_ADMIN');
  306.            foreach($admins as $admin){
  307.                $notificationManager->pushMessage('Nouvelle Réponse au Sujet ! '$notification_message$admin$edit_demande_url);
  308.            }
  309.            // End send comment
  310.             return $this->redirectToRoute('show_forum_detail', ['id' => $sujet->getId()]);
  311.         }
  312.         else{
  313.             return $this->render('login/index.html.twig');
  314.         }
  315.     }
  316.     #[Route('/delete/forum/reponse/{id}'name'delete_forum_response')]
  317.     public function deleteResponseForum(ForumReponse $reponseRequest $requestEntityManagerInterface $entityManagerSecurity $security): JsonResponse
  318.     {
  319.         $entityManager->remove($reponse);
  320.         $entityManager->flush();
  321.         return new JsonResponse(['data' => 'done'], Response::HTTP_OK, ['Content-Type''application/json']);
  322.     }
  323.     #[Route('/make/forum/comment/{id}/{repid}'name'make_forum_comment')]
  324.     public function responseComment(Sujetforum $sujetint $repidRequest $requestEntityManagerInterface $entityManagerSecurity $security NotificationManager $notificationManager): Response
  325.     {
  326.         $parent $entityManager->getRepository(ForumReponse::class)->find($repid);
  327.         $reponse= new ForumReponse();
  328.         $reponse->setReponse($request->request->get('message'));
  329.         $reponse->setUser($security->getUser());
  330.         $reponse->setDate(new \DateTime());
  331.         $reponse->setEtat(false);
  332.         $reponse->setSujetforum($sujet);
  333.         $reponse->setParent($parent);
  334.         $entityManager->persist($reponse);
  335.         $entityManager->flush();
  336.         $edit_demande_url =  $this->adminUrlGenerator
  337.         ->setController(ForumReponseCrudController::class)
  338.         ->setAction(Action::EDIT)
  339.         ->setEntityId($repid)
  340.         ->generateUrl();
  341.         $notification_message 'Nouveau Commentaire  ! ';
  342.         $admins $entityManager->getRepository(User::class)->findByRole('ROLE_ADMIN');
  343.         foreach($admins as $admin){
  344.             $notificationManager->pushMessage('Nouveau Commentaire ! '$notification_message$admin$edit_demande_url);
  345.         }
  346.         return $this->redirectToRoute('show_forum_detail', ['id' => $sujet->getId()]);
  347.     }
  348.     #[Route('/update/forum/response/{id}'name'update_forum_response')]
  349.     public function updateResponseForum(ForumReponse $reponseRequest $requestEntityManagerInterface $entityManager): Response
  350.     {
  351.         $reponse->setReponse($request->request->get('message'));
  352.         $reponse->setDate(new \DateTime());
  353.         $entityManager->persist($reponse);
  354.         $entityManager->flush();
  355.         return $this->redirectToRoute('show_forum_detail', ['id' => $reponse->getSujetforum()->getId()]);
  356.     }
  357.     #[Route('/ajax/get/ReponseForum/{id}'name'show_forum_ReponseForum')]
  358.     public function ReponseForum(Sujetforum $sujetRequest $requestEntityManagerInterface $entityManagerPaginatorInterface $paginatorSecurity $security): JsonResponse
  359.     {
  360.         $offset = (int)$request->query->get('offset');
  361.       
  362.         if ($security->getUser()) {
  363.             $donnees $entityManager->getRepository(ForumReponse::class)->finResponsesdWithUser($sujet->getId(), $security->getUser()->getId(), $offset );
  364.         } else {
  365.             
  366.             $donnees $entityManager->getRepository(ForumReponse::class)->finResponsesdWithUser($sujet->getId(), null $offset);
  367.         }
  368.         $reponseForums $donnees;
  369.         foreach ($donnees as $key => $obj) {
  370.             $childrenData = [];
  371.             foreach ($obj->getChildren() as $child) {
  372.                 $childrenData[] = [
  373.                     'id' => $child->getId(),
  374.                     'date' => $child->getDate()->format('d/m/Y'),
  375.                     'userName' => $child->getUser()->getUsername(),
  376.                     'reponse' => $child->getReponse(),
  377.                     'userId' => $child->getUser()->getId(),
  378.                     'etat' => $child->isEtat(),
  379.                 ];
  380.             }
  381.         
  382.             $result[$key] = [
  383.                 'id' => $obj->getId(),
  384.                 'date' => $obj->getDate()->format('d/m/Y'),
  385.                 'userName' => $obj->getUser()->getUsername(),
  386.                 'userId' => $obj->getUser()->getId(),
  387.                 'reponse' => $obj->getReponse(),
  388.                 'etat' => $obj->isEtat(),
  389.                 'childs' => $childrenData,
  390.             ];
  391.         }
  392.         
  393.         return new JsonResponse([
  394.             'result'=>$result,
  395.             'reponsesForums'=>$reponseForums
  396.          
  397.         ], Response::HTTP_OK, ['Content-Type''application/json']);
  398.     }
  399. }