Home > Enterprise >  add hook in product search query
add hook in product search query

Time:02-22

I'm developing a plugin for my shopping site. The plugin works like this. Color variations of the same product are on different product pages. The products are connected together as shown in the photo below.

and on the product page as small photos, it is shown as color variants of the product.

It works flawlessly so far. but I am using multi-vendor plugin on my website. . I want it to search only the products belonging to the author, the user, that is the store, while selecting the product.

for this, is it possible to add a filter to the query made in the ajax request and rewrite the query?

CodePudding user response:

add_filter('woocommerce_product_pre_search_products', 'woocommerce_product_pre_search_products', 10, 6);
function woocommerce_product_pre_search_products( $custom_query=false, $term, $type, $include_variations, $all_statuses, $limit) {
        global $wpdb;

        $post_types   = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' );
        $join_query   = '';
        $type_where   = '';
        $status_where = '';
        $limit_query  = '';

        // When searching variations we should include the parent's meta table for use in searches.
        if ( $include_variations ) {
            $join_query = " LEFT JOIN {$wpdb->wc_product_meta_lookup} parent_wc_product_meta_lookup
             ON posts.post_type = 'product_variation' AND parent_wc_product_meta_lookup.product_id = posts.post_parent ";
        }

        /**
         * Hook woocommerce_search_products_post_statuses.
         *
         * @since 3.7.0
         * @param array $post_statuses List of post statuses.
         */
        $post_statuses = apply_filters(
            'woocommerce_search_products_post_statuses',
            current_user_can( 'edit_private_products' ) ? array( 'private', 'publish' ) : array( 'publish' )
        );

        // See if search term contains OR keywords.
        if ( stristr( $term, ' or ' ) ) {
            $term_groups = preg_split( '/\s or\s /i', $term );
        } else {
            $term_groups = array( $term );
        }

        $search_where   = '';
        $search_queries = array();

        foreach ( $term_groups as $term_group ) {

                $search_terms = array( $term_group );
            

            $term_group_query = '';
            $searchand        = '';

            foreach ( $search_terms as $search_term ) {
                $like = '%' . $wpdb->esc_like( $search_term ) . '%';

                // Variations should also search the parent's meta table for fallback fields.
                if ( $include_variations ) {
                    $variation_query = $wpdb->prepare( " OR ( wc_product_meta_lookup.sku = '' AND parent_wc_product_meta_lookup.sku LIKE %s ) ", $like );
                } else {
                    $variation_query = '';
                }

                $term_group_query .= $wpdb->prepare( " {$searchand} ( ( posts.post_title LIKE %s) OR ( posts.post_excerpt LIKE %s) OR ( posts.post_content LIKE %s ) OR ( wc_product_meta_lookup.sku LIKE %s ) $variation_query)", $like, $like, $like, $like ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                $searchand         = ' AND ';
            }

            if ( $term_group_query ) {
                $search_queries[] = $term_group_query;
            }
        }

        if ( ! empty( $search_queries ) ) {
            $search_where = ' AND (' . implode( ') OR (', $search_queries ) . ') ';
        }

        if ( ! empty( $include ) && is_array( $include ) ) {
            $search_where .= ' AND posts.ID IN(' . implode( ',', array_map( 'absint', $include ) ) . ') ';
        }

        if ( ! empty( $exclude ) && is_array( $exclude ) ) {
            $search_where .= ' AND posts.ID NOT IN(' . implode( ',', array_map( 'absint', $exclude ) ) . ') ';
        }

        $search_where .= ' AND posts.post_author='. get_current_user_id();
        
        if ( 'virtual' === $type ) {
            $type_where = ' AND ( wc_product_meta_lookup.virtual = 1 ) ';
        } elseif ( 'downloadable' === $type ) {
            $type_where = ' AND ( wc_product_meta_lookup.downloadable = 1 ) ';
        }

        if ( ! $all_statuses ) {
            $status_where = " AND posts.post_status IN ('" . implode( "','", $post_statuses ) . "') ";
        }

        if ( $limit ) {
            $limit_query = $wpdb->prepare( ' LIMIT %d ', $limit );
        }

        // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
        $search_results = $wpdb->get_results(
            // phpcs:disable
            "SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts
             LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON posts.ID = wc_product_meta_lookup.product_id
             $join_query
            WHERE posts.post_type IN ('" . implode( "','", $post_types ) . "')
            $search_where
            $status_where
            $type_where
            ORDER BY posts.post_parent ASC, posts.post_title ASC
            $limit_query
            "
            // phpcs:enable
        );

        $product_ids = wp_parse_id_list( array_merge( wp_list_pluck( $search_results, 'product_id' ), wp_list_pluck( $search_results, 'parent_id' ) ) );

        if ( is_numeric( $term ) ) {
            $post_id   = absint( $term );
            $post_type = get_post_type( $post_id );

            if ( 'product_variation' === $post_type && $include_variations ) {
                $product_ids[] = $post_id;
            } elseif ( 'product' === $post_type ) {
                $product_ids[] = $post_id;
            }

            $product_ids[] = wp_get_post_parent_id( $post_id );
        }

        return wp_parse_id_list( $product_ids );
    }
  • Related