问题描述

我有一万个用户,大约 98%的用户从未发表过一篇文章 (我的意思是发表评论) 。

我需要一种方法来大量删除 0 个帖子的用户。

该方法必须对包含自定义帖子类型的所有帖子进行计数,并且必须使用正确的 WordPress 功能来删除用户,就像在仪表板中手动删除一样,而不仅仅是在 mysql 上放置一个表/行,因为这可能会导致意外的结果。

an old plugin 这样做,但不考虑所有的帖子类型,所以不能真正使用。

任何帮助赞赏。

最佳解决方案

如果您有大量用户要删除,可以使用 wp user delete wp-cli 命令来避免脚本超时。

Here’s 是一个 SQL 查询的示例,可以删除所有没有任何类型和状态的帖子的用户。

因此,您可以尝试此未经测试的 one-liner:

wp user delete $(wp db query "SELECT ID FROM wp_users WHERE ID NOT IN (SELECT DISTINCT post_author FROM wp_posts ) AND ID NOT IN (1,2,3)" | tail -n +2 ) --reassign=1

或扩展形式:

wp user delete $(wp db query
    "SELECT ID
         FROM wp_users
         WHERE ID NOT IN (
            SELECT DISTINCT post_author FROM wp_posts
         ) AND ID NOT IN (1,2,3)" | tail -n +2
  ) --reassign=1

请注意,我们添加了一个额外的 AND ID NOT IN (1,2,3)限制,以确保这些用户不被删除 (例如管理员用户) 。您将不得不根据自己的需要进行调整,并将表前缀 wp_

当我简单地测试了几个用户,我注意到我不得不添加 tail -n +2 部分,以避免头三个行和 wp db query 输出的表边界。

在这里,我们将所有帖子重新分配给用户 1,以避免通知:

--reassign parameter not passed. All associated posts will be deleted. Proceed? [y/n]

希望您可以进一步调整您的需求,如通过添加 WHERE post_status = 'publish'放宽用户删除条件。

注意:记住在测试之前进行备份!

次佳解决方案

这是 PHP 的一种方法。它可能是缓慢的和/或超时的,但是由于它是一个 one-time 的事情,这不应该太重要。临时放置在你的 functions.php 里面或作为一个新的插件上传。

//* You don't want to run this on admin_init. Run it once and deactivate
add_action( 'admin_init', 'wpse_262100_admin_init' );
function wpse_262100_admin_init() {
  $reserved_post_types = [
    'attachment',
    'revision',
    'nav_menu_item',
    'custom_css',
    'customize_changeset',
  ];

  //* Get the non-reserved post types
  $post_types = array_diff( array_keys( get_post_types() ), $reserved_post_types );
  foreach( get_users() as $user ) {
    if( 0 == count_user_posts( $user->ID, $post_types ) ) {
      wp_delete_user( $user->ID );
    }
  }
}

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。