<?php
namespace App\Controller\Frontend\Properties;
use App\Entity\Properties\Area;
use App\Entity\Properties\Feature;
use App\Entity\Properties\Image;
use App\Entity\Properties\Property;
use App\Entity\Properties\Type;
use App\Form\Frontend\Properties\PropertyEnquiryForm;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use App\Helper\ConfigHelper;
use App\Helper\ContentHelper;
use App\Helper\MailerHelper;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
final class PropertyController extends AbstractController
{
public function __construct(EntityManagerInterface $entityManager, PaginatorInterface $paginator, ConfigHelper $configHelper, ContentHelper $contentHelper, MailerHelper $mailerHelper)
{
$this->em = $entityManager;
$this->paginator = $paginator;
$this->configHelper = $configHelper;
$this->contentHelper = $contentHelper;
$this->mailerHelper = $mailerHelper;
$this->paginator = $paginator;
}
/**
* @Route("/lettings", name="frontend_properties_lettings")
*/
public function lettings(Request $request): Response
{
// Filter arrays
$propertyFilter = [];
$propertyLookup = [
"listingType" => "letting",
"showOnWebsite" => true
];
// Filtering by bedrooms (exact amount)
if(is_numeric($request->query->get('bedrooms')))
{
$propertyFilter['min_bedrooms'] = $request->query->get('bedrooms');
$propertyLookup[] = ["bedrooms", "gte", $request->query->get('bedrooms')];
$propertyFilter['max_bedrooms'] = $request->query->get('bedrooms');
$propertyLookup[] = ["bedrooms", "lte", $request->query->get('bedrooms')];
}
// Filtering by min bedrooms
if(is_numeric($request->query->get('min_bedrooms')))
{
$propertyFilter['min_bedrooms'] = $request->query->get('min_bedrooms');
$propertyLookup[] = ["bedrooms", "gte", $request->query->get('min_bedrooms')];
}
// Filtering by max bedrooms
if(is_numeric($request->query->get('max_bedrooms')))
{
$propertyFilter['max_bedrooms'] = $request->query->get('max_bedrooms');
$propertyLookup[] = ["bedrooms", "lte", $request->query->get('max_bedrooms')];
}
// Filtering by bathrooms
if(is_numeric($request->query->get('bathrooms')))
{
$propertyFilter['bathrooms'] = $request->query->get('bathrooms');
$propertyLookup[] = ["bathrooms", "eq", $request->query->get('bathrooms')];
}
// Filtering by min price
if(is_numeric($request->query->get('min_price')))
{
$propertyFilter['min_price'] = $request->query->get('min_price');
$propertyLookup[] = ["monthlyRentalPrice", "gte", $request->query->get('min_price') * 10];
}
// Filtering by max price
if(is_numeric($request->query->get('max_price')))
{
$propertyFilter['max_price'] = $request->query->get('max_price');
$propertyLookup[] = ["monthlyRentalPrice", "lte", $request->query->get('max_price') * 10];
}
// Filtering by type
if(is_numeric($request->query->get('type')))
{
$theType = $this->em->getRepository(Type::class)->findOneFiltered(["id" => $request->query->get('type')]);
if($theType)
{
$propertyFilter['type'] = $theType;
$propertyLookup[] = ["type", "eq", $theType];
}
}
// Filtering by area
if(is_numeric($request->query->get('area')))
{
$theArea = $this->em->getRepository(Area::class)->findOneFiltered(["id" => $request->query->get('area')]);
if($theArea)
{
$propertyFilter['area'] = $theArea;
$propertyLookup[] = ["area", "eq", $theArea];
}
}
// Get properties
$properties = $this->paginator->paginate($this->em->getRepository(Property::class)->buildQuery($propertyLookup), $request->query->getInt('page', 1), 16);
// Get all property types
$allTypes = $this->em->getRepository(Type::class)->findFiltered([]);
// Get all areas
$allAreas = $this->em->getRepository(Area::class)->findFiltered([]);
// Render view
return $this->render('Frontend/Properties/lettings.html.twig', [
'properties' => $properties,
'propertyFilter' => $propertyFilter,
'allTypes' => $allTypes,
'allAreas' => $allAreas
]);
}
/**
* @Route("/sales", name="frontend_properties_sales")
*/
public function sales(Request $request): Response
{
// Filter arrays
$propertyFilter = [];
$propertyLookup = [
"listingType" => "sale",
"showOnWebsite" => true
];
// Filtering by bedrooms (exact amount)
if(is_numeric($request->query->get('bedrooms')))
{
$propertyFilter['min_bedrooms'] = $request->query->get('bedrooms');
$propertyLookup[] = ["bedrooms", "gte", $request->query->get('bedrooms')];
$propertyFilter['max_bedrooms'] = $request->query->get('bedrooms');
$propertyLookup[] = ["bedrooms", "lte", $request->query->get('bedrooms')];
}
// Filtering by min bedrooms
if(is_numeric($request->query->get('min_bedrooms')))
{
$propertyFilter['min_bedrooms'] = $request->query->get('min_bedrooms');
$propertyLookup[] = ["bedrooms", "gte", $request->query->get('min_bedrooms')];
}
// Filtering by max bedrooms
if(is_numeric($request->query->get('max_bedrooms')))
{
$propertyFilter['max_bedrooms'] = $request->query->get('max_bedrooms');
$propertyLookup[] = ["bedrooms", "lte", $request->query->get('max_bedrooms')];
}
// Filtering by bathrooms
if(is_numeric($request->query->get('bathrooms')))
{
$propertyFilter['bathrooms'] = $request->query->get('bathrooms');
$propertyLookup[] = ["bathrooms", "eq", $request->query->get('bathrooms')];
}
// Filtering by min price
if(is_numeric($request->query->get('min_price')))
{
$propertyFilter['min_price'] = $request->query->get('min_price');
$propertyLookup[] = ["salesPrice", "gte", $request->query->get('min_price') * 10];
}
// Filtering by max price
if(is_numeric($request->query->get('max_price')))
{
$propertyFilter['max_price'] = $request->query->get('max_price');
$propertyLookup[] = ["salesPrice", "lte", $request->query->get('max_price') * 10];
}
// Filtering by type
if(is_numeric($request->query->get('type')))
{
$theType = $this->em->getRepository(Type::class)->findOneFiltered(["id" => $request->query->get('type')]);
if($theType)
{
$propertyFilter['type'] = $theType;
$propertyLookup[] = ["type", "eq", $theType];
}
}
// Filtering by area
if(is_numeric($request->query->get('area')))
{
$theArea = $this->em->getRepository(Area::class)->findOneFiltered(["id" => $request->query->get('area')]);
if($theArea)
{
$propertyFilter['area'] = $theArea;
$propertyLookup[] = ["area", "eq", $theArea];
}
}
// Get properties
$properties = $this->paginator->paginate($this->em->getRepository(Property::class)->buildQuery($propertyLookup), $request->query->getInt('page', 1), 16);
// Get all property types
$allTypes = $this->em->getRepository(Type::class)->findFiltered([]);
// Get all areas
$allAreas = $this->em->getRepository(Area::class)->findFiltered([]);
// Render view
return $this->render('Frontend/Properties/sales.html.twig', [
'properties' => $properties,
'propertyFilter' => $propertyFilter,
'allTypes' => $allTypes,
'allAreas' => $allAreas
]);
}
/**
* @Route("/property/{property_reference}", name="frontend_properties_viewproperty")
*/
public function viewProperty(Request $request, int $property_reference = 0): Response
{
// Get the property
$property = $this->em->getRepository(Property::class)->findOneFiltered([
"reference" => $property_reference,
"showOnWebsite" => true
]);
// Not found?
if(!$property)
throw new NotFoundHttpException("Property not found");
// Get images
$images = $this->em->getRepository(Image::class)->findFiltered([
'property' => $property
], [
"displayOrder" => "ASC"
]);
// Get features (via property features)
$features = $this->em->getRepository(Feature::class)->setup(function(string $alias, QueryBuilder $qb){
// Join propertyFeature
$qb->join($alias . '.propertyFeatures', 'pf');
return $qb;
})->findFiltered([
'pf.property' => $property
], []);
// Get similar propertoes
$similarProperties = $this->em->getRepository(Property::class)->findFiltered([
"showOnWebsite" => true,
"listingType" => $property->getListingType(),
["id", "neq", $property->getId()],
["or", [
["area", "eq", $property->getArea()],
["bedrooms", "eq", $property->getBedrooms()]
]]
], [], 3);
// Render view
return $this->render('Frontend/Properties/viewProperty.html.twig', [
'property' => $property,
'features' => $features,
'images' => $images,
'similarProperties' => $similarProperties
]);
}
/**
* @Route("/property/{property_reference}/enquire", name="frontend_properties_propertyenquiry")
*/
public function propertyEnquiry(Request $request, int $property_reference = 0): Response
{
// Get the property
$property = $this->em->getRepository(Property::class)->findOneFiltered([
"reference" => $property_reference,
"showOnWebsite" => true
]);
// Not found?
if(!$property)
throw new NotFoundHttpException("Property not found");
// Get type form
$propertyEnquiryForm = $this->createForm(PropertyEnquiryForm::class, [])
->add('save', SubmitType::class, array(
'label' => "Submit",
'attr' => array(
'class' => 'btn btn-primary'
)
));
// Handle the form
$propertyEnquiryForm->handleRequest($request);
// Form submitted
if($propertyEnquiryForm->isSubmitted())
{
// All valid?
if($propertyEnquiryForm->isValid())
{
// Send the email
$this->mailerHelper->send($this->configHelper->getValue('email_from'), "Property Enquiry: " . implode(", ", $property->getFullAddress()), "propertyEnquiry.html.twig", [
"submitted" => [
"name" => $propertyEnquiryForm->get('name')->getData(),
"email" => $propertyEnquiryForm->get('email')->getData(),
"phone" => $propertyEnquiryForm->get('phone')->getData(),
"message" => $propertyEnquiryForm->get('message')->getData()
],
"property" => $property
]);
// Redirect
return $this->redirect($this->generateUrl('frontend_properties_propertyenquiry_success', [
"property_reference" => $property->getReference()
]));
}
}
// Render view
return $this->render('Frontend/Properties/propertyEnquiry.html.twig', [
'property' => $property,
'propertyEnquiryForm' => $propertyEnquiryForm->createView()
]);
}
/**
* @Route("/property/{property_reference}/enquire/success", name="frontend_properties_propertyenquiry_success")
*/
public function propertyEnquirySuccess(Request $request, int $property_reference = 0): Response
{
// Render view
return $this->render('Frontend/Properties/propertyEnquirySuccess.html.twig');
}
}