I am creating advance woocommerce search and I want to add sku and product_tag and product_category in search query. Below I am using Enable custom taxonomies in WooCommerce product search answer code, that enable search for multiple taxonomies:
add_filter( 'posts_search', 'woocommerce_search_product_tag_extended', 999, 2 );
function woocommerce_search_product_tag_extended( $search, $query ) {
global $wpdb, $wp;
$qvars = $wp->query_vars;
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
return $search;
}
// Here set your custom taxonomies in the array
$taxonomies = array('product_tag', 'product_cat');
$tax_query = array('relation' => 'OR'); // Initializing tax query
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => esc_attr($qvars['s']),
);
}
// Get the product Ids
$ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => $tax_query,
) );
if ( sizeof( $ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search);
}
return $search;
}
I want to add product sku too in search query, how to add it ?
The following will extend Product search to multiple taxonomies (Product Category and Product tag) and multiple custom fields (as SKU here):
add_filter( 'posts_search', 'woocommerce_search_product_mega_extended', 999, 2 );
function woocommerce_search_product_mega_extended( $search, $query ) {
global $wpdb, $wp;
$qvars = $wp->query_vars;
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
return $search;
}
// SETTINGS:
$taxonomies = array('product_tag', 'product_cat'); // Here set your custom taxonomies in the array
$meta_keys = array('_sku'); // Here set your product meta key(s) in the array
// Initializing tax query
$tax_query = count($taxonomies) > 1 ? array('relation' => 'OR') : array();
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => esc_attr($qvars['s']),
);
}
// Get the product Ids from taxonomy(ies)
$tax_query_ids = (array) get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => $tax_query,
) );
// Initializing meta query
$meta_query = count($meta_keys) > 1 ? array('relation' => 'OR') : array();
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$meta_query[] = array(
'key' => '_sku',
'value' => esc_attr($qvars['s']),
);
}
// Get the product Ids from custom field(s)
$meta_query_ids = (array) get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'meta_query' => $meta_query,
) );
$product_ids = array_unique( array_merge( $tax_query_ids, $meta_query_ids ) ); // Merge Ids in one array with unique Ids
if ( sizeof( $product_ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $product_ids ) . ")) OR (", $search);
}
return $search;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related: Enable custom taxonomies in WooCommerce product search
Related
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 );
I've offert the possibility to my client to choose one by one the related post for each post. I've set up a custom field with ACF and use this to display the choosen posts or random posts :
<?php $terms = get_the_terms( $post->ID , 'custom-taxonomy1' ); if ( !empty( $terms ) ) :?>
<?php
$related_acf = get_field('related_group');
$rel_posts = $related_acf["related posts"];
$related_ids = array();
foreach ( $rel_posts as $rel_post) {
array_push($related_ids, $rel_post['post']);
}
global $post;
$current_post_type = get_post_type( $post );
$terms = get_the_terms( $post->ID , 'custom-taxonomy1' );
$term_ids = array_values( wp_list_pluck( $terms,'term_id' ) );
$post_count_skrn = get_theme_mod('progression_studios_media_more_like_post_count', '3');
if ( count($related_ids) > 0 ) {
$args=array(
'post_type' => array('custompost1', 'custompost2', 'post'),
'post__in' => $related_ids
);
} else {
$args=array(
'post_type' => $current_post_type,
'posts_per_page'=> $post_count_skrn,
'orderby'=>'rand', // Randomize the posts
'post__not_in' => array( $post->ID ),
'tax_query' => array(
array(
'taxonomy' => 'video-genres',
'terms' => $term_ids,
'field' => 'id',
'operator' => 'IN'
)
),
);
}
So I wonder if I can add something like :
if ( count($related_ids) > 0 ) {
$args=array(
'post_type' => array('custompost1', 'custompost2', 'post'),
'orderby'=>'XXXXX', // Ordering the posts with the order of selection
'post__in' => $related_ids
);
Best regards,
Clément
Wordpress have 'orderby'=>'post__in'
Posts will now be displayed according to their position in the $related_ids array
$args=array(
'post_type' => array('custompost1', 'custompost2', 'post'),
'orderby'=>'post__in', // Ordering the posts with the order of selection
'post__in' => $related_ids
);
I have custom tab for Frequently Bought Together products in my woocommerce site, that shows up on single product page. When i update products via WP All Import, only one product show up in custom tab and should be a two. Here is the settings of custom fields import and actually view of the single product page.
custom-fields-settings
single-product-accessory-tab
I'll provide Single Product Accessories template, just to make it clear
accessorie template function
global $product;
$loop_columns = apply_filters( 'mc_accessories_loop_columns', 4 );
$posts_per_page = 4;
if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.3', '<' ) ) {
global $woocommerce_loop;
$woocommerce_loop['columns'] = $loop_columns;
} else {
wc_set_loop_prop( 'columns', $loop_columns );
}
$product_id = mc_wc_get_product_id( $product );
$accessories = MediaCenter_WC_Helper::get_accessories( $product );
array_unshift( $accessories, $product_id );
if ( sizeof( $accessories ) === 0 && !array_filter( $accessories ) ) {
return;
}
$meta_query = WC()->query->get_meta_query();
$args = apply_filters( 'mc_accessories_query_args', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => $posts_per_page,
'orderby' => 'post__in',
'post__in' => $accessories,
'meta_query' => $meta_query
) );
unset( $args['meta_query'] );
$products = new WP_Query( $args );
$add_to_cart_checkbox = '';
$total_price = 0;
$count = 0;
Any help will be appreciated
Solution is so easy, just need to import post Id's, i lost two weeks on that problem.
What I want: modify the query of the WooCommerce search form (in frontend) to display the products by searching in the name, description and product_tag of the products.
What I have: I'm trying with this code inspired from this answer that return a result for the name and description of the product. But if i make a search with the tags names, no results. The search query don't search in tags of the product.
How to reproduce this issue (put the code below in functions.php file of your active theme):
function search_product_by_tag( $search, &$query_vars ) {
global $wpdb, $pagenow;
if ( 'edit.php' == $pagenow || empty($search) ) {
return $search;
}
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'taxonomy',
'value' => 'product_tag',
'field' => 'name',
'terms' => array($query_vars->query['s']),
'compare' => 'LIKE',
)));
$posts = get_posts( $args );
if ( empty( $posts ) ) return $search;
$get_post_ids = array();
foreach($posts as $post){
$get_post_ids[] = $post->ID;
}
if ( sizeof( $get_post_ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $get_post_ids ) . ")) OR (", $search);
}
return $search;
}
add_filter( 'posts_search', 'search_product_by_tag', 999, 2 );
Example: I've one product : Black Chocolate with the product tag "confection". With this code, if i search "Chocolate" in the search form, the product will be returned. But if i search "confection" : no results.
There are a lot of mistakes and errors in your code (a tax query is required for example).
To include WooCommmerce product tag terms in WooCommerce product search only (front end) use the following:
add_filter( 'posts_search', 'woocommerce_search_product_tag_extended', 999, 2 );
function woocommerce_search_product_tag_extended( $search, $query ) {
global $wpdb, $wp;
$qvars = $wp->query_vars;
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
return $search;
}
// Here set your custom taxonomy
$taxonomy = 'product_tag'; // WooCommerce product tag
// Get the product Ids
$ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => array( array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => esc_attr($qvars['s']),
)),
));
if ( count( $ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search);
}
return $search;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
To make it work On WordPress search too replace:
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
By the following:
if ( is_admin() || empty($search) || ! ( isset($qvars['s']) && ! empty($qvars['s']) ) ) {
For WooCommerce product category you will replace:
$taxonomy = 'product_tag'; // WooCommerce product tag
with:
$taxonomy = 'product_cat'; // WooCommerce product category
For WooCommerce product brands you will replace:
$taxonomy = 'product_tag'; // WooCommerce product tag
with:
$taxonomy = 'product_brand'; // WooCommerce product Brands
For multiple taxonomies.
To enable the search for both product category terms and product tag terms, you will use:
add_filter( 'posts_search', 'woocommerce_search_product_tag_extended', 999, 2 );
function woocommerce_search_product_tag_extended( $search, $query ) {
global $wpdb, $wp;
$qvars = $wp->query_vars;
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
return $search;
}
// Here set your custom taxonomies in the array
$taxonomies = array('product_tag', 'product_cat');
$tax_query = array('relation' => 'OR'); // Initializing tax query
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => esc_attr($qvars['s']),
);
}
// Get the product Ids
$ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => $tax_query,
) );
if ( sizeof( $ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search);
}
return $search;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
To make it work On WordPress search too replace:
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
By the following:
if ( is_admin() || empty($search) || ! ( isset($qvars['s']) && ! empty($qvars['s']) ) ) {
New Thread: Extend WooCommerce product search to custom taxonomies and custom fields
In WooCommerce with Advanced Custom Fields plugin, I am creating a function to up date a custom field for subscription orders on a WooCommerce store selling a print magazine. This function will update the 'starting_issue' field for subscription orders with the name for a single issue product depending on whether the user has opted to start their subscription from the previous, current or next issue of the magazine (chosen as a product variation for three different types of subscription products).
I have coded the function as follows but on any test orders I am completing, with changed attempted to the code below, it does not work as required - not updating the 'starting_issue' meta field for orders.
I have built similar functions before to auto-complete orders based on set conditions. I am struggling to see why this particular function is not working but I know I may be missing something very crucial.
The code I have written is:
/*** UPDATE 'STARTING ISSUE' FIELD FOR ORDERS ***/
// Club membership ID = '7968'
// Subscription (non-gift) ID = '13962'
// Subscription (gift) ID = '13966'
add_action( 'first_issue_for_subs', 'first_issue_for_subs' );
function first_issue_for_subs( $order_id ) {
if ( ! $order_id ) { return; }
global $woocommerce;
$order = new WC_Order( $order_id );
foreach( $order->get_items() as $item ) {
if ( ( $item['product_id'] == '7968' ) or ( $item['product_id'] == '13962' ) or ( $item['product_id'] == '13966' ) ) {
$product = wc_get_product( $item['product_id'] );
$variations = $product->children;
foreach ( $variations as $variation ) {
$variation_id = $variation->variation_id;
if ( $variation_id == '16171' or $variation_id == '16174' or $variation_id == '16168' ) {
// Current Issue
$current_args = [
'posts_per_page' => 1,
'post_type' => 'product',
'tax_query' => array( array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => 'single_issues' ) ),
];
$current_query = get_posts( $current_args );
foreach ( $current_query as $queried_issue ) {
$first_issue = the_title();
$order->update_field( 'starting_issue', $first_issue );
}
}
elseif ( $variation_id == '16167' or $variation_id == '16170' or $variation_id == '16173' ) {
// Next Issue
$next_args = [
'posts_per_page' => 1,
'post_status' => 'draft',
'post_type' => 'product',
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'single_issues'
) ),
'orderby' => 'date',
'order' => 'ASC',
];
$next_query = get_posts( $next_args );
foreach ( $next_query as $queried_issue ) {
$first_issue = the_title();
$order->update_field( 'starting_issue', $first_issue );
}
}
elseif ( $variation_id == '6169' or $variation_id == '16172' or $variation_id == '16166' ) {
// Previous Issue - gift
$previous_args = [
'posts_per_page' => 2,
'offset' => 1,
'post_type' => 'product',
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'single_issues'
) ),
];
$previous_query = get_posts( $previous_args );
foreach ( $previous_query as $queried_issue ) {
$first_issue = the_title();
$order->update_field( 'starting_issue', $first_issue );
}
}
}
} else {
$first_issue = 'NOT_SUBSCRIPTION';
$order->update_field( 'starting_issue', $first_issue );
}
}
}
Can anybody shed some light on this? Many thanks in advance for any help.