web-dev-qa-db-ja.com

特定の(カスタムタイプではない)ページとすべての子ページのみを編集できるカスタムユーザーロール

私のサイトにはいくつかの静的ページといくつかのカスタム投稿タイプがあります。私はstudentsというカスタムユーザーロールを作成し、特定のカスタム投稿タイプと特定の静的ページのみにアクセスできるようにします。

add_cap()を使用し、そのカスタム投稿タイプのためにregister_post_typeに渡される「capability_type」フィールドと「map_meta_cap」フィールドを設定することで、カスタム投稿タイプでこれを行う方法を理解しています。

しかしながら、私は一般的なページ(これはカスタムではありませんが、異なった内容で占められています)のためにこれをする方法を理解しません 。具体的には、internal-resourcesという親ページを使用して、その特定のページの編集機能をstudentユーザーに提供します。 internal-resourcesページのいくつかの子ページがあり、それらも編集できます。最後に、internal-resourcesの下に新しい子ページを作成できるようにしたいと思います。ただし、ResearchPeopleなどの他の静的ページは編集できません。これはそれほど難しくないはずですね。

助けてくれてありがとう!!

4
nViz

WordPressには、特定の投稿を編集するための機能(または任意のアクション)を役割に割り当てる方法はありません。

ただし、 map_meta_cap を使用して、機能チェックをフィルタリングし、その場で変更することができます。

投稿許可を処理する場合、WordPressは最終的に4つの機能だけを扱います。

  • edit_post
  • read_post
  • delete_post
  • publish_post

その後、投稿に対してアクションが実行されるたびに、これらの機能を「プリミティブ」機能にマッピングします。これらはあなたがもっとよく知っている能力です:

  • publish_posts
  • edit_posts
  • edit_others_posts
  • edit_private_posts
  • edit_published_posts
  • read
  • read_private_posts
  • delete_posts
  • delete_private_posts
  • delete_published_posts
  • delete_others_posts

create_postsもありますが、私が言うことができる限り、これはいくつかのRESTエンドポイントで、そして何らかのUIが表示されるかどうかを制御するためにのみ使用されます。投稿を保存するとき、create_postsedit_postsにマップされます。

map_meta_cap()がすることは、誰かが投稿を編集しようとしたときにどのプリミティブ機能が必要かを決定するということです。

そのため、ユーザーが投稿を編集しようとすると、map_meta_cap()は自分がその投稿の作者であるかどうかを確認します。そうであれば、edit_postメタ機能はedit_postsにマップされます。もし彼らが作者でなければ、それはedit_others_postsにマップされます。 WordPressはユーザーがマップされた機能を持っているかどうかを確認し、それに応じて応答します。

そのため、ページ単位で権限を変更したい場合は、map_meta_capをフィルタリングしてメタ機能の割り当て方法を変更する必要があります。

あなたの例では、Internal Resourcesページ(と他の人)のためにユーザにedit_pageをさせたいが、他のページは編集したくない。これを行うには、ダッシュボードの[ページ]メニューにアクセスする必要があるため、これは少し注意が必要です。そのため、studentロールにedit_pagesおよびpublish_pages機能を付与してから、フィルタを使用してページごとにこれらの機能を取り消す必要があります。

function wpse_293259_map_meta_cap( $required_caps, $cap, $user_id, $args ) {
    if ( in_array( $cap, ['edit_post', 'publish_post'] ) ) {
        $page_id = $args[0]; // The ID of the post being edited.
        $student_pages = [1,2,3]; // The IDs of the pages students are allowed to edit.

        /**
         * If the page being edited is not one students can edit, check if the user
         * is a student. If they are, set the required capabilities to 'do_not_allow'
         * to prevent them editing.
         */
        if ( ! in_array( $page_id, $student_pages ) ) {
            $user = new WP_User( $user_id );

            if ( in_array( 'students', $user->roles ) ) {
                $required_caps = ['do_not_allow'];
            }
        }
    }

    return $required_caps;
}
add_filter( 'map_meta_cap', 'wpse_293259_map_meta_cap', 10, 4 );

これは$student_pagesにないページの公開や編集を妨げます。

ユーザーがページを公開することを許可するための良い方法を見つけ出すことはできませんでしたが、それらが特定のページの子である場合に限られます。私が試した編集機能と公開機能のあらゆる組み合わせが、奇妙な振る舞いをもたらしました。子ページはページエディタで変更できるため、権限を管理するのに適した方法ではないと思います。つまり、投稿を公開してから編集するためにリダイレクトされるまでの間に、権限を変更することになります。

内部リソースページの編集を許可するために私が説明したテクニックを使うことをお勧めしますが、それからサブページをそれ自身の許可を持つ別の投稿タイプに分割します。

2
Jacob Peattie