Modifying WP_Query to order by total_sales meta_key - wordpress

I'm trying to update the sorting of search results in wordpress / woocommerce
so, when there is a search as: mydomain.com/?s=cases&post_type=product
The results get sorted by the 'total_sale' meta_key
I have the following hook
function sv_update_default_search_to_sales( $query ){
// check if the user is requesting an admin page
// or current query is not the main query
if ( is_admin() || ! $query->is_main_query() ){
return;
}
// Query Update for Search Results pages with products
if (is_search() && is_woocommerce() ){
if(get_query_var('post_type') != 'product'){
return;
}
$orderBy = get_query_var('orderby');
if(empty($orderBy) || $orderBy == 'relevance'){
$query->set('orderby', 'meta_value_num');
$query->set('order', 'desc');
$query->set('meta_key', 'total_sales');
$query->set('meta_type', 'NUMERIC');
}
}
}
add_action( 'pre_get_posts', 'sv_update_default_search_to_sales', 1 );
When I output $wp_query after the query has been parsed, i can see the 'meta_key' has been set to blank.
[meta_key] =>
[orderby] => meta_value_num
[order] => DESC
[meta_type] => NUMERIC
I've seen on other codes examples where they set meta_key and meta_value for matching; however, i don't have a set value, i need to order the results by 'total_sales' meta key.
Im basically trying to recreate this type of query call:
$query = new WP_Query([
'post_type' => 'product',
'meta_key' => 'total_sales',
'orderby' => 'meta_value_num'
]);

OK, so after further debugging. I realized there were other plugins modifying the query that were set to fire after my action.
I don't know which plugin specifically was modifying it, but after the page is rendered I printed the filter with
global $wp_filter;
echo '<pre>';
print_r($wp_filter['pre_get_posts']);
echo '</pre>';
Figured outthe action number: 90000 was the last action hooked, so I set mines to 90001
add_action( 'pre_get_posts', 'sv_update_default_search_to_sales', 900001 );
and it worked! x)

Related

WooCommerce product filter for an attribute in the backend

I want to have a filter for an attribute "brand" in the WooCommerce products section in the backend.
I am using the following code:
function custom_woocommerce_product_filters( $output ) {
global $wp_query;
$output .= wc_product_dropdown_categories(
array(
'show_option_none' => 'Filter by brand',
'taxonomy' => 'pa_brand',
'name' => 'pa_brand',
'selected' => isset( $wp_query->query_vars['pa_brand'] ) ? $wp_query->query_vars['pa_brand'] : ''
)
);
return $output;
}
add_filter( 'woocommerce_product_filters', 'custom_woocommerce_product_filters' );
This code displays the dropdown list for the filter with all brands inside it, but clicking on "Filter" does not return the filtered products. It simply shows all the products.
Can someone help please?
Thanks
I recently discovered that you have to actually filter the results using the pre_get_posts() filter, having the dropdown alone is not enough. What I was able to come up with after searching similar questions on stackoverflow:
// Filter woocommerce admin products by artist
function apply_artist_custom_product_filters( $query ) {
global $pagenow;
// Ensure it is an edit.php admin page, the filter exists and has a value, and that it's the products page
if ( $query->is_admin && $pagenow == 'edit.php' && isset( $_GET['pa_artist'] ) && $_GET['pa_artist'] != '' && $_GET['post_type'] == 'product' ) {
// Create meta query array and add to WP_Query
$meta_key_query = array(
array(
'taxonomy' => 'pa_artist',
'field' => 'slug',
'terms' => esc_attr( $_GET['pa_artist'] ),
'operator' => 'IN',
)
);
$query->set( 'tax_query', $meta_key_query );
}
}
add_action( 'pre_get_posts', 'apply_artist_custom_product_filters' );
The snippet that did most of the work is found here:WooCommerce: Adding a custom filter to the Product Admin area. I only changed the meta query to be a tax query. Not sure if it's the best way to do it, but it works for me. What I can't figure out is the "selected" part of the wc_product_dropdown_categories, for me when I select an artist and hit filter, the filter works but it doesn't save the selection.

WordPress: pre_get_posts action combine date_query and meta_query

In my WordPress project, I have gotten some problem.
I have many categories. The categories have a child category name New product.
Currently, I have used pre_get_posts to get the posts list in New product pages. If a post which have post_date > 2018/1/15 will be get in the category pages.
I want to add a custom checkbox keep_product in product which will keep product in New product page if post_date < 2018/1/15 when it checked.
So I think the conditions should be post_date > 2018/1/15** OR **keep_product = 1
I try to create a query, but it seem WP_Query only apply AND condition for date_query and meta_query.
function pre_get_posts_function($q){
//Code in here
$query->set('date_query', array(
array(
'after' => '2018/1/15'
);
));
$query->set('meta_query', array(
array(
'key' => 'keep_product',
'value' => '1'
)
));
}
I also try to create a posts_where action, but It ignores category condition. The product which is checked keep_after_60_days checkbox will be show in New product pages.
function pre_get_posts_function($q){
//Code in here
$query->set('date_query', array(
array(
'after' => '2018/1/15'
);
));
add_filter( 'posts_where', 'postmeta_new_releases',10,1);
}
function postmeta_new_releases( $where = '' ) {
global $wpdb;
$where .= " OR ($wpdb->postmeta.meta_key = 'keep_product' AND $wpdb->postmeta.meta_value = 1)";
return $where;
}
Could anyone help me. I get mad with it in some days.
Thanks!!

search multiple sku's on woocommerce admin side

This sounds simple but if you have hundreds of products and need to search multiple sku's on woocommerce admin side is not available.
Lets say you need to verify 600 products, you have to:
manually add one sku to search bar
click search
get results
start again
you can't separate by , or by space, or dash.
I searched and no one have an answer or they are questions made are not answered.
How can people search multiple sku's, or products names on woocommerce admin side?
First.. you mention you have to verify many products (600), needing a multiple sku search. It looks to me you're going to do this manually?
I recommend creating a product loop in PHP where you do your verify stuff. This is probably gonna save you alot off time, and you can re-use it.
Now to the problem... Search woo products using multiple sku's.
I agree many info on the internet is kinda misleading. I've done this before, and i always used the pre_get_posts hook to change the WP (search) query before it runs.
After testing it appears the query is not being setup as a search, and the search value is empty...
So woocommerce has to do a custom search query. Luckily i quickly found mircian's post.
WooCommerce uses a Data Store for its post types ( products, orders, etc ) and the search is also done using a custom function. In this case it’s called ‘search_products’ and it does a custom query which basically returns an array of ids to be used for the results.
I modified his function to search with multiple sku's.
Insert the function in your (child) theme's functions.php.
Use '|' as a SKU delimiter. Example: '1234|1235|1236'
Tested on:
Wordpress 4.9.6
Woocommerce 3.3.5
/**
* Use multiple sku's to find WOO products in wp-admin
* NOTE: Use '|' as a sku delimiter in your search query. Example: '1234|1235|1236'
**/
function woo_multiple_sku_search( $query_vars ) {
global $typenow;
global $wpdb;
global $pagenow;
if ( 'product' === $typenow && isset( $_GET['s'] ) && 'edit.php' === $pagenow ) {
$search_term = esc_sql( sanitize_text_field( $_GET['s'] ) );
if (strpos($search_term, '|') == false) return $query_vars;
$skus = explode('|',$search_term);
$meta_query = array(
'relation' => 'OR'
);
if(is_array($skus) && $skus) {
foreach($skus as $sku) {
$meta_query[] = array(
'key' => '_sku',
'value' => $sku,
'compare' => '='
);
}
}
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => $meta_query
);
$posts = get_posts( $args );
if ( ! $posts ) return $query_vars;
foreach($posts as $post){
$query_vars['post__in'][] = $post->ID;
}
}
return $query_vars;
}
add_filter( 'request', 'woo_multiple_sku_search', 20 );

Change publish date from meta date when publish post

When the post is publish, I want the publish date as the same as the date in the meta data, imic_sermon_date.
Here's my code. The problem is that it get stuck when publishing a post.
function update_sermon_date ($post_id) {
//automatically change publish date to sermon date when publish/save a postfunction update_sermon_date ($post_id) {
$sermon_date = get_post_meta($post_id, 'imic_sermon_date', true);
$mypost = array (
'ID' => $post_id,
'post_date' => $sermon_date);
wp_update_post( $mypost );
}
add_action ('save_post', 'update_sermon_date');
Can someone help me with this?
Thanks.
After searching online, I've fixed my code.
The code basically will only update when the post is edited. I added remove_action and add_action in order to prevent the code from running an endless loop.
****//automatically change publish date to sermon date when publish/save a post
function update_sermon_date () {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if ( !current_user_can('edit_post', $post_id) )
return;
$sermon_date = get_post_meta(get_the_ID(), 'imic_sermon_date', true);
$mypost = array (
'ID' => get_the_ID(),
'post_title' => $sermon_date,
'post_date' => $sermon_date,
'post_date_gmt' => $sermon_date);
if ( ! (wp_is_post_revision($post_id) || wp_is_post_autosave ( $post_id) ) ) {
remove_action('edit_post','update_sermon_date');
wp_update_post( $mypost );
add_action ('edit_post', 'update_sermon_date');
}
}
add_action ('edit_post', 'update_sermon_date');****

wordpress $query->set by meta key value

I am trying to modify all queries of a post type "products" to only show if the product/post has a certain meta_key of "wholesale_price" which the meta_value needs to be greater than 0.
Here is what i have:
add_action( 'pre_get_posts', 'rc_modify_query_get_design_projects' );
function rc_modify_query_get_design_projects( $query ) {
if($query->is_main_query() && $query->query_vars['post_type'] == 'product' ) {
$query->set('meta_key', 'wholesale_price');
$query->set('meta_compare', '>');
$query->set('meta_value', '0');
}
}
For some reason this still returns everything. Is this the right way of doing things?
The problem is the method by which you are setting your meta_query. You should read up on the WP_Query functionality, because meta queries are unfortunately not that simple.
You need to do something more like so:
add_action( 'pre_get_posts', 'rc_modify_query_get_design_projects' );
function rc_modify_query_get_design_projects( $query ) {
// Do not add meta arguments in admin pages
if (is_admin()) {
return;
}
if($query->is_main_query() && $query->query_vars['post_type'] == 'product' ) {
//Get original meta query
$meta_query = (array)$query->get('meta_query');
// Add your criteria
$meta_query[] = array(
'key' => 'wholesale_price',
'value' => 0,
'compare' => '>',
);
// Set the meta query to the complete, altered query
$query->set('meta_query',$meta_query);
}
And no need to return anything in this function.

Resources