src/Controller/PostController.php line 55

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Post;
  4. use App\Form\PostType;
  5. // use App\Form\PostFormType;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use App\Repository\PostRepository;
  8. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\Routing\Annotation\Route;
  12. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  13. use Symfony\Component\HttpFoundation\RedirectResponse;
  14. use Doctrine\Persistence\ManagerRegistry;
  15. use Doctrine\DBAL\Types\Types;
  16. use Symfony\Component\HttpFoundation\RequestStack;
  17. use Knp\Component\Pager\PaginatorInterface;
  18. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  19. use Imagine\Gd\Imagine;
  20. use Symfony\Component\HttpFoundation\File\File;
  21. use Imagine\Image\Box;
  22. use Imagine\Image\ManipulatorInterface;
  23. use Symfony\Component\Filesystem\Filesystem;
  24. class PostController extends AbstractController
  25. {
  26.   private $entityManager;
  27.   private $doctrine;
  28.   private $requestStack;
  29.   public function __construct(EntityManagerInterface $entityManagerManagerRegistry $doctrineRequestStack $requestStack)
  30.   {
  31.     $this->entityManager $entityManager;
  32.     $this->doctrine $doctrine;
  33.     $this->requestStack $requestStack;
  34.   }
  35.   #[Route('/'name'home'methods: ['GET'])]
  36.   public function home(PostRepository $postRepository): Response
  37.   {
  38.     $posts $postRepository->findAll();
  39.     return $this->render('post/home.html.twig', [
  40.       'posts' => $posts,
  41.     ]);
  42.   }
  43.   #[Route('/posts/{id<\d+>}'name'post_by_id'methods: ['GET'])]
  44.   public function byId(int $idPostRepository $postRepository): Response
  45.   {
  46.     $post $postRepository->find($id);
  47.     if (!$post) {
  48.       throw $this->createNotFoundException('Статья не найдена.');
  49.     }
  50.     $photo $post->getPhoto();
  51.     return $this->render('post/by-id.html.twig', [
  52.       'post' => $post,
  53.       'photo' => $photo,
  54.       'description' => $post->getTitle(),
  55.     ]);
  56.   }
  57.   #[Route('/posts/genre/{genre}'name'post_by_genre'methods: ['GET'])]
  58.   public function byGenre(string $genrePostRepository $postRepositoryPaginatorInterface $paginatorRequest $request): Response
  59.   {
  60.     $query $postRepository->createQueryBuilder('p')
  61.       ->where('p.genre = :genre')
  62.       ->andWhere('p.genre != :excludedGenre')
  63.       ->setParameter('genre'$genre)
  64.       ->setParameter('excludedGenre''non-genre')
  65.       ->getQuery();
  66.     $page $request->query->getInt('page'1);
  67.     $pageSize 6// Количество постов на странице
  68.     $pagination $paginator->paginate($query$page$pageSize);
  69.     $genreCounts $this->getPostCountByGenre($postRepository);
  70.     return $this->render('post/by-genre.html.twig', [
  71.       'posts' => $pagination,
  72.       'genre' => $genre,
  73.       'genreCounts' => $genreCounts,
  74.       'pagination' => $pagination,
  75.     ]);
  76.   }
  77.   #[Route('/admin/posts'name'app_admin_posts')]
  78.   #[IsGranted('ROLE_ADMIN')]
  79.   public function index(PostRepository $postRepository): Response
  80.   {
  81.     $posts $postRepository->findAll();
  82.     return $this->render('admin/posts.html.twig', [
  83.       'posts' => $posts,
  84.     ]);
  85.   }
  86.   #[Route('/admin/posts/{id}/edit'name'app_admin_post_edit')]
  87.   #[IsGranted('ROLE_ADMIN')]
  88.   public function edit(Request $requestPost $postEntityManagerInterface $entityManager): Response
  89.   {
  90.     $form $this->createForm(PostType::class, $post);
  91.     $form->handleRequest($request);
  92.     // Получение ссылки на текущую фотографию
  93.     $currentPhoto $post->getPhoto();
  94.     if ($form->isSubmitted() && $form->isValid()) {
  95. $cleanBody str_replace(["\r\n""\\r\\n"], "\n"$post->getBody());
  96.     $post->setBody($cleanBody);
  97.     $epigraph $form->get('epigraph')->getData();
  98.       // Получение значения поля "photoFile" из формы
  99.       $photoFile $form->get('photoFile')->getData();
  100.       // Загрузка новой фотографии, если она была выбрана
  101.       if ($photoFile) {
  102.         // Удаление старой фотографии, если она существует
  103.         if ($post->getPhoto()) {
  104.           $oldPhotoPath $this->getParameter('photos_directory') . '/' $post->getPhoto();
  105.           if (file_exists($oldPhotoPath)) {
  106.             unlink($oldPhotoPath);
  107.           }
  108.         }
  109.         // Создаем временную папку, если она не существует
  110.         $tempDir $this->getParameter('kernel.project_dir') . '/tmp';
  111.         if (!file_exists($tempDir)) {
  112.           mkdir($tempDir);
  113.         }
  114.         $newFilename 'img-post' $post->getId() . '.' $photoFile->guessExtension();
  115.         // Создаем полный путь к временному файлу
  116.         $tempFilename $tempDir '/' $newFilename;
  117.         // Создаем новый объект класса Imagine и получаем фото
  118.         $imagine = new Imagine();
  119.         $image $imagine->open($photoFile->getPathname());
  120.         $maxWidth 800;
  121.         $maxHeight 800;
  122.         $image->resize($image->getSize()->widen($maxWidth)->heighten($maxHeight));
  123.         // Сохраняем сжатое изображение во временный файл
  124.         $tempFilename sys_get_temp_dir() . '/' $newFilename;
  125.         $image->save($tempFilename, ['jpeg_quality' => 80]);
  126.         // Создаем новый экземпляр файла из временного файла
  127.         $compressedPhoto = new File($tempFilename);
  128.         // Перемещаем файл в каталог назначения и сохраняем сжатую фотографию
  129.         try {
  130.           $photoFile->move(
  131.             $this->getParameter('photos_directory') . '/post-img',
  132.             $newFilename
  133.           );
  134.           // Обновление ссылки на фотографию в объекте Post
  135.           $post->setPhoto('post-img/' $newFilename);
  136.         } catch (FileException $e) {
  137.           $this->addFlash('error''An error occurred while uploading the photo.');
  138.           return $this->redirectToRoute('app_admin');
  139.         }
  140.       }
  141.       $entityManager->flush();
  142.       $this->addFlash('success''Post updated successfully!');
  143.       return new RedirectResponse($this->generateUrl('app_admin_posts'));
  144.     }
  145.     return $this->render('admin/post_edit.html.twig', [
  146.       'form' => $form->createView(),
  147.       'currentPhoto' => $currentPhoto,
  148.       'post' => $post,
  149.     ]);
  150.   }
  151.   #[Route('/admin/posts/{id}/delete'name'app_admin_post_delete')]
  152.   #[IsGranted('ROLE_ADMIN')]
  153.   public function delete(Request $requestPost $postEntityManagerInterface $entityManagerFilesystem $filesystem): Response
  154.   {
  155.     if ($this->isCsrfTokenValid('delete_post_' $post->getId(), $request->request->get('_token'))) {
  156.       $photo $post->getPhoto();
  157.       if ($photo) {
  158.         // Полный путь к файлу
  159.         $filePath $this->getParameter('photos_directory') . '/' $photo;
  160.         if ($filesystem->exists($filePath)) {
  161.           $filesystem->remove($filePath);
  162.         }
  163.       }
  164.       $entityManager->remove($post);
  165.       $entityManager->flush();
  166.       $this->addFlash('success''Post deleted successfully!');
  167.     }
  168.     return new RedirectResponse($this->generateUrl('app_admin_posts'));
  169.   }
  170.   #[Route('/admin/posts/new'name'app_admin_post_new')]
  171.   #[IsGranted('ROLE_ADMIN')]
  172.   public function new(Request $request): Response
  173.   {
  174.     $post = new Post();
  175.     $form $this->createForm(PostType::class, $post);
  176.     $form->handleRequest($request);
  177.     if ($form->isSubmitted() && $form->isValid()) {
  178. $cleanBody str_replace(["\r\n""\\r\\n"], "\n"$post->getBody());
  179.     $post->setBody($cleanBody);
  180.     
  181.     $epigraph $form->get('epigraph')->getData();
  182.       // Получение значения поля "photoFile" из формы
  183.       $photoFile $form->get('photoFile')->getData();
  184.       // Загрузка фотографии, если она была выбрана
  185.       if ($photoFile) {
  186.         $newFilename uniqid() . '.' $photoFile->guessExtension();
  187.         // Создается новый объект класса Imagine и получаем фото
  188.         $imagine = new Imagine();
  189.         $image $imagine->open($photoFile->getPathname());
  190.         // Изменение размера и сжатие изображения
  191.         $maxWidth 800;
  192.         $maxHeight 800;
  193.         $image->resize($image->getSize()->widen($maxWidth)->heighten($maxHeight));
  194.         // Создайте временную папку, если она не существует
  195.         $tempDir $this->getParameter('kernel.project_dir') . '/tmp';
  196.         if (!file_exists($tempDir)) {
  197.           mkdir($tempDir);
  198.         }
  199.         // Сохраните сжатое изображение во временный файл
  200.         $tempFilename $tempDir '/' $newFilename;
  201.         $image->save($tempFilename, ['jpeg_quality' => 80]);
  202.         // Создайте новый экземпляр файла из временного файла
  203.         $compressedPhoto = new File($tempFilename);
  204.         // Переместите файл в каталог назначения и сохраните сжатую фотографию
  205.         try {
  206.           $compressedPhoto->move(
  207.             $this->getParameter('photos_directory') . '/post-img',
  208.             $newFilename
  209.           );
  210.           // Установка ссылки на фотографию в объекте Post
  211.           $post->setPhoto('post-img/' $newFilename);
  212.         } catch (FileException $e) {
  213.           $this->addFlash('error''An error occurred while uploading the photo.');
  214.           return $this->redirectToRoute('app_admin');
  215.         }
  216.       }
  217.       $this->entityManager->persist($post);
  218.       $this->entityManager->flush();
  219.       $this->addFlash('success''Post created successfully!');
  220.       return $this->redirectToRoute('app_admin_posts');
  221.     }
  222.     return $this->render('admin/post_new.html.twig', [
  223.       'form' => $form->createView(),
  224.     ]);
  225.   }
  226.   #[Route('/posts'name'app_posts')]
  227.   public function posts(Request $requestPostRepository $postRepositoryPaginatorInterface $paginator): Response
  228.   {
  229.     $genres $postRepository->getDistinctGenres();
  230.     // Получить выбранный жанр из запроса
  231.     $selectedGenre $request->query->get('genre');
  232.     // Получить все посты или посты определенного жанра
  233.     $query $postRepository->createQueryBuilder('p');
  234.     // Определить текущую страницу
  235.     $page $request->query->getInt('page'1);
  236.     $pageSize 6// Number of posts per page
  237.     if ($selectedGenre) {
  238.       $query->andWhere('p.genre = :genre')
  239.         ->setParameter('genre'$selectedGenre);
  240.     }
  241.     $query $query->getQuery();
  242.     // применяем пагинацию
  243.     $pagination $paginator->paginate($query$page$pageSize);
  244.     // Получить общее количество элементов в определенной категории
  245.     $totalItems $pagination->getTotalItemCount();
  246.     // Рассчитать общее количество страниц
  247.     $totalPages ceil($totalItems $pageSize);
  248.     $genreCounts $this->getPostCountByGenre($postRepository);
  249.     return $this->render('post/all_posts.html.twig', [
  250.       'genres' => $genres,
  251.       'pagination' => $pagination,
  252.       'genreCounts' => $genreCounts,
  253.       'totalPages' => $totalPages,
  254.       'currentPage' => $page,
  255.       'selectedGenre' => $selectedGenre// Передать выбранный жанр в шаблон
  256.     ]);
  257.   }
  258.   public function getPostCountByGenre(PostRepository $postRepository): array
  259.   {
  260.     // Получаем список уникальных жанров
  261.     $genres $postRepository->findDistinctGenres();
  262.     // Получаем количество постов для каждого жанра
  263.     $postCounts $postRepository->countPostsByGenre();
  264.     // Создаем массив для хранения количества постов по жанрам
  265.     $genreCounts = [];
  266.     // Проходим по каждому жанру и сохраняем количество постов для этого жанра
  267.     foreach ($genres as $genre) {
  268.       $genreCounts[$genre['genre']] = $postCounts[$genre['genre']] ?? 0;
  269.     }
  270.     // Возвращаем массив с количеством постов для каждого жанра
  271.     return $genreCounts;
  272.   }
  273. }