<?php
namespace App\Controller\Forum;
use App\Entity\ForumCategory;
use App\Entity\ForumComment;
use App\Entity\ForumCommentReply;
use App\Entity\ForumNotificationSubscriber;
use App\Entity\ForumPost;
use App\Entity\ForumReport;
use App\Entity\ForumTopic;
use App\Entity\ForumUser;
use App\Entity\User;
use App\Form\ForumCommentReplyType;
use App\Form\ForumCommentType;
use App\Form\ForumPostType;
use App\Form\ForumReportType;
use App\Repository\ForumPostRepository;
use App\Service\Forum\ForumSubscribeNotificationService;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
/**
* @Route("/forum")
*
*/
class ForumPostController extends AbstractController
{
/**
*
* POST UPDATE SLUG AFTER HAVE ID
*
* @param ForumPost $post
* @param SluggerInterface $slugger
* @return void
*/
private function postUpdateSlug(
ForumPost $post,
SluggerInterface $slugger
)
{
$slug = strtolower($slugger->slug($post->getTitle()));
$slug = $post->getId() . "-" . $slug;
$post->setSlug($slug);
}
/**
* RECUPERER LES ID DES TOPIC AVEC CATEGORIE
*
* @param EntityManagerInterface $entityManager
* @return array
*/
private function getTopicsIDs(
EntityManagerInterface $entityManager
): array
{
$categories = $entityManager->getRepository(ForumCategory::class)->findAll();
$topicIDS = [];
foreach ($categories as $category) {
$categoryName = $category->getName();
if (!isset($topicIDS[$categoryName])) {
$topicIDS[$categoryName] = [];
}
foreach ($category->getTopics() as $topic) {
$topicIDS[$categoryName][$topic->getName()] = $topic->getId();
}
}
return $topicIDS;
}
/**
* @Route("/{countryMin}/topic/recent", name="app_forum_recent")
*
*/
public function recentPost(
ForumPostRepository $forumPostRepository,
Request $request,
PaginatorInterface $paginator,
string $countryMin
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
$recentPost = $forumPostRepository->recentPost();
$knpPage = $request->get('page', 1);
$knpPerPage = 30;
/** @var ForumPost[] $posts */
$posts = $paginator->paginate(
$recentPost,
$request->query->getInt('page', $knpPage),
$knpPerPage
);
return $this->render('forum/forum_post/recent.html.twig', [
'posts' => $posts,
'currentForumUser' => $currentForumUser,
]);
}
/**
* @Route("/{countryMin}/new/{slug}", name="app_forum_forum_post_new")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function new(
Request $request,
ForumPostRepository $forumPostRepository,
EntityManagerInterface $entityManager,
SluggerInterface $slugger,
string $countryMin,
?string $slug = ''
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$forumUser = $currentUser->getForumUser();
$forumPost = new ForumPost();
$formOptions['topic_selected_id'] = null;
if ($slug) {
$topicSelected = $entityManager->getRepository(ForumTopic::class)->findOneBy([
'slug' => $slug
]);
if ($topicSelected)
$formOptions['topic_selected_id'] = $topicSelected->getId();
}
$formOptions['topicsIDs'] = $this->getTopicsIDs($entityManager);
$form = $this->createForm(ForumPostType::class, $forumPost, $formOptions);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$forumPost->setForumUser($forumUser);
$topic = $entityManager->getRepository(ForumTopic::class)->findOneBy([
'id' => $form->get('topic')->getData()
]);
if (!$topic) {
throw $this->createAccessDeniedException();
}
$forumPost->setTopic($topic);
$forumPostRepository->add($forumPost, true);
// UPDATE SLUG
$this->postUpdateSlug($forumPost, $slugger);
$forumPostRepository->add($forumPost, true);
return $this->redirectToRoute('app_forum_forum_post_show', [
'country' => $forumPost->getTopic()->getCountryMin(),
'topicslug' => $forumPost->getTopic()->getSlug(),
'slug' => $forumPost->getSlug()
], Response::HTTP_SEE_OTHER);
}
return $this->render('forum/forum_post/new.html.twig', [
'forum_post' => $forumPost,
'form' => $form->createView(),
]);
}
/**
* @Route("/{country}/{topicslug}/{slug}", name="app_forum_forum_post_show")
*
*/
public function show(
EntityManagerInterface $entityManager,
Request $request,
ForumSubscribeNotificationService $subscribeNotificationService,
ForumPost $post // GET BY SLUG
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
// -------------- VIEWED POST --------------
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
// ADD VIEWED POST
if (
$currentForumUser
&& $currentUser !== $post->getForumUser()
&& $post->isActived()
) {
$post->addUserView($currentForumUser);
$entityManager->persist($post);
$entityManager->flush();
}
}
// -------------- // VIEWED POST // --------------
// REDIRECT IF NOT ACTIVE
if (
!$post->isActived()
&& ($post->getForumUser() !== $currentForumUser && !$this->isGranted('ROLE_ADMIN'))
) {
throw $this->createNotFoundException();
}
// -------------- COMMENT SCRIPT --------------
$comment = new ForumComment();
$formComment = $this->createForm(ForumCommentType::class, $comment);
$formComment->handleRequest($request);
if ($formComment->isSubmitted() && $formComment->isValid()) {
if ($post->isClosed()) {
throw $this->createAccessDeniedException();
}
if ($currentForumUser) {
$comment->setForumUser($currentForumUser);
$comment->setPost($post);
$entityManager->persist($comment);
// ADD SUBSCRIBE
$notificationSubscriber = $entityManager->getRepository(ForumNotificationSubscriber::class)->findOneBy([
'post' => $post,
'forumUser' => $currentForumUser
]);
if (!$notificationSubscriber) {
$notificationSubscriber = new ForumNotificationSubscriber();
$notificationSubscriber->setPost($post);
$notificationSubscriber->setTypeComment();
$notificationSubscriber->setForumUser($currentForumUser);
$entityManager->persist($notificationSubscriber);
}
$entityManager->flush();
// GENERATE NOTIFICATION
$subscribeNotificationService->generateNotification($currentForumUser, $post);
return $this->redirectToRoute('app_forum_forum_post_show', [
'country' => $post->getTopic()->getCountryMin(),
'topicslug' => $post->getTopic()->getSlug(),
'slug' => $post->getSlug()
]);
}
}
// -------------- // COMMENT SCRIPT // --------------
// -------------- COMMENT SCRIPT --------------
/** @var ForumCommentReplyType[] $formReplys */
$formReplys = [];
foreach ($post->getComments() as $comment) {
$forumReply = new ForumCommentReply();
$formReplys['comment_' . $comment->getId()] = $this->createForm(
ForumCommentReplyType::class,
$forumReply
)->createView();
}
// -------------- // COMMENT SCRIPT // --------------
return $this->render('forum/forum_post/show.html.twig', [
'post' => $post,
'currentForumUser' => $currentForumUser,
'formComment' => $formComment->createView(),
'formReplys' => $formReplys,
'reportForm' => $this->createForm(ForumReportType::class, new ForumReport())->createView(),
]);
}
/**
* @Route("/comment/reply{id}", name="app_forum_forum_comment_reply")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function replyComment(
EntityManagerInterface $entityManager,
Request $request,
ForumSubscribeNotificationService $subscribeNotificationService,
ForumComment $comment
): Response
{
if ($comment->getPost()->isClosed()) {
throw $this->createAccessDeniedException();
}
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
$reply = new ForumCommentReply();
$formComment = $this->createForm(ForumCommentReplyType::class, $reply);
$formComment->handleRequest($request);
if ($formComment->isSubmitted() && $formComment->isValid()) {
if ($currentForumUser) {
$reply->setForumUser($currentForumUser);
$reply->setComment($comment);
$entityManager->persist($reply);
// ADD SUBSCRIBE
$notificationSubscriber = $entityManager->getRepository(ForumNotificationSubscriber::class)->findOneBy([
'comment' => $comment,
'forumUser' => $currentForumUser
]);
if (!$notificationSubscriber) {
$notificationSubscriber = new ForumNotificationSubscriber();
$notificationSubscriber->setComment($comment);
$notificationSubscriber->setPost($comment->getPost());
$notificationSubscriber->setTypeReply();
$notificationSubscriber->setForumUser($currentForumUser);
$entityManager->persist($notificationSubscriber);
}
$entityManager->flush();
// GENERATE NOTIFICATION
$subscribeNotificationService->generateNotification($currentForumUser, $comment->getPost(), $comment);
}
}
$post = $comment->getPost();
return $this->redirectToRoute('app_forum_forum_post_show', [
'country' => $post->getTopic()->getCountryMin(),
'topicslug' => $post->getTopic()->getSlug(),
'slug' => $post->getSlug()
]);
}
/**
* @Route("/{country}/post/edit/{id}", name="app_forum_forum_post_edit")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function edit(
EntityManagerInterface $entityManager,
Request $request,
ForumPostRepository $forumPostRepository,
SluggerInterface $slugger,
ForumPost $forumPost
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
if ($forumPost->getForumUser() !== $currentForumUser) {
throw $this->createAccessDeniedException();
}
if ($forumPost->isClosed()) {
throw $this->createAccessDeniedException();
}
$formOptions['topic_selected_id'] = $forumPost->getTopic()->getId();
$formOptions['topicsIDs'] = $this->getTopicsIDs($entityManager);
$form = $this->createForm(ForumPostType::class, $forumPost, $formOptions);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$topic = $entityManager->getRepository(ForumTopic::class)->findOneBy([
'id' => $form->get('topic')->getData()
]);
if (!$topic) {
throw $this->createAccessDeniedException();
}
$forumPost->setTopic($topic);
$forumPostRepository->add($forumPost, true);
// UPDATE SLUG
$this->postUpdateSlug($forumPost, $slugger);
$forumPostRepository->add($forumPost, true);
return $this->redirectToRoute('app_forum_forum_post_show', [
'country' => $forumPost->getTopic()->getCountryMin(),
'topicslug' => $forumPost->getTopic()->getSlug(),
'slug' => $forumPost->getSlug()
], Response::HTTP_SEE_OTHER);
}
return $this->render('forum/forum_post/edit.html.twig', [
'forum_post' => $forumPost,
'form' => $form->createView(),
]);
}
/**
* @Route("/post/favorite", name="app_forum_forum_post_favorite_index")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function favorite(
PaginatorInterface $paginator,
Request $request
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
$topicPosts = $currentForumUser->getFavoritePost();
$knpPage = $request->get('page', 1);
$knpPerPage = 30;
/** @var ForumPost[] $posts */
$posts = $paginator->paginate(
$topicPosts,
$request->query->getInt('page', $knpPage),
$knpPerPage
);
return $this->render('forum/forum_post/favorite.html.twig', [
'posts' => $posts,
'currentForumUser' => $currentForumUser,
]);
}
/**
* @Route("/post/favorite/add/{id}", name="app_forum_forum_post_favorite_add")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function favoriteAdd(
EntityManagerInterface $entityManager,
ForumPost $post
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
if ($currentForumUser) {
if ($post->isFavorite($currentForumUser)) {
$currentForumUser->removeFavoritePost($post);
// DELETE SUBSCRIBE
$notificationSubscriber = $entityManager->getRepository(ForumNotificationSubscriber::class)->findOneBy([
'post' => $post,
'forumUser' => $currentForumUser
]);
if ($notificationSubscriber) {
$entityManager->remove($notificationSubscriber);
}
} else {
$currentForumUser->addFavoritePost($post);
// ADD SUBSCRIBE
$notificationSubscriber = $entityManager->getRepository(ForumNotificationSubscriber::class)->findOneBy([
'post' => $post,
'forumUser' => $currentForumUser
]);
if (!$notificationSubscriber) {
$notificationSubscriber = new ForumNotificationSubscriber();
$notificationSubscriber->setPost($post);
$notificationSubscriber->setTypeFavory();
$notificationSubscriber->setForumUser($currentForumUser);
$entityManager->persist($notificationSubscriber);
}
}
$entityManager->persist($currentForumUser);
$entityManager->flush();
} else {
throw $this->createAccessDeniedException();
}
$json = [
'status' => 200
];
return new JsonResponse(json_encode($json), 200, [], true);
}
/**
* @Route("/f/re/report/submit", name="app_forum_post_report")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function reportPost(
Request $request,
EntityManagerInterface $entityManager
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
/** @var ForumPost $post */
$post = null;
$report = new ForumReport();
$formReport = $this->createForm(ForumReportType::class, $report);
$formReport->handleRequest($request);
if ($formReport->isSubmitted() && $formReport->isValid()) {
if ($currentForumUser) {
$typeEntity = $formReport->get('report_entity')->getData();
$rubriqueID = $formReport->get('rubrique_id')->getData();
$report->setForumUser($currentForumUser);
if ($typeEntity == 'comment') {
$comment = $entityManager->getRepository(ForumComment::class)->findOneBy([
'id' => $rubriqueID
]);
$report->setComment($comment);
$post = $comment->getPost();
} elseif ($typeEntity == 'reply') {
$commentReply = $entityManager->getRepository(ForumCommentReply::class)->find($rubriqueID);
$report->setCommentReply($commentReply);
$comment = $commentReply->getComment();
$post = $comment->getPost();
} elseif ($typeEntity == 'post') {
$post = $entityManager->getRepository(ForumPost::class)->findOneBy([
'id' => $rubriqueID
]);
}
if ($post) {
$report->setPost($post);
$entityManager->persist($report);
$entityManager->flush();
$this->addFlash('toastr_success', 'Your report has been sent successfully');
return $this->redirectToRoute('app_forum_forum_post_show', [
'country' => $post->getTopic()->getCountryMin(),
'topicslug' => $post->getTopic()->getSlug(),
'slug' => $post->getSlug()
]);
}
}
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/post/subscribe", name="app_forum_forum_post_subscribe")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function subscribeList(
EntityManagerInterface $entityManager,
PaginatorInterface $paginator,
Request $request
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
if (!$currentForumUser) {
throw $this->createAccessDeniedException();
}
/** @var ForumPost[] $subscribePost */
$subscribePost = [];
$subscribeNotification = $entityManager->getRepository(ForumNotificationSubscriber::class)->findBy(
['forumUser' => $currentForumUser],
['id' => 'DESC'],
);
foreach ($subscribeNotification as $sbNotif) {
if (
!in_array($sbNotif->getPost(), $subscribePost)
&& !$currentForumUser->getPosts()->contains($sbNotif->getPost())
) {
$subscribePost[] = $sbNotif->getPost();
}
}
return $this->render('forum/forum_post/subscribe_list.html.twig', [
'subscribePost' => $subscribePost,
'currentForumUser' => $currentForumUser,
]);
}
/**
* @Route("/{countryMin}/search/", name="app_forum_forum_post_search")
* @IsGranted("ROLE_FREELANCE")
*
*/
public function searchPost(
PaginatorInterface $paginator,
Request $request,
ForumPostRepository $forumPostRepository
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$query = $request->query->get("search");
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
$topicPosts = $forumPostRepository->findBySearch($query);
$knpPage = $request->get('page', 1);
$knpPerPage = 30;
/** @var ForumPost[] $posts */
$posts = $paginator->paginate(
$topicPosts,
$request->query->getInt('page', $knpPage),
$knpPerPage
);
return $this->render('forum/forum_post/search.html.twig', [
'posts' => $posts,
'currentForumUser' => $currentForumUser,
'search' => $query
]);
}
/**
* @Route("/closed/45654654{id}546543", name="app_forum_forum_post_closed")
*
*/
public function close(
EntityManagerInterface $entityManager,
Request $request,
ForumPost $forumPost
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
/** @var ?ForumUser $currentForumUser */
$currentForumUser = null;
$haveAccess = false;
if ($currentUser) {
$currentForumUser = $currentUser->getForumUser();
}
if ($forumPost->getForumUser() === $currentForumUser) {
$haveAccess = true;
}
if($currentUser->isRole('ROLE_ADMIN')){
$haveAccess = true;
}
if (! $haveAccess) {
throw $this->createAccessDeniedException();
}
$forumPost->setClosed(true);
$forumPost->setClosedAt(new \DateTime());
$entityManager->persist($forumPost);
$entityManager->flush();
return $this->redirectToRoute('app_forum_forum_post_show', [
'country' => $forumPost->getTopic()->getCountryMin(),
'topicslug' => $forumPost->getTopic()->getSlug(),
'slug' => $forumPost->getSlug()
], Response::HTTP_SEE_OTHER);
}
public function delete(Request $request, ForumPost $forumPost, ForumPostRepository $forumPostRepository): Response
{
if ($this->isCsrfTokenValid('delete' . $forumPost->getId(), $request->request->get('_token'))) {
$forumPostRepository->remove($forumPost, true);
}
return $this->redirectToRoute('app_forum_forum_post_index', [], Response::HTTP_SEE_OTHER);
}
}