是否允许贡献者更改其帖子的作者?

时间:2018-08-31 作者:Michael Rogers

是否可以让投稿人更改自己帖子的作者?我意识到这将有效地将他们锁定在帖子之外,这就是我想要的。我希望他们能够在完成编辑后更改作者。

5 个回复
SO网友:Levi Dulstein

我添加了第二个答案,因为我的第一个方法被否决了,而这一个没有得到应有的重视。

其想法是创建自定义元框,列出所有用户并更改作者save_post 钩这样,您就不会干扰用户的功能,并且当帖子已经保存时,作者也会发生更改。另外,您还可以控制“作者”下拉列表中可用的用户列表。要遵循的步骤:

Register meta box:

function wpse313020_add_custom_box() {

    // Bail out for users other than contributors
    if ( ! user_can( get_current_user_id(), \'contributor\' ) ) {
        return;
    } 

    // Register custom meta box
    add_meta_box(
        \'wpse313020_author_override\',
        \'Change Author\', // metabox title
        \'wpse313020_author_ovveride_box_html\', // callbac function
        \'post\' // a post type you want to show the metabox on
    );
}
add_action(\'add_meta_boxes\', \'wpse313020_add_custom_box\');

Build markup for your meta box:

/**
 * HTML for custom meta box
 */
 function wpse313020_author_ovveride_box_html() {
    // you can modify the list of users by passing additional args to get_users()
    $users = get_users();
    ?>
    <label for="wpse313020_author_override_id">Select post author</label><br />
    <select name="wpse313020_author_override_id" id="wpse313020_author_override_id" class="postbox">
        <option value="">Select user...</option>
        <?php
        // get post ID on admin edit screen and retrieve saved post meta
        $post_id     = is_admin() && isset( $_GET[\'post\'] ) ? absint( wp_unslash( $_GET[\'post\'] ) ) : \'\';
        $saved_value = ! empty( $post_id ) ? get_post_meta( $post_id, \'wpse313020_author_override\', true ) : \'\';

        foreach ( $users as $user ) {
            echo sprintf( \'<option value="%1$d" %2$s>%3$s</option>\', absint( $user->ID ), selected( $saved_value, absint($user->ID, false ) ), esc_html( $user->display_name ) );
        }
        ?>
    </select>
    <?php
 }

Hook into save_post to save data and override the author:

/**
 * Save custom post meta and override the post author
 */
function wpse313020_save_postdata( $post_id ) {

    if ( array_key_exists(\'wpse313020_author_override_id\', $_POST ) ) {
        // save post meta with author ID
        update_post_meta( $post_id, \'wpse313020_author_override\', absint( $_POST[\'wpse313020_author_override_id\'] ) );

        // now modify the post author, we need to unhook the current function to prevent infinite loop
        // you could add additional check here to see if the current author is not the same as chosen author

        remove_action( \'save_post\', \'wpse313020_save_postdata\' );

        $updated_data = [
            \'ID\'          => $post_id,
            \'post_author\' => absint( $_POST[\'wpse313020_author_override_id\'] ),
        ];

        wp_update_post( $updated_data );

        add_action( \'save_post\', \'wpse313020_save_postdata\' );
    }
}
add_action(\'save_post\', \'wpse313020_save_postdata\');
NOTE记住添加nonce字段并在保存后检查它。您还可以考虑使用其他挂钩,而不是save_post, i、 e。pre_post_updatewp_insert_post_data, 在初始后期保存时处理数据。

希望有帮助!

SO网友:Fayaz

陷阱:

即使允许作者(或撰稿人)使用user_has_cap 然而,过滤器挂钩和一些相关代码,this approach itself is fundamentally flawed. 因此,即使您采取了所有必要的安全措施,它仍然是一个漏洞,因为它一起破坏了功能架构。

让我给你一个示例场景:假设一个具有author角色的用户没有什么值得尊敬的意图,并且用大量的帖子(可能使用脚本)对另一个作者进行垃圾邮件。下次目标作者登录时,他/她将看到所有以他/她的名义发布的帖子!这将继续,因为其他作者没有办法阻止它!因此,我们必须找到一种没有这种缺陷的替代方法。

更好的方法:

如果作者更改是一项必要的功能,那么更好的方法是让其他作者(或其他编辑或管理员等更高权限的用户)参与作者更改过程,以便发起作者可能无法向目标作者发送垃圾邮件。

为了实现这一点,我们将让发起作者从编辑器中选择目标作者,但我们不会直接更改帖子作者。相反,在作者更改时,我们将保存一个自定义帖子元,该元将保存目标作者id。然后在管理面板中,我们将有一个帖子子菜单,其中将显示所有具有作者更改请求的帖子。仅目标作者和用户具有edit_others_post 功能(如编辑器、管理员等)将可以访问此作者更改请求UI。从UI中,具有适当访问权限的用户将批准更改,只有在此时,才会发生最终的作者更改。

在审批队列中的帖子会发生什么情况

代码实现可能因需求而异,但是,在没有任何其他代码实现的情况下,发起作者将能够在批准流程窗口内修改帖子,甚至恢复作者更改请求。一旦作者变更请求获得批准,他们将被拒之门外。

SO网友:cjbj

“作者”下拉框will only show 当用户拥有edit_others_posts 能力。然而,出于明显的原因,您不希望在默认情况下将此功能授予作者。解决办法是,只有在特定情况下,即当他编辑自己的一篇文章时,才提供这种能力。由于该功能已写入数据库,因此您还必须确保它已在任何其他页面上删除。

这是一个精确的时机问题。您想更改功能after WP已决定投稿人有权编辑帖子,但before 编辑页面的形式(post.php) 已生成。合适的挂钩是admin_init.

像这样:

add_action (\'admin_init\', \'wpse313020_change_author\');
function wpse313020_change_author () {
  global $pagenow;
  $current_user = wp_get_current_user();
  // only do this if current user is contributor
  if (\'contributor\' == $current_user->roles[0]) {
    // add capability when we\'re editing a post, remove it when we\'re not
    if (\'post.php\' == $pagenow)
       $current_user->add_cap(\'edit_others_posts\')
    else
       $current_user->remove_cap(\'edit_others_posts\');
    }
  }
我还没有测试代码,所以它可能有问题,但你明白了。

SO网友:Levi Dulstein

我试图通过过滤贡献者元功能来实现您所需的功能,它似乎工作得很好。我在这里所做的就是添加edit_others_posts 当WordPress请求时,贡献者的功能。

然而,我要说的是,这对我来说是一个有点黑的解决方案,我不确定它是否完全安全。根据我将过滤器置于functions.php WordPress不允许贡献者在其他上下文中编辑其他用户的帖子,而不是您要求的内容。这似乎很好,但我们无法真正明确地检查当前用户是否是当前编辑的帖子的作者(如果将条件检查添加到函数中,您将无法将帖子保存为其他用户)-这让我担心。

/**
 * author_cap_filter()
 *
 * Filter on the current_user_can() function.
 * This function is used to explicitly allow contributors to change post authors
 *
 * @param array $allcaps All the capabilities of the user
 * @param array $cap     [0] Required capability
 * @param array $args    [0] Requested capability
 *                       [1] User ID
 */
function author_cap_filter( $allcaps, $cap, $args ) {

    // Bail out if we\'re not dealing with right capability:
    if ( ! in_array( $args[0], [ \'edit_others_posts\' ] ) ) {
        return $allcaps;
    }

    // Bail out for users who are not contributors
    if ( ! user_can( $args[1], \'contributor\' ) ) {
        return $allcaps;
    }

    // Bail out for users who can already edit others posts:
    if ( isset( $allcaps[\'edit_others_posts\'] ) && $allcaps[\'edit_others_posts\'] ) {
        return $allcaps;
    }

    // overwrite \'edit_others_posts\' capability
    $allcaps[ $args[0] ] = true;

    return $allcaps;
}
add_filter( \'user_has_cap\', \'author_cap_filter\', 100, 3 );

SO网友:filipecsweb

首先,安装插件用户角色编辑器(https://wordpress.org/plugins/user-role-editor/).

其次,使用插件创建一个名为Post Manager的新角色,例如:

enter image description here

创建新角色后,您将能够编辑其功能。现在,是你解决问题的时候了,但你必须在两个选项之间做出决定:

(暂时不要担心参与者角色)

First:

<给你的新角色两个额外的能力,edit_others_postspublish_posts.

Second:

<给你的新角色一个额外的能力,edit_others_posts.决定后,单击“更新”。您的新角色现在应该具有read 功能加上您选择的功能。

现在,转到您的贡献者用户配置文件页面,并在页面末尾为他们提供额外的角色(用户角色编辑器功能):

enter image description here

现在,每个作为贡献者和帖子管理者的用户都可以更改未发布帖子的作者。根据您之前的选择,用户可能还会发布帖子,如果发布了,他们将无法再编辑帖子。

IMPORTANT!!!

我向您展示了一个创建新角色以保留贡献者默认功能的解决方案。If you want (not wise), you could skip the Post Manager creation and using User Role Editor you would just edit the Contributor capabilities directly.

为了记录在案,默认情况下WordPress只允许edit_others_posts 更改帖子作者的能力。看见https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-posts-list-table.php 第1483行。

结束

相关推荐

About Wordpress capabilities

我知道WordPress是博客引擎的最佳选择,通过一些插件,如Advance Custom Field,WP可以成为一个很棒的CMS。但它仍然有利于出版商将内容推送给用户。现在我的处境相当严峻。我的朋友想使用WP作为一个引擎,用户可以贡献他们的帖子,其他人可以查看它。是否可以使用WP我可以创建自定义主题(&a);插件可以做到这一点,但当用户在插件上放置很多东西(页面和帖子)时,它对性能有好处吗?