I'm building a website with Symfony for a project which will act like "booking.com" websites but much simplier and with some variations.
Some errors on the database fields but not really important for my issue.
As you can see, these tables concern two entities : apartment and visit. A customer can ask for a visit of an apartment. It is a many to one relationship.
I have a search form to search for apartments with criterias. I want to only show apartments that don't have any visits between the arrival and departure dates that the user provided. So I ended up making a function in apartmentRepository to manage that and other cases.
Problem is: how can I get these apartments ?
Here is a draft of this function which is of course not finished neither perfect (if you have some comments to improve it, it would be great !).
public function findByCustom($parameters): ?array
{
$query = $this->createQueryBuilder('a');
foreach ($parameters as $key=> $parameter){
if($key != 'keywords' and $key!= 'priceMin' & $key!='priceMax' and $key!="typeAp" and $key!="searchVisitDate") $query->orWhere('a.'.$key." = '".$parameter."'");
if($key == "typeAp")
{
$typeApQuery = "";
foreach ($parameters[$key] as $index => $type)
{
if($index !== count($parameters[$key])-1)
{
$typeApQuery.=" a.typeAp = '".$type."' or";
}
else
{
$typeApQuery.= " a.typeAp = '".$type."'";
}
}
$query->andWhere($typeApQuery);
}
}
$query->andWhere('a.rentPrice >='.$parameters['priceMin']." and a.rentPrice <= ".$parameters['priceMax']);
$withoutInner = $query;
$query
->join('App\Entity\Visit', 'v', Join::ON, 'a = v.apartment')
->where("v.date between '2020-03-15' and '2020-03-19'");
$query->getQuery()->getResult();
$sorted = $withoutInner->andWhere($this->createQueryBuilder('a')->expr()->notIn('a.id', $query));
return array($sorted);
Of course apartment has a collection of visits and visit as a field named "apartment" which is related to the apartment object.
I really didn't find a proprer way to do it and I want to avoid doing SQL, to improve my understanding of Doctrine.
Thank you for your help because I'm stuck right now :/
EDIT 1: forgot to mention that I want to get apartments that don't have visits between required dates or that don't have any visits at all
EDIT 2 :
public function findByCustom($parameters): ?array
{
$query = $this->createQueryBuilder('a');
$withoutInner = $this->createQueryBuilder("a");
foreach ($parameters as $key=> $parameter){
if($key != 'keywords' and $key!= 'priceMin' & $key!='priceMax' and $key!="typeAp" and $key!="searchVisitDate")
{
$withoutInner->orWhere('a.'.$key." = '".$parameter."'");
$query->orWhere('a.'.$key." = '".$parameter."'");
}
if($key == "typeAp")
{
$typeApQuery = "";
foreach ($parameters[$key] as $index => $type)
{
if($index !== count($parameters[$key])-1)
{
$typeApQuery.=" a.typeAp = '".$type."' or";
}
else
{
$typeApQuery.= " a.typeAp = '".$type."'";
}
}
$withoutInner->andWhere($typeApQuery);
$query->andWhere($typeApQuery);
}
}
$query->andWhere('a.rentPrice >='.$parameters['priceMin']." and a.rentPrice <= ".$parameters['priceMax']);
$withoutInner->andWhere('a.rentPrice >='.$parameters['priceMin']." and a.rentPrice <= ".$parameters['priceMax']);
$query
->join('App\Entity\Visit', 'v', Join::WITH, 'a.id = v.apartment')
->where("v.date between '2020-03-15' and '2020-03-19'");
$query->getQuery()->getResult();
$sorted = $withoutInner->andWhere($this->createQueryBuilder('a')->expr()->notIn('a.id', $query));
With this function I get doctrine error :
Error: Method Doctrine\Common\Collections\ArrayCollection::__toString() must not throw an exception, caught ErrorException: Catchable Fatal Error: Object of class Doctrine\ORM\EntityManager could not be converted to string