Search code examples
phpsymfonydoctrine-ormdql

Symfony createQueryBuilder oparator orX


I have problem for this part in my queryBuilder. I need to choose the parameters of developers

        $qb
        ->andWhere($qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_FREELANCER'.'%')))
        ->orWhere($qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_DEVELOPER'.'%')));

I want replace by

->andWhere($qb->expr()->orX('')))

but have many error, how to right ?

    public function notificationProject($paramFetcher)
{
    $em = $this->getEntityManager();

    $qb = $em->createQueryBuilder();

    $qb
        ->from('ArtelProfileBundle:Users', 'u')
        ->select('u.id, u.email as u_email, m.email, d.skills, u.roles, m.unsubscribeDate as uns_date')
        ->addSelect("IF(u.roles LIKE '%ROLE_DEVELOPER%', m.email, u.email) as send_email")

        ->leftJoin('u.developer', 'd') //this works assuming the doctrine mappings are correct on the $developer property in the ArtelProfileBundle:Users' entity
        ->leftJoin('d.teams', 't')
        ->leftJoin('t.users', 'm')
        ->where('u.unsubscribeDate <= :today');
    foreach ($paramFetcher[1] as $skill) {
        if ($skill) {
            $qb
            ->andWhere($qb->expr()->like('d.skills', $qb->expr()->literal('%"'.$skill.'"%')));
        }
    }
    $qb
        ->andWhere($qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_FREELANCER'.'%')))
        ->orWhere($qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_DEVELOPER'.'%')));

    foreach ($paramFetcher[0] as $tag) {
        if ($tag) {
            $qb
            ->andWhere($qb->expr()->notlike('d.tags', $qb->expr()->literal('%"'.$tag.'"%')));
        }
    }
    $qb
        ->andWhere($qb->expr()->orX('m.unsubscribeDate <= :today', $qb->expr()->isNull('m.unsubscribeDate')))
        ->groupBy('send_email')
        ->setParameter('today', new \DateTime());
    $entities = $qb->getQuery()->getArrayResult();
}

and I have this _dql

SELECT u.id, u.email as u_email, m.email, d.skills, u.roles, m.unsubscribeDate as uns_date, IF(u.roles LIKE '%ROLE_DEVELOPER%', m.email, u.email) as send_email FROM ArtelProfileBundle:Users u LEFT JOIN u.developer d LEFT JOIN d.teams t LEFT JOIN t.users m WHERE ((u.unsubscribeDate <= :today AND d.skills LIKE '%"ASP.NET"%' AND u.roles LIKE '%ROLE_FREELANCER%') OR u.roles LIKE '%ROLE_DEVELOPER%') AND d.tags NOT LIKE '%"blacklist"%' AND d.tags NOT LIKE '%"india"%' AND d.tags NOT LIKE '%"unsubscribed"%' AND d.tags NOT LIKE '%"bounced"%' AND (m.unsubscribeDate <= :today OR m.unsubscribeDate IS NULL) GROUP BY send_email

but I need this for ROLE_DEVELOPER too

(u.unsubscribeDate <= :today AND d.skills LIKE '%"ASP.NET"%' AND u.roles LIKE '%ROLE_FREELANCER%') 

hot to using orX instead of this for this if field roles array

->andWhere($qb->expr()->orX('')))

Solution

  • For the first part it should work OK like this:

    From:

     $qb
            ->andWhere($qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_FREELANCER'.'%')))
            ->orWhere($qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_DEVELOPER'.'%')));
    

    To:

    ->andWhere(
        $qb->expr()->orX(
            $qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_FREELANCER'.'%'))
            , $qb->expr()->like('u.roles', $qb->expr()->literal('%'.'ROLE_DEVELOPER'.'%'))
        )
    )
    

    For your straight DQL, why not just:

    (u.unsubscribeDate <= :today AND d.skills LIKE '%"ASP.NET"%' AND u.roles LIKE '%ROLE_FREELANCER%')
    

    To:

    (u.unsubscribeDate <= :today AND d.skills LIKE '%"ASP.NET"%' AND (u.roles LIKE '%ROLE_FREELANCER%' OR u.roles LIKE '%ROLE_DEVELOPER%'))