筛选wp_Query以在函数中搜索帖子标题

时间:2021-03-26 作者:rudtek

我正在根据表单中的用户条目进行查询,以从我的帖子查询中提取帖子。我希望表单保持简单,所以我希望只需要使用一个字段。该字段将显示搜索零件号或产品标题。这将是一个Ajax响应。下面是我现在掌握的代码:

function led_search_function(){

    $args = array(
              \'post_type\'   => \'al_product\',
              \'post_status\' => \'publish\',
        \'posts_per_page\' => 20,
    );
 
    // for taxonomies / categories
    if( isset( $_POST[\'categoryfilter\'] ) && $_POST[\'categoryfilter\'] )
        $args[\'tax_query\'] = array(
            array(
                \'taxonomy\' => \'product_category\',
                \'field\' => \'id\',
                \'terms\' => $_POST[\'categoryfilter\']
            )
        );
 
    // create $args[\'meta_query\'] array if one of the following fields is filled
    if( isset( $_POST[\'part_number\'] ) && $_POST[\'part_number\'] )
        $args[\'meta_query\'] = array( \'relation\'=>\'OR\' ); // OR means that both below conditions of meta_query should be true

    
    if( isset( $_POST[\'part_number\'] ) && $_POST[\'part_number\'] ) {
        //checks for the part number
        $args[\'meta_query\'][] = array(
            \'key\' => \'part_number\',
            \'value\' => $_POST[\'part_number\'],
            \'compare\'   => \'LIKE\',
        );
        //checks if variations have part numbers to add to the array
        $args[\'meta_query\'][] = array(
            \'key\' => \'product_variations_$_part_number\',
            \'value\' => $_POST[\'part_number\'],
            \'compare\'   => \'LIKE\',
        );
       }
 
    $query = new WP_Query( $args );
 
    if( $query->have_posts() ) :
              echo \'<h2>Your Search Results</h2><div class="productCategories grid">\';
        while( $query->have_posts() ): $query->the_post(); ?>
                                    <div class="product_cat">
                            <a href="<?php the_permalink();?>">
                                <?php the_post_thumbnail(\'small\');?>
                                <h2><?php the_title();?></h2>
                    <?php 
                                    $subtitle = get_field(\'subtitle\');
                                    if ( $subtitle ) { 
                                        echo \'<h3 class="entry-subtitle">\'.$subtitle.\'</h3>\';
                                    }
                    ?>
                            </a>
                        </div>
    
                        <?php
        endwhile;
        echo \'</div>\';
        wp_reset_postdata();
    else :
        echo \'No lights found\';
    endif;
 
    die();
}
现在有点误导,因为表单上的字段仍然称为;零件号“;即使它会搜索一切。

我希望能够在查询中添加第三部分来搜索帖子标题(或部分标题……因此,如果有人键入“sun”,它将返回名为“sunbeast”或“sun set light”的产品;。

第二个问题是,如果搜索词不在标题中,但仍然是零件号,我需要它返回结果。

我知道我可以使用;s“;变量,但它也搜索内容,并且对标题大小写要求严格。有没有更好的方法?

UPDATE基于@sally cj,我尝试过:(all in my functions.php),但无论我输入什么,它都会返回所有产品。

<?php
//enqueue product filter ajax js
add_action( \'wp_enqueue_scripts\', \'product_finder_scripts\' );
function product_finder_scripts() {
    if ( is_front_page() ) {
        wp_enqueue_script( \'ajax-filter-script\', get_stylesheet_directory_uri() . \'/js/ajax-filter.js\', array(\'jquery\'), false, true );
    } 
}

add_action(\'wp_ajax_myfilter\', \'led_search_function\'); 
add_action(\'wp_ajax_nopriv_myfilter\', \'led_search_function\');
 
function my_posts_where( $where ) {
    $where = str_replace("meta_key = \'product_variations_$", "meta_key LIKE \'product_variations_%", $where);
    return $where;
}
//add_filter(\'posts_where\', \'my_posts_where\');

function led_search_function(){

    $args = array(
        \'post_type\' => \'al_product\',
        \'post_status\' => \'publish\',
        \'posts_per_page\' => 20,
    );
 
    // for taxonomies / categories
    if( isset( $_POST[\'categoryfilter\'] ) && $_POST[\'categoryfilter\'] )
        $args[\'tax_query\'] = array(
            array(
                \'taxonomy\' => \'product_category\',
                \'field\' => \'id\',
                \'terms\' => $_POST[\'categoryfilter\']
            )
        );
 
    /**
    // create $args[\'meta_query\'] array if one of the following fields is filled
    if( isset( $_POST[\'part_number\'] ) && $_POST[\'part_number\'] )
        $args[\'meta_query\'] = array( \'relation\'=>\'OR\' ); // OR means that both below conditions of meta_query should be true

    
    if( isset( $_POST[\'part_number\'] ) && $_POST[\'part_number\'] ) {
        //checks for the part number
        $args[\'meta_query\'][] = array(
            \'key\' => \'part_number\',
            \'value\' => $_POST[\'part_number\'],
            \'compare\'   => \'LIKE\',
        );
        //checks if variations have part numbers to add to the array
        $args[\'meta_query\'][] = array(
            \'key\' => \'product_variations_$_part_number\',
            \'value\' => $_POST[\'part_number\'],
            \'compare\'   => \'LIKE\',
        );
    } 
    **/

    add_filter( \'posts_clauses\', \'my_posts_clauses\', 10, 2 );
    $query = new WP_Query( $args );
    remove_filter( \'posts_clauses\', \'my_posts_clauses\', 10 );
    
    if( $query->have_posts() ) :
        echo \'<h2>Your Search Results</h2><div class="productCategories grid">\';
        while( $query->have_posts() ): $query->the_post(); ?>
            <div class="product_cat">
                <a href="<?php the_permalink();?>">
                    <?php the_post_thumbnail(\'small\');?>
                    <h2><?php the_title();?></h2>
                    <?php 
                        $subtitle = get_field(\'subtitle\');
                        if ( $subtitle ) { 
                            echo \'<h3 class="entry-subtitle">\'.$subtitle.\'</h3>\';
                        }
                    ?>
                </a>
            </div>
        <?php
        endwhile;
        echo \'</div>\';
        wp_reset_postdata();
    else :
        echo \'No lights found\';
    endif;

    
    die();
}

// In the theme\'s functions.php file, or somewhere in your plugin:
function my_posts_clauses( $clauses, $query ) {
    $part_number = $_POST[\'part_number\'] ?? \'\';

    if ( strlen( $part_number ) && ! is_admin() ) {
        global $wpdb;

        $part_number2 = \'%\' . $wpdb->esc_like( $part_number ) . \'%\';

        $clauses[\'join\'] .= " INNER JOIN $wpdb->postmeta my_mt1 ON {$wpdb->posts}.ID = my_mt1.post_id";

        // Search in the metadata part_number.
        $where = $wpdb->prepare( "(my_mt1.meta_key = \'part_number\'
            AND my_mt1.meta_value LIKE %s)", $part_number2 );

        // Search in the metadata product_variations_$_part_number.
        $where .= $wpdb->prepare( " OR (my_mt1.meta_key = \'product_variations_\\$_part_number\'
            AND my_mt1.meta_value LIKE %s)", $part_number2 );

        // Search in post title.
        $where .= $wpdb->prepare( " OR ({$wpdb->posts}.post_title LIKE %s)", $part_number2 );

        $clauses[\'where\'] .= " AND ( $where )";
        $clauses[\'groupby\'] = "{$wpdb->posts}.ID";
    }

    return $clauses;
}

1 个回复
SO网友:Sally CJ

如果你想通过WP_Query 打电话,然后您可以使用posts_clauses filter hook.

诀窍是,不要设置part_numberproduct_variations_$_part_number 元查询通过meta_query arg,但改用上述挂钩,即手动构建SQL子句。

工作示例注:在led_search_function() 代码中,应首先删除上述元查询。

// In the theme\'s functions.php file, or somewhere in your plugin:
function my_posts_clauses( $clauses, $query ) {
    $part_number = $_POST[\'part_number\'] ?? \'\';

    if ( strlen( $part_number ) && ! is_admin() ) {
        global $wpdb;

        $part_number2 = \'%\' . $wpdb->esc_like( $part_number ) . \'%\';

        $clauses[\'join\'] .= " INNER JOIN $wpdb->postmeta my_mt1 ON {$wpdb->posts}.ID = my_mt1.post_id";

        // Search in the metadata part_number.
        $where = $wpdb->prepare( "(my_mt1.meta_key = \'part_number\'
            AND my_mt1.meta_value LIKE %s)", $part_number2 );

        // Search in the metadata product_variations_$_part_number.
        $where .= $wpdb->prepare( " OR (my_mt1.meta_key = \'product_variations_\\$_part_number\'
            AND my_mt1.meta_value LIKE %s)", $part_number2 );

        // Search in post title.
        $where .= $wpdb->prepare( " OR ({$wpdb->posts}.post_title LIKE %s)", $part_number2 );

        $clauses[\'where\'] .= " AND ( $where )";
        $clauses[\'groupby\'] = "{$wpdb->posts}.ID";
    }

    return $clauses;
}
因此,添加该函数,然后像这样进行WP查询(您可以使用闭包,而不是像下面那样添加/删除过滤器,但这将取决于您如何实现它):

add_filter( \'posts_clauses\', \'my_posts_clauses\', 10, 2 );
$query = new WP_Query( $args );
remove_filter( \'posts_clauses\', \'my_posts_clauses\', 10 );

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post