src/Controller/PostController.php line 76

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.       $epigraph $form->get('epigraph')->getData();
  96.       $post->setEpigraph($epigraph);
  97.       // Получение значения поля "photoFile" из формы
  98.       $photoFile $form->get('photoFile')->getData();
  99.       // Загрузка новой фотографии, если она была выбрана
  100.       if ($photoFile) {
  101.         // Удаление старой фотографии, если она существует
  102.         if ($post->getPhoto()) {
  103.           $oldPhotoPath $this->getParameter('photos_directory') . '/' $post->getPhoto();
  104.           if (file_exists($oldPhotoPath)) {
  105.             unlink($oldPhotoPath);
  106.           }
  107.         }
  108.         // Создаем временную папку, если она не существует
  109.         $tempDir $this->getParameter('kernel.project_dir') . '/tmp';
  110.         if (!file_exists($tempDir)) {
  111.           mkdir($tempDir);
  112.         }
  113.         $newFilename 'img-post' $post->getId() . '.' $photoFile->guessExtension();
  114.         // Создаем полный путь к временному файлу
  115.         $tempFilename $tempDir '/' $newFilename;
  116.         // Создаем новый объект класса Imagine и получаем фото
  117.         $imagine = new Imagine();
  118.         $image $imagine->open($photoFile->getPathname());
  119.         $maxWidth 800;
  120.         $maxHeight 800;
  121.         $image->resize($image->getSize()->widen($maxWidth)->heighten($maxHeight));
  122.         // Сохраняем сжатое изображение во временный файл
  123.         $tempFilename sys_get_temp_dir() . '/' $newFilename;
  124.         $image->save($tempFilename, ['jpeg_quality' => 80]);
  125.         // Создаем новый экземпляр файла из временного файла
  126.         $compressedPhoto = new File($tempFilename);
  127.         // Перемещаем файл в каталог назначения и сохраняем сжатую фотографию
  128.         try {
  129.           $photoFile->move(
  130.             $this->getParameter('photos_directory') . '/post-img',
  131.             $newFilename
  132.           );
  133.           // Обновление ссылки на фотографию в объекте Post
  134.           $post->setPhoto('post-img/' $newFilename);
  135.         } catch (FileException $e) {
  136.           $this->addFlash('error''An error occurred while uploading the photo.');
  137.           return $this->redirectToRoute('app_admin');
  138.         }
  139.       }
  140.       $entityManager->flush();
  141.       $this->addFlash('success''Post updated successfully!');
  142.       return new RedirectResponse($this->generateUrl('app_admin_posts'));
  143.     }
  144.     return $this->render('admin/post_edit.html.twig', [
  145.       'form' => $form->createView(),
  146.       'currentPhoto' => $currentPhoto,
  147.       'post' => $post,
  148.     ]);
  149.   }
  150.   #[Route('/admin/posts/{id}/delete'name'app_admin_post_delete')]
  151.   #[IsGranted('ROLE_ADMIN')]
  152.   public function delete(Request $requestPost $postEntityManagerInterface $entityManagerFilesystem $filesystem): Response
  153.   {
  154.     if ($this->isCsrfTokenValid('delete_post_' $post->getId(), $request->request->get('_token'))) {
  155.       $photo $post->getPhoto();
  156.       if ($photo) {
  157.         // Полный путь к файлу
  158.         $filePath $this->getParameter('photos_directory') . '/' $photo;
  159.         if ($filesystem->exists($filePath)) {
  160.           $filesystem->remove($filePath);
  161.         }
  162.       }
  163.       $entityManager->remove($post);
  164.       $entityManager->flush();
  165.       $this->addFlash('success''Post deleted successfully!');
  166.     }
  167.     return new RedirectResponse($this->generateUrl('app_admin_posts'));
  168.   }
  169.   #[Route('/admin/posts/new'name'app_admin_post_new')]
  170.   #[IsGranted('ROLE_ADMIN')]
  171.   public function new(Request $request): Response
  172.   {
  173.     $post = new Post();
  174.     $form $this->createForm(PostType::class, $post);
  175.     $form->handleRequest($request);
  176.     if ($form->isSubmitted() && $form->isValid()) {
  177.       $epigraph $form->get('epigraph')->getData();
  178.       $post->setEpigraph($epigraph);
  179.       // Получение значения поля "photoFile" из формы
  180.       $photoFile $form->get('photoFile')->getData();
  181.       // Загрузка фотографии, если она была выбрана
  182.       if ($photoFile) {
  183.         $newFilename uniqid() . '.' $photoFile->guessExtension();
  184.         // Создается новый объект класса Imagine и получаем фото
  185.         $imagine = new Imagine();
  186.         $image $imagine->open($photoFile->getPathname());
  187.         // Изменение размера и сжатие изображения
  188.         $maxWidth 800;
  189.         $maxHeight 800;
  190.         $image->resize($image->getSize()->widen($maxWidth)->heighten($maxHeight));
  191.         // Создайте временную папку, если она не существует
  192.         $tempDir $this->getParameter('kernel.project_dir') . '/tmp';
  193.         if (!file_exists($tempDir)) {
  194.           mkdir($tempDir);
  195.         }
  196.         // Сохраните сжатое изображение во временный файл
  197.         $tempFilename $tempDir '/' $newFilename;
  198.         $image->save($tempFilename, ['jpeg_quality' => 80]);
  199.         // Создайте новый экземпляр файла из временного файла
  200.         $compressedPhoto = new File($tempFilename);
  201.         // Переместите файл в каталог назначения и сохраните сжатую фотографию
  202.         try {
  203.           $compressedPhoto->move(
  204.             $this->getParameter('photos_directory') . '/post-img',
  205.             $newFilename
  206.           );
  207.           // Установка ссылки на фотографию в объекте Post
  208.           $post->setPhoto('post-img/' $newFilename);
  209.         } catch (FileException $e) {
  210.           $this->addFlash('error''An error occurred while uploading the photo.');
  211.           return $this->redirectToRoute('app_admin');
  212.         }
  213.       }
  214.       $this->entityManager->persist($post);
  215.       $this->entityManager->flush();
  216.       $this->addFlash('success''Post created successfully!');
  217.       return $this->redirectToRoute('app_admin_posts');
  218.     }
  219.     return $this->render('admin/post_new.html.twig', [
  220.       'form' => $form->createView(),
  221.     ]);
  222.   }
  223.   #[Route('/posts'name'app_posts')]
  224.   public function posts(Request $requestPostRepository $postRepositoryPaginatorInterface $paginator): Response
  225.   {
  226.     $genres $postRepository->getDistinctGenres();
  227.     // Получить выбранный жанр из запроса
  228.     $selectedGenre $request->query->get('genre');
  229.     // Получить все посты или посты определенного жанра
  230.     $query $postRepository->createQueryBuilder('p');
  231.     // Определить текущую страницу
  232.     $page $request->query->getInt('page'1);
  233.     $pageSize 6// Number of posts per page
  234.     if ($selectedGenre) {
  235.       $query->andWhere('p.genre = :genre')
  236.         ->setParameter('genre'$selectedGenre);
  237.     }
  238.     $query $query->getQuery();
  239.     // применяем пагинацию
  240.     $pagination $paginator->paginate($query$page$pageSize);
  241.     // Получить общее количество элементов в определенной категории
  242.     $totalItems $pagination->getTotalItemCount();
  243.     // Рассчитать общее количество страниц
  244.     $totalPages ceil($totalItems $pageSize);
  245.     $genreCounts $this->getPostCountByGenre($postRepository);
  246.     return $this->render('post/all_posts.html.twig', [
  247.       'genres' => $genres,
  248.       'pagination' => $pagination,
  249.       'genreCounts' => $genreCounts,
  250.       'totalPages' => $totalPages,
  251.       'currentPage' => $page,
  252.       'selectedGenre' => $selectedGenre// Передать выбранный жанр в шаблон
  253.     ]);
  254.   }
  255.   public function getPostCountByGenre(PostRepository $postRepository): array
  256.   {
  257.     // Получаем список уникальных жанров
  258.     $genres $postRepository->findDistinctGenres();
  259.     // Получаем количество постов для каждого жанра
  260.     $postCounts $postRepository->countPostsByGenre();
  261.     // Создаем массив для хранения количества постов по жанрам
  262.     $genreCounts = [];
  263.     // Проходим по каждому жанру и сохраняем количество постов для этого жанра
  264.     foreach ($genres as $genre) {
  265.       $genreCounts[$genre['genre']] = $postCounts[$genre['genre']] ?? 0;
  266.     }
  267.     // Возвращаем массив с количеством постов для каждого жанра
  268.     return $genreCounts;
  269.   }
  270. }