Bonjour,
I am having a problem with a simple request with QueryBuilder :
$query->where('ec.codeModePrelevement IN (:cbMode)')
->setParameter('cbMode', $modes)
->andWhere('ec.idStatusPaiement = :status')
->setParameter('status', EcheancesStatut::__EN_ATTENTE_PAIEMENT__)
->andWhere($query->expr()->eq('ec.idProduit',1))
->andWhere('ec.idProduit = :idProduit')
->setParameter('idProduit', 1 )
;
This return me no result as if in the database no user is corresponding to this : user with status = 1 codeproduit = 1 and modePaiement = VM or VMMANO.
Ihave verified all possible mistakes of typo. And users corresponding in database do exist.
I have tried to remove id produit filter it "works" i have some result:
$modes = array('VM','VMMANO');
$query->where('ec.codeModePrelevement IN (:cbMode)')
->setParameter('cbMode', $modes)
->andWhere('ec.idStatusPaiement = :status')
->setParameter('status', EcheancesStatut::__EN_ATTENTE_PAIEMENT__)
/*->andWhere('ec.idProduit = :idProduit')
->setParameter('idProduit', 1 )*/
;
This "works" to (removing modePaiement filter):
$query/*->where('ec.codeModePrelevement IN (:cbMode)')
->setParameter('cbMode', $modes)*/
->where('ec.idStatusPaiement = :status')
->setParameter('status', EcheancesStatut::__EN_ATTENTE_PAIEMENT__)
->andWhere('ec.idProduit = :idProduit')
->setParameter('idProduit', 1 )
;
but this returns me no result to (removing status payment filter) :
$query->where('ec.codeModePrelevement IN (:cbMode)')
->setParameter('cbMode', $modes)
/*->where('ec.idStatusPaiement = :status')
->setParameter('status', EcheancesStatut::__EN_ATTENTE_PAIEMENT__)*/
->andWhere('ec.idProduit = :idProduit')
->setParameter('idProduit', 1 )
;
Can you help me if you see something that i don't? Thank you.
Related
Retrieve a node based on condition:
$query = \Drupal::entityQuery('node')
->condition('type', 'my_content_type')
->condition('title', 'my node title');
$nid = $query->execute();
The result of $nid is the correct node ID but the format is a string, (es: "123")
When I want to load the node by its ID, I write:
$node_id = Node::load($nid);
Doing this, the result I get is NULL because the variable $nid is holding a string (not integer).
If I write the code like this:
$node_id = Node::load(123);
I get the node loaded.
How can I convert the variable string ($nid) as an integer ?
I tried:
$nid_int = (int) $nid;
$node_id = Node::load($nid_int);
also I tried:
$nid_int = intval($nid);
$node_id = Node::load($nid_int);
But I alwas get result NULL
Thanks for your help
You can't use Node::load($nid); directly, because the $query->execute() return an array like ['vid' => "nid"].
$query = \Drupal::entityQuery('node')
->condition('type', 'my_content_type')
->condition('title', 'my node title');
$nids = $query->execute();
$nid = (int)array_shift($nids);
Can try:-
$nid_string = $nid->__toString();
$node_id = Node::load((int) $nid_string);
I have a raw query which I would like to convert into doctrine ORM. It's basically a query which contains sub query to calculate total count.
SELECT Count(*) AS total_count
FROM (SELECT *
FROM content_item_languages
WHERE default_content_item_id IN (SELECT id AS default_content_item_id
FROM content_item
WHERE content_type = 1
AND is_translated = 0
AND modified_on >=
'$timePeriodStart'
AND is_active = 1)
AND language_id = '$language') AS t
I have written below doctrine ORM but still I am getting error
$em = $this->getEntityManager()->createQueryBuilder();
$totalPostSubselect = $em->addSelect('c.id AS defaultContentItemId')
->from('AppBundle\Entity\ContentItem\ContentItem', 'c')
->andWhere('c.contentType = 1')
->andWhere('c.isTranslated = 0')
->andWhere('c.modifiedOn >= :timeperiod')
->andWhere('c.isActive = :status')
->setParameter('status', 1)
->setParameter('timeperiod', $timePeriodStart)->getDQL();
$em = $this->getEntityManager()->createQueryBuilder();
$defaultSubSelect = $em->addSelect(['*'])
->from('AppBundle\Entity\ContentItem\ContentItemLanguages', 'cl')
->andWhere("cl.defaultContentItemId IN ($totalPostSubselect)")
->andWhere('cl.languageId = :language')
->setParameter('subSelect', $totalPostSubselect)
->setParameter('language', $language)->getDQL();
$em = $this->getEntityManager()->createQueryBuilder();
$mainQuerySelect = $em->addSelect(["count(*) as total_count"])
->from("(".$defaultSubSelect.")", 'AS t')->getQuery();
return $mainQuerySelect->getResult();
Here is the error I got
[Doctrine\ORM\Query\QueryException] [Syntax Error] line 0, col 13: Error: Expected Literal, got '*'
[Doctrine\ORM\Query\QueryException]
SELECT count(*) as total_count FROM (SELECT * FROM
AppBundle\Entity\ContentItem\ContentItemLanguages cl
WHERE (
cl.defaultContentItemId IN (SELECT c.id AS defaultContentItemId
FROM AppBundle\Entity\ContentItem\ContentItem c WHERE
c.contentType = 1 AND
c.isTranslated = 0 AND
c.modifiedOn >= :timeperiod AND c.isActive = :status))
AND cl.languageId = :language) AS t
can anyone suggest, in exactly where I am doing wrong ?
In doctrine query language you can't SELECT *, instead you have to deal with objects. For your example something like:
$mainQuerySelect = $em->addSelect("count(t.id) as total_count")
->from("(".$defaultSubSelect.")", 'AS t')->getQuery();
I need to make a sql query like this,
UPDATE org_mapping SET is_active = 1 WHERE (org_id = ? AND service_provider_id = ? )OR (org_id = ? AND service_provider_id = ?)
I tried this but its now working:
$q = $qb->update('Organization\Entity\OrgMapping', 'om')
->set('om.active', $qb->expr()->literal($isActive))
->where('om.organization = ?1')->andWhere('om.serviceProvider = ?2')
->orWhere('om.organization = ?2')->andWhere('om.serviceProvider = ?1')
->setParameter(1, $organizationId)
->setParameter(2, $hspId)
->getQuery();
When i am running, i am getting the following query:
UPDATE org_mapping SET is_active = 1 WHERE ((org_id = ? AND service_provider_id = ?) OR org_id = ?) AND service_provider_id = ?
Replace
->orWhere('om.organization = ?2')->andWhere('om.serviceProvider = ?1')
With
->orWhere('om.organization = ?2 AND om.serviceProvider = ?1')
Try this:
$q = $qb->update('Organization\Entity\OrgMapping', 'om')
->set('om.active', $qb->expr()->literal($isActive))
->where(
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->eq('om.organization', '?1')
,
$qb->expr()->eq('om.serviceProvider','?2')
),
$qb->expr()->andX(
$qb->expr()->eq('om.organization', '?2')
,
$qb->expr()->eq('om.serviceProvider','?1')
)
)
)
->setParameter(1, $organizationId)
->setParameter(2, $hspId)
->getQuery();
You should not do it.
If you do an UPDATE query, you're missing the whole point of using Doctrine, that is mapping objects to database rows, not just an abstraction to queries.
Instead, extract your objects, then do a cycle and perform actions on single objects, then flush after the cycle.
I'm trying to update a certain number of rows of my entity "Vehicule". I have no idea how could it work.
I'm actually trying to modify only two rows where direction= 5.This is the function I used in order to update.
public function ValidAction(\OC\UserBundle\Entity\User $direction) {
$qb = $this->getDoctrine()
->getRepository('CarPfeBundle:Vehicule')
->createQueryBuilder('v');
$q = $qb->update ('CarPfeBundle:vehicule v')
->set('v.direction', '?1')
->where('v.direction = ?2')
->setParameter(1, $direction)
->setParameter(2, 5)
->getQuery();
$p = $q->execute();
return $this->redirect($this->generateUrl('demandeveh_afficher'));
}
But the above code update all rows of my database. I need to update only two rows. Any help please?
Try to do this ;
public function ValidAction(\OC\UserBundle\Entity\User $direction) {
$qb = $this->getDoctrine()
->getRepository('CarPfeBundle:Vehicule')
->createQueryBuilder('v');
// $ids an array that contains all ids with your condition
$ids = $qb->select('v.id')
->where('v.direction = :direction')
->setParameter(
array(
'direction' => $direction
)
)
->getQuery()
->getResult();
$id1 = $ids[array_rand($ids)];
$id2 = $ids[array_rand($ids)];
//To be sure that $id1 is different from id2
while ($id1 == $id2) {
$id2 = $ids[array_rand($ids)];
}
$q = $qb->update ('CarPfeBundle:vehicule v')
->set('v.direction', ':val1')
->where('v.direction = :val2')
->andWhere('v.id IN (:id1, :id2)')
->setParameter(
array(
'val1' => $direction ,
'val2' => 5 ,
'id1' => $id1,
'id2' => $id2,
)
)
->getQuery();
$p = $q->execute();
return $this->redirect($this->generateUrl('demandeveh_afficher'));
}
With the above code I hope you can update only two rows and randomly.
Good luck !
While a solution like Houssem Zitoun suggested may work, why not use a subquery?
If you get the (like I did, if not, just skip the middle SELECT)
Error: #1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
go with this answer and something like (doc): - untested
UPDATE CarPfeBundle:Vehicule v
SET v.direction = ?1
WHERE v.direction IN
(SELECT * FROM (
SELECT v.direction
FROM CarPfeBundle:Vehicule v2
WHERE v.direction = ?2 LIMIT 2
)) AS sq
I want to produce a DQL for following MySQL query:
SELECT * FROM `folders` AS `t` WHERE `t`.`Library` = #myLib AND AND `t`.`Id` NOT IN (
SELECT DISTINCT(`f`.`Id`) FROM `folders` AS `f` JOIN `folders` AS `ff` ON (`f`.`Position` LIKE CONCAT(`ff`.`Position`, '%')) WHERE `ff`.`Active` = 1 AND `ff`.`Library` = #myLib AND `f`.`Library` = #myLib
)
ORDER BY `t`.`Position` ASC
The query works fine in mySQL and returns correct records.
To generate DQL I've tried both below options:
1.
$query = $em->createQuery("SELECT F FROM MyBundle:Folders T WHERE T.Library = :libid AND T.id NOT IN (
SELECT DISTINCT(F.id) FROM MyBundle:Folders F JOIN MyBundle:Folders FF WITH F.Position LIKE CONCAT(FF.Position, '%') AND F.Library = :libid AND FF.Library = :libid AND FF.Active = true
) ORDER BY T.Position ASC")
->setParameter('libid', $library);
$result = $query->getResult();
2.
$q1 = $this->createQueryBuilder('F')
->select('DISTINCT(F.id)');
$q1->join('\MyBundle\Entity\Folders', 'FF', 'WITH', $q1->expr()->like('F.Position', $q1->expr()->literal('CONCAT(FF.Position, \'%\')')))
->where('FF.Active = true')
->andWhere("FF.Library = '$library'")
->andWhere("F.Library = '$library'");
$q2 = $this->createQueryBuilder('T');
$q2->where('T.Library = :libid')
->andWhere($q2->expr()->notIn('T.id', $q1->getDQL()))
->setParameter('libid', $library)
->orderBy('T.Position', 'ASC');
$result = $q2->getQuery()->getResult();
In my perspective it seems OK but I don't know why in both ways it produce following exception:
ContextErrorException: Warning: Illegal offset type in
/var/www/Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php line 601
Any help will be appreciated.
It seems no one has an answer for this. I found a temporary solution as below (I call it temporary because I'm changing my unique query to two separate queries and it seems the issue is in core of doctrine).
$qb = $this->createQueryBuilder('F')
->select('DISTINCT(F.id)');
$qb->join('\MyBundle\Entity\Folders', 'FF', 'WITH', 'F.Position LIKE CONCAT(FF.Position, \'%\')')
->where('FF.Active = true')
->andWhere("FF.Library = :library")
->andWhere("F.Library = :library")
->setParameter('library', $library);
$included_folders = $qb->getQuery()->getArrayResult();
$query = $this->createQueryBuilder('F')
->where('F.Active = false')
->andWhere('F.Library = :library')
->setParameter('library', $library)
->orderBy('F.Position', 'ASC');
if (!empty($included_folders)) {
if (count($included_folders) > 1)
{
foreach ($included_folders as $index => $value)
{
if (is_array($value))
{
$included_folders[$index] = !empty($value['id']) ? $value['id'] : $value[1];
}
}
$query->andWhere($query->expr()->notIn('F.id', $included_folders));
}
else {
$query->andWhere('F.id != :folder ')
->setParameter('folder', $included_folders[0]);
}
}
$result = $query->getQuery()->getResult();
As you see instead of getting the dql from my first query and putting it inside my second dql in notIn section which will lead to the warning message, I execute the first query and get the results then put the results inside notIn if amount of returned values are more than one, otherwise it should be in regular !=. This solved my problem for now, but as you see amount of transactions are now increased
If anyone has a better solution or any fix for the warning I will be thankful.
I've encountered the same error and it seems that this has been fixed in latest trunk of Doctrine/ORM.
Using "2.5.*#dev" as version in your composer.json for doctrine/orm should fix this bug and will let you do what you want in a single query.