<?php
namespace App\Controller\Website;
use App\Manager\LocationManager;
use App\Manager\TypeManager;
use App\Repository\OfferRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
class OfferController extends AbstractController
{
public function __construct(TypeManager $typeManager, LocationManager $locationManager)
{
$this->typeManager = $typeManager;
$this->locationManager = $locationManager;
}
public function rent(Request $request)
{
return $this->render('pages/search_properties.html.twig', [
'seo' => $this->getSeo($request, true),
'urlImgSeo' => '/frontend/main/images/294-281-home.jpg',
'request' => $request,
'categories'=> $this->typeManager->mapData(),
'rent' => true,
'radiusOptions' => [0, 5, 10, 15, 20],
]);
}
public function buy(Request $request)
{
return $this->render('pages/search_properties.html.twig', [
'seo' => $this->getSeo($request, false),
'urlImgSeo' => '/frontend/main/images/294-281-home.jpg',
'request' => $request,
'categories'=> $this->typeManager->mapData(),
'rent' => false,
'radiusOptions' => [0, 5, 10, 15, 20],
]);
}
public function rentDetail($encodedTitle, OfferRepository $offerRepository, Request $request) {
return $this->detail($encodedTitle, $offerRepository, $request, true);
}
public function buyDetail($encodedTitle, OfferRepository $offerRepository, Request $request) {
return $this->detail($encodedTitle, $offerRepository, $request, false);
}
public function searchCardsPaginated(OfferRepository $offerRepository, Request $request, PaginatorInterface $paginator, $rent = true)
{
$resultsArray = $this->getResults($offerRepository, $request, $rent);
$priceSqm = $request->query->get('priceSqm');
$priceField = $priceSqm ? '[priceM2an]' : '[price]';
$pagination = $paginator->paginate(
$resultsArray,
$request->query->getInt('page', 1),
8,
[
'defaultSortFieldName' => 'price',
'defaultSortDirection' => $request->query->get('direction') ?: 'desc',
]
);
return $this->render('search_properties/_cards.html.twig', [
'pagination' => $pagination,
'sorting' => [
['direction' => 'asc', 'field' => $priceField, 'title' => 'Prix croissant'],
['direction' => 'desc', 'field' => $priceField, 'title' => 'Prix décroissant'],
['direction' => 'asc', 'field' => '[surface]', 'title' => 'Surface croissante'],
['direction' => 'desc', 'field' => '[surface]', 'title' => 'surface décroissante'],
['direction' => 'desc', 'field' => '[dateModificationInt]', 'title' => 'Plus récent'],
],
'parameters' => $request->query->all(),
'detailPath' => $rent ? 'rent_detail' : 'buy_detail',
]);
}
/**
* action that returns JSON with all results of search for map on the right side of offers page
*/
public function searchJson(OfferRepository $offerRepository, Request $request, $rent = false)
{
return new JsonResponse([
'results' => $this->getResults($offerRepository, $request, $rent),
'seo' => $this->getSeo($request, $rent)
]);
}
public function getSeo(Request $request, $rent=false)
{
/*** @var Array*/
$type = $request->query->get('type');
/*** @var Array */
$locations = $request->query->get('location');
$action = $rent ? 'louer' : 'acheter';
$template = $type ? implode( ', ', $type) : 'Biens';
$template .= ' à ' . $action;
if ($locations) {
$template .= ' à ' . implode(', ', array_map(function ($location) {
$parts = explode(',', $location);
return $parts[0];
}, $locations));
}
return [
// <title></title> of the page
'title' => $template,
// <meta name='description'> of the page
'metaDescription' => $template . '(meta description)',
// title above the list of cards
'topTitle' => $template,
// title below the list of cards
'bottomTitle' => $template
];
}
private function getResults(OfferRepository $offerRepository, Request $request, $rent = true)
{
$resultsArray = $offerRepository->search($request, null, $rent);
foreach ($resultsArray as &$result) {//dd($result['status']);
$result['tags'] = [];
$result['tags'][] = $result['type'];
if ($result['surface']) {
$result['tags'][] = "~".$result['surface']."m<sup class='lh-0'>2</sup>";
}
}
return $resultsArray;
}
public function detail($encodedTitle, OfferRepository $offerRepository, Request $request, $rent = true)
{
$detail = $offerRepository->findByEncodedTitle($encodedTitle, $rent);
if ($detail === null) {
throw $this->createNotFoundException('The offer does not exist');
}
$similar = $offerRepository->search($request, $detail['id'], $detail['isForRent'], true);
foreach ($similar as &$card) {
$card['tags'] = [];
$card['tags'][] = $card['type'];
$card['tags'][] = "~".$card['surface']."m<sup class='lh-0'>2</sup>";
}
$detail['similar'] = $similar;
$seo = $this->getSeo($request);
// override title and metaDescription with information from this Offer
$seo['title'] = $detail['title'];
$seo['metaDescription'] = $detail['title'];
$dataToReturn = [
'seo' => $seo,
'request' => $request,
'detail' => $detail,
];
$dataToReturn['radiusOptions'] = [0, 5, 10, 15, 20];
if ($request->query->get('json')) {
return new JsonResponse($dataToReturn);
}
return $this->render('pages/search_properties.html.twig', $dataToReturn);
}
/**
* action that returns JSON with all matching locations as user is typing in "location" field
*/
public function locationsAutocomplete(Request $request)
{
if ($request->query->get('top')) {
return new JsonResponse($this->locationManager->mapDataTopSearch());
}
return new JsonResponse($this->locationManager->mapDataSearch());
}
}