How to change order of commands in doctrine Criteria - symfony

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', /**/)
)
);

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`

How filter woocommerce products by min and max values of attribute?

The products have the attribute Tempo. This is a text field in which to enter the number.
How to sort products by the minimum and maximum attribute value?
using such url ?filtering=1&filter_min-tempo=100&filter_max-tempo=150
Is it possible to create an attribute of type integer?
All attributes are stored as text, but you can cast them to the type you need.
Look at this code:
function isequal($v1,$v2) {
return intval($v1) == intval($v2);
}
function filter_loop_shop_post_in( $array ) {
if ( !array_key_exists('min_tempo',$_GET) && !array_key_exists('max_tempo',$_GET) ) return $array;
global $wpdb;
$min = isset( $_GET['min_tempo'] ) ? floatval( $_GET['min_tempo'] ) : 0;
$max = isset( $_GET['max_tempo'] ) ? floatval( $_GET['max_tempo'] ) : 9999999999;
$query = "
SELECT DISTINCT
tr.object_id
FROM
{$wpdb->term_relationships} AS tr
LEFT JOIN
{$wpdb->term_taxonomy} AS tt
ON
tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN
{$wpdb->terms} AS t
ON
tt.term_id = t.term_id
WHERE
tt.`taxonomy` = 'pa_tempo' AND CAST(t.name AS DECIMAL(10, 1)) BETWEEN $min AND $max";
$raw_results = $wpdb->get_results( $query );
if (!sizeof($raw_results)) return $array;
$results = array();
foreach ($raw_results as $res) {
$results[] = intval($res->object_id);
}
if (!sizeof($array)) return $results;
return array_uintersect($results, $array, 'isequal');
};
add_filter( 'loop_shop_post_in', 'filter_loop_shop_post_in', 10, 1 );
It works for me in WooCommerce 2.6.14.

how to make this in doctrine2

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.

ZF2 Doctrine with Symfony < OR null query

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.

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();

Resources