允许贡献者更改自己帖子的作者?


9

是否可以让贡献者更改自己帖子的作者?我意识到这将有效地将他们锁定在职位之外,这就是我想要的。我希望他们一旦完成编辑就可以更改作者。


在这里只是想知道是否还有另一种方式可以满足业务需求。赋予非编辑者/管理员能力以指派其他任何作者其职位似乎有点宽泛。是否存在可以分配为“作者”的预定义作者列表?贡献者和允许的作者之间是否存在任何已定义的关系?还是可以选择他们喜欢的任何作者?
anmari

我还注意到,这不会“发布”他们的帖子。因此,听起来好像是要模仿某种工作流,其中贡献者将帖子分配给作者,而不是说编辑选择“待处理”帖子进行审核。如果您的作者可能是编辑者,那么也许可以直接使用wp并使用标签而不是交流或突出显示哪些编辑者应该选择哪些帖子?
anmari

啊,你说“把他们锁在岗位之外,这就是我想要的”。这更重要吗?一旦他们“提交审查”,他们就不再能够编辑?有必要惹上“作者”吗?还是一些非公开身份的作品?也许使用codex.wordpress.org/Post_Status#Custom_Status
anmari

Answers:


1

我要添加第二个答案,因为我的第一种方法被否决了,并且该方法没有得到适当的关注。

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

注册元框:

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');

为您的元框构建标记:

/**
 * 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
 }

挂钩save_post以保存数据并覆盖作者:

/**
 * 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');

注意 请记住添加随机数字段,并在保存后检查。您也可以考虑使用其他挂钩代替save_post,即pre_post_updatewp_insert_post_data,以在初始后保存时处理数据。

希望有帮助!


1

陷阱:

即使可以允许作者(或贡献者)使用user_has_cap过滤器挂钩和一些相关的CODE 将另一位作者分配给他/她自己的帖子,但是,这种方法本身在根本上是有缺陷的。因此,即使您采取了所有必要的安全措施,它仍然是一个漏洞,因为它将功能架构分解在一起。

让我给您提供一个示例场景:假设具有作者角色的用户意图不佳,并且向拥有大量帖子(可能使用脚本)的另一位作者发送垃圾邮件。下一次目标作者登录时,他/她将以他/她的名字看到所有这些帖子!这将继续,因为其他作者无法阻止它!因此,我们必须找到一种没有此缺陷的替代方法。

更好的方法:

如果作者更改是必要的功能,则更好的方法是让其他作者(或其他编辑或管理员这样的高级用户)参与作者更改过程,以使发起作者可能无法向该作者发送垃圾邮件。目的作者。

为此,我们让发起作者从编辑器中选择目标作者,但我们不会直接更改帖子作者。相反,在更改作者时,我们将保存一个自定义帖子元,该元将保存目标作者ID。然后在管理面板中,我们将有一个帖子子菜单,其中将显示所有带有作者更改请求的帖子。只有目标作者和有edit_others_post能力的用户(例如编辑者,管理员等)才能访问此作者更改请求UI。具有正确访问权限的用户将从用户界面中批准更改,然后才进行最终的作者更改。

审批队列中的帖子会如何处理?

CODE的实现可能会根据要求而有所不同,但是,没有任何其他CODE的实现,发起作者将能够在批准过程的窗口内修改帖子,甚至还原作者的更改请求。作者变更请求获得批准后,他们将被锁定在职位之外。


0

作者下拉列表框在用户具有此edit_others_posts功能时显示。但是,出于明显的原因,您不想默认将此功能提供给作者。解决方案是仅在特定情况下(即当他正在编辑自己的帖子时)才提供此功能。由于该功能已写入数据库,因此您还必须确保在其他页面上将其删除。

这是一个精确的时间问题。您要 WP确定贡献者有权编辑帖子之后但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');
    }
  }

我没有测试过代码,因此可能有问题,但是您明白了。


-1

我试图通过过滤贡献者的元功能来实现您所需的功能,并且它似乎可以正常工作。我要做的只是edit_others_posts在WordPress请求时为贡献者添加功能。

但是,我会说这对我来说有点棘手,而且我不确定它是否完全安全。根据我将过滤器放入functions.phpWordPress 后的检查内容,贡献者无法在其他情况下编辑您所要求的其他用户的帖子。看起来不错,但是我们不能真正明确地检查当前用户是否是当前编辑的帖子的作者(如果将有条件检查添加到函数中,您将无法将帖子另存为其他用户)-让我担心

/**
 * 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 );

2
请注意,授予作者edit_others_posts权限实际上将使他们能够编辑其他人的帖子。我们同样可以使作者成为编辑,这可能比赋予他们更高的功能更好。第二种解决方案是可能的,但是需要做更多的工作,恕我直言。
斯科特(Scott)

我觉得这里的不赞成票是不公平的,我实际上是在回答中指出两点,指出第一个解决方案不安全,并指出第二个解决方案需要更多的工作,但是我认为这很有用,因为它显示了一个可行的解决方案OP可以改善(我不认为回答WPSE问题应该意味着提供生产就绪的代码段)。另外,如果您可以更精确地指出要改进的地方,或者如果要进行一些小的调整,甚至可以编辑我的帖子,这将非常有用。干杯!
Levi Dulstein '18

此外,关于edit_others_posts始终允许编辑其他用户的帖子,您并不完全正确。请从我的答案中测试代码-即使安装了过滤器if ( ! current_user_can( 'edit_post', $post_id ) )github.com / WordPress / WordPress / blob /…中的功能检查仍会返回false。再次,我确实同意这不是我的答案中提到的安全解决方案,但我认为值得一提,因为它确实有效。(对不起,连续两次发表评论,我不符合该字符数限制)
Levi Dulstein

-2

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

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

在此处输入图片说明

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

(现在不用担心贡献者的角色)

第一:

  • 为您的新角色提供两个额外的功能,edit_others_postspublish_posts
  • 这样,您的贡献者将只能编辑未发布的帖子(仅待处理和草稿帖子)。因此,如果贡献者仅更改帖子作者,他们仍然可以编辑该帖子。他们只会在发布后被禁止编辑该帖子。这也意味着,如果贡献者发布帖子而忘记更改作者,则他们将失去更改帖子作者的机会。

第二:

  • 为您的新角色提供一项额外的功能edit_others_posts
  • 这种方式与第一种方法一样,但是您的贡献者无法在这里发布,这意味着他们无法发布并且忘记更改作者。在这里,必须有人发布该帖子。

决定后,单击“更新”。现在,您的新角色应具有该read能力以及您选择的一个或多个角色。

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

在此处输入图片说明

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

重要!!!

我向您展示了一种创建新角色以保留贡献者默认功能的解决方案。如果需要(不明智的话),可以跳过Post Manager的创建,而使用User Role Editor,您只需直接编辑Contributor功能

仅作记录,默认情况下WordPress仅允许edit_others_posts更改帖子作者。参见https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-posts-list-table.php第1483行。


1
这使用户成为编辑器,无需为此安装插件,只需使用用户admin。无论如何,这不是OP所要求的。
马克·卡普伦

该解决方案明确允许贡献者更改帖子作者。所以,是的,这就是他的要求。其次,默认情况下,编辑器分配有20多种功能。我的解决方案没有使贡献者成为编辑者。让问我的人决定我的答案是否能解决他们的问题。请三思而后行。
filipecsweb

OP要求捐献者去做事。您的解决方案是让他的编辑器可以
Mark Kaplun
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.