用于在处理之前获取(和更改)搜索字符串的挂钩

时间:2018-11-19 作者:arathra

我试图在Wordpress中执行搜索查询之前拦截它。我试过很多方法,但都不管用。

例如,用户输入搜索词RED SHOES。我想把所有出现的红色都改成ROSSO(比这更复杂,但你明白了;这是翻译)。

我在看这样的东西:

function modify_search_vars($search_vars) {

    $change_to = array(
        "blue"  => "blu",
        "red"   => "rosso",
    );

    if ( !empty($search_vars[\'s\']) ) {
        $search_vars[\'s\'] = str_ireplace(array_keys($change_to), array_values($change_to), $search_vars[\'s\']);
    }
    return $search_vars;

}
add_filter(\'request\', \'modify_search_vars\', 99);
如果您有任何帮助或想法,我们将不胜感激!谢谢

1 个回复
最合适的回答,由SO网友:coolpasta 整理而成

为了在搜索中实现更深入的“注入”,并尽快捕获用户搜索的内容,我们必须查看WP_Query 类并查看它如何处理帖子查询:

在its中parse_query 函数wee使用一个标志向整个类发出信号,实际上,查询是一个“搜索”,毫不奇怪,它会查找s 查询内部:

if ( isset( $this->query[\'s\'] ) ) {
    $this->is_search = true;
}
很好,但没有像do_action( \'super_important_hook\' . $handle_that_we_could_use, $query) WordPress让我们在“按姓名”的基础上加入这一重要的大过程,那么我们能做些什么呢?

我们有parse_query 之前发生过哪些火灾pre_get_posts:

function replace_search( $query_object )
{
    if( $query_object->is_search() ) {
        $raw_search = $query_object->query[\'s\'];

        $replacement = str_replace( \'red\', \'rosso\', $raw_search );

        if( $replacement ) {
            $query_object->set( \'s\', $replacement );
        }
    }
}

add_action( \'parse_query\', \'replace_search\' );
。。。而且很有效!我们正在尽可能早地挂钩,并在查询发生时立即修改查询。这个set 函数完全按照它所说的做,它是用于类的任何内部变量的setter。

顺便说一下,钩子parse_tax_query fires before parse_query 自从$this->parse_tax_query() 其中包含parse_tax_query 在内部调用parse_query() 的功能WP_Query 通过相同的WP_Query Object 到行动。但我的观点可能是错误的:我不会像看起来那样使用这个钩子parse_query 对于这种类型的行为更受欢迎。

第一Remember that 除非插件也使用这个钩子来查找搜索字符串,否则它们可能会查找$_REQUEST[\'s\'] 在这些挂钩之前,它可能会被修改。无论如何,用户搜索进入系统的最早点是$_REQUEST[\'s\'] 因此,您需要尽早地连接到这个值,我的答案在这里很好,但我认为在使用搜索时需要考虑更多的事情,当然,如果它们的函数具有更高的优先级,并且它们将字符串转换为其他内容,那么您将注定失败。

显然,您将有一个更复杂的“替换”机制,但这只是为了显示您需要什么挂钩。

其次,这些操作的一个有趣之处在于,它们通过引用传递对象:

/**
 * Fires after the main query vars have been parsed.
 *
 * @since 1.5.0
 *
 * @param WP_Query $this The WP_Query instance (passed by reference).
 */
do_action_ref_array( \'parse_query\', array( &$this ) );
这意味着什么,最好牢记在心——当脚本挂接到parse_query 反映在传递给它所连接的下一个脚本的实际类本身上,或者,您的更改将反映在所述类的整个生命周期中。我不知道这是否是一个好的设计选择,只是让你知道万一你会有一些“为什么这个变量没有重置?它是一个新的类实例。”,该类的行为类似于单例,但它不是,因此请记住,在WP完成之前,您一直在使用同一个类,并且您对它所做的所有更改都将由您之后的任何人使用,简言之:请注意您所做的事,有很多进程/插件将其用作WP_Query 是WP本身的实际核心。

如果您希望尽可能晚地“钩住”,这仍然会修改查询本身,但(我相信)钩住会很晚,让主题/插件可以在您看到它之前使用该值:

add_filter( \'get_search_query\', function( $user_search_query ) {
    $replacement = str_replace( \'red\', \'rosso\', $user_search_query );

    if( $replacement ) {
        return $replacement;
    }

    return $user_search_query;
}, 999);
你要找的钩子是get_search_query. 但是请知道,有很多插件/东西可以使用它,因此,请注意改变它的含义。使用它的主要功能是:

/**
 * Displays the contents of the search query variable.
 *
 * The search query string is passed through esc_attr() to ensure that it is safe
 * for placing in an html attribute.
 *
 * @since 2.1.0
 */
function the_search_query() {
    /**
     * Filters the contents of the search query variable for display.
     *
     * @since 2.3.0
     *
     * @param mixed $search Contents of the search query variable.
     */
    echo esc_attr( apply_filters( \'the_search_query\', get_search_query( false ) ) );
}
发件人general-template.php WP核心。此参数从传递到我们的筛选器get_search_query 这只是一个简单的包装$_REQUEST[\'s\'].

结束