投稿者に自分の投稿の著者を変更させることは可能ですか?私はこれが彼らをポストから効果的に締め出すことを理解しています、それが私が望んでいることです。編集が終わったら、著者に変更を許可してほしい。
投稿者に自分の投稿の著者を変更させることは可能ですか?私はこれが彼らをポストから効果的に締め出すことを理解しています、それが私が望んでいることです。編集が終わったら、著者に変更を許可してほしい。
回答:
私の最初のアプローチが不合格になり、これが適切な注意を引かなかったため、2番目の回答を追加します。
アイデアは、すべてのユーザーをリストし、作成者を変更するカスタムメタボックスを作成すること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');注: 
nonceフィールドを追加し、ポスト保存時にチェックすることを忘れないでください。またsave_post、pre_post_updateまたはの代わりに他のフックを使用してwp_insert_post_data、最初のポスト保存でデータを処理することを検討することもできます。
お役に立てば幸いです。
著者(または寄稿者)がuser_has_capフィルターフックといくつかの関連するCODE を使用して自分の投稿に別の著者を割り当てることを許可することは可能ですが、このアプローチ自体には根本的な欠陥があります。したがって、必要なセキュリティ対策をすべて講じたとしても、機能アーキテクチャをすべて壊してしまうため、依然として脆弱性です。
シナリオの例を挙げましょう:作成者の役割を持つユーザーが、立派な意図を持たず、多くの投稿(おそらくスクリプトを使用)で別の作成者にスパムを送信するとします。宛先の作者が次回ログインすると、彼/彼女の名前でそれらすべての投稿が表示されます!他の作者がそれを止める方法がないので、これは続くでしょう!したがって、この欠陥がない代替アプローチを見つける必要があります。
著者の変更が必要な機能である場合、より良いアプローチは、著者の変更のプロセスに他の著者(または他の編集者や管理者のようなより強力なユーザー)を関与させることです。宛先著者。
これを実現するために、開始著者に宛先著者をエディターから選択させますが、投稿著者を直接変更することはしません。代わりに、著者の変更時に、宛先の著者IDを保存するカスタム投稿メタを保存します。次に、管理パネル内に投稿サブメニューが表示され、投稿者変更リクエストを含むすべての投稿が表示されます。宛先の作成者と機能を持つユーザーedit_others_post(編集者、管理者など)のみが、この作成者変更リクエストUIにアクセスできます。UIから、適切なアクセス権を持つユーザーが変更を承認すると、最終的な作成者の変更が行われます。
CODEの実装は要件によって異なる場合がありますが、他のCODE実装がなければ、開始した作成者は投稿を変更したり、承認プロセスのウィンドウ内で作成者の変更要求を元に戻したりすることができます。著者変更リクエストが承認されるとすぐに、投稿はロックされます。
作成者ドロップダウンボックスは、ユーザーがedit_others_posts機能を持っている場合にのみ表示されます。ただし、明らかな理由により、デフォルトでこの機能を作成者に提供することは望ましくありません。解決策は、特定の状況下、つまり自分の投稿の1つを編集しているときにのみ、この機能を提供することです。機能はデータベースに書き込まれるため、他のページから削除されていることも確認する必要があります。
これは正確なタイミングの問題です。投稿者が投稿を編集する権利を持っていると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');
    }
  }私はコードをテストしていないので、バグがあるかもしれませんが、あなたは考えを理解しています。
貢献者のメタ機能をフィルタリングすることで必要なことを達成しようとしましたが、うまく機能しているようです。私がここで行うのは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 );edit_others_postsすると、基本的には他の投稿を編集できるようになります。著者を編集者にすることもできます。これは、より高い機能を提供するよりも優れています。2番目の解決策は可能性ですが、さらに作業が必要です、IMHO。
                    edit_others_posts他のユーザーの投稿の編集を常に許可することは完全に適切ではありません。私の回答からコードをテストしてください-フィルターを配置していてもif ( ! current_user_can( 'edit_post', $post_id ) )、github.com / WordPress / WordPress / blob /…の機能チェックでfalseが返されます。繰り返しになりますが、私の回答で述べた安全な解決策ではないことに同意しますが、実際に機能するため、言及する価値があると思いました。(2つのコメントを続けて申し訳ありませんが、文字数制限に適合しませんでした)
                    まず、プラグインのユーザーロールエディター(https://wordpress.org/plugins/user-role-editor/)をインストールします。
次に、プラグインを使用して、たとえばPost Managerという新しいロールを作成します。
新しいロールを作成した後、その機能を編集できます。さて、問題を解決した瞬間ですが、次の2つのオプションのいずれかを決定する必要があります。
(投稿者の役割についてはまだ心配しないでください)
最初:
edit_others_postsしpublish_postsます。第二:
edit_others_posts。決定後、「更新」をクリックします。これで、新しい役割に、選択したread機能に加えて機能が追加されます。
次に、寄稿者のユーザープロフィールページに移動し、ページの最後に追加の役割を与えます(ユーザー役割エディター機能)。
これで、投稿者であり投稿マネージャーであるすべてのユーザーが、非公開の投稿の投稿者を変更できるようになります。以前の選択に応じて、ユーザーは投稿を公開することもできますが、公開すると、投稿を編集できなくなります。
重要!!!
コントリビューターのデフォルト機能を保持するための新しいロールを作成するソリューションを紹介しました。必要に応じて(賢くはありません)、ポストマネージャーの作成をスキップし、ユーザーロールエディターを使用して、投稿者機能を直接編集することができます。
念のため、デフォルトでは、WordPress edit_others_postsは投稿者を変更する機能のみを許可します。https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-posts-list-table.php line 1483を参照してください。