src/Aqarmap/Bundle/NeighborhoodBundle/Controller/DefaultController.php line 74

  1. <?php
  2. namespace Aqarmap\Bundle\NeighborhoodBundle\Controller;
  3. use Aqarmap\Bundle\DiscussionBundle\Entity\Discussion;
  4. use Aqarmap\Bundle\DiscussionBundle\Form\DiscussionType;
  5. use Aqarmap\Bundle\DiscussionBundle\Service\DiscussionManager;
  6. use Aqarmap\Bundle\ListingBundle\Entity\Listing;
  7. use Aqarmap\Bundle\ListingBundle\Entity\Location;
  8. use Aqarmap\Bundle\ListingBundle\Entity\Section;
  9. use Aqarmap\Bundle\ListingBundle\Form\ContactSellerFormType;
  10. use Aqarmap\Bundle\ListingBundle\Form\QuickLeadType;
  11. use Aqarmap\Bundle\ListingBundle\Service\LocationManager;
  12. use Aqarmap\Bundle\MainBundle\Form\ConfirmFormType;
  13. use Aqarmap\Bundle\NeighborhoodBundle\Service\NeighborhoodManager;
  14. use Aqarmap\Bundle\UserBundle\Constant\UserInterestStatus;
  15. use Aqarmap\Bundle\UserBundle\Entity\User;
  16. use Aqarmap\Bundle\UserBundle\Entity\UserInterest;
  17. use Aqarmap\Bundle\UserBundle\Form\QuickRegistrationFormType;
  18. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  19. use Symfony\Component\Form\FormInterface;
  20. use Symfony\Component\HttpFoundation\RedirectResponse;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\Response;
  23. use Symfony\Component\Routing\Attribute\Route;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. #[Route(path: '/neighborhood')]
  26. class DefaultController extends AbstractController
  27. {
  28. public const NEIGHBORHOOD_LOCATION_LEVEL = 0;
  29. public function __construct(private readonly DiscussionManager $discussionManager, private readonly NeighborhoodManager $neighborhoodManager, private readonly TranslatorInterface $translator, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry)
  30. {
  31. }
  32. /**
  33. * Neighborhood Compounds View.
  34. *
  35. * @return array
  36. */
  37. #[Route(path: '/compounds', name: 'neighborhood_compounds')]
  38. public function compounds(): RedirectResponse
  39. {
  40. // Redirect For now as 301 to neighborhoods page
  41. return $this->redirectToRoute('neighborhood_all_locations', [], Response::HTTP_MOVED_PERMANENTLY);
  42. }
  43. /**
  44. * Add Neighbourhood Subscribers.
  45. */
  46. #[Route(path: '/{location}/subscription', name: 'neighbourhood_add_subscriber')]
  47. public function addNeighbourhoodSubscriber(Location $location, Request $request): RedirectResponse
  48. {
  49. $this->neighborhoodManager->addSubscriber($this->getUser(), $location);
  50. $request->getSession()->getFlashBag()->add(
  51. 'success',
  52. $this->translator->trans('neighborhoods.discussion.subscriber_success_message')
  53. );
  54. return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));
  55. }
  56. /**
  57. * Remove Neighbourhood Subscribers.
  58. */
  59. #[Route(path: '/{location}/subscription/remove', name: 'neighbourhood_remove_subscriber')]
  60. public function unsetNeighbourhoodSubscriber(Location $location, Request $request): RedirectResponse
  61. {
  62. $this->neighborhoodManager->removeLocationSubscriber($this->getUser(), $location);
  63. $request->getSession()->getFlashBag()->add(
  64. 'success',
  65. $this->translator->trans('neighborhoods.discussion.subscriber_unset_message')
  66. );
  67. return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));
  68. }
  69. /**
  70. * @return RedirectResponse
  71. *
  72. * @throws BadRequestHttpException
  73. */
  74. #[Route(path: '/{location}/{user}/subscription/confirm/remove', name: 'neighborhood_mail_remove_subscriber')]
  75. public function unSubscribeLocationConfirm(User $user, Location $location, Request $request)
  76. {
  77. /* Valid User Md5 valid */
  78. if (md5($user->getId()).$this->getParameter('secret') !== $request->query->get('token')) {
  79. throw new BadRequestHttpException('Permission Denied !');
  80. }
  81. // Create confirmation form (button)
  82. $form = $this->createForm(ConfirmFormType::class, null, [
  83. 'method' => 'POST',
  84. 'action' => $this->generateUrl(
  85. 'neighborhood_mail_remove_subscriber',
  86. ['location' => $location->getId(),
  87. 'user' => $user->getId(),
  88. 'token' => $request->query->get('token'), ]
  89. ),
  90. ]);
  91. $form->handleRequest($request);
  92. if ($form->isSubmitted() && $form->isValid()) {
  93. if ($form->get('confirm')->isClicked()) {
  94. $this->neighborhoodManager->removeLocationSubscriber($user, $location);
  95. $request->getSession()->getFlashBag()->add(
  96. 'success',
  97. $this->translator->trans('neighborhoods.discussion.subscriber_unset_message')
  98. );
  99. return $this->redirectToRoute('homepage');
  100. }
  101. }
  102. return $this->render('@AqarmapNeighborhood/Default/Email/unSubscribeLocationConfirm.html.twig', [
  103. 'form' => $form,
  104. 'location' => $location,
  105. ]);
  106. }
  107. /**
  108. * Neighborhood Main Action.
  109. */
  110. #[Route(path: '/{location_slug}/', requirements: ['location_slug' => '.+?[^/]'], name: 'neighborhood_main_page', methods: ['GET'])]
  111. public function index(#[\Symfony\Bridge\Doctrine\Attribute\MapEntity(mapping: ['location_slug' => 'slug'])]
  112. ?Location $location, Request $request, LocationManager $locationManager)
  113. {
  114. /** @var $em \Doctrine\ORM\EntityManager */
  115. $em = $this->managerRegistry->getManager();
  116. if (!$location || $location->getDisabled()) {
  117. return $this->redirectToParentLocation($request->attributes->get('location_slug'));
  118. }
  119. $subLinksSections = $em->getRepository(Section::class)->getSearchableSection();
  120. if (0 == $location->getLevel()) {
  121. return $this->render(
  122. '@AqarmapNeighborhood/Default/location_neighborhood_level.html.twig',
  123. [
  124. 'location' => $location,
  125. 'subLinksSections' => $subLinksSections,
  126. ]
  127. );
  128. }
  129. $historyData = $this->neighborhoodManager->generateStatisticsHistoryData($location);
  130. foreach ($historyData['historyData'] as &$value) {
  131. $value['data']['average_price'] = array_values($value['data']['average_price']);
  132. $value['data']['demand_heat'] = array_values($value['data']['demand_heat']);
  133. $value['data']['growth'] = array_values($value['data']['growth']);
  134. }
  135. $discussion = new Discussion();
  136. $discussionForm = $form = $this->createForm(DiscussionType::class, $discussion, [
  137. 'action' => $this->generateUrl('neighborhood_discussion_create', ['location' => $location->getId()]),
  138. 'method' => 'POST',
  139. 'flatLocations' => serialize($locationManager->getLocationsArrayWithParent($request->getLocale())['searchable']) ?? serialize([]),
  140. ]);
  141. $statistics = $em->getRepository(\Aqarmap\Bundle\NeighborhoodBundle\Entity\LocationStatistics::class)->findby(['location' => $location]);
  142. $subNeighbourhoods = [];
  143. foreach ($statistics as $statisticsObject) {
  144. $subNeighbourhoods[$statisticsObject->getPropertyType()->getId()]['propertyType'] = $statisticsObject->getPropertyType();
  145. $subNeighbourhoods[$statisticsObject->getPropertyType()->getId()]['locations'] = $em->getRepository(Location::class)
  146. ->getNeighbourhoodSubLocations(
  147. $location,
  148. $statisticsObject->getPropertyType()
  149. );
  150. }
  151. $contact_seller_form = null;
  152. if ($location->getListing()) {
  153. $contact_seller_form = $this->contactSellerForm($location
  154. ->getListing())->createView();
  155. }
  156. $subscribedUser = null;
  157. if ($this->getUser()) {
  158. $subscribedUser = $em->getRepository(UserInterest::class)->findOneBy([
  159. 'user' => $this->getUser(),
  160. 'location' => $location,
  161. 'status' => UserInterestStatus::LIVE,
  162. ]);
  163. }
  164. $locationStatistics = $this->neighborhoodManager->getStatistics($location);
  165. return $this->render('@AqarmapNeighborhood/Default/index.html.twig', [
  166. 'location' => $location,
  167. 'locationChildren' => $em->getRepository(Location::class)->getLocationChildren($location),
  168. 'location_statistics' => $locationStatistics,
  169. 'isStatisticsContainsAveragePrice' => $this->neighborhoodManager->isStatisticsContainsAveragePrice($locationStatistics),
  170. 'sections' => $em->getRepository(Section::class)->findBy(['searchable' => true]),
  171. 'updatedDate' => $em->getRepository(\Aqarmap\Bundle\NeighborhoodBundle\Entity\LocationStatistics::class)->getLastRowDate(),
  172. 'discussionForm' => $discussionForm,
  173. 'responsiveDiscussionForm' => $discussionForm,
  174. 'discussions' => $this->discussionManager->getTrendingWithLocation($location, 3),
  175. 'quick_registration_form' => $this->quickRegistrationForm(),
  176. 'contact_seller_form' => $contact_seller_form,
  177. 'subscribedUser' => $subscribedUser,
  178. 'defaultSection' => $em->getRepository(Section::class)->findOneBy(['main' => true]),
  179. 'historyData' => $historyData['historyData'],
  180. 'nearestNeighbourhoods' => $em->getRepository(Location::class)
  181. ->getNearestNeighbourhoods(
  182. $location
  183. ),
  184. 'subNeighbourhoods' => $subNeighbourhoods,
  185. 'subLinksSections' => $subLinksSections,
  186. 'form' => $this->createQuickLeadForm(),
  187. ]);
  188. }
  189. private function redirectToParentLocation(?string $slug = null): RedirectResponse
  190. {
  191. $parentLocation = $this->getParentSlug($slug);
  192. if (!empty($parentLocation)) {
  193. return $this->redirectToRoute('neighborhood_main_page', [
  194. 'location_slug' => $parentLocation,
  195. ], Response::HTTP_MOVED_PERMANENTLY);
  196. }
  197. return $this->redirectToRoute('neighborhood_all_locations', [], Response::HTTP_MOVED_PERMANENTLY);
  198. }
  199. /**
  200. * Neighborhood All Locations View.
  201. */
  202. #[Route(path: '/', name: 'neighborhood_all_locations', methods: ['GET'])]
  203. public function locations(): Response
  204. {
  205. /** @var $em \Doctrine\ORM\EntityManager */
  206. $em = $this->managerRegistry->getManager();
  207. return $this->render('@AqarmapNeighborhood/Default/locations.html.twig', [
  208. 'subLinksSections' => $em->getRepository(Section::class)->getSearchableSection(),
  209. 'locations' => $em
  210. ->getRepository(Location::class)
  211. ->getNeighbourhoodLocations(['level' => self::NEIGHBORHOOD_LOCATION_LEVEL]),
  212. ]);
  213. }
  214. // ---------------------------------------------------------------------
  215. /**
  216. * Creates quick registration form.
  217. *
  218. * @return \Symfony\Component\Form\Form The form
  219. */
  220. public function quickRegistrationForm()
  221. {
  222. return $this->createForm(QuickRegistrationFormType::class, null, [
  223. 'method' => 'POST',
  224. 'action' => $this->generateUrl('aqarmap_user_quick_registration'),
  225. ]);
  226. }
  227. // ------------------------------------------------------------------------------
  228. /**
  229. * Creates contact seller form.
  230. *
  231. * @param Listing $listing The listing entity
  232. *
  233. * @return \Symfony\Component\Form\Form The form
  234. */
  235. public function contactSellerForm(Listing $listing)
  236. {
  237. return $this->createForm(ContactSellerFormType::class, null, [
  238. 'method' => 'POST',
  239. 'action' => $this->generateUrl('aqarmap_listing_contact_seller', ['id' => $listing->getId()]),
  240. ]);
  241. }
  242. /**
  243. * Create Quick Lead Form.
  244. */
  245. private function createQuickLeadForm(): FormInterface
  246. {
  247. return $this->createForm(
  248. QuickLeadType::class,
  249. null,
  250. [
  251. 'action' => $this->generateUrl('add_quick_lead'),
  252. 'method' => 'POST',
  253. ]
  254. );
  255. }
  256. /**
  257. * @return string|null
  258. */
  259. private function getParentSlug(?string $slug = null)
  260. {
  261. $parentLocation = explode('/', (string) $slug);
  262. array_pop($parentLocation);
  263. return implode('/', $parentLocation);
  264. }
  265. }