How to get WooCommerce products from database based on multiple attributes - mysql

I want to get related products based on some criteria on product attributes like, the same sku, ean and gtin codes. But my query doesn't return any results. I tried different ways to query the database but all fail. Here is my query.
$sku = $product->get_sku();
$ean = $product->get_attribute( 'EAN' );
$gtin = $product->get_attribute( 'GTIN' );
$query = new WP_Query( array(
'post_type' => array('product'),
'posts_per_page' => 20,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_sku',
'value' => $sku,
'compare' => '='
)
),
'tax_query' => array(
array(
'taxonomy' => 'pa_ean',
'field' => 'value',
'terms' => $ean,
'operator' => '=',
),
array(
'taxonomy' => 'pa_gtin',
'field' => 'value',
'terms' => $gtin,
'operator' => '=',
)
)
) );
By the way, if a product has ean code than it doesn't have a gtin and vice versa. It always has a sku which is unique to it self. But I have it added as a check to check if query at least returns value.
I can't find good documentary on this topic and hope someone here can help.

Related

WordPress Order by using a meta_value not resulting in the correct order

There is a custom post type called guides and this has a meta post_views_count. The count is incremented each time someone visits a page of this post type. The data is being stored accurately.
Now I want to get a list of all posts ordered by the post_views_count so that I can see which article has been viewed the most.
Here is my query.
$query = new WP_Query( array(
'post_type' => 'guides',
'post_status' => 'publish',
'suppress_filters' => false,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'post_views_count',
'compare' => '>',
'value' => 0
)
),
'meta_key' => 'post_views_count',
'orderby' => 'meta_value post_date',
'order' => 'ASC',
) );
The problem is that meta_value in WordPress is stored as longtext, making it difficult to order a numeric value.
Any suggestions on how to get this working?
looks like it is sorting it as text, you will have to add 'meta_type' => 'NUMERIC', in your query so that meta_value is converted to number before sorting i guess. also try meta_value_num instead of meta_value in orderby
try
// Sort by numeric meta
'meta_key' => 'post_views_count',
'meta_type' => 'NUMERIC',
'order' => 'ASC',
'orderby' => 'meta_value_num',

Ordering by multiple ACF fields

I've seen a few questions similar to this but I still can't get things working so I thought I'd ask.
I have a Custom Post Type called 'Course'. This CPT has a custom field called 'date' which is either past, future or not set (null).
I am trying to write a query that hides the past courses, then shows future courses (ordered by date, soonest first) and then shows the courses where the date is not set (placeholder courses).
My plan was to add a 'placeholder_course' field to the course CPT and the date box would only appear if this was set to false. That way all of the placeholders would have a value of 1 for this field so I could sort by this to have them appear at then end, and then sort by the date to order the values in the date field correctly.
This is what I've been using:
<?php
$today = current_time('Ymd');
$args = array(
'post_type' => 'course',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
'placeholder' => array(
'key' => 'placeholder_course',
'compare' => '=',
'value' => '1
),
'future_dates' => array(
'key' => 'date',
'compare' => '>=',
'value' => $today,
)
),
'orderby' => array(
'placeholder' => 'ASC',
'future_dates' => 'ASC',
),
);
?>
but the ordering is still coming out muddled. I'm pretty sure I've just done something wrong in the query, can anyone shed any light please?
Set up a true/false field for your placeholder value (if no date is set you can check on it) then the following code runs through either future dates or any post with the placeholder true/false value set to true
UPDATE: your'e probably gonna have to do this with 2 queries.
$args = array(
'post_type' => 'course',
'posts_per_page' => -1,
'meta_key' => 'date',
'meta_query' => array(
array(
'key' => 'date',
'value' => $today,
'compare' => '>=',
),
),
'orderby'=> 'meta_value_num',
'order' => 'ASC'
);
$args2 = array(
'post_type' => 'course',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'placeholder_course',
'value' => true,
'compare' => '=',
),
),
'order' => 'ASC'
);

how use multiple conditions to get data from 2 HABTM tables in Cakephp 2.x

I'm trying to get only those products which have specific brand and category.
in Product model i used this query
$products = $this->find('all', array(
'joins' => array(
array('table' => 'brands_products',
'alias' => 'BrandsProducts',
'type' => 'INNER',
'conditions' => array(
'BrandsProducts.brand_id' => $brandId,
'BrandsProducts.product_id = Product.id'
)
)
),
'group' => 'Product.id'
));
By using above query i can get only those products which has specific brand id.
Exactly i don't know how to use multiple conditions to get data from 2 HABTM tables.
in my example product HABTM relation with Category and Brands.
$products = $this->find('all', array(
'joins' => array(
array('table' => 'brands_products',
'alias' => 'BrandsProducts',
'type' => 'INNER',
'conditions' => array(
'BrandsProducts.brand_id' => $brandId,
'BrandsProducts.product_id = Product.id'
)
),
array('table' => 'categories_products',
'alias' => 'CategoriesProducts',
'type' => 'INNER',
'conditions' => array(
'CategoriesProducts.category_id' => $categoriesId,
'CategoriesProducts.product_id = Product.id'
)
)
),
'group' => 'Product.id'
));
By using this query i got error in db. SO i'm looking how to write proper query to get only those products where brand and category match.

Fetch random row from group by query (mysql) in Cakephp

I have a table 'activities' and the columns are grouped by three of its attributes. Now I want to fetch Activity ID that is randomly selected from all the set of groups. The query is as follows:
$act = $this->find('all', array('conditions' => $cond,
'limit' => $limit,
'fields' => array('count(*) as count, Activity.id as id'),
'page' => $page,
'group' => $group,
));
These are the things I tried and none of them worked.
1. Create a self join which should have random records
$this->bindModel(array(
'belongsTo' => array(
'Random' => array(
'className' => 'Activity',
'order' => 'rand()',
'foreignKey' => 'id',
'fields' => 'Random.id'
)
)
));
This failed because the rand() order is appended in the end which simply randomizes all fetched activities.
Added a join option
'joins' => array(
array(
'table' => 'activities',
'alias' => 'Random',
'type' => 'LEFT',
'conditions' => array(
'Activity.id = Random.id'
),
'fields' => 'Random.id',
'order' => 'rand()'
)
This also didn't work as order value is not parsed by Cake
Tried to add condition
'Activity.id >= floor(rand() * (max(Activity.id) - min(Activity.id)) - min(Activity.id))'
Gave a mysql error
Please help me out
Assuming that your query is working:
$act = $this->find('all', array('conditions' => $cond,
'limit' => $limit,
'fields' => array('count(*) as count, Activity.id as id'),
'page' => $page,
'group' => $group,
'order' => 'rand()',
'limit' => '1' // if you only want one random activity ID
));
Ok finally figured it out. We need to hack the way cake php works. In place of table name, I wrote a query to fetch randomly ordered records. Also notice the join type is 'right'. Left join wont produce randomly sorted list
$activities = $this->find('all', array('conditions' => $cond,
'page' => $page,
'limit' => $limit,
'fields' => array('count(*) as count, Random.id as id, max(Activity.modified) as Modified'),
'group' => $group,
'order' => 'Modified desc',
'joins' => array(
array(
'table' => '(select * from activities order by rand())',
'alias' => 'Random',
'type' => 'RIGHT',
'conditions' => array(
'Activity.id = Random.id'
),
)
)
));

Cakephp: find contained associated parent_id only once

I cant get rid of some "duplicates" in this query:
$data = $this->Collection->find('first', array(
'conditions' => array('Collection.id' => $id),
'Collection' => array(
'fields' => array(
'Collection.name'
),
),
'contain' => array(
'Product' => array(
'fields' => array(
'id'
),
'order' => 'lft ASC',
),
'Product.Detail' => array(
'fields' => array(
'product_id', // should occur only once
'image_1_zoom',
'image_1_slide',
'image_1_detail',
'image_1_thumb',
),
))));
Detail belongsTo Product and Product hasMany Detail.
My problem is, that I dont want to get more than one Detail with the same product_id.
I tried 'group' with no success. DISTINCT is not possible, since the other fields have different content and are no "real" duplicates.
Any ideas greatly appreciated! :)
Try putting 'limit'=>1 in your Product.Detail array!