Reputation: 23
There are 2 tables: Providers and Adverts. A Provider has Adverts.
First table "Provider":
Second table "Advert":
Relation:
/**
* @ORM\OneToMany(targetEntity="Advert", mappedBy="provider", cascade={"persist"})
*/
private $adverts;
I want:
All Providers who DON'T have any adverts which are currently active (= currently between "Begin" and "End") AND DON'T have any adverts which are planned for the future (= "Begin" and "End" are in the future).
In other words:
I want ALL Providers who DON'T have any current or upcoming adverts.
My issue:
I don't know and find any information how to do it.
I use Doctrine2 with Symfony 2.8 / 3.0.
Upvotes: 1
Views: 83
Reputation: 1025
Please note that some MySQL specific funtions are not supported by default in Doctrine. You can have an extension installed for that. I am going to propose a way without extensions. (But you should opt out for a Bundle on your own judgement)
In your Provider
repository you can do something like this:
public function getProvidersWithoutAdverts()
{
$now = date("Y-m-d H:i:s");
$qb = $this->createQueryBuilder('provider');
$qb->leftJoin('provider.adverts', 'advert', Join::WITH)
->where("advert.end < {$now}") //Advert has ended
->andWhere("advert.begin < {$now}") //Advert is not scheduled
;
return $qb->getQuery()->getResult();
}
Upvotes: 1
Reputation: 23
This code works fine but maybe it is not fully optimized.
Warning: You should create a repository for the Provider entity. The following code is working if you have $em
as Doctrine EntityManager.
$qb = $em->createQueryBuilder();
$qb = $qb->select('IDENTITY(advert.provider)')
->from('AppBundle:Advert', 'advert')
->where("advert.begin <= :now AND advert.end > :now")
->andWhere('advert.active = true')
->setParameter(':now', new \DateTime(), Type::DATETIME)
$nots = $qb->getQuery()->getArrayResult();
$qb = $em->createQueryBuilder();
$qb = $qb->select('p')
->from('AppBundle:Provider', 'provider')
->leftJoin('provider.adverts', 'advert');
if (isset($nots[0])) {
$qb->where($qb->expr()->notIn('provider.id', $nots[0]));
}
$providers = $qb->getQuery()->getArrayResult();
Maybe "not exists" would be better: NOT IN vs NOT EXISTS
Upvotes: 0