<?php namespace App\Controller; use App\Entity\Capsule; use App\Entity\Group; use App\Entity\User; use App\Form\DeleteCapsuleFormType; use App\Form\DuplicateCapsuleFormType; use App\Form\FilterByGroupFormType; use App\Helper\StringHelper; use App\Repository\CapsuleRepository; use App\Builder\CapsuleBuilder; use App\Form\CreateCapsuleFormType; use Knp\Component\Pager\PaginatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Uid\Uuid; use Symfony\Contracts\Translation\TranslatorInterface; class CapsuleController extends AbstractController { private CapsuleRepository $capsule_repository; private TranslatorInterface $translator; public function __construct( CapsuleRepository $capsule_repository, TranslatorInterface $translator ) { $this->capsule_repository = $capsule_repository; $this->translator = $translator; } /** * @Route("/my_capsules", name="capsule_list") * @Route("/", name="home") */ public function index( PaginatorInterface $paginator, Request $request ): Response { $current_user = $this->getUser(); if (! $current_user instanceof User) { return $this->redirectToRoute('app_logout'); } $all_capsules = $current_user->getCapsules(); $form = $this->createForm(FilterByGroupFormType::class, ['groups' => $current_user->getGroups()]); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $group = $form->getData()['name']; if (! $group instanceof Group) { throw new \Exception('Group not found'); } $all_capsules = $current_user->getCapsulesFilteredByGroup($group); } $capsules = $paginator->paginate( $all_capsules, $request->query->getInt('page', 1), 5 ); return $this->render('capsule/index.html.twig', [ 'filterByGroupForm' => $form->createView(), 'capsules' => $capsules, 'current_user' => $current_user, 'legacy_url' => $this->getParameter('app.legacy_external_prefix') ]); } /** * @Route("/create", name="create_capsule") */ public function create(Request $request): Response { $form = $this->createForm(CreateCapsuleFormType::class); $form->handleRequest($request); $current_user = $this->getUser(); if (! $current_user instanceof User) { return $this->redirectToRoute('app_logout'); } if ($form->isSubmitted() && $form->isValid()) { $video_url = htmlspecialchars($form->get('video_url')->getData()); $capsule = $this->createCapsuleInDB($form, $current_user); return $this->forward('App\Controller\ProjectController::create', [ 'capsule' => $capsule, 'video_url' => $video_url ]); } return $this->render('capsule/create.html.twig', [ 'capsuleCreationForm' => $form->createView() ]); } /** * @Route("capsule/preview/{path}", name="preview_capsule") */ public function preview(string $path): Response { $file_path = '../legacy/' . $path; if (!file_exists($file_path)) { return $this->render('project/project_not_found.html.twig'); } $url = $this->getParameter('app.legacy_external_prefix') . '/' . $path . "/?w=1"; return $this->render( 'project/project_view.html.twig', [ 'url' => $url ] ); } /** * @Route("capsule/edit/{path}", name="edit_capsule") */ public function edit(string $path): Response { $current_user = $this->getUser(); if (! $current_user instanceof User) { return $this->redirectToRoute('app_logout'); } $capsule = $this->capsule_repository->findOneBy(['link_path' => $path]); if (null === $capsule) { $this->addFlash('warning', $this->translator->trans('capsule.edit.not_found')); return $this->redirectToRoute('capsule_list'); } if (! $capsule->getEditors()->contains($current_user)) { $this->addFlash('warning', $this->translator->trans('capsule.edit.not_allowed')); return $this->redirectToRoute('capsule_list'); } $file_path = '../legacy/' . $path; if (!file_exists($file_path)) { return $this->render('project/project_not_found.html.twig'); } $url = $this->getParameter('app.legacy_external_prefix') . '/' . $capsule->getEditionLink(); return $this->render( 'project/project_view.html.twig', [ 'url' => $url ] ); } /** * @Route("/capsule/delete/{id}", name="delete_capsule") */ public function delete( int $id, Request $request ): Response { $form = $this->createForm(DeleteCapsuleFormType::class); $form->handleRequest($request); $current_user = $this->getUser(); if (! $current_user instanceof User) { return $this->redirectToRoute('app_logout'); } $entityManager = $this->getDoctrine()->getManager(); $capsule = $entityManager->getRepository(Capsule::class)->find($id); if (! $capsule) { throw $this->createNotFoundException( 'No capsule found for id ' . $id ); } $capsule_name = $capsule->getName(); if ($capsule->getCreationAuthor() !== $current_user) { $this->addFlash( 'warning', $this->translator->trans( 'capsule.delete.error', [ 'capsule_name' => $capsule_name ] ) ); return $this->redirectToRoute('capsule_list'); } if ($form->isSubmitted() && $form->isValid()) { $current_user->removeCapsule($capsule); $capsule->removeEditor($current_user); $entityManager->remove($capsule); $entityManager->flush(); $this->addFlash( 'success', $this->translator->trans( 'capsule.delete.success', [ 'capsule_name' => $capsule_name ] ) ); return $this->redirectToRoute('capsule_list'); } return $this->render('capsule/delete.html.twig', [ 'deleteCapsuleForm' => $form->createView(), 'capsule_name' => $capsule_name ]); } /** * @Route("/capsule/duplicate/{id}", name="duplicate_capsule") */ public function duplicate( int $id, Request $request, Filesystem $file_system ): Response { $form = $this->createForm(DuplicateCapsuleFormType::class); $form->handleRequest($request); $current_user = $this->getUser(); if (! $current_user instanceof User) { return $this->redirectToRoute('app_logout'); } $entityManager = $this->getDoctrine()->getManager(); $parent_capsule = $entityManager->getRepository(Capsule::class)->find($id); if (! $parent_capsule instanceof Capsule) { throw new \Exception('The retrieved capsule is not an instance of Capsule.'); } $capsule_editors = $parent_capsule->getEditors(); if (! in_array($current_user, $capsule_editors->toArray())) { $this->addFlash( 'warning', $this->translator->trans( 'capsule.duplicate.error', [ 'capsule_name' => $parent_capsule->getName() ] ) ); return $this->redirectToRoute('capsule_list'); } $parent_directory_name = $parent_capsule->getLinkPath(); $parent_directory_exists = $file_system->exists('../legacy/' . $parent_directory_name); if (! $parent_directory_exists) { $this->addFlash( 'warning', $this->translator->trans( 'project.not_exist', [ 'capsule_name' => $parent_capsule->getName() ] ) ); return $this->redirectToRoute('capsule_list'); } if ($form->isSubmitted() && $form->isValid()) { $capsule = $this->createCapsuleInDB($form, $current_user); return $this->forward('App\Controller\ProjectController::duplicate', [ 'capsule' => $capsule, 'parent_directory' => $parent_directory_name ]); } return $this->render('capsule/duplicate.html.twig', [ 'duplicateCapsuleForm' => $form->createView(), 'capsule_name' => $parent_capsule->getName() ]); } private function createCapsuleInDB(FormInterface $form, User $current_user): Capsule { $new_date_time = new \DateTime(); $capsule_name = $form->get('name')->getData(); $password = StringHelper::generateRandomHashedString(); $preview_link = Uuid::v4(); $entityManager = $this->getDoctrine()->getManager(); $capsule_builder = new CapsuleBuilder(); $capsule = $capsule_builder ->withName($capsule_name) ->withCreationAuthor($current_user) ->withCreationDate($new_date_time) ->withLinkPath($preview_link) ->withUpdateDate($new_date_time) ->withPassword($password) ->createCapsule(); $entityManager->persist($capsule); $entityManager->flush(); return $capsule; } }