<?php
namespace App\Repository;
use App\Entity\Property;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
/**
* @extends ServiceEntityRepository<Property>
*
* @method Property|null find($id, $lockMode = null, $lockVersion = null)
* @method Property|null findOneBy(array $criteria, array $orderBy = null)
* @method Property[] findAll()
* @method Property[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PropertyRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Property::class);
}
public function findById(int $id): ?Property
{
$property = $this->find($id);
if (!$property) {
return null;
}
return $property;
}
public function create(): Property
{
return new Property();
}
public function add(Property $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(int $id): void
{
/** @var object $bien */
$bien = $this->getEntityManager()->getReference(
$this->getClassName(),
$id
);
$this->getEntityManager()->remove($bien);
$this->getEntityManager()->flush();
}
public function findOneByApiId($value): ?Property
{
return $this->createQueryBuilder('p')
->andWhere('p.api_id = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
public function findByLocation($value,$id): array
{
return $this->createQueryBuilder('p')
->andWhere('p.adresse = :val')
->andWhere('p.id != :val1')
->setParameter('val', $value)
->setParameter('val1', $id)
->orderBy('p.id', 'ASC')
->setMaxResults(2)
->getQuery()
->getResult()
;
}
public function filterByStatus($transactionType)
{
return $this->createQueryBuilder('p')
->andWhere('p.transactionType = :val')
->setParameter('val', $transactionType)
->orderBy('p.id', 'ASC')
->getQuery()
->getResult()
;
}
public function findFeatured(int $nbr, int $type_transction = 1)
{
$builder = $this->createQueryBuilder('p')
->andWhere('p.featured = 1')
->andWhere('p.transactionType = :transction')
->setParameter('transction', $type_transction)
;
if($nbr>0){
$builder->setMaxResults($nbr);
}
$builder->orderBy('p.lastupdate', 'DESC');
$query = $builder->getQuery();
return $query->getResult();
}
public function search(Request $request, int $isRent):array
{
$typeArray = $request->query->get('type');
/**@var array */
$location = $request->query->get('location');
$surfaceMin = $request->query->get('surfaceMin');
$surfaceMax = $request->query->get('surfaceMax');
$priceMin = $request->query->get('priceMin');
$priceMax = $request->query->get('priceMax');
$boundsJson = $request->query->get('bounds');
$isNewProject = $request->query->get('isNewProject');
$bounds = $boundsJson ? json_decode($boundsJson) : null;
$radius = $request->query->get('radius');
$qb = $this->createQueryBuilder('p')
->join('p.type', 't')
// ->join('p.canton', 'c')
// ->join('p.district', 'd')
// ->join('p.city', 'city')
// ->join('p.zone', 'z')
->andWhere('p.transactionType = :isrent')
->setParameter('isrent', $isRent)
;
if ($typeArray && !(!empty($typeArray) && empty($typeArray[0]))) {
$qb->andWhere('t.title IN (:titles)')
->setParameter('titles', $typeArray)
;
}
if ($radius) {
foreach ($location as $value) {
$arr = explode(',', $value);
if (count($arr) >= 4) {
$lat = $arr[2];
$lng = $arr[3];
$latPerDg = 111;
$lngPerDg = 77;
$qb ->andWhere('p.latitude BETWEEN :south AND :north')
->andWhere('p.longitude BETWEEN :west AND :east')
->setParameter('north', $lat + $radius / $latPerDg)
->setParameter('south', $lat - $radius / $latPerDg)
->setParameter('east', $lng + $radius / $lngPerDg)
->setParameter('west', $lng - $radius / $lngPerDg);
}
}
} else if ($location && !(!empty($location) && empty($location[0]))) {
$or = "";
$sql = "";
foreach ($location as $value) {
$arr = explode(',', $value);
$value = $arr[0];
$code = isset($arr[1]) ? $arr[1] : '';
if (strpos($value, '-') && is_numeric(substr($value, 0, 4))) {
$value = substr($value, 0, strpos($value, '-') - 1);
}
switch ($code) {
case 'canton':
$sql .= $or."p.cantonFr = '".$value."'";
break;
case 'district':
$sql .= $or."p.districtFr = '".$value."'";
break;
case 'zone':
$sql .= $or."p.zoneFr = '".$value."'";
break;
case 'zip':
$sql .= $or."p.zip = '".$value."'";
break;
default:
$sql .= $or."p.cityFr = '".$value."'";
break;
}
$or = " OR ";
}
$qb->andWhere($sql);
}
if ($surfaceMin) {
$qb->andWhere('CAST(p.surface AS DECIMAL) >= :surfaceMin')
->setParameter('surfaceMin', (float)$surfaceMin)
;
}
if ($surfaceMax) {
$qb->andWhere('CAST(p.surface AS DECIMAL) <= :surfaceMax')
->setParameter('surfaceMax', (float)$surfaceMax)
;
}
if ($priceMin) {
$qb->andWhere('p.price >= :priceMin')
->setParameter('priceMin', $priceMin)
;
}
if ($priceMax) {
$qb->andWhere('p.price <= :priceMax')
->setParameter('priceMax', $priceMax)
;
}
if ($isNewProject) {
$qb->andWhere('p.status = :isNewProject')
->setParameter('isNewProject', 'NEW')
;
}
if ($bounds) {
$qb ->andWhere('p.latitude BETWEEN :south AND :north')
->andWhere('p.longitude BETWEEN :west AND :east')
->setParameter('north', $bounds->north)
->setParameter('south', $bounds->south)
->setParameter('east', $bounds->east)
->setParameter('west', $bounds->west)
;
}
return $qb
->orderBy('p.id', 'DESC')
->getQuery()
->getResult()
;
}
public function searchSimilaire($id, int $isRent):array
{
$qb = $this->_em->createQueryBuilder()
->select('p, SQRT((p2.latitude - p.latitude)*(p2.latitude - p.latitude) + ( p2.longitude - p.longitude)*( p2.longitude - p.longitude)) as dist')
->from("App:Property", "p")
->andWhere('p.transactionType = :isrent')
->setParameter('isrent', $isRent)
->distinct('p.reference')
;
$qb->join("App:Property", 'p2')
->andWhere('p2.id = ' . $id)//p2 pour bien encours
->andWhere('p.id <> ' . $id)
->andWhere('p2.type = p.type')
;
$qb->andHaving("dist <= 35000")
->orderBy('dist', 'ASC');
$qb->andWhere('p.surface <= p2.surface + (p2.surface * 0.5)')
->andWhere('p.surface >= p2.surface - (p2.surface * 0.5)')
;
$qb->andWhere('p.price <= p2.price + (p2.price * 0.5)')
->andWhere('p.price >= p2.price - (p2.price * 0.5)')
;
$qb->orderBy('p.id', 'DESC');
$query = $qb->getQuery();
return $query->getResult();
}
}