Doctrine parameters issue - symfony

I have the following piece of code that is giving the following exception and I can't figure out why, any help would be appreciated.
Invalid parameter number: number of bound variables does not match
number of tokens
if (!empty($ids)) {
$queryIds = implode(",", $ids);
$query = $em->createQueryBuilder()
->from('MainClientBundle:Posts','p')
->select('p')
->where('p.id >= :rand')
->where('p.id NOT IN (:ids)')
->orderBy('p.id','ASC')
->setParameter('rand', rand(1, $max))
->setParameter('ids', $queryIds)
->setMaxResults(1);
} else {
$query = $em->createQueryBuilder()
->from('MainClientBundle:Posts','p')
->select('p')
->where('p.id >= :rand')
->orderBy('p.id','ASC')
->setParameter('rand', rand(1, $max))
->setMaxResults(1);
}
try {
if($options['videos'] == "off"){
$query->where("p.type <> :type")->setParameter("type",1);
}
if($options['sfw'] == "on"){
$query->where("p.safeForWork <> :sfw")->setParameter("sfw",0);
}
$post = $query->getQuery()->getSingleResult();
} catch (\Doctrine\Orm\NoResultException $e) {
$post = null;
}

Your first query is the problem. Your query should look like this
if (!empty($ids)) {
$queryIds = implode(",", $ids);
$query = $em->createQueryBuilder()
->from('MainClientBundle:Posts','p')
->select('p')
->where('p.id >= :rand')
->andWhere('p.id NOT IN (:ids)')
->orderBy('p.id','ASC')
->setParameter('rand', rand(1, $max))
->setParameter('ids', $queryIds)
->setMaxResults(1);
} else {
$query = $em->createQueryBuilder()
->from('MainClientBundle:Posts','p')
->select('p')
->where('p.id >= :rand')
->orderBy('p.id','ASC')
->setParameter('rand', rand(1, $max))
->setMaxResults(1);
}
try {
if($options['videos'] == "off"){
$query->where("p.type <> :type")->setParameter("type",1);
}
if($options['sfw'] == "on"){
$query->where("p.safeForWork <> :sfw")->setParameter("sfw",0);
}
$post = $query->getQuery()->getSingleResult();
} catch (\Doctrine\Orm\NoResultException $e) {
$post = null;
}
Note that I changed your second where to andWhere. When you use two where() in the same query builder, the first gets overwritten by the second.

As stated above in the comments the problems lies with the double usage of ->where in your querybuilder. If you want to combine multiple where clauses you need to use ->andWhere or/and ->orWhere.
Also I changed your result to ->getOneOrNullResult(), with that you don't need to use this whole try/catch block you used to catch the doctrine exception.
if (!empty($ids)) {
$queryIds = implode(",", $ids);
$query = $em->createQueryBuilder()
->from('MainClientBundle:Posts','p')
->select('p')
->where('p.id >= :rand')
->where('p.id NOT IN (:ids)')
->orderBy('p.id','ASC')
->setParameter('rand', rand(1, $max))
->setParameter('ids', $queryIds)
->setMaxResults(1);
} else {
$query = $em->createQueryBuilder()
->from('MainClientBundle:Posts','p')
->select('p')
->where('p.id >= :rand')
->orderBy('p.id','ASC')
->setParameter('rand', rand(1, $max))
->setMaxResults(1);
}
if($options['videos'] == "off"){
$query->where("p.type <> :type")->setParameter("type",1);
}
if($options['sfw'] == "on"){
$query->where("p.safeForWork <> :sfw")->setParameter("sfw",0);
}
$post = $query->getQuery()->getOneOrNullResult();

Related

Doctrine query builder parenthesis bad place

I have a query that receive some array parameters without any ideas how rows there is. It must return contents with all filters (AND clause), and one or more categories (OR clause).
I can't get results I'd like because parentheses are not a the good place. I should got this SQL rendering:
WHERE (
f3_.idfilter = '87'
AND f5_.idfilter = '90'
AND f7_.idfilter = '154'
AND f9_.idfilter = '165'
)
AND (
c0_.content_category_idcontent_category = 1
OR c0_.content_category_idcontent_category = 3
)
and got this instead:
WHERE (
(
f3_.idfilter = '87'
AND f5_.idfilter = '90'
AND f7_.idfilter = '154'
AND f9_.idfilter = '165'
AND c0_.content_category_idcontent_category = 1
)
OR c0_.content_category_idcontent_category = 3
)
My code:
public function getContentByFiltersAjax($categs, $filters, $offset, $limit) {
$filtersTab = explode(',', $filters);
$query = $this->createQueryBuilder('c');
for ($i = 1; $i <= count($filtersTab); $i++) {
$query = $query
->leftJoin('c.filterfilter', 'f' . $i)
->andWhere('f' . $i . '.idfilter = :filter_idfilter' . $i)
->setParameter('filter_idfilter' . $i, $filtersTab[$i - 1]);
}
$categsTab = explode(',', $categs);
if(sizeof($categsTab) > 1) {
$expr = $query->expr();
$categsTab = explode(',', $categs);
foreach ($categsTab as $key => $value) {
if($key === 0){
$query->andWhere($expr->eq('c.contentCategorycontentCategory', $value));
} else {
$query->orWhere($expr->eq('c.contentCategorycontentCategory', $value));
}
}
} else {
$query
->andWhere('c.contentCategorycontentCategory = :category')
->setParameter('category', $categs);
}
$query
->andWhere('c.status = :status')
->setParameter('status', 'publie');
$query->orderBy('editor.plan', 'DESC');
$query->addOrderBy('c.creationDate', 'DESC');
$query
->setFirstResult($offset)
->setMaxResults($limit);
$result = $query->distinct()->getQuery()->getResult();
return $result;
}
You put the orWhere's inside 1 andWhere like this:
$query->andWhere(
$query->expr->orX(
$query->expr->eq('c.contentCategorycontentCategory', $value1),
$query->expr->eq('c.contentCategorycontentCategory', $value2)
)
);
Or in your foreach loop:
$orX = $query->expr->orX();
foreach ($categsTab as $value) {
$orX->add($query->expr->eq('c.contentCategorycontentCategory', $value));
}
$query->andWhere($orX);

Custom repository Symfony

I got an array of IDs (idExam)
And i would like to make a custom respository that on the WHERE it add all IDs.
This this my code:
public function examNotValidated($idExam)
{
return $this->createQueryBuilder('q')
->where('q.creadetby = :creadetby and q.id = :idExam')
->setParameter('creadetby', false)
->setParameter('idExam', $idExam)
->getQuery()
->getResult();
}
And i would like something like this:
public function examNotValidated($idExam)
{
return $this->createQueryBuilder('q')
->where('q.creadetby = :creadetby and (q.id = :idExams[0] or q.id = :idExams[1] or q.id = :idExams[3])')
->setParameter('creadetby', false)
->setParameter('idExams', $idExams)
->getQuery()
->getResult();
}
Is there anyway to do that?
You can be using IN expression:
public function examNotValidated(array $ids)
{
$qb = $this->createQueryBuilder('q');
return $qb->where('q.creadetby = :creadetby')
->andWhere($qb->expr()->in('q.id', $ids))
->setParameter('creadetby', false)
->getQuery()
->getResult();
}
Here is the opposite logic (e.g: q.id = :idExams[0] or q.id = :idExams[1] or q.id = :idExams[3])
public function examNotValidated(array $ids)
{
$qb = $this->createQueryBuilder('q');
$orX = $qb->expr()->orX();
foreach ($ids as $id) {
$orX->add('q.id = '.$id);
}
return $qb->where('q.creadetby = :creadetby')
->andWhere($orX);
->setParameter('creadetby', false)
->getQuery()
->getResult();
}

Invalid parameter: token 1 is not defined in the query

Here is my code to filter pets base on a JSON ajax Query
I am getting error follwoing image
public function filter($object, $active=true){
$query = $this->createQueryBuilder('p');
$query->innerjoin('TadpetProfessionalBundle:ProPet', 'pp', 'WITH', 'pp.professionalId = p.id');
$query->innerjoin('TadpetManagerBundle:Pet', 'ppp', 'WITH', 'ppp.id = pp.petId');
$query->where('p.isActive = :active')
->setParameter('active', $active);
if(!empty($object->pets)){
$qString = "";
for($i=1; $i<=sizeof($object->pets); $i++){
if($i == 1){
$qString .= "ppp.name = :petname".$i;
}else{
$qString .= " OR ppp.name = :petname".$i;
}
}
$query->andWhere($qString);
$query->setParameter('petname'+1,$object->pets[0]);
$query->setParameter('petname'+2,$object->pets[1]);
$query->setParameter('petname'+3,$object->pets[2]);
}
return $query->getQuery()->getResult();
}
Help me please
In these lines:
$query->setParameter('petname'+1,$object->pets[0]);
$query->setParameter('petname'+2,$object->pets[1]);
$query->setParameter('petname'+3,$object->pets[2]);
You are adding 'petname' to the numbers, but you should concatenate them:
$query->setParameter('petname'.1,$object->pets[0]);
$query->setParameter('petname'.2,$object->pets[1]);
$query->setParameter('petname'.3,$object->pets[2]);
Also, you could use a loop:
for($i=1; $i<=sizeof($object->pets); $i++){
$query->setParameter('petname'.$i,$object->pets[$i-1]);
}

Symfony 3 - undefined method named "getResult"

/**
* Search result information between two dates
*
*#Route("/search/{startDate}/{endDate}/{type}", name="maintenance_search_result")
*#Method("GET")
*/
public function searchResultAction($startDate, $endDate, $type)
{
$em = $this->getDoctrine()->getManager()->getRepository('CarMaintenanceBundle:Maintenance');
$query = $em->createQueryBuilder('c')
->select('c.id')
->addSelect('c.type')
->addSelect('c.date')
->addSelect('c.cost')
->addSelect('c.remark')
->where('c.date > :SDATE')->setParameter('SDATE', $startDate)
->andWhere('c.date < :EDATE')->setParameter('EDATE', $endDate);
if ("All" != $type){
$query->andWhere('c.type = :TYPE1')->setParameter('TYPE1', $type);
}
$query->orderBy('c.date', 'DESC')
->getQuery();
$SearchRes = $query->getResult();
return $this->render('maintenance/search_result.html.twig', array(
'SearchResults'=> $SearchRes,));
}
I have the following error:
Attempted to call an undefined method named "getResult" of class
"Doctrine\ORM\QueryBuilder".
When I write this way, there is no problem. It displays the search result.
public function searchResultAction($startDate, $endDate, $type)
{
$em = $this->getDoctrine()->getManager()->getRepository('CarMaintenanceBundle:Maintenance');
if ("All" != $type){
$query = $em->createQueryBuilder('c')
->select('c.id')
->addSelect('c.type')
->addSelect('c.date')
->addSelect('c.cost')
->addSelect('c.remark')
->where('c.date > :SDATE')->setParameter('SDATE', $startDate)
->andWhere('c.date < :EDATE')->setParameter('EDATE', $endDate)
->andWhere('c.type = :TYPE1')->setParameter('TYPE1', $type)
->orderBy('c.date', 'DESC')
->getQuery();
} else {
$query = $em->createQueryBuilder('c')
->select('c.id')
->addSelect('c.type')
->addSelect('c.date')
->addSelect('c.cost')
->addSelect('c.remark')
->where('c.date > :SDATE')->setParameter('SDATE', $startDate)
->andWhere('c.date < :EDATE')->setParameter('EDATE', $endDate)
->orderBy('c.date', 'DESC')
->getQuery();
}
$SearchRes = $query->getResult();
return $this->render('maintenance/search_result.html.twig', array(
'SearchResults'=> $SearchRes,));
}
What is wrong with the shortest code?
You're not assigning the result of getQuery() anywhere:
$query->orderBy('c.date', 'DESC')
->getQuery();
This is gonna do the trick:
$query = $query->orderBy('c.date', 'DESC')
->getQuery();

Cannot count query which selects two FROM components, cannot make distinction when i try to break my query to add conditional statement symfony 2 .8

pls help i get this error
Cannot count query which selects two FROM components, cannot make distinction
when i try to break my query to add conditional statement
i have read this
KnpPaginatorBundle/Resources/doc/manual_counting.md and i arrived at this
public function findCategoryProduct($category,$minPrice=null,$maxPrice=null,$gender=null)
{
$countgb = $this->createQueryBuilder('1')
->select('count(p)')
->from('AppBundle:Product','p')
->join('p.group', 'g')
->join('g.category', 'c')
->where('c = :category')
->andWhere('p.visible >= :true')
->setParameter('category', $category)
->setParameter('true', 1);
$count = $countgb->getQuery()->getSingleScalarResult();
$query = $this->createQueryBuilder('1')
->select('p')
->from('AppBundle:Product','p')
->join('p.group', 'g')
->join('g.category', 'c')
->where('c = :category')
->andWhere('p.visible >= :true')
->setParameter('category', $category)
->setParameter('true', 1);
$query ->getQuery()
->setHint('knp_paginator.count', $count);
return $query;
}
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($query,$request->query->getInt('page', 1),10,array('distinct' => false));
and i still get the error
Hi I advise you to use subquery like :
$query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM CmsPhonenumber p WHERE p.user = u.id)');
$ids = $query->getResult();
or with expr:
$query->andWhere($query->expr()->notIn('c.id', $subquery->getDQL()));
some documentation here

Resources