如何仅针对搜索查询修改posts_where过滤器


8

我正在使用posts_where过滤器来修改用户在网络上的搜索,但是我发现某些默认小部件(例如“最新帖子”)也使用了此过滤器,并且它们的行为也被修改了。我试图找到一种方法来避免除用户搜索之外的任何内容都使用posts_where过滤器。

这是我的代码:

add_filter( 'posts_where' , 'posts_where_statement' );

function posts_where_statement( $where ) {
   global $wp_query;
   global $expp;
   global $wpdb;
   $local_db = $wpdb->prefix."posts";
   $front_page_id = get_option('page_on_front');

   if ( ('page' != get_option('show_on_front') || $front_page_id != $wp_query->query_vars['page_id']) && (!($wp_query->is_search)) )
       return $where;

   //some $where modifications

   remove_all_actions ( '__after_loop');
   return $where;
}

还有其他功能或方法可以使此挂钩/过滤器仅适用于搜索查询吗?(从用户输入中获取结果的那个)

Answers:


17

问题:

当前代码段的问题是,无论当前查询对象是什么,您都只是在检查全局主查询对象。

解决方法:

请注意,posts_where过滤器回调的第二个输入参数是当前查询对象。

使用它来确定它是否是前端上的主要搜索查询,包括:

add_filter( 'posts_where', function ( $where, \WP_Query $q ) 
{
    if( ! is_admin() && $q->is_main_query() && $q->is_search()) // No global $wp_query here
    {
        // ... your modifications
    }

    return $where;      

}, 10, 2 ); // Note the priority 10 and number of input arguments is 2

posts_search如果您需要修改WHERE搜索部分的过滤器。

但是总的来说,如果您确实必须并且没有其他选择,那么我只会说手动修改生成的SQL。


+1用于类型提示。$q虽然不是粉丝。
Michael Ecklund

1
谢谢,有一个界面会很好。是的,这是关于变量名称的有效点。我必须承认,该网站上的代码滚动条会影响我编写答案的方式-我尽量避免使用它们;-)有些用法,$wp_query但是可能与global $wp_query,其他用法$qry$query混淆,但是在我们使用时可能也会造成混淆处理SQL查询;-)我定居$q在这短短的片段,并看起来也比简单如$wp_query_obj。平时我走的多,如果-contidtions成一个单独的线@MichaelEcklund
birgire

\ WP_Query $ q是什么意思?我的意思是为什么要斜杠?
布雷特

@brett如果我们在插件中使用命名空间,则WordPress类需要使用命名空间,因为WordPress使用全局空间。
birgire
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.