Display sale items on shop page in WooCommerce - wordpress

I'm trying to figure out a direct link to display all sale items in the shop. URLs can usually filter out specific attributes and queries, so I was hopeful that this would be possible. So far, no luck.
My result turns up: no products found. But there are indeed products on sale.
I've tried the following:
add_filter( 'woocommerce_product_query_meta_query', 'filter_on_sale_products', 20, 1 );
function filter_on_sale_products( $meta_query ){
if( isset($_GET['onsale']) && $_GET['onsale'] ){
$meta_query[] = array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>'
);
}
return $meta_query;
}
This should return all sale items by URL: https://www.example.com/shop/?onsale=1
Any advice would be appreciated

Your code contains some very minor errors.
You can use the woocommerce_product_query action hook instead. This should suffice:
function action_woocommerce_product_query( $q ) {
if ( is_admin() ) return;
// Isset & NOT empty
if ( isset( $_GET['onsale'] ) ) {
// Equal to 1
if ( $_GET['onsale'] == 1 ) {
// Function that returns an array containing the IDs of the products that are on sale.
$product_ids_on_sale = wc_get_product_ids_on_sale();
$q->set( 'post__in', $product_ids_on_sale );
}
}
}
add_action( 'woocommerce_product_query', 'action_woocommerce_product_query', 10, 1 );

check this link out
$args = array(
'post_type' => 'product',
'posts_per_page' => 8,
'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'
)
)
);
$loop = new WP_Query( $args );

Related

Wordpress Orderby, Multiple acf meta fields + date doesnt work

I'm missing something.
Trying to filter "query_two" first in DESC so items with a date are on top.
Then i want to filter "query_one" by custom meta date.
Query_two == ACF true/false field
Query_one == ACF Date field
Doesn't matter what i do it either orders by Query_two or Query_one. Not a combi. I checked if the "date fields" are empty for the first orderby... so thats not the problem.
What am i doing wrong?
function custom_query_vars( $query ) {
if ( !is_admin() && $query->is_main_query() ) {
if ( is_post_type_archive() == 'activiteiten' ) {
$query->set( 'post_parent', 0 );
$query->set( 'posts_per_page', -1 );
$meta_query = array(
'relation' => 'OR',
'query_one' => array(
'key' => 'activi_datum',
'value' => date('Ymd'),
'type' => 'DATE',
'compare' => '>='
),
'query_two' => array(
'key' => 'activi_datumperiode',
'value' => 0,
'compare' => '='
),
);
$query->set( 'meta_query', $meta_query );
$order_by = array(
'query_two' => 'DESC',
'query_one' => 'ASC',
);
$query->set( 'orderby', $order_by );
}
}
return $query;
}

Modify products query using custom field

I need to show products on a category page using the custom field.
For example, I have custom filed 'members_access_role' (multi check) and try
add_action( 'woocommerce_product_query', 'action_product_query', 10, 2 );
function action_product_query( $q, $query ) {
$meta_query = $q->get( 'meta_query');
$q->set( 'meta_query', array( array(
'key' => 'members_access_role',
'value' => 'wholesale',
'compare' => 'IN',
) ) );
$q->set( 'meta_query', $meta_query );
}
This doesnt work, i try change compare to 'LIKE', '=' but nothing too.
Please replace function like this:
add_action( 'woocommerce_product_query', 'action_product_query', 10, 2 );
function action_product_query( $q, $query ) {
$meta_query = $q->get( 'meta_query');
$meta_query[] = array(
'key' => 'members_access_role',
'value' => 'wholesale',
'compare' => 'IN'
);
$q->set( 'meta_query', $meta_query );
}
You seems to be setting meta_query twice and the 2nd time you are setting it is exactly the same as you received using get method.
Here is one way to write it
function action_product_query( $q, $query ) {
$meta_query = $q->get( 'meta_query'); //Get the query
//Update the array.
$meta_query[] = array(
'key' => 'members_access_role',
'value' => 'wholesale',
'compare' => '=',
);
//Set the updated value below.
$q->set( 'meta_query', $meta_query );
}

How add arguments to query

i use a Toolset plugin to make view on WP and they give us possibility to manipulate with API.
I try to add argument to my view but it doesn't work.
here is the function :
add_filter( 'wpv_filter_query', 'add_city_tax', 99, 3 );
function add_city_tax( $query_args, $view_settings, $view_id )
{
if($view_id == 7706)
{
$args = array(
'tax_query' => array
(
array
(
[taxonomy] => 'ville',
[field] => 'id',
[terms] => Array
(
[0] => 220
),
[operator] => 'IN'
),
[relation] => 'OR',
),
);
}
$query_args = new WP_Query( $args );
return $query_args;
}
the page make an error
The method you are declaring args is not correct. You should not create array like that. Please check following example.
function add_city_tax( $query_args, $view_settings, $view_id ) {
if($view_id == 7706) {
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'ville',
'field' => 'id',
'terms' => array( 220 ),
'operator' => 'IN',
),
'relation' => 'OR',
),
);
}
$query_args = new WP_Query( $args );
return $query_args;
}
And here doc
Description
When displaying a View listing posts, this filter is applied to the arguments being generated by the View settings before they are passed to the WP_Query class.
Views filters - wpv_filter_query
Note that the filters that you can add to the View are also hooked here, each of them using a different priority that gets up to 100. To ensure that your filter runs after them, you would need to use a higher priority number.
Remember that the filter can take three parameters. If you pass more than one, you need to specify it in your code using the fourth argument:
1
add_filter( 'wpv_filter_query', 'my_callback_function', 99, 3 );
Arguments
array $query_args Τhe query arguments as in WP_Query.
array $view_settings The View settings.
int $view_id The View ID.
No it doesn't work like this.
i have tried like this :
function add_city_tax( $query_args, $view_settings, $view_id ) {
if($view_id == 7706) {
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'ville',
'field' => 'id',
'terms' => array( 220 ),
'operator' => 'IN',
),
'relation' => 'AND',
),
);
}
$query_args[] = $args ;
$msg = '<pre>' . print_r($query_args, true) . '</pre>';
mail('franck#efficonex.fr', 'test', $msg);
return $query_args;
}
add_filter( 'wpv_filter_query', 'add_city_tax', 99, 3 );
But it is the same result without filter.
here is the example of api
//Return only posts from the current author when listing posts of type company:
add_filter( 'wpv_filter_query', 'prefix_show_only_current_author' );
function prefix_show_only_current_author( $query_args ) {
global $current_user;
$types = (array) $query_args['post_type'];
if ( !is_admin() && in_array( 'company', $types ) ) {
$query_args['author'] = empty( $current_user->ID ) ? -1 : $current_user->ID;
}
return $query_args;
}

woocommerce - list hidden products

I am working on a project where I need to list all hidden products in a page. I have created a shortcode for that and I have used following meta query, but it's not working.
$meta_query = array(
'key' => '_visibility',
'value' => array('hidden'),
'compare' => 'IN'
);
Any idea why this is not working? Thank you in advance for your help.
$args = array(
'post_type' => 'product',
'meta_key' => '_visibility',
'meta_value' => 'hidden'
);
$query = new WP_Query($args);
Then your usual loop worked for me :)
WooCommerce 3+ visibility has been changed to a taxonomy instead of post meta and if you're using WC()->query->get_tax_query() function call for building the args, you can just remove that call from setting tax_query.
IF you don't have access to the args or how they are built and it is ran through get_tax_query you can use the filter to remove the NOT IN tax query for visibility:
add_filter( 'woocommerce_product_query_tax_query', 'smyles_show_all_products' );
// do something that calls some fn that makes product query
remove_filter( 'woocommerce_product_query_tax_query', 'smyles_show_all_products' );
function smyles_show_all_products( $tax_query ) {
foreach( (array) $tax_query as $t_index => $t_query ){
if( isset( $t_query['taxonomy'], $t_query['operator'] ) && $t_query['taxonomy'] === 'product_visibility' && $t_query['operator'] === 'NOT IN' ){
unset( $tax_query[ $t_index ] );
break;
}
}
return $tax_query;
}
Use this
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array( 'catalog', 'visible' ),
'compare' => 'IN'
)
)

WooCommerce: Display ONLY on-sale products in Shop

I need to create a products archive page (usually the Shop page in WooCommerce) but displays ONLY the ON SALE products. Basically it should use the same template layout as that in the archive-product.php. There will be a link in the main menu that will direct to this page. How do I go about this?
UPDATE
I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...
$args = array(
'post_type' => 'product',
'order' => 'ASC',
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
query_posts( $args );
The code is placed in a copy of archive-product.php which I named archive-product_sale.php and made as a page template.
However, this only works for Simple products type and I need it to work for both Simple products and Variable products type.
#mirus' answer regarding the shortcode gave me the idea to check out how WooCommerce is querying only the on-sale items. Apparently WooCommerce has a wc_get_product_ids_on_sale() function that will return the IDs of the on-sale items. Then we can easily adjust the query using the post__in parameter to only return those specific items.
WooCommerce has a woocommerce_product_query hook in the class-wc-query.php class that allows for us to modify the query before it is run.... it is run on pre_get_posts which is the usual place for modifying the query. Using Woo's hook just means you let them handle the majority of the conditional logic about when this query modification should be applied.
add_action( 'woocommerce_product_query', 'so_20990199_product_query' );
function so_20990199_product_query( $q ){
$product_ids_on_sale = wc_get_product_ids_on_sale();
$q->set( 'post__in', $product_ids_on_sale );
}
I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...
$args = array(
'post_type' => 'product',
'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'
)
)
);
query_posts( $args );
The code is placed in a copy of archive-product.php which I renamed archive-product_sale.php and made as a page template.
#gmaggio using query_posts() will break your site.
Use pre_get_posts
add_filter( 'pre_get_posts', 'catalog_filters' );
function catalog_filters( $query ) {
if ( $query->is_main_query() && $query->post_type = 'product' ) {
if(isset($_GET['onsale'])) {
$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'
)
); $query->set('meta_query', $meta_query);
}
if(isset($_GET['bestsellers'])) {
$meta_query = array(
array(
'key' => 'total_sales',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
);
}
}
return $query;
}
Create a new page using shortcode [sale_products per_page="12"]
List of available shortcodes and their parameters is here: http://docs.woothemes.com/document/woocommerce-shortcodes/
Solution for variable and simple products:
add_action( 'save_post_product', 'update_product_set_sale_cat_var' );
function update_product_set_sale_cat_var( $post_id ) {
$sales_ids = wc_get_product_ids_on_sale();
foreach ( $sales_ids as $sale_id ) :
if ($sale_id == $post_id) :
wp_set_object_terms($post_id, 'sale', 'product_cat', true );
else :
if ( has_term( 'sale', 'product_cat', $post_id ) ) {
wp_remove_object_terms( $post_id, 'sale', 'product_cat' );
}
endif;
endforeach;
}

Resources