ZF2 Doctrine with Symfony < OR null query - symfony

How do I write this "WHERE" condition in a way which is compatible with Doctrine?
( ( `translations_es_google`.`translation_date` < `translations_masters`.`translation_date` ) OR ( `translations_es_google`.`translation_date` is null ) )
What I have tried (unsuccessfully) are:
$query1
->andWhere('((t.translationDate < m.translationDate) OR (t.translationDate is NULL))');
$query1
->andWhere('(t.translationDate < m.translationDate) OR (t.translationDate is NULL)');
Table alias for the Doctrine query are
t represents the table translations_es_google
m represents the table translations_masters
When I remove this "andWhere" condition the rest of the QueryBuilder query executes as expected.
The query I am trying to execute is
SELECT
`translations_masters`.`translation_key` , `translations_masters`.`text_domain` , `translations_masters`.`translation_date`
FROM
`translations_masters`
LEFT JOIN
`translations_es_google` ON ( ( `translations_masters`.`text_domain` = `translations_es_google`.`text_domain` ) AND ( `translations_masters`.`translation_key` =`translations_es_google`.`translation_key` ) )
WHERE
`translations_masters`.`language_iso` NOT LIKE 'es-Google' AND ( ( `translations_es_google`.`translation_date` < `translations_masters`.`translation_date` ) OR ( `translations_es_google`.`translation_date` is null ) )
GROUP BY
`translations_masters`.`translation_key` , `translations_masters`.`text_domain`
ORDER BY
`translations_masters`.`translation_date` ASC
As requested the QueryBuilder version of this query is:
$query1 = $this->entityManager
->createQueryBuilder()
->select('m.textDomain , m.translationKey , m.translationDate , m.translationDate AS translationMasterDate , t.translationDate')
->from(
'AMDatabase\Entity\TheVerse\Translations' . $explode1 . $explode2,
't'
)
->leftJoin(
'AMDatabase\Entity\TheVerse\TranslationsMasters',
'm',
Join::WITH,
'(m.textDomain = t.textDomain) AND (m.translationKey = t.translationKey)'
)
->groupBy('m.textDomain , m.translationKey')
->orderBy(
'm.translationDate',
'ASC'
)
->setMaxResults('1');
$query1
->andWhere(
$query1->expr()
->notLike(
'm.languageIso',
':languageIso'
)
)
->setParameter(
'languageIso',
$value
);
$query1->andWhere(
$query1->expr()->orX(
't.translationDate < m.translationDate',
't.translationDate IS NULL'
)
);
$result1 = $query1->getQuery()
->getArrayResult();
The output of $query1->getQuery()->getSQL() is
SELECT
t0_.text_domain AS text_domain_0, t0_.translation_key AS translation_key_1, t0_.translation_date AS translation_date_2, t0_.translation_date AS translation_date_3, t1_.translation_date AS translation_date_4
FROM
thev1010_theverseoftheday.translations_es_google t1_
LEFT JOIN
thev1010_theverseoftheday.translations_masters t0_ ON ((t0_.text_domain = t1_.text_domain) AND (t0_.translation_key = t1_.translation_key))
WHERE
t0_.language_iso NOT LIKE ? AND (t1_.translation_date < t0_.translation_date OR t1_.translation_date IS NULL)
GROUP BY
t0_.text_domain, t0_.translation_key
ORDER BY
t0_.translation_date ASC
LIMIT 1
The ? value is 'es-Google'
The output of $query1->getQuery()->getDQL(); is
SELECT
m.textDomain , m.translationKey , m.translationDate , m.translationDate AS translationMasterDate , t.translationDate
FROM
AMDatabase\Entity\TheVerse\TranslationsEsGoogle t
LEFT JOIN
AMDatabase\Entity\TheVerse\TranslationsMasters m WITH (m.textDomain = t.textDomain) AND (m.translationKey = t.translationKey)
WHERE
m.languageIso NOT LIKE :languageIso AND (t.translationDate < m.translationDate OR t.translationDate IS NULL)
GROUP BY
m.textDomain , m.translationKey
ORDER BY
m.translationDate ASC
The ? value is 'es-Google'

How about orX expression?
You can try it this way:
$query1->andWhere(
$query1->expr()->orxX(
't.translationDate < m.translationDate',
't.translationDate IS NULL'
)
);
orX gives you the ability to add multiple conditions, separated by comma.
You can also separate your orX condition to its own variable and pass everything added to it to andWhere condition.

Related

WooCommerce Product Feeds Google merchant center

I have been trying to extract useful product feeds but there is still one attribute missing in the feed "image link"
Can anyone suggest me a tweak in the following query to make it perfect?
SELECT
`product`.`ID` AS `product_id`,
`product`.`post_title` AS `Title`,
`product`.`post_title` AS `Description`,
`product_price`.`meta_value` AS `Price`,
'no' AS `Identifier_exists`,
'Free' AS `Shipping`,
'in stock' AS `Availability`,
'new' AS `Condition`,
`product`.`guid` AS `Link`
FROM
(
(
(
`wp_posts` `product`
LEFT JOIN `wp_postmeta` `product_sku`
ON
(
(
`product`.`ID` = `product_sku`.`post_id`
)
)
)
LEFT JOIN `wp_postmeta` `product_price`
ON
(
(
`product`.`ID` = `product_price`.`post_id`
)
)
)
LEFT JOIN `wp_postmeta` `product_weight`
ON
(
(
`product`.`ID` = `product_weight`.`post_id`
)
)
)
WHERE
(
(
(`product`.`post_type` = 'product')
OR(`product`.`post_type` = 'product_variation')
) AND(`product_sku`.`meta_key` = '_sku') AND(
`product_price`.`meta_key` = '_price'
) AND(
`product_weight`.`meta_key` = '_weight'
)
)
ORDER BY
`product_id`

wpdb get_var OR get_results didn't give me the results, but I get results on phpmyadmin

Below is my code, I got a query echo by var_dump method, wpdb get_var and get_results don't give me the expected results, get_var returns NULL and get_results returns array()
when I run the generated query on phpmyadmin it gave me proper results.
below is my code
$minAge = xprofile_get_field_data(3471, bp_loggedin_user_id());
$maxAge = xprofile_get_field_data(7475, bp_loggedin_user_id());
$age_q = "SELECT GROUP_CONCAT(distinct ".$wpdb->base_prefix."bp_xprofile_data.user_id) as user_ids FROM ".$wpdb->base_prefix."bp_xprofile_data JOIN ".$wpdb->base_prefix."bp_xprofile_fields ON ".$wpdb->base_prefix."bp_xprofile_data.field_id = ".$wpdb->base_prefix."bp_xprofile_fields.id WHERE field_id =2 AND ".$wpdb->base_prefix."bp_xprofile_data.user_id !=".bp_loggedin_user_id();
$agewhere = "";
if($minAge){
$agewhere .= " AND TIMESTAMPDIFF( YEAR, STR_TO_DATE( ".$wpdb->base_prefix."bp_xprofile_data.value, '%Y-%m-%d' ) , CURDATE( ) ) >= ".$minAge;
}
if($maxAge){
$agewhere .= " AND TIMESTAMPDIFF( YEAR, STR_TO_DATE( ".$wpdb->base_prefix."bp_xprofile_data.value, '%Y-%m-%d' ) , CURDATE( ) ) <= ".$maxAge;
}
var_dump($age_q.$agewhere);
if(!empty($agewhere)){
$ageResults = $wpdb->get_var($age_q.$agewhere);
var_dump($ageResults);
}
Query Generated by var_dump function like below
"SELECT GROUP_CONCAT(distinct wp_bp_xprofile_data.user_id) as user_ids FROM wp_bp_xprofile_data JOIN wp_bp_xprofile_fields ON wp_bp_xprofile_data.field_id = wp_bp_xprofile_fields.id WHERE field_id =2 AND wp_bp_xprofile_data.user_id !=5 AND TIMESTAMPDIFF( YEAR, STR_TO_DATE( wp_bp_xprofile_data.value, '%Y-%m-%d' ) , CURDATE( ) ) >= 18 AND TIMESTAMPDIFF( YEAR, STR_TO_DATE( wp_bp_xprofile_data.value, '%Y-%m-%d' ) , CURDATE( ) ) <= 31"
anyone help me in that issue?

search with Doctrine if blank field

i have written a DQL query for my multiple search,working fine if i specify the all fields but if i keep one of the field blank it won't show me the result
$query = $em->createQuery
('SELECT d FROM EntityBundle:Doctor d WHERE d.name =:name AND d.degree =:degree AND d.area = :area_id AND d.sex = :sex AND
(
( YEAR(d.dob) BETWEEN :d2 AND :d1 ) OR
( YEAR(d.dob) BETWEEN :e2 AND :e1 ) OR
( YEAR(d.dob) BETWEEN :f2 AND :f1 )
)' )
->setParameter('name', $name)
->setParameter('degree', $degree)
->setParameter('area_id', $area)
->setParameter('sex', $sex)
->setParameter('d1', $this->p1)
->setParameter('d2', $this->p2)
->setParameter('e1', $this->q1)
->setParameter('e2', $this->q2)
->setParameter('f1', $this->r1)
->setParameter('f2', $this->r2)
->getResult();
i have tried setParameter('name', (is_null($name)? "IS NULL" : $name)) also but still there is no luck..
You can use QueryBuilder instead of DQL
$qb = $qb->select('d');
if($name !== null) {
$qb = $qb->where('d.name = :name')->setParameter(...);
}
...
$qb->getQuery()->getResult();

How to change order of commands in doctrine Criteria

So this is how I use criteria:
$criteria = Criteria::create();
$criteria->andWhere($criteria->expr()->eq('author', /**/));
$criteria->orWhere($criteria->expr()->eq('author', /**/));
$criteria->orWhere($criteria->expr()->eq('author', /**/));
which results in this sql command:
WHERE
(
(
t0.author_id = ?
OR t0.author_id = ?
)
OR t0.author_id = ?
)
What if I need this?
WHERE
(
(
t0.author_id = ?
OR t0.author_id = ?
OR t0.author_id = ?
)
)
Is there any way how I can change the association of brackets?
Try this:
$criteria = Criteria::create();
$criteria->andWhere(
$criteria->expr()->orX(
$criteria->expr()->eq('author', /**/),
$criteria->expr()->eq('author', /**/),
$criteria->expr()->eq('author', /**/)
)
);

Convert native sql query in Symfony2 query builder ( with select in join )

i have this ( huge ) sql query to convert into doctrine2 .
i already succeeded with createNativeQuery() but sometimes results don't match original one ( from mysql )
here is the query :
SELECT e1_.etapes AS etapes3, e1_.position AS position4, c0_.exercicesData_id AS Exercice_id, exo.titre as Exo, age.bornInf as ageInf, age.bornSup as ageSup, imc.bornInf as imcInf, imc.bornSup as imcSup, sexe.bornInf as sexeInf, sexe.bornSup as sexeSup
FROM ContrainteData c0_
LEFT JOIN ExerciceData e1_ ON c0_.exercicesData_id = e1_.id
LEFT JOIN Exercice exo ON e1_.exercice_id = exo.id
LEFT JOIN contraintedata_entrydata c3_ ON c0_.id = c3_.contraintedata_id
INNER JOIN (SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup) AS age ON age.type_id = 1
INNER JOIN (SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup) AS imc ON imc.type_id = 4
INNER JOIN (SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup) AS sexe ON sexe.type_id = 5
WHERE
( age.bornSup >= 30 and age.bornInf <= 30 ) and
( imc.bornSup >= 20 and imc.bornInf <= 20 ) and
( sexe.bornSup >= 1 and sexe.bornInf <= 1 ) and
e1_.entrainement_id = 6
GROUP BY etapes3, position4
ORDER BY etapes3 ASC, position4 ASC
with the queryBuilder , i have done the following :
$qb1 = $this->createQueryBuilder('c');
$qb2 = $this->createQueryBuilder('t');
$qb2->select( 't' )
->from ( 'bonk\AppBundle\Entity\EntryData', 'en' )
->groupBy( 'en.type')
->addGroupBy( 'en.bornInf' )
->addGroupBy( 'en.bornSup' );
$qb1->select( 'c' )
->leftJoin( 'c.exercicesData', 'e' )
->leftJoin( 'e.exercice' , 'ex' )
->join ( $qb2->getDql(), 'age', 'with', 'age.type = 1' )
->join ( $qb2->getQuery()->getDql(), 'imc', 'with', 'imc.type = 4' )
->join ( $qb2->getQuery()->getDql(), 'sexe', 'with', 'sexe.type = 5')
->where ( 'age.bornSup >= 30 and age.bornInf <= 30' )
->andWhere( 'imc.bornSup >= 20 and imc.bornInf <= 20' )
->andWhere( 'sexe.bornSup >= 1 and sexe.bornInf <= 1' )
->andWhere( 'e.entrainement = 6' )
->groupBy ( 'e.etapes', 'ASC' )
->addGroupBy( 'e.position', 'ASC' );
return $qb1->getQuery()->getArrayResult();
i have the following error :
"[Semantical Error] line 0, col 116 near 'SELECT t FROM': Error: Class 'SELECT' is not defined "
i finally succeed with a mysql view which is called by a fake entity in doctrine and DQL Query .
to create a view on sql , simply execute this line :
"create view VIEWNAME YOUQUERY"
in my example :
"create view entrydataView SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup"

Resources