使用posts_orderby时如何避免影响其他查询?

时间:2013-08-13 10:00:59

标签: wpml wordpress

在您必须已知的WordPress中,当使用get_posts()query_posts()或甚至WP_Query时,无法通过指定帖子ID列表来订购返回的帖子。我们想要的订单。

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

值得庆幸的是,posts_orderby可用于指定自定义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);

但上述代码存在问题,是否会影响页面上所有查询的顺序!包括插件,短代码等的查询。

轻松修复!

解决此问题的简单方法是仅应用过滤器一次,并在调用过程后立即将其删除,方法是在过滤器本身中放置remove_filter(),因此它只运行一次:< / p>

// 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 plugin的情况,此过滤器会影响其他查询而导致错误。我相信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);

1 个答案:

答案 0 :(得分:4)

此过滤器takes two parameters$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;
}