I've included a function to show the product count in on the category overview page in WooCommerce:
add_action( 'woocommerce_before_subcategory_title', 'custom_woocommerce_subcategory_thumbnail', 10 );
function custom_woocommerce_subcategory_thumbnail( $category ) {
echo $category->count;
}
The problem is that I've for example 4 products in category a, but one of them is hidden in the catalog. So there should be a changed category count of 3 because the 4th one is hidden. But there is stillt 4 shown.
How can I exclude hidden products from the count?
You will have to use a custom WP_Query that will only return visible items. Something like this:
add_action( 'woocommerce_before_subcategory_title', 'custom_woocommerce_subcategory_thumbnail', 10 );
function custom_woocommerce_subcategory_thumbnail( $category ) {
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'product_cat' => $category->term_id,
'meta_query' => array(
array(
'key' => '_visibility',
'value' => 'hidden',
'compare' => '!=',
)
)
);
$wc_query = new WP_Query($args);
echo $wc_query->found_posts;
}
Related
My goal at the end is adding all my variations to the cart fast using only the ID list of the variations, but whatever I try I can't get to display a list of this variations on the cart page...
add_action( 'woocommerce_before_cart', 'custom_echo_product_ids' );
function custom_echo_product_ids() {
$all_ids = get_posts( array(
'post_type' => 'product',
'numberposts' => -1,
'post_status' => 'publish',
'fields' => 'ids',
) );
foreach ( $all_ids as $id ) {
echo $id->get_children() . , . ;
}
}
I'm writing some code to modify the related products section as follows:
If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category*
Or
If a product has no cross sell products, show 4 products from the same category*
Here's my function to filter the related products so far:
add_filter( 'woocommerce_related_products', 'fivem_add_linked_to_related_products', 9999, 3 );
function fivem_add_linked_to_related_products( $related_posts, $product_id, $args ) {
$product = wc_get_product( $product_id );
$cross_sell_ids = $product->get_cross_sell_ids();
$product_categories = $product->get_category_ids();
// Get cross sell products
$cross_sell_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'post__in' => $cross_sell_ids,
'posts_per_page' => 4,
'exclude' => array( $product_id ),
));
// Calculate how many filler products are needed
$category_product_count = 4 - count( $cross_sell_products );
// Exclude main product and cross sell products
$excluded_products = array_push( $cross_sell_ids, $product_id );
// Get filler products from same category
$category_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'orderby' => 'rand',
'fields' => 'ids',
'post__not_in' => $excluded_products,
'posts_per_page' => $category_product_count,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $product_categories,
'operator' => 'IN',
)
)
));
// Merge cross sell products with filler products
$related_products = array_merge( $cross_sell_products, $category_products );
// Return related products
return $related_products;
}
Currently, the above code mostly works.
If cross-sells are set, it only displays those cross-sell products- ie. does not fill out to 4 total
If no cross-sells are set, it displays products from the same category as expected.
There are two problems I'm trying to solve:
Code above doesn't fill with category products. If I remove the post__not_in and tax_query arguments, it fills out, but obviously not with products from the same category.
I want to show cross-sell products first, then the category-related products. There appears to be another randomization somewhere that mixes the order up, and I can't work out where that comes from.
Any ideas how I can fix this? Thanks in advance.
Code contains
If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category
If a product has no cross sell products, show 4 products from the same category
function filter_woocommerce_related_products( $related_posts, $product_id, $args ) {
// Taxonomy
$taxonomy = 'product_cat';
// Show products
$show_products = 4;
// Get product
$product = wc_get_product( $product_id );
// Get cross sell IDs
$cross_sell_ids = $product->get_cross_sell_ids();
// Calculate how many filler products are needed
$category_product_needed_count = $show_products - count( $cross_sell_ids );
// If category product needed
if ( $category_product_needed_count >= 1 ) {
// Retrieves product term ids for a taxonomy.
$product_cats_ids = wc_get_product_term_ids( $product_id, $taxonomy );
// Get product id(s) from a certain category, by category-id
$product_ids_from_cats_ids = get_posts( array(
'post_type' => 'product',
'numberposts' => $category_product_needed_count,
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => $product_cats_ids,
'operator' => 'IN',
)
),
));
// Merge array
$related_posts = array_merge( $cross_sell_ids, $product_ids_from_cats_ids );
} else {
// Slice array until show products
$related_posts = array_slice( $cross_sell_ids, 0, $show_products );
}
// Return
return $related_posts;
}
add_filter( 'woocommerce_related_products', 'filter_woocommerce_related_products', 10, 3 );
// Order by
function filter_woocommerce_output_related_products_args( $args ) {
$args['orderby'] = 'id';
$args['order'] = 'ASC';
return $args;
}
add_filter( 'woocommerce_output_related_products_args', 'filter_woocommerce_output_related_products_args', 10, 1 );
I'm building a woocommerce website using storefront.
On each category page, I wish to display product ordered by tag.
Each product has only one tag.
TAG 1
product a
product b
TAG 2
product x
product y
I think I can retrieve all the data I need from the DB.
But I have no clue how to use them to display my products ordered by tags.
EDITED
// GET CATEGORY ID
$currentCategory = get_queried_object();
$catSlug = $currentCategory->slug;
// GET PRODCUTS FROM CURRENT CATEGORY
$args = array(
'post_type' => 'product',
'product_cat' => $catSlug,
'orderby' => 'rand'
);
$prodLoop = new WP_Query( $args );
while ( $prodLoop->have_posts() ){
$prodLoop->the_post();
global $product;
echo the_title();
echo the_ID();
echo '</br>';
}
// GET TAGS ID
$tag_args = array(
'taxonomy' => 'product_tag',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
);
$tag_query = new WP_Term_Query($tag_args);
foreach($tag_query->get_terms() as $term){
print_r($term->term_id);
}
//GET ALL PRODUCTS ID
$prod_args = new WC_Product_Query( array(
'limit' => 5,
'order' => 'ASC',
'return' => 'ids',
));
$products = $prod_args->get_products();
foreach($products as $prod){
print_r($prod);
}
I read many things, maybe I could you a SELECT xxx query, something like a one to many realtionship query, or an usort function, but I don't know where to do... I tried many things, but by now all I got is a headache and feeling hopeless...
I've made a custom post type "product" on my Wordpress site. The detail page of a product is single-product.php which shows everything about the product perfectly.
All the product will be categorized in the following structure:
Toegangscontroles
Elektronische sloten
Wandlezers
Software
...
Overige producten
Sleutelkaarten
Kluizen
...
I have two test products on my website. Both products have the category "Electronische sloten". Which is a child category of "Toegangscontroles".
I want to show related products on single-product.php This related product cannot be the current product itself and must be under the same parent category. So in this case, a product with child category "Toegangscontroles" must show 5 random related products from the child categories from parent "Toegangscontroles".
This is my code now:
<?php
$related = get_posts( array(
'post_type' => 'product',
'category__in' => wp_get_post_categories($post->ID),
'numberposts' => 5,
'post__not_in' => array($post->ID) ) );
if( $related ) foreach( $related as $post ) {
setup_postdata($post); ?>
<?php the_title(); ?>
<?php }
wp_reset_postdata();
?>
When I go the product A, I see product B under related products, but when I go the the product B page, I don't see product A. Tough they have exactly the same category.
Thanks in advance.
Haven't tested this, but you can try
$related = get_posts( array(
'post_type' => 'product',
'tax_query' => array( array(
'taxonomy' => $taxonomy_name,
'field' => 'term_id',
'terms' => wp_get_post_terms($post->ID, $taxonomy_name, array('fields' => 'ids'))
) ),
'numberposts' => 5,
'exclude' => array($post->ID)
) );
Please use below code i think it will work.
$related = new WP_Query(
array(
'category__in' => wp_get_post_categories( $post->ID ),
'posts_per_page' => 5,
'post__not_in' => array( $post->ID )
)
);
if( $related->have_posts() ) {
while( $related->have_posts() ) {
$related->the_post(); ?>
<?php the_title(); ?>
<?php }
wp_reset_postdata();
} ?>
I want to display 8 "related products" in every product page of my site based on tags. But if there are less than 8 results fill the gaps with products in the same Categories.
Here is code that I'm using for showing only tag-related products (functions.php):
//New "Related Products" function for WooCommerce
function get_related_custom( $id, $limit = 5 ) {
global $woocommerce;
// Related products are found from category and tag
$tags_array = array(0);
$cats_array = array(0);
// Get tags
$terms = wp_get_post_terms($id, 'product_tag');
foreach ( $terms as $term ) $tags_array[] = $term->term_id;
// Get categories (removed / commented)
/*
$terms = wp_get_post_terms($id, 'product_cat');
foreach ( $terms as $term ) $cats_array[] = $term->term_id;
*/
// Don't bother if none are set
if ( sizeof($cats_array)==1 && sizeof($tags_array)==1 ) return array();
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
// Get the posts
$related_posts = get_posts( apply_filters('woocommerce_product_related_posts', array(
'orderby' => 'rand',
'posts_per_page' => $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
array(
'taxonomy' => 'product_tag',
'field' => 'id',
'terms' => $tags_array
)
)
) ) );
$related_posts = array_diff( $related_posts, array( $id ));
return $related_posts;
}
add_action('init','get_related_custom');
The function you wrote is now discontinued (see this in GitHub)
(As we can read here), you can add one of two snippets in functions.php file in wp-content/themes/theme-name/.
If you want to hide related products by tag, add this:
/**
* Does not filter related products by tag
*/
add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false' );
or add this, if you want to hide related products by category:
/**
* Does not filter related products by category
*/
add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false' );
After this, you might need to clear your transients to see a result (or wait for their expiration).
If you add both snippets (as in the other answer), your related products would be empty, because they won't be populated from tags and from categories
Open your functions.php file in wp-content/themes/your-theme-name/ and add this code at the end of the file:
/**
* Does not filter related products by tag
*/
add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false' );
/**
* Does not filter related products by category
*/
add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false' );
There is a beautiful free plugin to do exactly what you are asking: https://wordpress.org/plugins/woo-related-products-refresh-on-reload/