Symfony2 KNP Pagination "Cannot count query " - php

So , i'm working on a news portal . I'm using KNP Paginator,and i've got an error :
Cannot count query which selects two FROM components, cannot make distinction
And now , my source code :
#block of code from controller
$rep = $this->getDoctrine()->getRepository('NickCoreBundle:News');
$user = $this->get('security.context')->getToken()->getUser();
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$rep->getNewsFeedQuery($user->getId()),
$page,
10
);
and from my repository:
public function getNewsFeedQuery($userid)
{
$userid = intval($userid);
return $this->getEntityManager()->createQueryBuilder()
->select('n')
->from('NickCoreBundle:News', 'n')
->innerJoin('NickCoreBundle:Subscriptions', 's', 'WITH', 's.user = :userid AND n.source = s.source')
->orderBy("n.date","DESC")
->setParameter('userid', $userid)->getQuery();
}
how to solve it :) ? tried to get result from query , in ArrayCollection , it works (partialy,not sorted by date , and i think this method used a lot of time)

It's a little late to answer but it could be of help to other readers.
I would suggest doing away with the explicit innerJoin and let Doctrine handle the joins.
return $this->getEntityManager()->createQueryBuilder()
->select('n')
->from('NickCoreBundle:News', 'n')
->join('n.source', 's')
->where('s.user'= :userid )
->orderBy("n.date","DESC")
->setParameter('userid', $userid)->getQuery();

Related

Doctrine- setting query parameters conditionally

I building application in Symfony 2.
I have to filter users basing on data passed in form.
I wrote something like this in my controller:
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb->addSelect('user');
$qb->from('Application\Sonata\UserBundle\Entity\User', 'user');
if(($filter['freelancer'])){
$qb->setParameters(array('freelancer' => $filter['freelancer']))
->andWhere('user.firstname = :freelancer');
}
if(($filter['category'])){
$qb->innerJoin('Flexihub\MainBundle\Entity\Category', 'category', 'WITH', 'user.category = category.id')
->setParameters(array('category' => $filter['category']))
->andWhere('user.category = :category');
}
$query = $qb->getQuery();
$result = $query->getResult();
dump($result);
Im stuck with error when im trying to pass both parameters.
Invalid parameter number: number of bound variables does not match number of tokens
What am I doing wrong?
Is there better solution to solve my problem?
It's logical to write it like this, so, first add criteria then provide arguments:
if(($filter['freelancer'])){
$qb
->andWhere('user.firstname = :freelancer')
->setParameter('freelancer', $filter['freelancer']);
}
if(($filter['category'])){
$qb
->innerJoin('Flexihub\MainBundle\Entity\Category', 'category', 'WITH', 'user.category = category')
->andWhere('user.category = :category')
->setParameter('category', $filter['category']);
}

How to join two entities with doctrine 2 and zf2?

I have two entities, Carros and Msg, i am looking to get Carros that have Msg messages
$query = $entityManager->createQuery("
SELECT u
FROM Auto\Entity\Carros u
JOIN Auto\Entity\Msg m WITH m.idautoad=u.idcarros
WHERE u.identidade='".$emailidentidade."'
ORDER BY u.datadoanuncio DESC
");
I'm using the paginator:
// Create the paginator itself
$paginator = new Paginator(
new DoctrinePaginator(new ORMPaginator($query))
);
and i am getting the following errors i have zend 2.3.9 and doctrine 2.4
Arquivo:
C:\websites\auto\vendor\zendframework\zendframework\library\Zend\Paginator\Paginator.php:637
Mensagem: Error producing an iterator
C:\websites\auto\vendor\doctrine\orm\lib\Doctrine\ORM\Tools\Pagination\WhereInWalker.php:85
Mensagem:
Cannot count query which selects two FROM components, cannot make distinction
its generating the error when i try to do this :
foreach ($paginator as $carro)
{}
The error disappears when getting the results like this :
$fi = $query->getResult();
and then
$paginator = new \Zend\Paginator\Paginator(new
\Zend\Paginator\Adapter\ArrayAdapter($fi)
);
In case you have a ManyToOne relationship you can do like this (be sure to see this link before to make your mapping correct : Bidirectionnal ManyToOne relation
public function getInvoices($idProformaGroup, $paginate = false)
{
$query = $this->getEntityManager()->createQueryBuilder();
$query->select('po', 'i')
->from('Invoice\Entity\Proforma', 'po')
->innerJoin('po.idInvoice', 'i')
->andWhere("po.idProformaGroup = :idProformaGroup")
->orderBy('po.idProforma', 'ASC')
->setParameter('idProformaGroup', $idProformaGroup);
if ($paginate) {
$doctrineAdapter = new DoctrineAdapter(new ORMPaginator($query, true));
return new Paginator($doctrineAdapter);
} else {
return $query->getQuery()->getResult();
}
}
Like you see, my join use the foreign key po.idInvoice to join the two tables. And because of this my Paginator don't show me your error.
EDIT : With a param I can decide to paginate or not. Don't use it if you don't need it.
EDIT 2 : From the link to the other question join before Doctrine : Pagination with left Joins The futurereal's answer is the same point I tried to explain to you.
i am not using anymore
new DoctrinePaginator(new ORMPaginator($query))
now i am using \Zend\Paginator\Paginator and its working
$fi = $query->getResult();
$paginator = new \Zend\Paginator\Paginator(new
\Zend\Paginator\Adapter\ArrayAdapter($fi)
);

Update query with LIMIT ( setMaxResults ) in doctrine2 using createQueryBuilder not working

I have the following code
$qb = $this->createQueryBuilder('cs')
->update()
->set('cs.is_active', 1)
->where('cs.reward_coupon = :reward_coupon')
->setMaxResults($limit)
->setParameter('reward_coupon', $rewardCoupon);
$qb->getQuery()->execute();
This doesn’t apply the LIMIT in the resultant query.
setMaxResult() has to be your last Doctrine statement in order to properly works
example :
$qb = $this->createQueryBuilder('cs')
->update()
->set('cs.is_active', 1)
->where('cs.reward_coupon = :reward_coupon')
->setParameter('reward_coupon', $rewardCoupon)
->setMaxResults($limit);
return $qb->getQuery()->execute();
I think that this may help
$limit=50;
$i=0;
$qb = $this->createQueryBuilder('cs')
->update()
->set('cs.is_active', 1)
->where('cs.reward_coupon = :reward_coupon')
->setParameter('reward_coupon', $rewardCoupon)
->setFirstResult($i)
->setMaxResults($limit);
$qb->getQuery()->execute();

Symfony2 Query Builder Not Returning Many To One Value

I have an entity that has a column "inventoryLcoation_id" that has a many to one relationship. For some reason when I use createQueryBuilder() it is not returning that value in my ajax call, but it returns everything else: id, name, etc etc.. This is not an issue with Symfony2, its an issue with my lack of knowledge :)
Here is my query builder code:
$qb = $this
->createQueryBuilder('p')
->select('p.id', 'p.name')
->where('p.inventoryLocation = :inventoryId')
->andWhere('p.account = :account_id')
->setParameter('inventoryId', $value)
->setParameter('account_id', $account_id)
->orderBy('p.id', 'DESC');
if($qb->getQuery()->getArrayResult()){
return $qb->getQuery()->getArrayResult();
}else{
return false;
}
What do I need to code to have it also include the value from the inventoryLocation table which is mapped to the column value "inventoryLocation_id"?
Thanks so much for your help in enlightening my understanding to the awesome world of Symfony2!
try a join:
$qb->join('p.inventoryLocation','i')
and in the select especify both entities
$qb->select('p','i')
it should look like this:
$qb = $this
->createQueryBuilder('p')
->select('p','i')
->join('p.inventoryLocation','i')
->where('p.inventoryLocation = :inventoryId') // or ->where('i = :inventoryId')
->andWhere('p.account = :account_id')
->setParameter('inventoryId', $value)
->setParameter('account_id', $account_id)
->orderBy('p.id', 'DESC');

How to select distinct query using symfony2 doctrine query builder?

I have this symfony code where it retrieves all the categories related to a blog section on my project:
$category = $catrep->createQueryBuilder('cc')
->Where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->getQuery();
$categories = $category->getResult();
This works, but the query includes duplicates:
Test Content
Business
Test Content
I want to use the DISTINCT command in my query. The only examples I have seen require me to write raw SQL. I want to avoid this as much as possible as I am trying to keep all of my code the same so they all use the QueryBuilder feature supplied by Symfony2/Doctrine.
I tried adding distinct() to my query like this:
$category = $catrep->createQueryBuilder('cc')
->Where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->distinct('cc.categoryid')
->getQuery();
$categories = $category->getResult();
But it results in the following error:
Fatal error: Call to undefined method Doctrine\ORM\QueryBuilder::distinct()
How do I tell symfony to select distinct?
This works:
$category = $catrep->createQueryBuilder('cc')
->select('cc.categoryid')
->where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->distinct()
->getQuery();
$categories = $category->getResult();
Edit for Symfony 3 & 4.
You should use ->groupBy('cc.categoryid') instead of ->distinct()
If you use the "select()" statement, you can do this:
$category = $catrep->createQueryBuilder('cc')
->select('DISTINCT cc.contenttype')
->Where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->getQuery();
$categories = $category->getResult();
you could write
select DISTINCT f from t;
as
select f from t group by f;
thing is, I am just currently myself getting into Doctrine, so I cannot give you a real answer. but you could as shown above, simulate a distinct with group by and transform that into Doctrine. if you want add further filtering then use HAVING after group by.
Just open your repository file and add this new function, then call it inside your controller:
public function distinctCategories(){
return $this->createQueryBuilder('cc')
->where('cc.contenttype = :type')
->setParameter('type', 'blogarticle')
->groupBy('cc.blogarticle')
->getQuery()
->getResult()
;
}
Then within your controller:
public function index(YourRepository $repo)
{
$distinctCategories = $repo->distinctCategories();
return $this->render('your_twig_file.html.twig', [
'distinctCategories' => $distinctCategories
]);
}
Good luck!

Categories