はい、どーも。
ユーザーに、既存記事の編集などはさせたいけれども、新規追加はさせたくない、例えば、編集者権限で記事の追加を行い、投稿者で編集のみを担当させるなんて場合に使える、いつ使うかわからないようなニッチな内容を紹介します。
と、いいつつ、この実現方法は、CODEX にも載ってないため、正式な仕様として扱っていいのか分かりません。
利用するときは自己責任でお願いいしますね。
var_dump( get_post_type_object( 'post' ) );
などとして、投稿のオブジェクトを表示すると、cap プロパティに create_posts というプロパティが存在しているのが分かります。
["cap"]=>
object(stdClass)#1932 (15) {
["edit_post"]=>
string(9) "edit_post"
["read_post"]=>
string(9) "read_post"
["delete_post"]=>
string(11) "delete_post"
["edit_posts"]=>
string(10) "edit_posts"
["edit_others_posts"]=>
string(17) "edit_others_posts"
["publish_posts"]=>
string(13) "publish_posts"
["read_private_posts"]=>
string(18) "read_private_posts"
["read"]=>
string(4) "read"
["delete_posts"]=>
string(12) "delete_posts"
["delete_private_posts"]=>
string(20) "delete_private_posts"
["delete_published_posts"]=>
string(22) "delete_published_posts"
["delete_others_posts"]=>
string(19) "delete_others_posts"
["edit_private_posts"]=>
string(18) "edit_private_posts"
["edit_published_posts"]=>
string(20) "edit_published_posts"
["create_posts"]=>
string(10) "edit_posts"
}
この create_posts というプロパティが、新規追加ができるかどうかの権限に利用されているのですが、このプロパティは通常、edit_posts プロパティと同値となっていて、通常の指定方法では切り分けができません。
ただし、register_post_type の capabilities を指定することによって、edit_posts とは異なる値を指定することができます。
register_post_type で cretate_posts を指定する
下記の様に、capabilities の指定を行うと、
register_post_type( 'character', array( 'label' => 'キャラクター', 'public' => true, 'show_ui' => true, 'capability_type' => 'post', 'capabilities' => array( 'create_posts' => 'create_characters' ), 'map_meta_cap' => true, 'has_archive' => true, 'menu_position' => 8, 'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ) ) );
["cap"]=>
object(stdClass)#1932 (15) {
["edit_post"]=>
string(9) "edit_post"
["read_post"]=>
string(9) "read_post"
["delete_post"]=>
string(11) "delete_post"
["edit_posts"]=>
string(10) "edit_posts"
["edit_others_posts"]=>
string(17) "edit_others_posts"
["publish_posts"]=>
string(13) "publish_posts"
["read_private_posts"]=>
string(18) "read_private_posts"
["read"]=>
string(4) "read"
["delete_posts"]=>
string(12) "delete_posts"
["delete_private_posts"]=>
string(20) "delete_private_posts"
["delete_published_posts"]=>
string(22) "delete_published_posts"
["delete_others_posts"]=>
string(19) "delete_others_posts"
["edit_private_posts"]=>
string(18) "edit_private_posts"
["edit_published_posts"]=>
string(20) "edit_published_posts"
["create_posts"]=>
string(17) "create_characters"
}
のように、create_posts の値に、capabilities で指定した create_characters が反映しているのが分かります。
この状態で、管理画面のメニューを表示すると

と、メニューに新規追加が表示されていない事が分かります。
また、直に新規作成のURLにアクセスした場合も

権限がないため、すげなくあしらわれてしまいます。
あとは、User Role Editor などで、変更した create_posts の権限を編集者など特定の権限グループに追加すれば大丈夫です。
標準の投稿タイプの変更方法
カスタム投稿などの場合は、register_post_type での指定で済まされますが、標準の投稿や固定ページの新規作成を制限したい場合はどうすればよいでしょうか。
この場合は、残念ながら投稿タイプの権限を後から書き換える関数が存在していないため、少々強引ですが、投稿タイプのオブジェクトが格納されているグローバル変数 $wp_post_types を書き換えるか、再度、register_post_type を実行して投稿タイプ自体を上書きすることになります。(両方とも若干微妙な方法ですが。。)
以下が、投稿の新規作成権限を create_posts に変更するためのサンプルコードです。
グローバル変数を上書きする方法
$wp_post_types['post']->cap->create_posts = 'create_posts';
register_post_type で上書きする方法
※ wp-includes/post.php の標準の投稿タイプの登録を行っている部分から、コピーしてきて変更する部分を追記すると間違いがありません。
register_post_type( 'post', array( 'labels' => array( 'name_admin_bar' => _x( 'Post', 'add new on admin bar' ), ), 'public' => true, '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ 'capability_type' => 'post', 'capabilities' => array( 'create_posts' => 'create_posts' ), 'map_meta_cap' => true, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'delete_with_user' => true, 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ), ) );
これで、投稿や固定ページなども新規追加を、編集とは別の権限として利用できるようになります。
ただし、現状1つ抜けがあって、ダッシュボードのクイック投稿の表示条件、この create_posts ではなく、edit_posts が固定的に指定されているために非表示になりません。このクイック投稿については、別途 remove_meta_box で削除する必要があります。