Home » Php » PHP Doctrine Query AND with either OR

PHP Doctrine Query AND with either OR

Posted by: admin February 25, 2020 Leave a comment

Questions:

A database has Products with many options, two of them are, say, Option 1 and Option 2. I need to make a query (I know how to build the whole thing, I’m just stuck with the following logic only) which will show only such products where:

  1. If neither Option 1 nor Option 2 selected, show all products
  2. If Options 1 selected, only show those products with this option
  3. If Options 2 selected, only show those products with this option
  4. If Options 1 and Option 2 selected, only show those products with these two options

I tried this:

function GetProducts(keywords) {
...
    ->andWhere($qb->expr()->orX(
        $qb->expr()->eq('option1', keywords['option1']),
        $qb->expr()->eq('option2', keywords['option2'])
    ))
...
}

The keywords[‘option1’] and keywords[‘option2’] are values 0 or 1 from check boxes with such options.

But the result is the following:

  1. If neither Option 1 nor Option 2 selected, all products are shown – OK
  2. If Options 1 selected, products with Option 1 AND all those without any of these 2 options are shown – NOT what I need
  3. If Options 2 selected, products with Option 1 AND all those without any of these 2 options are shown – NOT what I need
  4. If Option 1 and Option 2 selected, all products are shown – NOT what I need
How to&Answers:
public function getRandomSearch($keywords)
{
    $em = DatabaseORM::entityManager();
    $qb = $em->createQueryBuilder();
    $qb->select('c')
        ->from('Products\Product', 'c');

    if ($keywords['option1'] && !$keywords['option2']) {
        $qb->andWhere($qb->expr()->eq('c.option1', $keywords['option1']));
    }
    elseif (!$keywords['option1'] && $keywords['option2']) {
        $qb->andWhere($qb->expr()->eq('c.option2', $keywords['option2']));
    }
    elseif ($keywords['option1'] && $keywords['option2']) {
        $qb->andWhere($qb->expr()->orX(
            $qb->expr()->eq('c.option1', $keywords['option1']),
            $qb->expr()->eq('c.option2', $keywords['option2'])
        ));
    }

    return $qb->getQuery()
        ->getResult();
}