How to check if a product is onsale - WooCommerce - php

I'm trying to get onsale products in a custom query, anybody can help to form the query or the condition to make it happen...
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
echo '<ul class="owl-carousel">';
$products_onsale = array();
while ( $query->have_posts() ) : $query->the_post();
// get_template_part('template-parts/product-slider');
$product_id = get_the_ID();
$product = new WC_Product( $product_id );
if ( $product->is_on_sale() ) {
echo 'on sale';
}
endwhile;
echo '</ul>';
print_r( $products_onsale );
endif;
here is the working i'm working on

global $product;
if ( $product->is_on_sale() ) {
do_something();
}

I have two types of code for done this thing
<!-- Get WooCommerce On-Sale Products fetch -->
<ul class="get-onsale-product">
<?php
$args_for_onsale_product = array(
'post_type' => 'product',
'posts_per_page' => 4, //If you want all the post replace 4 with -1.
'meta_query' => array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
$onsale_product_items = new WP_Query( $args_for_onsale_product );
if ( $onsale_product_items->have_posts() ) {
while ( $onsale_product_items->have_posts() ) : $onsale_product_items->the_post();
woocommerce_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'Sorry We have no products.' );
}
wp_reset_postdata();
?>
</ul>
<!-- End WooCommerce On-Sale Products fetch -->
And second is following, Before you getting this code please review this link
<!-- Get WooCommerce On-Sale Products fetch -->
<ul class="get-onsale-product">
<?php
$args_for_onsale_product = array(
'post_type' => 'product',
'posts_per_page' => 4,
'post__in' => wc_get_product_ids_on_sale(),
);
$onsale_product_items = new WP_Query( $args_for_onsale_product );
if ( $onsale_product_items->have_posts() ) {
while ( $onsale_product_items->have_posts() ) : $onsale_product_items->the_post();
woocommerce_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'Sorry We have no products.' );
}
wp_reset_postdata();
?>
</ul>
<!-- End WooCommerce On-Sale Products fetch -->

You can use following to check if product has sale price:
$sale_price = get_post_meta( $product_id, '_sale_price', true);
If the $sale_price is greater than 0 and not empty, the product is on sale.
Hope this helps!

$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>'
)
),
);
$query = new WP_Query($args);
if ($query->have_posts()) :
echo '<ul class="owl-carousel">';
$products_onsale = array();
while ($query->have_posts()) : $query->the_post();
echo 'on sale';
endwhile;
echo '</ul>';
print_r($products_onsale);
endif;
It will fetch only products with sale price greater than zero ( onsale )

Related

Loop through the meta value of WooCommerce products using a WP Query

I am working in WooCommerce API and I would like to make a new endpoint which lists me specific products. We have made previously new fields with a plugin and I would like to check them. If the property is ticked in the settings, then show it, else do not.
The new property of the products (checkbox in advanced settings):
woocommerce_wp_checkbox(
array(
'id' => '_checkbox_badge_hot',
'desc' => __('set the checkbox', 'woocommerce'),
'label' => __('Hot', 'woocommerce'),
'desc_tip' => 'true',
'value' => get_post_meta( $post->ID, '_checkbox_badge_hot', true )
)
);
The Code which should list me the products (now if I try to request to the endpoint it just keeps loading):
function get_hot_products(){
$args_for_hot_product = array(
'post_type' => 'product',
'posts_per_page' => -1
);
$loop = new WP_Query( $args_for_hot_product );
$hotproducts = [];
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
while ( $loop->have_posts() ): $loop->the_post(){
$hot = $loop->get_meta('_checkbox_badge_hot');
if( $hot === "yes" ){
array_push($hotproducts, $hot);
}
}
//wp_reset_postdata();
return $hotproducts;
}
add_action( 'rest_api_init', function () {
register_rest_route( '/wc/v3', '/featuredproducts', array(
'methods' => 'GET',
'callback' => 'get_hot_products',
) );
} );
Thanks for your help guys!
To get and display all products that have a specific custom field value, using a WP_Query, you will simply use a eta query as follow:
function display_hot_products(){
$loop = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array( array(
'key' => '_checkbox_badge_hot',
'value' => 'yes',
'compare' => '=',
)),
));
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
the_title(); // Display product title
endwhile;
wp_reset_postdata();
endif;
}
Don't forget that when using a WP_Query you get WC_Post objects and not WC_Product Objects.

How to group woocommerce products by category in WordPress

I have at least 4 Parent Categories and each parent category has a sub-category.
The categories in WordPress looks like this:
Lidingö (Parent Category)
Direktåtkomst Förrådslänga(SubCategory)
7 kvm (product)
6 kvm (product)
Entréplan (SubCategory)
1 kbm (product)
1.5 kvm (product)
Nacka (Parent Category)
Sample(SubCategory)
aa (product)
bbb (product)
I want to query the products in WordPress and they should be grouped by categories.
This is my current code:
<?php
$args = array(
'post_type' => 'product',
array(
'taxonomy' => 'product_cat'
),
'posts_per_page' => 6,
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
echo woocommerce_template_single_title();
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
I think the code above is not correct because the same products are being displayed for every pagination.
Do you have any idea what is the correct query to group all woocommerce products by category? Thanks
First you need to overwrite this woocommerce template to your current theme as you have to use custom loop to get products by category.
Just copy that template of woocommerce to your current_theme->create folder name (Woocommerce) -> Paste template to that folder.
Use Below Code:
$parent_terms= get_terms( array( 'taxonomy' => 'product_cat', 'parent' => 0 ) );
if($parent_terms= )
{
foreach( $parent_terms as $parent_term )
{
$child_terms = get_terms( array( 'taxonomy' => 'product_cat', 'parent' => $parent_term->term_id ) );
if($child_terms)
{
foreach( $child_terms as $child_term )
{
$product_args=
array(
'posts_per_page' => 50,
'post_type' => 'my_custom_type',
'posts_per_page' => 6,
'cat' => $child_term->term_id
);
$product_query = new WP_Query( $product_args );
while($product_query->have_posts()) : $product_query->the_post();
{
Here you will get product detail so you can display product details as you wanted
}
}
}
}
}
Your query is asking for all products that belong to the product category taxonomy - that is, all of them.
You need to narrow the search by adding the category you wish to search to the arguments. For example, if you wanted to search via the category slug, you would use:
$args = array(
'post_type' => 'product',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-slug1'
),
'posts_per_page' => 6,
);
To loop through all the categories on one page, you'll want something like this:
$my_categories = get_terms( 'TERM_NAME_HERE' );
$my_categories_count = count( $my_categories );
if ( $my_categories_count > 0 && is_array( $my_categories ) ) {
echo '<div class="wrap">';
foreach ( $my_categories as $single_cat ) { ?>
<h2><?php echo $single_cat->name; ?></h2>
<?php
$cat_posts_args = array(
'post_type' => 'product',
'order' => 'ASC',
'orderby' => 'date',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $single_cat->term_id,
'include_children' => false
)
)
);
$cat_posts = new WP_Query( $cat_posts_args );
if ( $cat_posts->have_posts() ) :
echo '<p>';
while ( $cat_posts->have_posts() ) : $cat_posts->the_post(); ?>
<span><?php the_title(); ?></span>: <?php echo get_the_excerpt(); ?><br>
<?php endwhile;
echo '</p>';
else :
if ( !$parent ) echo '<p>No products found.</p>';
endif;
wp_reset_postdata();
} // end foreach
echo '</div>';
}

Woocommerce Separate Product Loops for Each Category

On the main shop page (archive-product.php) on my Woocommerce shop, I want to be able to display all the products but separate them by categories. So I would need to be able to create a loop for each product category.
For a visual reference, this is what I'm trying to achieve: for reference
Each gray block represents a new category and will loop through the products in that category.
Is there a way to achieve this?
Well as you mentioned in the comment, if you don't need any pagination, to list all products leading by their category you can first loop through the categories using get_terms() function and get whatever information you need on each iteration ( e.g: category name ), and then create one custom query per category and show the query's products, something like this will get you what you're trying to do:
<?php
foreach( get_terms( array( 'taxonomy' => 'product_cat' ) ) as $category ) :
$products_loop = new WP_Query( array(
'post_type' => 'product',
'showposts' => -1,
'tax_query' => array_merge( array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'terms' => array( $category->term_id ),
'field' => 'term_id'
)
), WC()->query->get_tax_query() ),
'meta_query' => array_merge( array(
// You can optionally add extra meta queries here
), WC()->query->get_meta_query() )
) );
?>
<h2 class="category-title"><?php echo $category->name; ?></h2>
<?php
while ( $products_loop->have_posts() ) {
$products_loop->the_post();
/**
* woocommerce_shop_loop hook.
*
* #hooked WC_Structured_Data::generate_product_data() - 10
*/
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
wp_reset_postdata(); ?>
<?php endforeach; ?>
Try this code on your page template. It will get result for Woocommerce Separate Product Loops for Each Category.
$taxonomy = 'product_cat';
$orderby = 'name';
$show_count = 0; // 1 for yes, 0 for no
$pad_counts = 0; // 1 for yes, 0 for no
$hierarchical = 1; // 1 for yes, 0 for no
$title = '';
$empty = 0;
$args = array(
'taxonomy' => $taxonomy,
'orderby' => $orderby,
'show_count' => $show_count,
'pad_counts' => $pad_counts,
'hierarchical' => $hierarchical,
'title_li' => $title,
'hide_empty' => $empty
);
$all_categories = get_categories( $args );
foreach ($all_categories as $cat) {
if($cat->category_parent == 0) {
$category_id = $cat->term_id;
echo '<br />'. $cat->name .'';
//get product
$args = array(
'post_type' => 'product',
'product_cat' => $cat->name,
'posts_per_page' => $count,
'paged' => $paged,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<span class="title"><h2> <?php the_title(); ?> </h2></span>
<?php
}
wp_reset_postdata();
}
}
}

Exclude the current product from WooCommerce custom Related Products output

The aim is to display 4 products on the product page however remove the current product from the filter. At present I am pulling through products with related brands and categories, however this is also pulling through the current product to the related products...
Current related.php file for Woocommerce contains the following:
if ( ! $related = $product->get_related( $posts_per_page ) ) {
return;
}
$brands_array = array(0);
$cats_array = array(0);
$cur_product_id = $product->id;
// get categories
$terms = wp_get_post_terms( $product->id, 'product_brand' );
$category_terms = wp_get_post_terms( $product->id, 'product_cat' );
// select only the category which doesn't have any children
foreach ( $terms as $term ) {
$brands_array[] = $term->term_id;
}
foreach ( $category_terms as $category_term ) {
$cats_array[] = $category_term->term_id;
}
$final_array = array_merge($brands_array, $cats_array);
$filtered_array = array_filter($final_array, "test_odd");
function test_odd($var)
{
return($var & 1);
}
var_dump($final_array);
$args = apply_filters( 'woocommerce_related_products_args', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => 4,
'columns' => 4,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_brand',
'field' => 'id',
'terms' => $final_array
),
)
));
$products = new WP_Query( $args );
$woocommerce_loop['name'] = 'related';
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_related_products_columns', $columns );
if ( $products->have_posts() ) : ?>
<div class="related products">
<h2><?php _e( 'Related Products', 'woocommerce' ); ?></h2>
<?php echo $filtered_array ?>
<?php woocommerce_product_loop_start();
while ( $products->have_posts() ) : $products->the_post();
wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
</div>
<?php endif;
wp_reset_postdata();
How do I go about filtering the current product from the array of products that are shown on the product page?
Thanks
To exclude current product, the missing argument in your WP_Query is 'post__not_in' (array). So your $args array is going to be:
$args = apply_filters( 'woocommerce_product_related_posts_query', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'post__not_in' => array( $product->get_id() ), // <==== HERE
'no_found_rows' => 1,
'posts_per_page' => 4,
'columns' => 4,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_brand',
'field' => 'id',
'terms' => $final_array
),
)
));
$products = new WP_Query( $args );
// . . .
See: woocommerce_product_related_posts_query replace woocommerce_related_products_args since WooCommerce 3+ (thanks to #strarsis).

wordpress query , that shows featured products

I Want show featured products but my query return nothing!
I featured one of my products but not shown any thing.
<?php
$terms = array(
"post_type" => "product",
"orderby" => "date",
"order" => "DESC",
"posts_per_page" => 12,
"meta_query" => array(array('key' => '_featured','value' => 'yes'))
);
$query = new WP_Query( $terms );
while($query->have_posts()){
$query->the_post();
global $product;
?>
Thanks Also
use short code [featured_products per_page="12" columns="4"]
or custom logic as :
$args = array(
'post_type' => 'product',
'meta_key' => '_featured',
'meta_value' => 'yes',
'posts_per_page' => 12
);
$featured_query = new WP_Query( $args );
if ($featured_query->have_posts()) :
while ($featured_query->have_posts()) :
$featured_query->the_post();
$product = get_product( $featured_query->post->ID );
// Output product information here
echo "<pre>";print_r($product);echo "</pre>";
endwhile;
endif;
wp_reset_query(); // Remember to reset
Ref here : http://biostall.com/how-to-display-woocommerce-featureds-product-without-a-shortcode/

Categories