src/Aqarmap/Bundle/DiscussionBundle/Controller/DiscussionController.php line 267
<?phpnamespace Aqarmap\Bundle\DiscussionBundle\Controller;use App\Exception\BadRequestHttpException;use Aqarmap\Bundle\DiscussionBundle\Constant\DiscussionSearchTabs;use Aqarmap\Bundle\DiscussionBundle\Constant\DiscussionStatus;use Aqarmap\Bundle\DiscussionBundle\Entity\Comment;use Aqarmap\Bundle\DiscussionBundle\Entity\Discussion;use Aqarmap\Bundle\DiscussionBundle\Form\CommentType;use Aqarmap\Bundle\DiscussionBundle\Form\DiscussionSearchType;use Aqarmap\Bundle\DiscussionBundle\Form\DiscussionType;use Aqarmap\Bundle\DiscussionBundle\Repository\CategoryRepository;use Aqarmap\Bundle\DiscussionBundle\Repository\CommentRepository;use Aqarmap\Bundle\DiscussionBundle\Repository\DiscussionRepository;use Aqarmap\Bundle\DiscussionBundle\Service\DiscussionManager;use Aqarmap\Bundle\DiscussionBundle\Service\WordpressManager;use Aqarmap\Bundle\ListingBundle\Entity\Location;use Aqarmap\Bundle\ListingBundle\Form\QuickLeadType;use Aqarmap\Bundle\ListingBundle\Repository\ListingRepository;use Aqarmap\Bundle\ListingBundle\Repository\LocationRepository;use Aqarmap\Bundle\ListingBundle\Repository\SectionRepository;use Aqarmap\Bundle\ListingBundle\Service\LocationManager;use Aqarmap\Bundle\ListingBundle\Service\SupplyDemandManager;use Aqarmap\Bundle\MainBundle\Form\ConfirmFormType;use Aqarmap\Bundle\NotificationBundle\DatabaseNotification;use Aqarmap\Bundle\UserBundle\Entity\User;use Aqarmap\Bundle\UserBundle\Form\QuickRegistrationFormType;use Aqarmap\Bundle\UserBundle\Repository\UserInterestRepository;use Aqarmap\Bundle\UserBundle\Services\UserInterestManager;use Aqarmap\Bundle\UserBundle\Services\UserManager;use Doctrine\ORM\EntityManagerInterface;use Knp\Component\Pager\PaginatorInterface;use Predis\Client;use Psr\Log\LoggerInterface;use Psr\Log\LogLevel;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;use Symfony\Component\Form\FormInterface;use Symfony\Component\HttpFoundation\RedirectResponse;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpFoundation\Session\SessionInterface;use Symfony\Component\Routing\Attribute\Route;use Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface;use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;use Symfony\Contracts\Translation\TranslatorInterface;/*** Discussion controller.*/class DiscussionController extends AbstractController{public function __construct(private readonly DiscussionManager $discussionManager,private readonly WordpressManager $wordpressManager,private readonly UserInterestRepository $userInterestRepository,private readonly UserInterestManager $userInterestManager,private readonly EntityManagerInterface $em,Client $redisClient,private readonly LocationRepository $locationRepository,private readonly DiscussionRepository $discussionRepository,private readonly ListingRepository $listingRepository,private readonly SectionRepository $sectionRepository,private readonly CategoryRepository $categoryRepository,TokenStorageInterface $tokenStorage,private readonly SupplyDemandManager $supplyDemandManager,private readonly ParameterBagInterface $parameterBag,private readonly TranslatorInterface $translator,private readonly PaginatorInterface $paginator,private readonly UserManager $userManager,private readonly CommentRepository $commentRepository,EventDispatcherInterface $eventDispatcher,LoggerInterface $logger,private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,) {}/*** Lists all Discussion entities.*/#[Route(path: 'ask-neighbors/', name: 'neighborhood_discussion_list', methods: ['GET'])]#[Route(path: 'discussion/', name: 'discussion_list', methods: ['GET'])]#[Route(path: 'question/', name: 'neighborhood_question_discussion_list', methods: ['GET'])]public function discussions(Request $request, LocationManager $locationManager){$response = $this->removePageQuery($request);if ($response instanceof RedirectResponse) {return $response;}if ('discussion_list' == $request->get('_route')) {return $this->redirectToRoute('neighborhood_discussion_list', $request->query->all(), Response::HTTP_MOVED_PERMANENTLY);}$this->managerRegistry->getManager();$user = $this->getUser();$userInterests = [];if ($user instanceof User) {$userInterests = $this->userInterestRepository->getUserInterests($user, 4)->getQuery()->getResult();}$userInterests = !empty($userInterests) ? $userInterests : [$this->userInterestManager->getListingsMayBeInterested()];$interestsListings = $this->discussionManager->getInterestsListings($userInterests);$location = $request->query->get('location') ? $this->locationRepository->find($request->query->get('location')) : null;$discussion = new Discussion();$discussionForm = $form = $this->createForm(DiscussionType::class, $discussion, ['action' => $this->generateUrl('neighborhood_discussion_create'),'method' => 'POST','flatLocations' => [],'selectedLocation' => $location ? [$location->getTitle() => $location->getId()] : [],'selectedLocationId' => $location ? $location->getId() : null,]);$discussionSearchForm = $form = $this->createForm(DiscussionSearchType::class, $discussion, ['action' => $this->generateUrl('neighborhood_discussion_list'),'method' => 'GET','flatLocations' => serialize($locationManager->getFlatByMaxLevel(2)),'selectedLocation' => $location ? [$location->getTitle() => $location->getId()] : [],'selectedLocationId' => $location ? $location->getId() : null,]);$locationChildren = [];if ($location) {$locationChildren = $this->supplyDemandManager->getLocationChildren($location);}$criteria = ['status' => DiscussionStatus::APPROVED,'location' => $locationChildren,'category' => $request->query->get('category'),'tab' => $request->query->get('tab', DiscussionSearchTabs::TRENDING),'sort' => 'commentsCounter',];$discussions = $this->discussionRepository->filter($criteria);if ($request->query->get('submitted')&& DiscussionSearchTabs::TRENDING == $request->query->get('tab')&& empty($discussions)) {$criteria = $request->query->all();$criteria['tab'] = DiscussionSearchTabs::ALLQUESTIONS;return $this->redirectToRoute('neighborhood_discussion_list', $criteria);}$discussions = $this->paginator->paginate($discussions,$request->query->getInt('page', 1),10);$latestLocationListings = [];if ($location) {$latestLocationListings = $this->listingRepository->getLatestListings(4, $this->supplyDemandManager->getLocationChildren($location))->getQuery()->getResult();}return $this->render('@AqarmapDiscussionBundle/Discussion/discussions.html.twig', ['subLinksSections' => $this->sectionRepository->getSearchableSection(),'discussionForm' => $discussionForm,'responsiveDiscussionForm' => $discussionForm,'discussionSearchForm' => $discussionSearchForm,'discussions' => $discussions,'interestsListings' => $interestsListings,'quick_registration_form' => $this->createForm(QuickRegistrationFormType::class, null, ['method' => 'POST','action' => $this->generateUrl('aqarmap_user_quick_registration'),]),'location' => $location,'latestLocationListings' => $latestLocationListings,'popularArticles' => json_decode($this->wordpressManager->getCachedPosts($request->getLocale()),true),'aqarmap_advice_link' => $this->parameterBag->get('aqarmap_advice_url'),'form' => $this->createQuickLeadForm(),'metaDescriptionContent' => $this->discussionManager->concatTitles($discussions->getItems()),'selectedCategory' => $request->get('category') ?$this->categoryRepository->find($request->get('category')) : null,]);}/*** Creates a new Discussion entity.*/#[Route(path: 'question/create/', name: 'neighborhood_discussion_create', methods: ['POST'])]public function create(Request $request,LocationManager $locationManager,SessionInterface $session,): RedirectResponse {$entity = new Discussion();$form = $this->createForm(DiscussionType::class, $entity, ['action' => $this->generateUrl('neighborhood_discussion_create'),'method' => 'POST','flatLocations' => serialize($locationManager->getLocationsArrayWithParent($request->getLocale())['searchable']) ?? serialize([]),]);$location = null;if ($locationId = $request->request->get('location')) {$location = $this->locationRepository->find($locationId);$request->request->set('location', null);$form->get('location')->setData(null);}$form->handleRequest($request);if ($form->isValid() && $this->getUser()) {$entity->setLocation($location);$entity->setUser($this->getUser());$this->em->persist($entity);$this->em->flush();$this->discussionManager->createSubscriber($this->getUser(), $entity);$session->getFlashBag()->add('success',$this->translator->trans('neighborhoods.discussion.success_message'));}return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));}/*** Lists all Discussion comments.*/#[Route(path: 'ask-neighbors/{discussion}/answers/', name: 'neighborhood_discussion_comments', methods: ['GET'])]#[Route(path: 'discussion/{discussion}/comments/', name: 'discussion_comments', methods: ['GET'])]#[Route(path: 'question/{discussion}/comments/', name: 'neighborhood_question_discussion_comments', methods: ['GET'])]public function discussionComments(Request $request,DatabaseNotification $databaseNotification,LoggerInterface $logger,SessionInterface $session,?Discussion $discussion = null,) {if ($request->get('notification')) {try {$databaseNotification->markOneAsRead($request->get('notification'));} catch (\Exception $exception) {$logger->log(LogLevel::ERROR, $exception->getMessage());}}if (!$discussion) {return $this->redirectToRoute('neighborhood_discussion_list', [], Response::HTTP_MOVED_PERMANENTLY);}if ($discussion->getDeletedAt()) {if ($discussion->getUser() != $this->getUser()) {return $this->redirectWhenDiscussionDeleted($discussion);}$session->getFlashBag()->add('warning',$this->translator->trans('neighborhoods.discussion.already_deleted'));} elseif (DiscussionStatus::PENDING == $discussion->getStatus()) {$session->getFlashBag()->add('warning',$this->translator->trans('neighborhoods.discussion.pending_approval'));}if (\in_array($request->get('_route'), ['neighborhood_question_discussion_comments','discussion_comments',])) {return $this->redirectToRoute('neighborhood_discussion_comments', array_merge(['discussion' => $discussion->getId()], $request->query->all()), Response::HTTP_MOVED_PERMANENTLY);}$comment = new Comment();$commentForm = $this->createForm(CommentType::class, $comment, ['action' => $this->generateUrl('neighborhood_comment_create', ['discussion' => $discussion->getId()]),'method' => 'POST',]);$user = $this->getUser();$userInterests = [];if ($user instanceof User) {$userInterests = $this->userInterestRepository->getUserInterests($user, 4)->getQuery()->getResult();}$userInterests[] = $this->userInterestManager->getListingsMayBeInterested($discussion->getLocation());$interestsListings = $this->discussionManager->getInterestsListings($userInterests);return $this->render('@AqarmapDiscussionBundle/Discussion/discussionComments.html.twig', ['commentForm' => $commentForm,'discussion' => $discussion,'discussionComments' => $this->commentRepository->getCommentsWithLikes($discussion),'interestsListings' => $interestsListings,'quick_registration_form' => $this->createForm(QuickRegistrationFormType::class, null, ['method' => 'POST','action' => $this->generateUrl('aqarmap_user_quick_registration'),]),'popularArticles' => json_decode($this->wordpressManager->getCachedPosts($request->getLocale()),true),'aqarmap_advice_link' => $this->parameterBag->get('aqarmap_advice_url'),]);}/*** Add Discussion Subscribers.*/#[Route(path: 'question/add/subscriber/{discussion}/', name: 'neighborhood_discussion_add_subscriber')]public function addDiscussionSubscriber(Discussion $discussion,Request $request,SessionInterface $session,): RedirectResponse {$user = $this->getUser();$this->discussionManager->createSubscriber($user, $discussion);$session->getFlashBag()->add('success',$this->translator->trans('neighborhoods.discussion.subscriber_success_message'));return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));}/*** Remove Discussion Subscribers.*/#[Route(path: 'question/remove/subscriber/{discussion}/', name: 'neighborhood_discussion_remove_subscriber')]public function unsetDiscussionSubscriber(Discussion $discussion,Request $request,SessionInterface $session,): RedirectResponse {$this->discussionManager->unsetSubscriber($this->getUser(), $discussion);$session->getFlashBag()->add('success',$this->container->get('translator')->trans('neighborhoods.discussion.subscriber_unset_message'));return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));}/*** @return RedirectResponse** @throws BadRequestHttpException*/#[Route(path: 'question/un-subscribe/{user}/{discussion}/', name: 'neighborhood_discussion_mail_remove_subscriber')]public function unsubscribeConfirm(User $user,Discussion $discussion,Request $request,SessionInterface $session,) {/* Valid User Md5 valid */if (md5($user->getId()).$this->parameterBag->get('secret') !== $request->query->get('token')) {throw new BadRequestHttpException('Permission Denied !');}// Create confirmation form (button)$form = $this->createForm(ConfirmFormType::class, null, ['method' => 'POST','action' => $this->generateUrl('neighborhood_discussion_mail_remove_subscriber',['discussion' => $discussion->getId(), 'user' => $user->getId(), 'token' => $request->query->get('token')]),]);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {if ($form->get('confirm')->isClicked()) {$this->discussionManager->unsetSubscriber($user, $discussion);$session->getFlashBag()->add('success',$this->translator->trans('neighborhoods.discussion.subscriber_unset_message'));return $this->redirectToRoute('homepage');}}return $this->render('@AqarmapDiscussionBundle/Discussion/unsubscribeConfirm.html.twig', ['form' => $form,'discussion' => $discussion,]);}/*** Edit Comment entity.** @return array|RedirectResponse*/#[Route(path: 'question/{discussion}/edit', name: 'neighborhood_discussion_edit')]public function edit(Request $request,Discussion $discussion,LocationManager $locationManager,SessionInterface $session,) {$form = $this->createForm(DiscussionType::class, $discussion, ['action' => $this->generateUrl('neighborhood_discussion_edit', ['discussion' => $discussion->getId(),]),'method' => 'POST','flatLocations' => serialize($locationManager->getLocationsArrayWithParent($request->getLocale())['searchable']) ?? serialize([]),]);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$em = $this->managerRegistry->getManager();$discussion->setStatus(DiscussionStatus::PENDING);$em->persist($discussion);$em->flush();$session->getFlashBag()->add('success',$this->translator->trans('neighborhoods.comment.edit_success_message'));return $this->redirectToRoute('neighborhood_discussion_comments', ['discussion' => $discussion->getId()]);}return $this->render('@AqarmapDiscussionBundle/Discussion/edit.html.twig', ['form' => $form,'discussion' => $discussion,]);}/*** Delete Discussion.** @return RedirectResponse|Response*/#[Route(path: 'question/{discussion}/delete', name: 'discussion_delete')]public function delete(Discussion $discussion, SessionInterface $session): RedirectResponse{if (!$discussion) {throw $this->createNotFoundException('The Discussion does not exist');}$this->discussionManager->remove($discussion);$session->getFlashBag()->add('success',$this->translator->trans('neighborhoods.discussion.delete_success_message'));return $this->redirectToRoute('neighborhood_discussion_list');}/*** Redirect when the discssuion is deleted.** @return RedirectResponse*/public function redirectWhenDiscussionDeleted(?Discussion $discussion = null){$criteria = [];if ($discussion) {$location = $discussion->getLocation();if ($location) {$criteria['location'] = $location->getId();}$category = $discussion->getCategory();if ($category) {$criteria['category'] = $category->getId();}}return $this->redirectToRoute('neighborhood_discussion_list', $criteria, Response::HTTP_MOVED_PERMANENTLY);}/*** Create Quick Lead Form.*/private function createQuickLeadForm(): FormInterface{return $this->createForm(QuickLeadType::class,null,['action' => $this->generateUrl('add_quick_lead'),'method' => 'POST',]);}#[Route(path: 'unsubscribe-ask-neighbors/{token}/{location}', requirements: ['id' => '\d+'], name: 'aqarmap_discussion_unsubscribe', methods: ['GET'])]public function unsubscribe(Request $request, SessionInterface $session, ?Location $location = null): RedirectResponse{$user = $this->userManager->findEncryptedBy($request->get('token'));if (!$user) {throw new \Exception('User Not Found!');}$criteria = ['user' => $user,];if ($location) {$criteria['location'] = $location;}$this->userInterestManager->removeBy($criteria);$session->getFlashBag()->add('success',$this->translator->trans($location ? 'neighborhoods.unsubscribe_from_successeded' : 'neighborhoods.unsubscribe_all_successeded', ['%location%' => $location]));return $this->redirectToRoute('homepage');}/*** Remove the page query if equals one.** @return RedirectResponse|void*/private function removePageQuery(Request $request){if ($request->query->getInt('page') && 1 == $request->query->getInt('page')) {$request->query->remove('page');return $this->redirectToRoute($request->get('_route'), $request->query->all(), Response::HTTP_MOVED_PERMANENTLY);}}}