WordPressでは、複数の投稿タイプ(カスタム投稿タイプ含む)を扱うサイトで、特定のユーザーまたはユーザーグループに対して編集できる投稿タイプを制限したいケースがあります。本記事では、ユーザーごとに編集可能な投稿タイプを制限する方法について、実装例を交えて紹介します。
なぜ投稿タイプの制限が必要なのか?
たとえば、地域団体や複数の管理担当者が投稿するサイトでは、それぞれに編集権限のある投稿タイプを限定することで、以下のようなメリットがあります。
- 誤操作や意図しない編集の防止
- 投稿の役割分担を明確化
- セキュリティと管理性の向上
実装方針 pre_get_posts と current_user_can() を活用
基本的な実装方針としては、下記のステップで制御します。
- 特定ユーザーごとに編集可能な投稿タイプを定義
- 投稿一覧・編集画面の表示をフィルターで制御
- 投稿の保存・更新時にもフックを使って制限
ユーザーと投稿タイプのマッピングを定義
以下のように、ユーザーIDと編集許可された投稿タイプを配列で定義します。
function get_user_allowed_post_types() {
$user = wp_get_current_user();
// ユーザーIDに応じた編集可能な投稿タイプ
$user_post_type_permissions = array(
2 => array('event', 'news'), // ユーザーID 2 は event, news の編集が可能
3 => array('custom_type'), // ユーザーID 3 は custom_type のみ編集可能
// 必要に応じて追加
);
return $user_post_type_permissions[$user->ID] ?? array();
}
投稿一覧・編集画面でアクセス制御する
管理画面上の投稿一覧に不要な投稿タイプが表示されないように制御します。
add_action('pre_get_posts', function ($query) {
if (!is_admin() || !$query->is_main_query()) return;
$screen = get_current_screen();
if (empty($screen->post_type)) return;
$allowed = get_user_allowed_post_types();
if (!in_array($screen->post_type, $allowed)) {
// 投稿タイプが許可されていない場合、一覧に表示しない
$query->set('post_type', 'none');
}
});
投稿の編集・保存自体をブロックする
投稿編集URLを直接開いた場合でも制限をかける必要があります。
add_action('admin_init', function () {
global $pagenow;
if ($pagenow === 'post.php' || $pagenow === 'post-new.php') {
$post_type = $_GET['post_type'] ?? get_post_type($_GET['post'] ?? null);
if ($post_type) {
$allowed = get_user_allowed_post_types();
if (!in_array($post_type, $allowed)) {
wp_die('この投稿タイプを編集する権限がありません。');
}
}
}
});
その他の対策(REST APIやメニューの非表示)
必要に応じて、REST API や管理画面メニューからも該当投稿タイプを非表示にすることも可能です。
add_action('admin_menu', function () {
$allowed = get_user_allowed_post_types();
$post_types = get_post_types(['_builtin' => false], 'names');
foreach ($post_types as $pt) {
if (!in_array($pt, $allowed)) {
remove_menu_page("edit.php?post_type=$pt");
}
}
});
まとめ
ユーザーごとに編集可能な投稿タイプを制限することで、運用の混乱を防ぎ、セキュアで役割分担された管理画面を実現できます。
複数投稿タイプを運用する大規模サイトや組織サイトでは、こうした制御は非常に有効です。