"css/fontello.css" did not exist on "e81eafcd68a219f025e82a155e59ba572d0aaacb"
Select Git revision
fontello-codes.css
CapsuleController.php 13.76 KiB
<?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 Doctrine\ORM\EntityManagerInterface;
use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
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\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Uid\Uuid;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CapsuleController extends AbstractController
{
private const DEFAULT_LOCALE = 'en';
public function __construct(
private CapsuleRepository $capsule_repository,
private TranslatorInterface $translator,
private EntityManagerInterface $entity_manager
) {
}
#[Route('/')]
public function indexNoLocale(Request $request): Response
{
$locale = self::DEFAULT_LOCALE;
$current_user = $this->getUser();
if (! $current_user instanceof User) {
return $this->redirectToRoute('app_logout');
}
if ($request->getLocale()) {
$locale = $request->getLocale();
}
if ($current_user->getLocale()) {
$locale = $current_user->getLocale();
}
return $this->redirectToRoute('home', ['_locale' => $locale]);
}
#[Route('/{_locale<%app.supported_locales%>}/my_capsules', name:'capsule_list')]
#[Route('/{_locale<%app.supported_locales%>}', name:'home')]
public function index(
PaginatorInterface $paginator,
Request $request,
HttpClientInterface $http_client
): Response {
$current_user = $this->getUser();
if (! $current_user instanceof User) {
return $this->redirectToRoute('app_logout');
}
// get all capsules without any filter
$all_capsules = $current_user->getCapsules()->toArray();
$groups = $this->prependGroupAllToUserGroups($current_user);
$group_id = $request->query->getInt('group', Group::$GROUP_ALL_ID);
$group = $this->getGroupByIdOrNull($groups, $group_id, $groups[0]);
$filter_by_group_form = $this->createForm(
FilterByGroupFormType::class,
['groups' => $groups, 'method' => 'GET', 'selected_group' => $group]
);
$filter_by_group_form->handleRequest($request);
if ($filter_by_group_form->isSubmitted() && $filter_by_group_form->isValid()) {
$group = $filter_by_group_form->getData()['name'];
if (! $group instanceof Group) {
throw new \Exception('Group not found');
}
}
if ($group instanceof Group && $group->getId() !== Group::$GROUP_ALL_ID) {
$all_capsules = $group->getCapsules()->toArray();
}
$nb_elements_per_page = 5;
// Fix the current page.
// For example, the user is on the page 5 without filter and apply a filter that reduce the number of pages.
// We display the last page.
$current_page = min(
[
intval((count($all_capsules) / $nb_elements_per_page) + 1),
$request->query->getInt('page', 1)
]
);
$request->query->set('page', $current_page);
// Pass group param to the paginator (it will be sent as GET data)
$capsules = $paginator->paginate(
$all_capsules,
$current_page,
$nb_elements_per_page
);
if ($capsules instanceof SlidingPagination) {
$capsules->setParam('group', $group->getId());
}
return $this->renderForm('capsule/index.html.twig', [
'filterByGroupForm' => $filter_by_group_form,
'capsules' => $capsules,
'current_user' => $current_user,
'legacy_url' => $this->getParameter('app.legacy_external_prefix'),
'http_client' => $http_client
]);
}
#[Route('/{_locale<%app.supported_locales%>}/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->renderForm('capsule/create.html.twig', [
'capsuleCreationForm' => $form
]);
}
#[Route('/{_locale<%app.supported_locales%>}/capsule/preview/{path}', name:'preview_capsule')]
public function preview(string $path, UrlGeneratorInterface $urlGenerator): 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,
'linkHome' => $urlGenerator->generate('home', [], UrlGeneratorInterface::ABSOLUTE_URL)
]
);
}
#[Route('/{_locale<%app.supported_locales%>}/capsule/edit/{path}', name:'edit_capsule')]
public function edit(string $path, UrlGeneratorInterface $urlGenerator): 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/edit.html.twig',
[
'url' => $url,
'linkHome' => $urlGenerator->generate(
'home',
[],
UrlGeneratorInterface::ABSOLUTE_URL
)
,
'linkPreview' => $urlGenerator->generate(
'preview_capsule',
[ 'path' => $capsule->getLinkPath() ],
UrlGeneratorInterface::ABSOLUTE_URL
)
]
);
}
#[Route('/{_locale<%app.supported_locales%>}/capsule/delete/{capsule_id}', name:'delete_capsule')]
public function delete(
int $capsule_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');
}
$capsule = $this->capsule_repository->findOneBy(['id' => $capsule_id]);
if (! $capsule) {
throw $this->createNotFoundException(
'No capsule found for id ' . $capsule_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);
$this->entity_manager->remove($capsule);
$this->entity_manager->flush();
$this->addFlash(
'success',
$this->translator->trans(
'capsule.delete.success',
[
'capsule_name' => $capsule_name
]
)
);
return $this->redirectToRoute('capsule_list');
}
return $this->renderForm('capsule/delete.html.twig', [
'deleteCapsuleForm' => $form,
'capsule_name' => $capsule_name
]);
}
#[Route('/{_locale<%app.supported_locales%>}/capsule/duplicate/{capsule_id}', name:'duplicate_capsule')]
public function duplicate(
int $capsule_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');
}
$parent_capsule = $this->capsule_repository->findOneBy(['id' => $capsule_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->renderForm('capsule/duplicate.html.twig', [
'duplicateCapsuleForm' => $form,
'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();
$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();
$this->entity_manager->persist($capsule);
$this->entity_manager->flush();
return $capsule;
}
private function createGroupAll(User $current_user): Group
{
$group_all = new Group();
$group_all->setName($this->translator->trans('groups.filter.no_filter'));
$group_all->setId(Group::$GROUP_ALL_ID);
$group_all->setAuthor($current_user);
return $group_all;
}
/**
* @return array<Group>
*/
private function prependGroupAllToUserGroups(User $current_user): array
{
$group_all = $this->createGroupAll($current_user);
$author_groups_without_group_all = $current_user->getGroups()->toArray();
$groups[] = $group_all;
$groups = array_merge($groups, $author_groups_without_group_all);
return $groups;
}
/**
* @param array<Group> $groups
* @param int|null $id
* @param Group $defaultGroup The returned group if current groups isn't found
* @return Group
*/
private function getGroupByIdOrNull(array $groups, ?int $id, Group $defaultGroup): Group
{
if (null === $id) {
return $defaultGroup;
}
foreach ($groups as $g) {
if ($g->getId() === $id) {
return $g;
}
}
return $defaultGroup;
}
}