Search code examples
phpsqlsymfonydoctrine-orm

How to make a UNION with Doctrine?


I'm trying to do the following query:

    public function findByNotifications($ownerId)
    {
        $em = $this->getEntityManager();
        $query = $em->createQuery('
           SELECT n FROM
            (SELECT n FROM DelivveWebBundle:UserAd n
                INNER JOIN n.ad ad
                    WHERE ad.owner = :ownerId
                LIMIT 20
            UNION
            SELECT n FROM DelivveWebBundle:UserAd n
                INNER JOIN n.user u
                INNER JOIN n.ad ad
                   WHERE u.id = :ownerId
                       AND ad.status = :progress
                LIMIT 20)
           notofication
           LIMIT 20;
        ')->setParameter('ownerId', $ownerId)
            ->setParameter('progress', Constant::AD_IN_PROGRESS);

        $result = $query->getResult();

        return $result;
    }

to generate all my notifications:

    public function showNotificationsAction()
    {
        $this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');

        $owner = $this->getUser();

        $repository = $this->getDoctrine()->getRepository('DelivveWebBundle:UserAd');

        $notifications = $repository->findByAdOwner($owner->getId());

        return $this->render('DelivveWebBundle:Ad:notification.html.twig', array(
            'owner' => $owner,
            'notifications' => $notifications
        ));
    }

The idea is to do a search on AdUser table that returns all notifications that have ads that logged User owns, along with any notifications that logged User requested.

Notification the User requested is a line of AdUser table that has the column the user logged in User.


Solution

  • I decided to breaking in two searches and giving a marge in results

    public function findByAdOwner($ownerId)
    {
        $qb = $this->getEntityManager()->createQueryBuilder('n');
    
        return $qb->select('n')
            ->from('DelivveWebBundle:UserAd', 'n')
            ->join('n.ad', 'ad')
            ->where('ad.owner = :ownerId')
            ->setParameter('ownerId', $ownerId)
            ->setMaxResults(20)
            ->getQuery()
            ->getResult();
    }
    
    public function findByUserNotify($userId)
    {
        $qb = $this->getEntityManager()->createQueryBuilder('n');
    
        return $qb->select('n')
            ->from('DelivveWebBundle:UserAd', 'n')
            ->join('n.ad', 'ad')
            ->where('n.user = :userId')
            ->andWhere('ad.status = :status')
            ->setParameter('userId', $userId)
            ->setParameter('status', Constant::AD_IN_PROGRESS)
            ->setMaxResults(20)
            ->getQuery()
            ->getResult();
    }
    
    public function findNotifcations($userId){
        $notification = $this->findByAdOwner($userId);
        $append = $this->findByUserNotify($userId);
    
        return array_merge($notification, $append);
    }
    

    To become more readable'll just put after something that distinguishes the two types of notice to do the treatment on the page.

    I discovered that there is a way to add commands to the doctrine that does not exist, but appears to be quite complex if anyone knows do this, put the answer please.