4

在 WordPress 中,您必须已经知道,在使用get_posts()orquery_posts()或什至时WP_Query,无法通过按照我们想要的顺序指定帖子 ID 列表来对返回的帖子进行排序。

相反,我们必须遍历结果并在 PHP 端对它们重新排序。这是性能下降和不好的做法。相反,我们应该使用内置的 MySQL 函数来预先以所需的顺序检索帖子。

值得庆幸的是posts_orderby,可以使用 which 来指定自定义 ORDERBY 语句,如下所示:

// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);

// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
    global $my_post_ids;
    $orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';     
    return $orderby_statement;
}

// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);

但是上面的代码有个问题,就是会影响页面上所有查询的顺序!包括由插件、简码等进行的查询。

轻松修复!

解决此问题的简单方法是仅应用一次过滤器,并在调用时立即将其删除,方法是将 a 放入remove_filter()过滤器本身,因此它只运行一次:

// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);

// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {

    // Disable this filter for future queries!
    remove_filter(current_filter(), __FUNCTION__);

    global $my_post_ids;
    $orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';     
    return $orderby_statement;
}

// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);

因为我在我的自定义查询之前设置了这个过滤器,所以一旦我执行我的自定义查询,它应该被posts_orderby上面设置的过滤器过滤,然后立即禁用它,这样它就不会影响任何未来的查询。

从理论上讲,这很好,并且在大多数情况下都很好用!

WPML 的问题

但是,我在使用WPML 插件时遇到过这种情况,该过滤器会影响除我之外的其他查询并导致错误。我相信 WPML 插件正在创建自己的查询,该查询在我自己的自定义查询之前执行,使我的过滤器适用于 WPML 查询而不是我的!

是否有任何可能的方法在过滤器中添加检查以确保它影响正确的查询?

非常感谢


编辑:

WPML 的修复

有关信息,虽然这个问题的公认答案是正确的,但它并没有解决我在使用 WPML 时遇到的问题。以下是我修复 WPML 冲突的方法:

// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);

// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {

    // Disable this filter for future queries!
    remove_filter(current_filter(), __FUNCTION__);

    global $my_post_ids, $wpdb;
    $orderby_statement = 'FIELD('.$wpdb->base_prefix.'posts.ID, '.implode(',',$my_post_ids).')';     
    return $orderby_statement;
}

// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
4

1 回答 1

4

这个过滤器有两个参数$orderby&$this。“this”是 WP_Query 对象。我不确定如何检测 WPML 正在拨打电话,但我们可以检查您的电话是否是正在拨打的电话。

$my_post_ids = array(1,3,2);

add_filter( 'posts_orderby', 'my_custom_orderby', 10, 2 );

function my_custom_orderby( $orderby_statement, $object ) 
{
    global $my_post_ids;
    if( $my_post_ids != $object->query['post__in'] )
        return $orderby_statement;

    // Disable this filter for future queries!
    remove_filter( current_filter(), __FUNCTION__ );

    $orderby_statement = 'FIELD(ID, ' . implode( ',', $my_post_ids ) . ')';     
    return $orderby_statement;
}
于 2013-08-18T19:51:02.010 回答