pre_get_posts with meta_query effects static pages in WooCommerce - php

I used a big part of this code to add a meta_query in the WooCommerce product query. I don't get any errors, but the products are NOT getting filtered by the meta. It still shows all products.
function yl_custom_product_query( $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;
}
global $product;
$blog_id = get_current_blog_id();
if ($blog_id == '1') {
$subsite = '_visibility_3rdmillennium';
} elseif ($blog_id == '2') {
$subsite = '_visibility_fight2win';
} elseif ($blog_id == '3') {
$subsite = '_visibility_muaythai';
} elseif ($blog_id == '4') {
$subsite = '_visibility_taekwondo';
} elseif ($blog_id == '5') {
$subsite = '_visibility_xprtfightgear';
} elseif ($blog_id == '6') {
$subsite = '_visibility_hayabusashop';
} elseif ($blog_id == '7') {
$subsite = '_visibility_kmushop';
}
$meta_query = array();
// add meta_query elements
if ( !empty( get_query_var( $subsite ) ) ) {
$meta_query[] = array( 'key' => $subsite, 'value' => get_query_var( 'yes' ), 'compare' => 'LIKE' );
}
// unused meta_query for now
if ( !empty( get_query_var( 'key2' ) ) ) {
$meta_query[] = array( 'key' => 'key2', 'value' => get_query_var( 'key2' ), 'compare' => 'LIKE' );
}
if ( count( $meta_query ) > 1 ) {
$meta_query['relation'] = 'AND';
}
if ( count( $meta_query ) > 0 ) {
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'yl_custom_product_query' );
But, when I change:
// add meta_query elements
if ( !empty( get_query_var( $subsite ) ) ) {
$meta_query[] = array( 'key' => $subsite, 'value' => get_query_var( 'yes' ), 'compare' => 'LIKE' );
}
to
// add meta_query elements
if ( !empty( $subsite ) ) {
$meta_query[] = array( 'key' => $subsite, 'value' => 'yes', 'compare' => 'LIKE' );
}
(so removing get_query_var twice) the meta_query works great but all static pages suddenly become unreachable...
What am I missing here?

Related

Search multiple products by custom field in WooCommerce Admin

Using the answer from search multiple sku's on woocommerce admin side I adapted my code to replace $sku with the value of the custom field within my product, which is $winner.
When I search by separating product custom fields with a delimiter, it does not work. How can I edit my code so I can search products multiple by custom field?
function woo_multiple_title_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;
$names = explode('|',$search_term);
$meta_query = array(
'relation' => 'OR'
);
if(is_array($winners) && $winners) {
foreach($winners as $winner) {
$meta_query[] = array(
'key' => '_winner',
'value' => $winner,
'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_title_search', 20 );

Relating Wordpress Users with Order Export

We are using Advanced Custom Fields, WP All Export Pro, and WordPress with Woocommerce.
I have an ACF field created for our accountant in users area of WordPress called "traverse_customer_id". This is for her to know what customer this order is for.
I have this ACF field showing in the orders export but the data comes back blank on each export. I think it's because I'm not relating the order with the customer or user ID. I've attempted to use a code snippet from WP All Exports' support without any luck. Could anyone with knowledge help me see what I'm doing wrong?
This is what I have in the "Custom export field" area: (I think this is running the function on each line of the import.)
[sf_helper_meta_query_lookup("traverse_customer_id",{Customer User ID},"user")]
Then I have this below in the Function Editor:
function sf_helper_meta_query_lookup( $meta_key = '', $meta_value = '', $object_type = 'post', $taxonomy = '', $return_field = 'ID', $compare = '=', $custom_args = array() ) {
if ( empty( $object_type ) || empty( $meta_key ) || empty( $meta_value ) ) return;
$func = 'get_posts';
switch ( $object_type ) {
case 'user':
$func = 'get_users';
break;
case 'term':
$func = 'get_terms';
if ( $return_field == 'ID' ) {
$return_field = 'term_id';
}
break;
default:
$func = 'get_posts';
break;
}
if ( ! empty( $custom_args ) ) {
$objects = $func( $custom_args );
if ( ! empty( $objects ) ) {
return $objects[0]->$return_field;
} else {
return false;
}
}
$args = array();
$meta_query = array( array(
'key' => $meta_key,
'value' => $meta_value,
'compare' => $compare
) );
if ( $func == 'get_terms' ) {
$args = array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'meta_query' => $meta_query
);
} elseif ( $func == 'get_users' ) {
$args = array(
'meta_query' => $meta_query
);
} else {
$args = array(
'post_type' => $object_type,
'meta_query' => $meta_query
);
}
if ( $objects = $func( $args ) ) {
return $objects[0]->$return_field;
} else {
return false;
}
}
Any help would be greatly appreciated!

URL Query to filter WooCommerce products by ACF checkbox values?

I need to be able to filter WooCommerce products according to the values from an ACF field with a series of checkboxes e.g. Apples, Bananas, Grapes etc. Ideally I'd like to be able to do this with a URL query e.g. https://example.com/shop/?fruit=apples
I've been trying something along these lines with no success:
function product_initial_filter( $query ) {
if( !is_admin() ) {
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'product' ) {
if( isset($GET['fruit']) ) {
$query->set('meta_value', $GET['fruit']);
$query->set('meta_key', 'fruits');
$query->set('meta_compare', 'IN');
}
}
}
// return
return $query;
}
add_action('pre_get_posts', 'product_initial_filter');
You can pass meta argument in meta_query. and also if you are 'compare' => 'IN', the value must be an array. check the below code.
Using WP pre_get_posts action hook.
function product_initial_filter( $query ) {
if( !is_admin() && $q->is_main_query() ) {
if( $query->get('post_type') == 'product' && isset( $GET['fruit'] ) && $GET['fruit'] != '' ) {
$meta_query = array(
array(
'key' => 'fruits',
'value' => array( $GET['fruit'] ),
'compare' => 'IN',
),
);
$query->set( 'meta_query', $meta_query );
}
}
}
add_action('pre_get_posts', 'product_initial_filter');
OR
Using WC woocommerce_product_query action hook.
function product_initial_filter( $query ) {
if( !is_admin() && $q->is_main_query() ) {
if( $query->get('post_type') == 'product' && isset( $GET['fruit'] ) && $GET['fruit'] != '' ) {
$meta_query = array(
array(
'key' => 'fruits',
'value' => array( $GET['fruit'] ),
'compare' => 'IN',
),
);
$query->set( 'meta_query', $meta_query );
}
}
}
add_action('woocommerce_product_query', 'product_initial_filter');
USEFUL LINKS.
pre_get_posts
woocommerce_product_query
meta_query

WooCommerce filter admin order list based on added custom header field

In WooCommerce, I have added a new custom column 'Language' in my admin order list with custom values 'Japanese' or 'Non Japanese'.
How should I add filter option for Japanese language and Non Japanese language.
I added a filter drop down using below code:
add_action( 'restrict_manage_posts', 'wpse45436_admin_posts_filter_restrict_manage_posts' );
function wpse45436_admin_posts_filter_restrict_manage_posts(){
global $post_type;
if( $post_type == 'shop_order' ) {
//change this to the list of values you want to show
//in 'label' => 'value' format
$values = array(
'Japanese' => 'Japanese',
'Non Japanese' => 'Non Japanese',
);
?>
<select name="ADMIN_FILTER_FIELD_VALUE">
<option value=""><?php _e('Filter By ', 'wose45436'); ?></option>
<?php
$current_v = isset($_GET['ADMIN_FILTER_FIELD_VALUE'])? $_GET['ADMIN_FILTER_FIELD_VALUE']:'';
foreach ($values as $label => $value) {
printf (
'<option value="%s"%s>%s</option>',
$value,
$value == $current_v? ' selected="selected"':'',
$label
);
}
?>
</select>
<?php
}
}
I also added some code for filtering order list but its not working, here is my code:
add_action( 'pre_get_posts', 'apply_my_custom_product_filters' );
function apply_my_custom_product_filters( $query ) {
global $pagenow;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if ( $query->is_admin && $pagenow == 'edit.php' && isset( $_GET['ADMIN_FILTER_FIELD_VALUE'] ) && $_GET['ADMIN_FILTER_FIELD_VALUE'] != '' && $_GET['post_type'] == 'shop_order' ) {
$meta_key_query = array(
array(
'meta_key' => 'order_add_language',
'value' => esc_attr( $_GET['ADMIN_FILTER_FIELD_VALUE'] ),
'compare' => '=',
),
'posts_per_page' => 10,
'paged' => $paged,
);
$query->set( 'meta_query', $meta_key_query );
}
}
There is some errors in your codeā€¦ Try the following revisited code:
add_action( 'restrict_manage_posts', 'display_admin_shop_order_language_filter' );
function display_admin_shop_order_language_filter(){
global $pagenow, $post_type;
if( 'shop_order' === $post_type && 'edit.php' === $pagenow ) {
$domain = 'woocommerce';
$languages = array( __('Japanese', $domain), __('Non Japanese', $domain) );
$current = isset($_GET['filter_shop_order_language'])? $_GET['filter_shop_order_language'] : '';
echo '<select name="filter_shop_order_language">
<option value="">' . __('Filter By ', $domain) . '</option>';
foreach ( $languages as $value ) {
printf( '<option value="%s"%s>%s</option>', $value,
$value === $current ? '" selected="selected"' : '', $value );
}
echo '</select>';
}
}
add_action( 'pre_get_posts', 'process_admin_shop_order_language_filter' );
function process_admin_shop_order_language_filter( $query ) {
global $pagenow;
if ( $query->is_admin && $pagenow == 'edit.php' && isset( $_GET['filter_shop_order_language'] )
&& $_GET['filter_shop_order_language'] != '' && $_GET['post_type'] == 'shop_order' ) {
$meta_query = $query->get( 'meta_query' ); // Get the current "meta query"
$meta_query[] = array( // Add to "meta query"
'meta_key' => 'order_add_language',
'value' => esc_attr( $_GET['filter_shop_order_language'] ),
);
$query->set( 'meta_query', $meta_query ); // Set the new "meta query"
$query->set( 'posts_per_page', 10 ); // Set "posts per page"
$query->set( 'paged', ( get_query_var('paged') ? get_query_var('paged') : 1 ) ); // Set "paged"
}
}
Code goes in function.php file of your active child theme (or active theme). It should works.
This is wrong in your meta_key_query.You can try this code.
add_action( 'pre_get_posts', 'apply_my_custom_product_filters' );
function apply_my_custom_product_filters( $query ) {
global $pagenow;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if ( $query->is_admin && $pagenow == 'edit.php' && isset( $_GET['ADMIN_FILTER_FIELD_VALUE'] ) && $_GET['ADMIN_FILTER_FIELD_VALUE'] != '' && $_GET['post_type'] == 'shop_order' ) {
$meta_key_query = array(
array(
'meta_key' => 'order_add_language',
'value' => esc_attr( $_GET['ADMIN_FILTER_FIELD_VALUE'] ),
)
);
$query->set( 'meta_query', $meta_key_query );
}
}

Exclude conditionally a meta key from meta_query

I have in the Wordpress functions.php the next code that changes the main_query when posts are sorted using a form. The question is: how to exclude from the main_query the second array of the meta_query when the $country variable is empty?
if ( $query->is_main_query() && ( $orderby || $order || $country ) ) {
if ( in_array( $orderby, array( 'event_start_date' ) ) ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', $order );
$query->set( 'meta_query', array( // WordPress has all the results, now, return only the events after today's date
array(
'key' => 'event_start_date', // Check the start date field
'value' => date_i18n("Y-m-d"), // Set today's date (note the similar format)
'compare' => '>=', // Return the ones greater than or equal to today's date
'type' => 'DATE' // Let WordPress know we're working with date
),
array(
'key' => 'venue_country',
'value' => $country,
)
) );
}
}
UPDATE
A suggestion how to solve this I found here.
The problem was solved in this way:
if ( $query->is_main_query() && ( $orderby || $order || $country ) ) {
if ( in_array( $orderby, array( 'event_start_date' ) ) ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', $order );
if( !empty( $_GET['country'] ) ) {
$query->set( 'meta_query', $metaquery1 );
} else {
$query->set( 'meta_query', $metaquery2 );
}
}
}

Categories