web-dev-qa-db-ja.com

寄稿者が自分の投稿の作者を変更できるようにしますか?

投稿者に自分の投稿の作者を変更させることは可能ですか?私はこれがポストから彼らを効果的に締め出すだろうことを実感します、それが私が欲しいものです。編集が終わったら、著者に変更を加えてもらいたいのです。

8
Michael Rogers

落とし穴:

作者(または寄稿者)がuser_has_capフィルタフックと関連するCODEを使って他の作者を自分の投稿に割り当てることを許可することは可能ですが、 このアプローチ自体は根本的に欠陥があります 。したがって、必要なセキュリティ対策をすべて講じても、機能アーキテクチャが完全に破壊されるため、依然として脆弱性となります。

シナリオの例を挙げましょう。作者の役割を持つユーザーが名誉ある意図を下回り、(おそらくスクリプトを使用して)多数の投稿で別の作家をスパムしているとします。宛先の作者が次にログインしたときに、自分の名前でそれらの投稿がすべて表示されます。他の作者がそれを止める方法がないのでこれは続きます!だから私たちはこの欠陥を持たない代替アプローチを見つけなければなりません。

より良いアプローチ

作成者の変更が必要な機能である場合は、作成者変更のプロセスに他の作成者(または他の編集者や管理者のような上級ユーザー)を関与させて、開始作成者が迷惑メールを送信できないようにします。宛先の作者.

これを達成するために、開始作者にエディタから宛先作者を選択させますが、投稿作者を直接変更することはしません。代わりに、投稿者の変更時に、送信先の投稿者IDを保存するカスタム投稿メタを保存します。その後、管理者パネル内に投稿サブメニューが表示され、そこに作者変更要求があるすべての投稿が表示されます。送り先の作者とedit_others_post機能を持つユーザ(編集者、管理者など)だけがこの作者変更要求UIにアクセスできます。 UIから、適切なアクセス権を持つユーザーが変更を承認し、その後で初めて作成者が変更されます。

承認待ちの間に投稿はどうなりますか?

CODEの実装は要件によって異なりますが、他のCODEの実装がなければ、作成者は投稿を変更したり、承認プロセスのウィンドウ内で作成者の変更要求を元に戻したりすることができます。投稿者の変更要求が承認されるとすぐに、投稿から締め出されます。

サンプルコード

注: この回答は進行中の作業です。サンプルコードを後で追加します。

2
Fayaz

私の最初のアプローチは却下され、これは適切な注目を集めなかったので、私は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');

_ note _ ナンスフィールドを追加して保存後にチェックすることを忘れないでください。また、最初の保存後にデータを処理するために、save_postの代わりに他のフック、つまりpre_post_updateまたはwp_insert_post_dataを使用することを検討することもできます。

それが役立つことを願っています!

1
Levi Dulstein

作成者ドロップダウンボックス は、ユーザーがedit_others_posts機能を持っている場合にのみ を表示します。しかし、明白な理由で、デフォルトでこの機能を作者に与えたくはありません。解決策は、特定の状況下、つまり自分の投稿の1つを編集しているときにのみ、この機能を付与することです。この機能はデータベースに書き込まれるため、他のページでも削除されていることを確認する必要があります。

これは正確なタイミングの問題です。機能を変更したい場合は、afterWPが投稿者を編集する権限を持っていると判断しましたが、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');
    }
  }

私はコードをテストしていないので、それはバグがあるかもしれませんが、あなたはアイデアを得ます。

0
cjbj