2016 年 9 月 15 日 195日前)
2,656文字 (読了時間6分)

SPONSORED LINK

タイトルの通りですが、今日やってみたらできたので、軽くご紹介。

WordPressの権限についておさらい

WordPressにはcapability(権限)とrole(役割)という概念があります。Codexのユーザーの種類と権限が勉強になります。

edit_usersなら他のユーザーを編集する権限、manage_optionsなら設定をいじれる権限となります。で、これらのcapabilityを複数持つのが購読者、編集者、管理者などのroleですね。

これらのうち、meta_capという特殊な権限があり、これは「他の権限に翻訳される権限」です。たとえば、 edit_post というcapabilityは「投稿を編集する権限があるか」を意味するのではなく、「特定の投稿を編集する権限があるか」という使われ方をします。実際の使い方を見ると、こんな感じです。

// $post_idの投稿を編集できるか
if ( current_user_can( 'edit_post', $post_id ) ) {
    // なんかする
}

内部的には「投稿の編集画面に入れるか」などの判断に使われています。こういう他の権限に変換しうる権限をmeta_capと呼ぶわけですね。

条件付きの権限

さて、上で見たとおり、ユーザーの権限を判別する関数は引数を2つ取ることができます。この性質を利用して、条件付きの権限を考えてみましょう。破滅派の例で言うと、これまでのアクセス権はこんな感じでした。

  • 投稿者は電子書籍を書き出すことができず、編集者以上じゃないと駄目
  • 電子書籍ファイルへの一覧は編集者以上じゃないとアクセスできない

され、ここで「プレミアム電子書籍サービス」が誕生したとします。具体的に言うと、HamePub Enterprise(エンタープライズ向けePub作成代行)ですね。ここでは、特定のユーザー(お金を払った投稿者)は特定のプレミアム投稿だけ書き出せるようになります。「すべての自分の投稿」ではなく、特定の投稿ですね。

その投稿のIDが10だとすると、これがオッケーにならないといけないわけですね。

if ( current_user_can( 'publish_epub', 10 ) ) {
    // オーケーなはず
}

ここで、「特別な投稿」はカスタムフィールド _is_secret が1になっているとしましょう。で、それを判別する関数をis_secret_post()とすると以下のような分岐が可能です。

if ( is_secret_post( 10 ) ) {
    // true になる
}

これら2つを組み合わせ、current_user_can('publish_epub', $post_id) としたとき……

  • 編集者は常にtrueとなる。
  • 投稿者の場合、該当する投稿が自分のもので、かつプレミアム投稿ならtrue、そうじゃなければfalse

が実現する事になります。そのための具体的なフィルターがmap_meta_capです。早速コードを見てみましょう。

/**
 * ユーザーに特別な権限を付与する
 */
add_filter( 'map_meta_cap', function( $caps, $cap, $user_id, $args ) {
    switch ( $cap ) {
        case 'publish_epub':
            // 引数は$argsに入ってくる
            $post_id = $args[0];
            // デフォルトだとそのまま追加されるので、削除
            $index = array_search( $cap, $caps );
            if ( false !== $index ) {
                array_splice( $caps, $index, 1 );
            } 
            // 投稿を取得
            $post = get_post( $post_id );
            if ( $post->post_author != $user_id ) {
                // 投稿の作者とユーザーIDが一致していなければ、
                // それはつまり編集者と同等の権限がないとダメ
                $caps[] = 'edit_others_posts';
            } elseif ( is_secret_post( $post ) ) {
                // 投稿の作者とユーザーIDが一致しており、
                // なおかつそれがプレミアム投稿なら、
                // ユーザーは投稿権限を持っていればよい
                $caps[] = 'edit_posts';
            } else {
                // 上記に一致しない場合、存在しない権限を割り当てる
                // 結果的に「権限がない」ことになる
                $caps[] = 'do_not_allow';
            }
            break;
    }
    return $caps;
}, 10, 4 );

というわけで、map_meta_capフィルターを使って「権限を別の権限に置き換えるフローに割り込みする」という手法を使うと、わりと複雑な権限が実現できるかと思います。

プラグインだと「役割」ベースの監理をしてくれるヤツは多いですが、特定の条件を満たした時だけなんかしたいという需要は結構あると思うので、参考にしてください。

さて、僕が実行委員長を務めるWordCamp Tokyo 2016はいよいよ今週土曜日、9月17日です。申し込みはこちらから。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-09-12-25-22

 

フォローしてください

ここで会ったのもなにかの縁。
高橋文樹.comの最新情報を見逃さないためにもフォローをお願いします。
めったに送らないメルマガもあります。

SPONSORED LINK

この記事について

この記事はが2016 年 9 月 15 日にプログラミングの記事として公開しました。

高橋先生の電子書籍

高橋先生の電子書籍

Amazonで電子書籍も買えます。

好きな言葉

「川をのぼり下りするとしても、いったいいつまで続けられるとお思いですか?」
フロレンティーノ・アリーサは五十三年七ヶ月十一日前から、ちゃんと答えを用意していた。
「命の続く限りだ」と彼は言った。

— ガブリエル・ガルシア=マルケス

高橋先生の処女作

『途中下車』高橋文樹

2001年幻冬舎NET学生文学大賞受賞作です。

Web制作やります

Web制作やります

Web制作のご依頼は株式会社破滅派へ

不定期メルマガ

高橋文樹.comでは、不定期でニュースレターを配信しています。滅多に送らないので是非購読してください。

高橋文樹.comではプライバシーポリシーに準じて登録情報を取り扱います。