Woocommerce Get all product variations by category - wordpress

I need to get all Woocommerce product variations that belongs to selected category. I tried to query that this way:
$args = array(
'post_type' => 'product_variation',
'post_status' => array( 'private', 'publish' ),
'tax_query' => array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $selected_category_id
)
);
$variations = get_posts( $args );
but "tax_query" part seems to be ignored and no matter what will be provided inside, it does not affect the query.
Any ideas how to do that?

Tax Query Docs
Important Note: tax_query takes an array of tax query arguments arrays
(it takes an array of arrays). This construct allows you to query
multiple taxonomies by using the relation parameter in the first
(outer) array to describe the boolean relationship between the
taxonomy arrays.
I suggest you to use new WP_QUERY() instead get_posts() using WP_QUERY you can see query ran against your arguments via var_dump($variations->request);
$args = array(
'post_type' => 'product_variation',
'post_status' => array('private', 'publish'),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $selected_category_id
)
)
);
$variations = new WP_Query($args);
var_dump($variations->request); // dump SQL query

Related

Show related posts based on two custom taxonomies in WordPress - AND relationship issue

I have a custom post type "product", and two custom taxonomies: "productfamily" and "industry".
On my single product page, I need to show products that are in the same productfamily and industry.
Some products might be in a few different industries...and my related products section only needs to match one of the industries of the current post to show up.
Here's what I have so far...
$wp_query = new WP_Query(
array(
'posts_per_page' => '4',
'post_type' => 'product',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'productfamily',
'field' => 'slug',
'terms' => $prodfam,
'operator' => 'IN'
),
array(
'taxonomy' => 'industry',
'field' => 'term_id',
'terms' => $prodindustry,
'operator' => 'IN'
),
),
'orderby' => 'title',
'order' => 'ASC',
)
);
If I change the "AND" relation to "OR", it seems to partly work by showing products from the same "productfamily", but doesn't seem to be taking the "industry" into account at all.
How can I get this to show related products based off of my two custom taxonomies please? Thanks in advance for your help.
As you described in comment that you have slugs array in variables but in one of your tax query condition, you've used term_id to match with slug. that is incorrect.
You can directly use the terms ids instead of slugs since it's dynamic things. in function wp_get_post_terms you can pass array( 'fields' => 'ids' ) as 3rd param and it will give you array of ids. so you don't have make an extra loop.
Then you'll have to check both terms array if they both are empty of one of them or both of them as values?
then you can check them individually and then add the tax query part if ids are available.
This is how you can write the code in a clean way with proper checks:
global $post;
// Get the terms ids array,
// we can pass 'fields' => 'ids' in 3rd param so we don't need to run the loop to collect ids.
$product_family_ids = wp_get_post_terms( $post->ID, 'productfamily', array( 'fields' => 'ids' ) );
$industry_ids = wp_get_post_terms( $post->ID, 'industry', array( 'fields' => 'ids' ) );
// Prepare query args.
$query_args = array(
'posts_per_page' => '4',
'post_type' => 'product',
'orderby' => 'title',
'order' => 'ASC',
'tax_query' => array(
'relation' => 'AND',
),
);
// We need to check if both ids are not empty.
// if both empty we don't wanna run query.
if ( ! empty( $product_family_ids ) || ! empty( $industry_ids ) ) {
// If product family terms are available.
if ( ! empty( $product_family_ids ) ) {
$query_args['tax_query'][] = array(
'taxonomy' => 'productfamily',
'field' => 'term_id',
'terms' => (array) $product_family_ids,
'operator' => 'IN',
);
}
// If industry terms are available.
if ( ! empty( $industry_ids ) ) {
$query_args['tax_query'][] = array(
'taxonomy' => 'industry',
'field' => 'term_id',
'terms' => (array) $industry_ids,
'operator' => 'IN',
);
}
$related_posts = new WP_Query( $query_args );
if ( $related_posts->have_posts() ) {
while ( $related_posts->have_posts() ) {
$related_posts->the_post();
/**
* DO you thing here.
*/
}
}
wp_reset_postdata();
}
Note: I have not tested the code so there might be syntax errors, if you use the code and find errors after using the code please let me know so that I could fix errors in my answers. Also, Make sure you have site backup and FTP access to fix the errors, Don't add code from WordPress backend

WP_Query not working with tax_query and woocommerce product attribute

Im trying to make ajax filter by attributes for woocommerce.
The problem is query giving empty result, when I'm adding tax_query. This code goes in functions.php
$newquery = new WP_Query( array(
'post_type' => 'product',
'posts_per_page' => '22',
'post_status' => 'publish',
'tax_query' => array( array(
'taxonomy' => 'pa_chrisi', // Product attribute taxonomy: always start with 'pa_'
'field' => 'term_id', // Can be 'term_id', 'slug' or 'name'
'terms' => 170,
), ),
) );
I've checked the database for pa_chrisi taxonomy.
I've tried:
to init woocommerce (not sure why) before my code.
to add 'suppress_filters' => true, and 'include_children' => false,
echo $newquery->request; gives me
SELECT SQL_CALC_FOUND_ROWS dmg0j_posts.ID FROM dmg0j_posts WHERE 1=1 AND ( 0 = 1 ) AND dmg0j_posts.post_type = 'product' AND ((dmg0j_posts.post_status = 'publish')) GROUP BY dmg0j_posts.ID ORDER BY dmg0j_posts.post_date DESC LIMIT 0, 22
If I remove tax_query part it works well. Im getting all products.
Please help me!
solution:
if you are using WP_Query with tax_query in functions.php put the code inside an action with low priority:
add_action( 'init', 'maratgenius', 999 );
function maratgenius()
{
$newquery = new WP_Query( array(
'post_type' => 'product',
'posts_per_page' => '-1',
'post_status' => 'publish',
'tax_query' => array( array(
'taxonomy' => 'pa_chrisi', // Product attribute taxonomy: always start with 'pa_'
'field' => 'term_id', // Can be 'term_id', 'slug' or 'name'
'terms' => $_POST['get_what'],
), ),
) );
//other code
}
As alternative you can register WC taxonomies before query via:
\WC_Post_Types::register_taxonomies();

How to display post with two custom taxonomy in wordpress

I have a custom post type - Poems.
And I create a two taxonomy - Cities and Authors.
When I clicked on "Paris" menu item - I need to displayed all Authors and his list of poems in that city.
How to do it ?
Thanks.
You'll likely want to take a look at the Codex entry for WP Query. That gives you all the information you could want on creating custom WordPress queries. Including taxonomy arguments.
You'd want to pass to tax query arguments using the AND relation. Something along the lines of this example:
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'city',
'field' => 'slug',
'terms' => 'london',
),
array(
'taxonomy' => 'author',
'field' => 'slug',
'terms' => 'dickens',
),
),
);
$query = new WP_Query( $args );
Edit: 10/30/17 per comment below
If you were saving your author's as post meta you could order by that. But if your author is also a taxonomy it gets a little trickier since there isn't a good way to order by a taxonomy. See this related question.
Instead we could get all of our author taxonomy terms using get_terms.
$authors = get_terms( 'author', array(
'hide_empty' => false,
) );
That gives us all author terms that have at least one post assigned to them.
Now that we have the terms we could run through each author and run a query to get the poems for that author in that city. Like so:
foreach ( $authors as $author ) {
$args = array(
'post_type' => 'poem',
'tax_query' => array(
relation => 'AND',
array(
'taxonomy' => 'city',
'field' => 'slug',
'terms' => 'london',
),
array(
'taxonomy' => 'author',
'field' => 'term_id',
'terms' => $author->term_id,
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
// Put your post markup here
endwhile;
endif; wp_reset_query();
}
If you are not good with coding you can use free Content Views plugin, and combine that yyou have to combine. I started like this.

WP_Query Woocommerce products that belong in distinct multiple categories only tax_query

I'm using WP_Query for Woocommerce products in attempt to query products in a particular category. This is the syntax that worked for me -
$args = array(
'posts_per_page' => -1,
'product_cat' => 'category-slug-here',
'post_type' => 'product',
'orderby' => 'title',
);
$the_query = new WP_Query( $args );
// The Loop
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '' . get_the_title() . '<br /><br />';
}
wp_reset_postdata();
This returns data, but I want to pass an ID, not a category slug, to filter and I want to find products that exist in multiple categories only.
The argument product_cat is not native to WP_Query (at least that I can find), so I'm assuming this is something custom to Woocommerce. Through their documentation, I haven't been able to find anything that will allow me to filter by category ID, nor use an AND condition for this filtering.
Using cat, the array of tax_query, and category__and have not yielded any results. Essentially, I would like to query all products that exist in both category ID 102, and 115. If I have to use slugs, I'm sure there is a way around getting that info based on the ID I have, but I'd like to avoid 2 queries to filter by multiple categories.
Does anyone know how to accomplish this?
UPDATE: I have learned that separating category slugs by commas in the product_cat argument will produce an "OR" effect, so it will combine distinct products from both, but this is not what I am looking for. So, for example:
'product_cat' => 'category-slug1, category-slug2'
will return products from both categories in total, but I am still searching for a way to find distinct products that ONLY belong to both, or multiple, categories.
Wow, so after hours of banging my head, this is how I was able to solve this -
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-slug1'
),
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-slug2'
)
),
'post_type' => 'product',
'orderby' => 'title',
);
$the_query = new WP_Query( $args );
This takes advantage of the tax_query argument, including the relation => 'AND' to make sure the product falls under BOTH categories.
Hope this helps someone in the future.
I was also not able to figure out how to pass an ID, rather than a slug (although I'm sure there's a way), but here's the function to retrieve the slug based on an ID:
$terms = get_term($YOURID, 'product_cat');
$theslug = $terms->slug;
From the WordPress codex on WP_Query for Category Parameters:
equivalent of OR
$args = array( 'product_cat' => 'category-slug1,category-slug2' );
equivalent of AND
$args = array( 'product_cat' => 'category-slug1+category-slug2' );
e.g.
$query = new WP_Query( $args );
To query by category_ID this is what worked for me.
// First obtain term id:
//...
$all_categories = get_categories( $args );
$cat_ids = array();
foreach ($all_categories as $cat)
{
array_push($cat_ids, $cat->term_id);
}
//Now use ids from array:
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cat_ids
)
)
);
Inside a 'tax_query' array's array you can specify an 'operator' to be performed on the query. You can achieve what you want using the 'AND' operator.
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'category-slug1', 'category-slug2' )
'operator => 'AND',
),
),
'post_type' => 'product',
'orderby' => 'title',
);
$the_query = new WP_Query( $args );
All of the products selected by this query will match the provided 'terms'. See this link for more info: https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
In case the link ever breaks, here's the relevant info:
operator (string) - Operator to test. Possible values are 'IN', 'NOT IN', 'AND', 'EXISTS' and 'NOT EXISTS'. Default value is 'IN'.

Get multiple posts by multiple slugs

I have an array with multiple slugs (post names) and I want to get all posts where the slug is in the array.
I use Event Organsier and want to get all events these slugs. I haven't worked with WordPress for a couple of years so I need some help.
$events = eo_get_events(array(
'numberposts'=>5,
'event_start_after'=> $year.'-'.$month.'-'.$list_day,
'event_end_before'=> $year.'-'.$month.'-'.$list_day,
'showpastevents'=>false,//Will be deprecated, but set it to true to play it safe.
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array('slug-example-1', 'slug-example-2'),
'operator' => 'IN'
)
)
));
This should (imo) return all posts that has a slug that is slug-example-1 or slug-example-2.
I don't even know if tax_query/taxonomy is the right thing to use.
You can use the post_name__in argument in conjunction with get_posts(), it's available since Version 4.4.
E.g. :
$args = [
'post_name__in' => [ 'slug-1', 'slug-2' ],
'post_type' => 'page',
'post_status' => 'publish',
];
$result = get_posts( $args );

Resources