<?php
namespace Aqarmap\Bundle\ListingBundle\Controller;
use Aqarmap\Bundle\ListingBundle\Entity\CompoundLocation;
use Aqarmap\Bundle\ListingBundle\Service\CompoundService;
use Aqarmap\Bundle\ListingBundle\Service\ListingManager;
use Aqarmap\Bundle\MainBundle\Constant\CustomParagraphPlaceTypes;
use Aqarmap\Bundle\MainBundle\Entity\CustomParagraph;
use Aqarmap\Bundle\MainBundle\Repository\CustomParagraphRepository;
use Aqarmap\Bundle\SearchBundle\Services\CompoundAdviserSearchService;
use Doctrine\ORM\NonUniqueResultException;
use Gedmo\Translatable\TranslatableListener;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("compounds")
*/
class CompoundSearchController extends AbstractController
{
/**
* @var CompoundAdviserSearchService
*/
private $compoundAdvisorSearchService;
/**
* @var CompoundService
*/
private $compoundService;
/**
* @var TranslatableListener
*/
private $translatableListener;
public function __construct(
CompoundAdviserSearchService $compoundAdvisorSearchService,
CompoundService $compoundService,
TranslatableListener $translatableListener,
ListingManager $listingManager
) {
$this->compoundAdvisorSearchService = $compoundAdvisorSearchService;
$this->compoundService = $compoundService;
$this->translatableListener = $translatableListener;
$this->listingManager = $listingManager;
}
/**
* @Route(path="/advisor", name="compound_adviser", methods={"GET"})
* @Route(path="/advisor/matcherLocation", name="compound_adviser_location", methods={"GET"})
* @Route(path="/advisor/matcherPriceLevel", name="compound_adviser_price", methods={"GET"})
* @Route(path="/advisor/matcherAreaMethod", name="compound_adviser_area", methods={"GET"})
* @Route(path="/advisor/matcherPropertyType", name="compound_adviser_property_type", methods={"GET"})
* @Route(path="/advisor/matcherFinishType", name="compound_adviser_finish_type", methods={"GET"})
* @Route(path="/advisor/matcherDelivery", name="compound_adviser_delivery", methods={"GET"})
*
* @return array|RedirectResponse
*/
public function adviser(): Response
{
return $this->render('@AqarmapListing/CompoundSearch/adviser.html.twig', []);
}
/**
* Compound advisor Search (POST).
*
* @Route(path="/advisor", name="compound_adviser_search_post", methods={"POST"})
*
* @return RedirectResponse
*/
public function adviserPost(Request $request)
{
$criteria = $this->compoundAdvisorSearchService->prepareAdviserScoringCriteria(json_decode($request->request->get('data'), true));
$response = new RedirectResponse($this->generateUrl('compound_adviser_search_results', []));
$cookie = new Cookie('advisor-criteria', serialize($criteria));
$response->headers->setCookie($cookie);
$response->prepare($request);
$response->send();
return $response;
}
/**
* @Route("/advisor/search", name="compound_adviser_search_results", methods={"GET"})
*
* @throws \Exception
*/
public function compoundAdviserResult(Request $request): Response
{
$cookies = $request->cookies;
$criteria = [];
if ($cookies->has('advisor-criteria')) {
$criteria = unserialize($cookies->get('advisor-criteria'));
}
$results = $this->compoundAdvisorSearchService->getCompounds($criteria, $request->query->get('page', 1));
$entityManager = $this->getDoctrine()->getManager();
$criteria['selectedParagraphId'] = (int) $request->get('custom_paragraph');
$isNoIndexMetaTag = (bool) $request->get('noindex') || $this->compoundAdvisorSearchService->isNoIndexMetaTag($request->query->all());
return $this->render(
'@AqarmapListing/CompoundSearch/compoundAdviserResult.html.twig',
[
'canonicalUrl' => $canonicalUrl ?? null,
'listings' => $results,
'adviserCriteria' => $criteria,
'listingsCount' => \count($results),
'customParagraph' => $this->getCustomParagraph($criteria),
'subLinksSections' => $entityManager->getRepository(\Aqarmap\Bundle\ListingBundle\Entity\Section::class)->getSearchableSection(),
'isNoIndexMetaTag' => $isNoIndexMetaTag,
'form' => $this->compoundService->createQuickLeadForm('add_quick_lead'),
'liveListingsPerUser' => $this->listingManager->getLiveListingsCountPerUser($results->getItems()),
'isMobile' => false,
]
);
}
/**
* @Route("/", methods={"GET"}, name="compound_search")
* @Route (
* "/{location}", methods={"GET"},
* name="compound_search_with_location",
* requirements={"location": ".+[^/]"},
* )
*
* @ParamConverter(
* "location",
* options={"mapping": {"location": "slug"}}
* )
*
* @return array|RedirectResponse
*
* @throws \Exception
*/
public function compoundSearchResult(Request $request, ?CompoundLocation $location = null)
{
$response = $this->compoundService->search($request, $location);
if ($response instanceof Response) {
return $response;
}
return $this->render(
'@AqarmapListing/CompoundSearch/compoundSearchResult.html.twig',
$response
);
}
/**
* Compound Search (POST).
*
* @Route("/compound", methods={"POST"}, name="compound_Search")
*
* @throws \Exception
*/
public function searchPost(Request $request)
{
$redirect = $this->redirect($this->generateUrl('compound_search'), Response::HTTP_MOVED_PERMANENTLY);
$compoundSearchForm = $this->compoundService->compoundSearchForm();
$compoundSearchForm->handleRequest($request);
if ($compoundSearchForm->isValid()) {
$criteria = $this->compoundService->prepareCriteria($compoundSearchForm, $request);
$redirect = $this->redirect(urldecode($this->generateUrl('compound_search', $criteria)), Response::HTTP_MOVED_PERMANENTLY);
}
return $redirect;
}
/**
* @return CustomParagraph|null
*/
public function getCustomParagraph(array $criteria)
{
$selectedCustomParagraphId = $criteria['selectedParagraphId'] ?? null;
$criteria = [
'place' => CustomParagraphPlaceTypes::SEARCH_RESULTS,
'section' => $criteria['section'] ?? null,
'location' => $criteria['location'] ?? null,
'propertyType' => $criteria['propertyType'] ?? null,
];
/** @var CustomParagraphRepository $customParagraphRepository */
$customParagraphRepository = $this->getDoctrine()->getRepository(CustomParagraph::class);
$this->translatableListener->setTranslationFallback(false);
if ($selectedCustomParagraphId) {
$criteria['id'] = $selectedCustomParagraphId;
try {
return $customParagraphRepository
->get($criteria)
->getQuery()
->setMaxResults(1)
->getOneOrNullResult();
} catch (NonUniqueResultException $e) {
return null;
}
}
$customParagraphs = $customParagraphRepository
->get(array_merge($criteria, ['published' => true]))
->getQuery()
->getResult();
if (empty($customParagraphs)) {
return null;
}
return $customParagraphs[array_rand($customParagraphs)];
}
}