src/Controller/ProjectController.php line 22

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\EquipmentSet;
  4. use App\Entity\Organization;
  5. use App\Entity\Project;
  6. use App\Form\EquipmentSetType;
  7. use App\Form\ProjectIntroType;
  8. use App\Service\ProjectService;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Doctrine\Persistence\ManagerRegistry;
  11. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  12. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. class ProjectController extends AbstractController
  17. {
  18.     #[Route('/new-project/{id}'name'new_project')]
  19.     public function index(Request $requestManagerRegistry $managerRegistryOrganization $organization): Response
  20.     {
  21.         $project = new Project($organization);
  22.         $form $this->createForm(ProjectIntroType::class, $project, ['action' => $this->generateUrl('new_project', ['id' => $organization->getId()]), 'method' => 'POST']);
  23.         $form->handleRequest($request);
  24.         if ($form->isSubmitted() && $form->isValid()) {
  25.             $managerRegistry->getManager()->persist($project);
  26.             $managerRegistry->getManager()->flush();
  27.             return $this->redirectToRoute('project_detail', ['uuid' => $project->getUuid(), '_locale' => $request->getLocale()]);
  28.         }
  29.         return $this->renderForm('project/index.html.twig', [
  30.             'form' => $form,
  31.             'organization' => $organization,
  32.         ]);
  33.     }
  34.     #[Route('/project/detail/{uuid}/remove/{id}'name'project_detail_remove_equipment_set')]
  35.     #[ParamConverter('project', class: Project::class, options: ['mapping' => ['uuid' => 'uuid']])]
  36.     #[ParamConverter('equipmentSet', class: EquipmentSet::class, options: ['mapping' => ['id' => 'id']])]
  37.     public function removeEquipmentSet(Project $projectEquipmentSet $equipmentSetEntityManagerInterface $entityManager): Response
  38.     {
  39.         if ($equipmentSet->getProject() !== $project) {
  40.             $this->addFlash('error''trying to remove an invalid equipment set');
  41.             return $this->redirectToRoute('project_detail');
  42.         }
  43.         $entityManager->remove($equipmentSet);
  44.         $entityManager->flush();
  45.         return $this->redirectToRoute('project_detail', ['uuid' => $project->getUuid()]);
  46.     }
  47.     #[Route('/project/detail/{uuid}'name'project_detail')]
  48.     public function detail(Project $projectRequest $requestEntityManagerInterface $entityManagerProjectService $projectServiceResponse $response null): Response
  49.     {
  50.         // I will create dynamically multiple forms on the same page (one for each equipmentSet, plus one for creating a new equipmentSet).
  51.         // I can't use neither $this->renderForm, nor $this->createForm because it is designed for a fixed list of forms, associated to different FormType (2 forms with the same FormType will have the same name, so we can't know which one have been submitted)
  52.         // So I do nearly the same thing as $this->renderForm + the same thing we usually do to treat a form, with adaptations to my custom situation
  53.         if (is_null($response)) {
  54.             $response = new Response();
  55.         }
  56.         // Create forms for each equipment set
  57.         $equipmentSets $project->getEquipmentSets();
  58.         $equipmentSetForms = [];
  59.         $equipmentSetFormViews = [];
  60.         foreach ($equipmentSets as $k => $equipmentSet) {
  61.             //  I do the same thing as $this->createForm, but with a name that will allow me to detect wich form is currently submitted
  62.             $equipmentSetForms[$k] = $this->container->get('form.factory')->createNamed('equipment_set_'.$kEquipmentSetType::class, $equipmentSet);
  63.             $equipmentSetForms[$k]->handleRequest($request);
  64.             //  I do the same thing as $this->renderForm, but on each included form
  65.             $equipmentSetFormViews[$k] = $equipmentSetForms[$k]->createView();
  66.         }
  67.         // Create form for new equipment set
  68.         $newEquipmentSet = new EquipmentSet();
  69.         //  Here I use $this->createForm, I know that this form only will have the standard name 'equipment_set'
  70.         $newEquipmentSetForm $this->createForm(EquipmentSetType::class, $newEquipmentSet);
  71.         $newEquipmentSetForm->handleRequest($request);
  72.         //  I do the same thing as $this->renderForm, but on each subform
  73.         $newEquipmentSetFormView $newEquipmentSetForm->createView();
  74.         // Handle submission on the right for every form. I do the same thing as $this->renderForm, but here
  75.         if ($newEquipmentSetForm->isSubmitted()) {
  76.             if ($newEquipmentSetForm->isValid()) {
  77.                 // As usual, I handle the request if this form is submitted and valid
  78.                 /** @var EquipmentSet $newEquipmentSet */
  79.                 $newEquipmentSet $newEquipmentSetForm->getData();
  80.                 $entityManager->persist($project);
  81.                 $project->addEquipmentSet($newEquipmentSet);
  82.                 $entityManager->flush();
  83.                 // I redirect so that my new equipment set will now have a form, and a new newEquipmentSetForm will be created
  84.                 return $this->redirectToRoute('project_detail', ['uuid' => $project->getUuid()]);
  85.             } else {
  86.                 //  I do the same thing as $this->renderForm. The code 422 will allow the form view to know that errors must be displayed on this form.
  87.                 // (otherwise the errors are well computed by Symfony, they appear in the profiler, but they are not displayed by the FormView)
  88.                 $response->setStatusCode(422);
  89.             }
  90.         } else {
  91.             // approximately the same on each existing equipmentSetForm
  92.             foreach ($equipmentSetForms as $equipmentSetForm) {
  93.                 if ($equipmentSetForm->isSubmitted()) {
  94.                     if ($equipmentSetForm->isValid()) {
  95.                         // As usual
  96.                         $equipmentSet $equipmentSetForm->getData();
  97.                         $entityManager->persist($equipmentSet);
  98.                         $entityManager->flush();
  99.                         // I also redirect even if it is not actually mandatory, just to keep consistency with the creation process
  100.                         return $this->redirectToRoute('project_detail', ['uuid' => $project->getUuid()]);
  101.                     } else {
  102.                         // make FormView know that there are errors on the form
  103.                         $response->setStatusCode(422);
  104.                     }
  105.                     break;
  106.                 }
  107.             }
  108.         }
  109.         // Some values of the project are not stored in database, but computed on the fly
  110.         $projectService->calculate($project);
  111.         return $this->render('project/detail.html.twig', [
  112.             'project' => $project,
  113.             'equipmentSets' => $equipmentSets,
  114.             'equipmentSetForms' => $equipmentSetFormViews,
  115.             'newEquipmentSetForm' => $newEquipmentSetFormView,
  116.         ], $response);
  117.     }
  118. }