Multiple joins not working with createQueryBuilder - php

When I use createQuery it works:
$this->getEntityManager()
->createQuery(
'SELECT e FROM CPBundle:Event e, CPBundle:Player p, CPBundle:EventType et
WHERE e.player = p.id AND e.eventType = et.id';
)
->getResult();
but when I try the same query with createQueryBuilder it doesn't work:
public function findEventsByParams($params)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$query = $qb->select('e', 'p', 'et')
->from('CPBundle:Event', 'e')
->innerJoin('CPBundle:Player', 'p')
->innerJoin('CPBundle:EventType', 'et')
->where('e.player = p.id')
->andWhere('e.eventType = et.id');
if ($params['username']) {
$qb->andWhere('p.username = :username')
->setParameter('username', $params['username']);
}
//TODO: other params
return $query->getQuery()->getResult();
}
I'm getting this error message:
[Syntax Error] line 0, col 73: Error: Expected Literal, got 'JOIN'

See this answer: https://stackoverflow.com/questions/17989473/symfony2-doctrine-multiple-joins-returns-error
public function findEventsByParams($params)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$query = $qb->select('e')
->from('CPBundle:Event', 'e')
->innerJoin('e.player', 'p')
->innerJoin('e.eventType', 'et');
if ($params['username']) {
$qb->andWhere('p.username = :username')
->setParameter('username', $params['username']);
}
//TODO: other params
return $query->getQuery()->getResult();
}

Related

What does ':'(colon) mean in dql?

I'm working on a server that uses doctrine orm, and i came across the following function:
public function showForJustWhoCanSee() {
$subquery = $this->em->createQueryBuilder();
$subquery->select('userSignature')
->from('HospitalApi\Entity\EletronicDocumentSignature', 'signature')
->innerJoin('HospitalApi\Entity\User', 'userSignature', 'WITH', 'userSignature = signature.user')
//->where('signature.signed = 0')
->groupBy('signature._document')
->orderBy('signature.order', 'ASC');
$select = $this->em->createQueryBuilder();
$select->select('ed')
->from($this->getEntityPath(), 'ed')
->innerJoin("HospitalApi\Entity\User", "u", "with", "ed.user = u")
->leftJoin("HospitalApi\Entity\EletronicDocumentSignature", 'eds', 'WITH', 'eds._document = ed')
->leftJoin("eds.user", 'us', 'WITH', 'u = :user OR us = :user')
->where( $select->expr()->eq( 'us', $select->expr()->any( $subquery->getDQL() )) )
// ->andwhere('eds.signed = 0')
// ->andwhere( $select->expr()->in('ed.status', $this->_alowedStatusToSign) )
->orwhere('u = :user')
->setParameter('user', $this->getSession() )
->andWhere('ed.c_removed = 0');
return $select;
}
I would like to know what the colon on ':user' does at:
->leftJoin("eds.user", 'us', 'WITH', 'u = :user OR us = :user')
Thanks in advance.
The colon is used in parameter binding... you define a name: :user
And then you assign a value to that parameter in:
->setParameter('user', $this->getSession() )

How to correctly alias a table in codeigniter?

I would like to do a join between 2 tables from my db.
this is my code:
public function getEpisodes($limit = 12, $order = 'id_e', $das = 'desc')
{
$this->db->select('e.id_e, e.id_s, e.num_e, s.id_s, s.nom_s, s.thumb_s')
->from('s_episodes as e, s_series as s')
->join('s', 'e.id_s = s.id_s', 'left')
->order_by('e.'.$order, $das)
->limit($limit);
$query = $this->db->get();
return $query->result_array();
}
This is the error code I get, when running my code:
What is wrong with my table alias?
Maybe try moving the s_series as s...
public function getEpisodes($limit = 12, $order = 'id_e', $das = 'desc')
{
$this->db->select('e.id_e, e.id_s, e.num_e, s.id_s, s.nom_s, s.thumb_s')
// Move s_series as s
->from('s_episodes as e')
->join('s_series as s', 'e.id_s = s.id_s', 'left')
->order_by('e.'.$order, $das)
->limit($limit);
$query = $this->db->get();
return $query->result_array();
}

Doctrine nested condition (andWhere) with join

I want to do something like this with my QueryBuilder:
$query = $qb
->select('u')
->from('AppBundle:School', 'u')
->where('u.superAdmin = :user')
->andWhere(
$qb->join('u.admins', 'admins')
->where('admins = :user'))
->setParameters(array(':user' => $userArray))
->getQuery();
How can I make this work?
In your SchoolRepository.php :
$query = $this->createQueryBuilder('u')
->where('u.superAdmin = :user')
->leftJoin('u.admins', 'a')
->andWhere('a = :user')
->setParameter('user', $userArray)
->getQuery()
;
$results = $query->getResult();

Symfony2 Doctrine NotIn issue

I can't work out what I'm doing wrong. I am doing a notin query where I am following all the Stack overflow posts that I have found saying to create the notin query first then put it into the actual query. Here is the query I am trying to run.
public function loadCompleted()
{
$notIn = $this->getEntityManager()->createQueryBuilder()
->select('DISTINCT j.id')
->from($this->getEntityName(), 'j')
->join('NucleoManagerBundle:JobStatus', 'js', Join::WITH, 'j.jobStatus = js.id')
->join('NucleoManagerBundle:Task', 't', Join::WITH, 't.job = j.id')
->join('NucleoManagerBundle:TaskStatus', 'ts', Join::WITH, 't.taskStatus = ts.id');
$notIn->where('ts.draft = 1')
->orWhere('ts.pending = 1')
->orWhere('ts.depending = 1')
->orWhere($notIn->expr()->andX(
$notIn->expr()->eq('ts.draft', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.completed', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.pending', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.invoiced', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.cancelled', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.depending', $notIn->expr()->literal(false))
))
->getQuery()
->getResult();
$query = $this->getEntityManager()->createQueryBuilder()
->select('j')
->from($this->getEntityName(), 'j')
->join('NucleoManagerBundle:JobStatus', 'js', Join::WITH, 'j.jobStatus = js.id')
->where('j.billable = 1')
->andWhere('j.invoiced = 0')
->andWhere('j.template = 0')
->andWhere('js.invoiced = 0')
->andWhere('js.cancelled = 0');
$query->andWhere($query->expr()->notIn('j.id', $notIn));
return $query->getQuery()->getResult();
}
And I get the following error:
ContextErrorException: Catchable Fatal Error: Object of class Doctrine\ORM\EntityManager could not be converted to string in C:\BitNami\wampstack-5.4.24-0\apps\manager\htdocs\vendor\doctrine\orm\lib\Doctrine\ORM\Query\Expr\Func.php line 76
Can anyone help??
Thanks in advance!
Looks like I figured out how to do it this way, through this post: Subquery in doctrine2 notIN Function. I use the getDQL function on the notin query and make sure that all my aliases don't coincide with the regular query ones.
public function loadCompleted()
{
$notIn = $this->getEntityManager()->createQueryBuilder()
->select('DISTINCT j')
->from($this->getEntityName(), 'j')
->join('NucleoManagerBundle:JobStatus', 'js', Join::WITH, 'j.jobStatus = js.id')
->join('NucleoManagerBundle:Task', 't', Join::WITH, 't.job = j.id')
->join('NucleoManagerBundle:TaskStatus', 'ts', Join::WITH, 't.taskStatus = ts.id');
$notIn->where('ts.draft = 1')
->orWhere('ts.pending = 1')
->orWhere('ts.depending = 1')
->orWhere($notIn->expr()->andX(
$notIn->expr()->eq('ts.draft', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.completed', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.pending', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.invoiced', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.cancelled', $notIn->expr()->literal(false)),
$notIn->expr()->eq('ts.depending', $notIn->expr()->literal(false))
));
$query = $this->getEntityManager()->createQueryBuilder()
->select('job')
->from($this->getEntityName(), 'job')
->join('NucleoManagerBundle:JobStatus', 'jstatus', Join::WITH, 'job.jobStatus = jstatus.id')
->where('job.billable = 1')
->andWhere('job.invoiced = 0')
->andWhere('job.template = 0')
->andWhere('jstatus.invoiced = 0')
->andWhere('jstatus.cancelled = 0');
$query->andWhere($query->expr()->notIn('job.id', $notIn->getDQL()));
return $query->getQuery()->getResult();
}

Doctrine QueryBuilder Re-Use Parts

I want to count all fields that fits my conditions and get them page by page with doctrine query builder.
I'm generating the query depends my filter fields.
First section is counting the records so i can calculate the pages.
$qb = $em->createQueryBuilder();
$qb
->select('COUNT(m.id)')
->from('CSMediaBundle:MediaItem', 'm')
->where(
$qb->expr()->eq('m.media', $media->getId())
);
$filters = $request->request->get('filter');
if(!empty($filters['size'])) {
foreach($filters['size'] as $key => $value) {
if(!empty($value)) {
$qb->andWhere(
$qb->expr()->eq('m.'.$key, ':'.$key)
)->setParameter($key, $value);
}
}
}
if(!empty($filters['sliders'])) {
$qb
->leftJoin('CSSliderBundle:SliderItem', 's', 'ON', 'm.id = s.media_id')
->andWhere(
$qb->expr()->in('s.sliders', $filters['sliders'])
);
}
$media_count = $qb->getQuery()->getSingleScalarResult();
Second section is getting records by calculated page using same filters, just changing the select and final parts (getSingleScalarResult to getResult)
I wonder if is there any way to just change the select and the result parts so i would not use the filters again and again...
Yeah, that's what functions are for:
function filter($qb, $filters) {
if (!empty($filters['size'])) {
foreach($filters['size'] as $key => $value) {
if (!empty($value)) {
$qb->andWhere(
$qb->expr()->eq('m.'.$key, ':'.$key)
)->setParameter($key, $value);
}
}
}
if (!empty($filters['sliders'])) {
$qb
->leftJoin('CSSliderBundle:SliderItem', 's', 'ON', 'm.id = s.media_id')
->andWhere(
$qb->expr()->in('s.sliders', $filters['sliders'])
);
}
return $qb;
}
$filters = $request->request->get('filter');
// count
$qb = $em->createQueryBuilder();
$qb
->select('COUNT(m.id)')
->from('CSMediaBundle:MediaItem', 'm')
->where(
$qb->expr()->eq('m.media', $media->getId())
);
$media_count = filter($qb, $filters)->getQuery()->getSingleScalarResult();
// entities
$qb = $em->createQueryBuilder();
$qb
->select('m')
->from('CSMediaBundle:MediaItem', 'm')
->where(
$qb->expr()->eq('m.media', $media->getId())
);
$media_entities = filter($qb, $filters)->getQuery()->getResult();
Another way is to clone the query builder object:
$qb = $em->createQueryBuilder();
$qb->from('CSMediaBundle:MediaItem', 'm')
->where(
$qb->expr()->eq('m.media', $media->getId())
);
$filters = $request->request->get('filter');
if (!empty($filters['size'])) {
foreach($filters['size'] as $key => $value) {
if (!empty($value)) {
$qb->andWhere(
$qb->expr()->eq('m.'.$key, ':'.$key)
)->setParameter($key, $value);
}
}
}
if (!empty($filters['sliders'])) {
$qb
->leftJoin('CSSliderBundle:SliderItem', 's', 'ON', 'm.id = s.media_id')
->andWhere(
$qb->expr()->in('s.sliders', $filters['sliders'])
);
}
$qb2 = clone $qb;
$qb->select('COUNT(m.id)')
$media_count = $qb->getQuery()->getSingleScalarResult();
$qb2->select('m')
$media_entities = $qb2->getQuery()->getResult();
In Javascript-TypeORM you can clone the existing query builder as shown below.
let baseQuery=this.Repository.createQueryBuilder("user");
//Add conditions
if(user_type==="admin"){
baseQuery.where("user.user_type = : user_type",{user_type:"admin"})
}
//Clone query builder
let count_query= new SelectQueryBuilder(baseQuery);
const count= count_query.select('COUNT(*)', 'count').getRawOne();
let sum_query= new SelectQueryBuilder(baseQuery);
const sum= sum_query.select('SUM(user.amount)', 'amount').getRawOne();

Categories