I’m currently trying to extend the WooCommerce product search so that the search uses my custom field I’ve created within the general product data section:
add_action( 'woocommerce_product_options_general_product_data', 'woocommerce_product_options_general_product_data_action', 9999, 0 ); function woocommerce_product_options_general_product_data_action(): void { global $post; echo '<div class="options_group">'; woocommerce_wp_text_input( [ 'id' => '_pdc_notch', 'wrapper_class' => '', 'label' => 'Notch', 'desc_tip' => true, 'type' => 'text', 'description' => 'Enter notch PDC', 'value' => get_post_meta( $post->ID, '_pdc_notch', true ) ] ); echo '</div>'; } add_action( 'woocommerce_process_product_meta', 'woocommerce_process_product_meta_action', 10, 1 ); function woocommerce_process_product_meta_action( int $product_id ): void { $pdc_notch = sanitize_text_field( wp_unslash( $_POST['_pdc_notch'] ?? null ) ); update_post_meta( $product_id, '_pdc_notch', $pdc_notch ); }
With the above code, I can add and save my custom field. Now I’ve extended the search with the below hook:
add_action( 'woocommerce_product_query', 'woocommerce_product_query_action', 10, 2 ); function woocommerce_product_query_action( WP_Query $q, object $instance ) { if ( ! is_admin() && $q->is_main_query() && $q->is_search() ) { $meta_query = $q->get( 'meta_query' ); $meta_query[] = [ 'key' => '_pdc_notch', 'value' => $q->query['s'], 'compare' => 'LIKE' ]; $q->set( 'meta_query', $meta_query ); } }
When I set a text like “Iamabigtestword” to my field and put it in the search, I’m still getting nothing. What am I missing? I really can’t find the issue here. Normally, the hook should work (regarding an answer from StackOverflow: Include custom fields value in woocommerce search)
Note
You can copy/paste the code directly in the functions.php
file of your child theme to test it, since it has no dependencies and should add the field to the Products > Product > General
tab at the end.
Advertisement
Answer
I think I have found a way after some testing. First, I’ve debugged the WC function where the action gets applied, but changed my approach since I was making no progress. I’ve now extended the post search via the given WordPress filter:
add_filter( 'posts_search', 'filter_posts_search', 10, 2 ); /** * Extend product search to use the new custom field within search * * @param string $search * @param WP_Query $query * * @return string */ function filter_posts_search( string $search, WP_Query $query ): string { global $wpdb; if ( empty( $search ) || ! ( isset( $query->query_vars['s'], $query->query_vars['post_type'] ) && ! empty( $query->query_vars['s'] ) && $query->query_vars['post_type'] === 'product' ) || is_admin() || ! is_search() || ! is_main_query() ) { return $search; } $product_ids = []; $products = wc_get_products( [ 'post_type' => 'product', 'limit' => - 1, 'meta_key' => '_pdc_notch', 'meta_value' => esc_attr( $query->query_vars['s'] ), 'meta_compare' => 'LIKE' // or '=' ] ); /** * @var WC_Product $product */ foreach ( $products as $product ) { $product_ids[] = $product->get_id(); } $product_ids = array_unique( $product_ids ); if ( count( $product_ids ) > 0 ) { $search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $product_ids ) . ")) OR (", $search ); } return $search; }
I hope it helps someone! If someone finds a better approach, I can test it for you.