2026年5月20日

2026年5月20日

ユーザーロールと権限をカスタマイズする方法|add_role・add_cap・カスタム投稿タイプの権限

WordPress では、ユーザーにできること(投稿の公開、プラグインの有効化など)を「権限(capability)」で管理し、権限をまとめたものを「ロール(権限グループ)」としてユーザーに割り当てます。既定のロールで足りないときは、独自のロールを作ったり、既存のロールに権限を足し引きしたりできます。

この記事の関数と既定の権限は、developer.wordpress.org の「Roles and Capabilities」と WordPress 6.9 のソースコード、WP-CLI のコマンドは WP-CLI 本体のヘルプで2026年10月時点の内容を確認しています。

既定のロールと主な権限

単一サイトの WordPress には次の5つのロールがあります(マルチサイトでは、これに全サイトを管理する「特権管理者」が加わります)。

ロール(スラッグ) できること 代表的な権限
管理者(administrator) サイトのすべての管理 manage_options、activate_plugins、edit_theme_options、create_users
編集者(editor) 他人の投稿・固定ページも含めた編集と公開、コメントやカテゴリーの管理 edit_others_posts、edit_pages、manage_categories、moderate_comments
投稿者(author) 自分の投稿の作成・公開、画像のアップロード publish_posts、edit_published_posts、upload_files
寄稿者(contributor) 自分の投稿の作成(公開はできず、レビュー待ちで提出) edit_posts、delete_posts
購読者(subscriber) ログインとプロフィールの編集 read

ロールと権限の一覧はデータベースの wp_options テーブルに、オプション名 wp_user_roles(wp_ はテーブル接頭辞)として保存されています。現在の状態は WP-CLI で確認できます。

# ロールの一覧
wp role list

# 編集者ロールが持つ権限の一覧
wp cap list editor

WP-CLI の基本は WP-CLIの基本コマンド を参照してください。

大事な前提: ロールの変更はデータベースに保存される

add_role()・remove_role()・add_cap()・remove_cap() は、実行するとその結果がデータベースに書き込まれます。コードを消しても変更は残り、毎回のリクエストで実行する必要はありません。

  • init などで毎回実行すると、そのたびにデータベースへの書き込みが起き、管理画面やプラグインで変えた権限がコードの内容で上書きされます。
  • テーマやプラグインのコードでは、「一度だけ実行する」仕組み(バージョン番号をオプションに保存して比較する、プラグインの有効化時に実行する)を用意します。

手順1: 独自のロールを作る

例として、投稿の編集・公開とカテゴリー・コメントの管理はできるが、固定ページ・テーマ・プラグイン・設定には触れない「コンテンツ管理者」ロールを作ります。

<?php
// functions.php またはサイト用の独自プラグイン
function mytheme_setup_roles() {
    $version = '1';
    if ( get_option( 'mytheme_roles_version' ) === $version ) {
        return; // 実行済みなら何もしない
    }

    remove_role( 'content_manager' ); // 作り直すときのために一度消す(無ければ何もしない)
    add_role(
        'content_manager',          // ロールのスラッグ
        'コンテンツ管理者',            // 画面に表示される名前
        array(
            'read'                   => true,
            'edit_posts'             => true,
            'edit_others_posts'      => true,
            'edit_published_posts'   => true,
            'publish_posts'          => true,
            'delete_posts'           => true,
            'delete_others_posts'    => true,
            'delete_published_posts' => true,
            'upload_files'           => true,
            'manage_categories'      => true,
            'moderate_comments'      => true,
        )
    );

    update_option( 'mytheme_roles_version', $version );
}
add_action( 'admin_init', 'mytheme_setup_roles' );
  • add_role() は、同じスラッグのロールが既にあると何もしません。権限の内容を変えたいときは、$version を '2' に上げると、remove_role() で消してから作り直されます。
  • 権限の配列に書かなかった権限は「持っていない」扱いです。'manage_options' => false のように書く必要はありません。
  • ロールを作り直しても、そのロールが割り当てられたユーザーの設定は保たれます(ユーザーにはロールのスラッグが保存されているため)。

コードを書かずに作る場合は WP-CLI で既存ロールを複製できます。

# 投稿者ロールの権限をコピーして新しいロールを作る
wp role create content_manager 'コンテンツ管理者' --clone=author

# 権限を追加する
wp cap add content_manager edit_others_posts delete_others_posts manage_categories moderate_comments

作ったロールは、「ユーザー」→ 各ユーザーの編集画面の「権限グループ」で選べます。WP-CLI なら wp user set-role <ユーザー名> content_manager です。

手順2: 既存のロールに権限を足す・外す

既存ロールの権限は get_role() でロールを取り出し、add_cap()・remove_cap() で変えます。例として、編集者に「外観」→「メニュー」と「ウィジェット」を触らせるため、edit_theme_options を与えます。

<?php
function mytheme_update_editor_caps() {
    if ( get_option( 'mytheme_editor_caps_version' ) === '1' ) {
        return;
    }

    $editor = get_role( 'editor' );
    if ( $editor ) {
        $editor->add_cap( 'edit_theme_options' );   // 外観のメニュー・ウィジェットなど
        $editor->remove_cap( 'moderate_comments' ); // コメントの承認はさせない
    }

    update_option( 'mytheme_editor_caps_version', '1' );
}
add_action( 'admin_init', 'mytheme_update_editor_caps' );
  • edit_theme_options を与えると、メニュー・ウィジェットに加えてカスタマイザーや、ブロックテーマではサイトエディターも使えるようになります。与える権限が何を開放するかを確かめてから追加してください。
  • プラグインのインストール(install_plugins)やユーザー作成(create_users)を管理者以外に与えると、その人がサイト全体を操作できるのと変わらなくなります。

既定のロールを WordPress の初期状態に戻すには、WP-CLI の wp role reset を使います。

# 編集者ロールを既定の権限に戻す
wp role reset editor

手順3: カスタム投稿タイプに専用の権限を付ける

既定では、カスタム投稿タイプは通常の投稿と同じ権限(edit_posts など)で編集できます。「ニュースだけ編集できる人」を作るには、投稿タイプの登録時に capability_type と map_meta_cap を指定して専用の権限名にします。

<?php
function mytheme_register_news() {
    register_post_type( 'news', array(
        'label'           => 'ニュース',
        'public'          => true,
        'has_archive'     => true,
        'show_in_rest'    => true,
        'supports'        => array( 'title', 'editor', 'thumbnail' ),
        'capability_type' => array( 'news_item', 'news_items' ), // 単数形・複数形
        'map_meta_cap'    => true,
    ) );
}
add_action( 'init', 'mytheme_register_news' );

capability_type を単数形と複数形の配列で渡すと、次の権限名が使われます(文字列で 'news' とだけ書くと、複数形は末尾に s を付けた edit_newss のような名前になります)。

意味 権限名
自分のニュースを編集・新規作成 edit_news_items
他人のニュースを編集 edit_others_news_items
公開済みのニュースを編集 edit_published_news_items
非公開のニュースを編集・閲覧 edit_private_news_items、read_private_news_items
ニュースを公開 publish_news_items
ニュースを削除 delete_news_items、delete_others_news_items、delete_published_news_items、delete_private_news_items

edit_news_item・read_news_item・delete_news_item(単数形)は「この1件を編集できるか」を判定するメタ権限で、map_meta_cap が上の権限に置き換えて判定します。ロールに与えるのは上の表の権限だけです。

登録しただけでは、管理者を含めて誰もこの権限を持っていないため、管理画面に「ニュース」が表示されなくなります。管理者とコンテンツ管理者に権限を与えます。

<?php
function mytheme_grant_news_caps() {
    if ( get_option( 'mytheme_news_caps_version' ) === '1' ) {
        return;
    }

    $caps = array(
        'edit_news_items',
        'edit_others_news_items',
        'edit_published_news_items',
        'edit_private_news_items',
        'read_private_news_items',
        'publish_news_items',
        'delete_news_items',
        'delete_others_news_items',
        'delete_published_news_items',
        'delete_private_news_items',
    );

    foreach ( array( 'administrator', 'content_manager' ) as $role_name ) {
        $role = get_role( $role_name );
        if ( ! $role ) {
            continue;
        }
        foreach ( $caps as $cap ) {
            $role->add_cap( $cap );
        }
    }

    update_option( 'mytheme_news_caps_version', '1' );
}
add_action( 'admin_init', 'mytheme_grant_news_caps' );

自分のニュースだけを書かせて公開はさせない人には、edit_news_items と delete_news_items だけを与えます(通常の投稿の寄稿者と同じ考え方です)。

手順4: コードの中で権限を確かめる

自作の処理で「この人に実行させてよいか」を判定するときは、ロール名ではなく権限名で current_user_can() を呼びます。

<?php
// 正しい: 権限で判定する
if ( current_user_can( 'publish_news_items' ) ) {
    // ニュースを公開できる人だけの処理
}

// 特定の投稿を編集できるか(メタ権限は投稿IDと一緒に使う)
$post_id = 123;
if ( current_user_can( 'edit_post', $post_id ) ) {
    // この投稿を編集できる人だけの処理
}

// ロールそのものを確かめる必要があるときは、ユーザーのロール一覧を見る
$user = wp_get_current_user();
if ( in_array( 'content_manager', (array) $user->roles, true ) ) {
    // コンテンツ管理者の処理
}

current_user_can( 'content_manager' ) のようにロール名を渡す書き方は一部動きますが、WordPress のリファレンスで「信頼できない結果になることがあるので推奨しない」とされています。

手順5: 管理画面のメニューを整理する

権限を持たないメニューは WordPress が自動で隠します。それでも表示を減らしたいときは remove_menu_page() を使えます。

<?php
function mytheme_simplify_menu_for_content_manager() {
    $user = wp_get_current_user();
    if ( in_array( 'content_manager', (array) $user->roles, true ) ) {
        remove_menu_page( 'tools.php' ); // 「ツール」を隠す
    }
}
add_action( 'admin_menu', 'mytheme_simplify_menu_for_content_manager', 999 );

remove_menu_page() はメニューを隠すだけで、URL を直接開けば画面に入れます。操作を禁止したいときは、メニューを隠すのではなく、その操作の権限をロールから外してください。

ロールを削除する・元に戻す

独自ロールを削除すると、そのロールだったユーザーはロールなしの状態になり、管理画面に入れなくなります。先に別のロールへ移してから削除します。

# content_manager のユーザーを確認して、投稿者に移す
wp user list --role=content_manager --fields=ID,user_login
wp user set-role 12 author

# ロールを削除する
wp role delete content_manager

テーマの切り替え時にコードで片付ける場合は switch_theme フックで remove_role() を呼び、手順1〜3で使ったバージョン用のオプションも削除します。

<?php
function mytheme_cleanup_roles() {
    remove_role( 'content_manager' );
    delete_option( 'mytheme_roles_version' );
    delete_option( 'mytheme_news_caps_version' );
}
add_action( 'switch_theme', 'mytheme_cleanup_roles' );

注意点

  • 権限を変えたら、そのロールのテスト用ユーザーでログインし、必要な画面が開けること、開けてはいけない画面が開けないことを確認します。
  • 1人のユーザーに複数のロールを持たせることもできますが($user->add_role())、標準のユーザー編集画面では1つしか表示・選択できません。
  • ロール管理のプラグインを使っている場合、コードとプラグインの両方で同じロールを変えると、どちらの設定が残るかわかりにくくなります。どちらか一方に寄せてください。

まとめ

  • ロールと権限はデータベースに保存されるので、add_role()・add_cap() は一度だけ実行する
  • 独自ロールは add_role() か wp role create --clone= で作り、権限は add_cap()・remove_cap() か wp cap add・wp cap remove で調整する
  • カスタム投稿タイプは capability_type(単数形・複数形)と map_meta_cap で専用の権限にし、管理者にも権限を与える
  • 判定は current_user_can() に権限名を渡す。メニューを隠しても操作の制限にはならない

お気軽にご相談ください

お見積りへ お問い合わせへ
▲