<?php
namespace Aqarmap\Bundle\NeighborhoodBundle\Controller;
use Aqarmap\Bundle\DiscussionBundle\Entity\Discussion;
use Aqarmap\Bundle\DiscussionBundle\Form\DiscussionType;
use Aqarmap\Bundle\DiscussionBundle\Service\DiscussionManager;
use Aqarmap\Bundle\ListingBundle\Entity\Listing;
use Aqarmap\Bundle\ListingBundle\Entity\Location;
use Aqarmap\Bundle\ListingBundle\Entity\Section;
use Aqarmap\Bundle\ListingBundle\Form\ContactSellerFormType;
use Aqarmap\Bundle\ListingBundle\Form\QuickLeadType;
use Aqarmap\Bundle\ListingBundle\Service\LocationManager;
use Aqarmap\Bundle\MainBundle\Form\ConfirmFormType;
use Aqarmap\Bundle\NeighborhoodBundle\Form\CompoundSearchType;
use Aqarmap\Bundle\NeighborhoodBundle\Service\NeighborhoodManager;
use Aqarmap\Bundle\UserBundle\Constant\UserInterestStatus;
use Aqarmap\Bundle\UserBundle\Entity\User;
use Aqarmap\Bundle\UserBundle\Entity\UserInterest;
use Aqarmap\Bundle\UserBundle\Form\QuickRegistrationFormType;
use Predis\ClientInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
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\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @Route("/neighborhood")
*/
class DefaultController extends AbstractController
{
public const NEIGHBORHOOD_LOCATION_LEVEL = 0;
private $discussionManager;
/**
* @var NeighborhoodManager
*/
private $neighborhoodManager;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var SessionInterface
*/
private $session;
public function __construct(
DiscussionManager $discussionManager,
CompoundSearchType $compoundSearchType,
NeighborhoodManager $neighborhoodManager,
ClientInterface $redisClient,
TranslatorInterface $translator,
SessionInterface $session
) {
$this->discussionManager = $discussionManager;
$this->neighborhoodManager = $neighborhoodManager;
$this->translator = $translator;
$this->session = $session;
}
/**
* Neighborhood Compounds View.
*
* @Route("/compounds", name="neighborhood_compounds")
*
* @return array
*/
public function compounds(): RedirectResponse
{
// Redirect For now as 301 to neighborhoods page
return $this->redirect($this->generateUrl('neighborhood_all_locations'), Response::HTTP_MOVED_PERMANENTLY);
}
/**
* Add Neighbourhood Subscribers.
*
* @Route("/{location}/subscription", name="neighbourhood_add_subscriber")
*/
public function addNeighbourhoodSubscriber(Location $location, Request $request): RedirectResponse
{
$this->neighborhoodManager->addSubscriber($this->getUser(), $location);
$this->session->getFlashBag()->add(
'success',
$this->translator->trans('neighborhoods.discussion.subscriber_success_message')
);
return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));
}
/**
* Remove Neighbourhood Subscribers.
*
* @Route("/{location}/subscription/remove", name="neighbourhood_remove_subscriber")
*/
public function unsetNeighbourhoodSubscriber(Location $location, Request $request): RedirectResponse
{
$this->neighborhoodManager->removeLocationSubscriber($this->getUser(), $location);
$this->session->getFlashBag()->add(
'success',
$this->translator->trans('neighborhoods.discussion.subscriber_unset_message')
);
return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));
}
/**
* @Route("/{location}/{user}/subscription/confirm/remove", name="neighborhood_mail_remove_subscriber")
*
* @return RedirectResponse
*
* @throws BadRequestHttpException
*/
public function unSubscribeLocationConfirm(User $user, Location $location, Request $request)
{
/* Valid User Md5 valid */
if (md5($user->getId()).$this->container->getParameter('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_mail_remove_subscriber',
['location' => $location->getId(),
'user' => $user->getId(),
'token' => $request->query->get('token'), ]
),
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($form->get('confirm')->isClicked()) {
$this->neighborhoodManager->removeLocationSubscriber($user, $location);
$this->session->getFlashBag()->add(
'success',
$this->translator->trans('neighborhoods.discussion.subscriber_unset_message')
);
return $this->redirect($this->generateUrl('homepage'));
}
}
return $this->render('@AqarmapNeighborhood/Default/Email/unSubscribeLocationConfirm.html.twig', [
'form' => $form->createView(),
'location' => $location,
]);
}
/**
* Neighborhood Main Action.
*
* @ParamConverter("location", options={"mapping": {"location_slug": "slug"}})
*
* @Route("/{location_slug}/", requirements={"location_slug": ".+?[^/]"}, name="neighborhood_main_page", methods={"GET"})
*/
public function index(?Location $location, Request $request, LocationManager $locationManager)
{
/** @var $em \Doctrine\ORM\EntityManager */
$em = $this->getDoctrine()->getManager();
if (!$location || $location->getDisabled()) {
return $this->redirectToParentLocation($request->attributes->get('location_slug'));
}
$subLinksSections = $em->getRepository(Section::class)->getSearchableSection();
if (0 == $location->getLevel()) {
return $this->render(
'@AqarmapNeighborhood/Default/location_neighborhood_level.html.twig',
[
'location' => $location,
'subLinksSections' => $subLinksSections,
]
);
}
$historyData = $this->neighborhoodManager->generateStatisticsHistoryData($location);
foreach ($historyData['historyData'] as &$value) {
$value['data']['average_price'] = array_values($value['data']['average_price']);
$value['data']['demand_heat'] = array_values($value['data']['demand_heat']);
$value['data']['growth'] = array_values($value['data']['growth']);
}
$discussion = new Discussion();
$discussionForm = $form = $this->createForm(DiscussionType::class, $discussion, [
'action' => $this->generateUrl('neighborhood_discussion_create', ['location' => $location->getId()]),
'method' => 'POST',
'flatLocations' => serialize($locationManager->getLocationsArrayWithParent($request->getLocale())['searchable']) ?? serialize([]),
]);
$statistics = $em->getRepository('AqarmapNeighborhoodBundle:LocationStatistics')->findby(['location' => $location]);
$subNeighbourhoods = [];
foreach ($statistics as $statisticsObject) {
$subNeighbourhoods[$statisticsObject->getPropertyType()->getId()]['propertyType'] = $statisticsObject->getPropertyType();
$subNeighbourhoods[$statisticsObject->getPropertyType()->getId()]['locations'] = $em->getRepository(Location::class)
->getNeighbourhoodSubLocations(
$location,
$statisticsObject->getPropertyType()
);
}
$contact_seller_form = null;
if ($location->getListing()) {
$contact_seller_form = $this->contactSellerForm($location
->getListing())->createView();
}
$subscribedUser = null;
if ($this->getUser()) {
$subscribedUser = $em->getRepository(UserInterest::class)->findOneBy([
'user' => $this->getUser(),
'location' => $location,
'status' => UserInterestStatus::LIVE,
]);
}
$locationStatistics = $this->neighborhoodManager->getStatistics($location);
return $this->render('@AqarmapNeighborhood/Default/index.html.twig', [
'location' => $location,
'locationChildren' => $em->getRepository(Location::class)->getLocationChildren($location),
'location_statistics' => $locationStatistics,
'isStatisticsContainsAveragePrice' => $this->neighborhoodManager->isStatisticsContainsAveragePrice($locationStatistics),
'sections' => $em->getRepository(Section::class)->findBy(['searchable' => true]),
'updatedDate' => $em->getRepository('AqarmapNeighborhoodBundle:LocationStatistics')->getLastRowDate(),
'discussionForm' => $discussionForm->createView(),
'responsiveDiscussionForm' => $discussionForm->createView(),
'discussions' => $this->discussionManager->getTrendingWithLocation($location, 3),
'quick_registration_form' => $this->quickRegistrationForm()->createView(),
'contact_seller_form' => $contact_seller_form,
'subscribedUser' => $subscribedUser,
'defaultSection' => $em->getRepository(Section::class)->findOneBy(['main' => true]),
'historyData' => $historyData['historyData'],
'nearestNeighbourhoods' => $em->getRepository(Location::class)
->getNearestNeighbourhoods(
$location
),
'subNeighbourhoods' => $subNeighbourhoods,
'subLinksSections' => $subLinksSections,
'form' => $this->createQuickLeadForm()->createView(),
]);
}
private function redirectToParentLocation(?string $slug = null): RedirectResponse
{
$parentLocation = $this->getParentSlug($slug);
if (!empty($parentLocation)) {
return $this->redirect($this->generateUrl('neighborhood_main_page', [
'location_slug' => $parentLocation,
]), Response::HTTP_MOVED_PERMANENTLY);
}
return $this->redirect($this->generateUrl('neighborhood_all_locations'), Response::HTTP_MOVED_PERMANENTLY);
}
/**
* Neighborhood All Locations View.
*
* @Route("/", name="neighborhood_all_locations", methods={"GET"})
*/
public function locations(): Response
{
/** @var $em \Doctrine\ORM\EntityManager */
$em = $this->getDoctrine()->getManager();
return $this->render('@AqarmapNeighborhood/Default/locations.html.twig', [
'subLinksSections' => $em->getRepository(Section::class)->getSearchableSection(),
'locations' => $em
->getRepository(Location::class)
->getNeighbourhoodLocations(['level' => self::NEIGHBORHOOD_LOCATION_LEVEL]),
]);
}
// ---------------------------------------------------------------------
/**
* Creates quick registration form.
*
* @return \Symfony\Component\Form\Form The form
*/
public function quickRegistrationForm()
{
return $this->createForm(QuickRegistrationFormType::class, null, [
'method' => 'POST',
'action' => $this->generateUrl('aqarmap_user_quick_registration'),
]);
}
// ------------------------------------------------------------------------------
/**
* Creates contact seller form.
*
* @param Listing $listing The listing entity
*
* @return \Symfony\Component\Form\Form The form
*/
public function contactSellerForm(Listing $listing)
{
return $this->createForm(ContactSellerFormType::class, null, [
'method' => 'POST',
'action' => $this->generateUrl('aqarmap_listing_contact_seller', ['id' => $listing->getId()]),
]);
}
/**
* Create Quick Lead Form.
*/
private function createQuickLeadForm(): FormInterface
{
return $this->createForm(
QuickLeadType::class,
null,
[
'action' => $this->generateUrl('add_quick_lead'),
'method' => 'POST',
]
);
}
/**
* @return string|null
*/
private function getParentSlug(?string $slug = null)
{
$parentLocation = explode('/', $slug);
array_pop($parentLocation);
return implode('/', $parentLocation);
}
}