从WordPress中删除除最新X帖子之外的所有帖子

时间:2015-09-07 作者:Robert hue

在一个项目中,我需要在网站上只保留10篇最新帖子,并自动删除所有其他帖子。所以我想出了这个函数,它在发布/更新后触发,我使用offset 参数以排除最近的10项。

function wpse_auto_delete_posts( $post_ID ) {
  global $post;

  $delete_posts = get_posts( array( \'post_type\' => \'post\', \'offset\' => 10, \'posts_per_page\' => -1 ) );
  foreach ( $delete_posts as $delete_post ) : setup_postdata( $delete_post );
    wp_delete_post( $delete_post->ID, true );
  endforeach;
  wp_reset_postdata();

}
add_action( \'publish_post\', \'wpse_auto_delete_posts\' );
但看起来,offset 没有在这里工作\'posts_per_page\' => -1 它会不断删除所有帖子。我曾想过使用日期查询,但它也不会太有效,因为新帖子创建得非常频繁。

有没有办法选择除最新10或5个帖子以外的所有帖子。所以WordPress可以处理它们并保留最新的X帖子。

2 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

这个offset 参数被忽略posts_per_page 设置为-1 在里面WP_Query. 如果您查看WP_Queryposts_per_page=-1 集合nopaging 为真。

if ( !isset($q[\'nopaging\']) ) {
    if ( $q[\'posts_per_page\'] == -1 ) {
        $q[\'nopaging\'] = true;
    } else {
        $q[\'nopaging\'] = false;
    }
}
这又不会附加LIMIT 到SQL查询(empty($q[\'nopaging\'] === false 这使条件语句失败,意味着忽略整个分页/偏移量,返回所有帖子

if ( empty($q[\'nopaging\']) && !$this->is_singular ) {
    $page = absint($q[\'paged\']);
    if ( !$page )
        $page = 1;

    if ( empty($q[\'offset\']) ) {
        $pgstrt = absint( ( $page - 1 ) * $q[\'posts_per_page\'] ) . \', \';
    } else { // we\'re ignoring $page and using \'offset\'
        $q[\'offset\'] = absint($q[\'offset\']);
        $pgstrt = $q[\'offset\'] . \', \';
    }
    $limits = \'LIMIT \' . $pgstrt . $q[\'posts_per_page\'];
}
我认为这里最好的解决方法是使用普通的PHP(array_slice()wp_delete_post 运行起来非常昂贵,而且只需要帖子ID,所以我们不需要任何其他帖子信息。

简而言之,您的查询如下所示:(NOTE: 这一切都未经测试,需要PHP 5.4+)

add_action( \'publish_post\', function ( $post_ID ) 
{
    $args = [
        \'nopaging\' => true,
        \'fields\'   => \'ids\'
    ];
    $posts_array = get_posts( $args );
    // Make sure that we have post ID\'s returned
    if ( $posts_array ) {
        // Get all post ids after the 10th post using array_slice
        $delete_posts = array_slice( $posts_array, 10 );
        // Make sure that we actually have post ID\'s in the $delete_posts array
        if ( $delete_posts ) {
            foreach ( $delete_posts as $delete_post )
                wp_delete_post( $delete_post, true );
        }
    }
});

EDIT

在我忘记之前,你还可以定义posts_per_page 作为不太可能的整数值,而不是-1. 这也将与您的代码一起使用offset 参数集

SO网友:Ignat B.

事实是\'nopaging\' => true\'posts_per_page\' => -1 行为相同。此参数正在取消LIMIT 您的WP发出的MySQL请求的子句。

偏移(int)-要置换或传递的桩号。警告:设置偏移参数会覆盖/忽略分页参数并中断分页(单击此处可获得解决方法)。The \'offset\' parameter is ignored when \'posts_per_page\'=>-1 (show all posts) is used.

考虑到MySQL docs 和他们的建议,你可以使用大量的posts_per_page 参数,保持偏移量不变。

要检索从某个偏移量到结果集末尾的所有行,可以对第二个参数使用一些较大的数字。此语句检索从第96行到最后一行的所有行:

SELECT * FROM tbl LIMIT 95,18446744073709551615;