サイトアイコン Gatespace's Blog

カスタム投稿タイプと専用のユーザー権限(完結編)

この記事をシェアする

複数ユーザーでWordPressを運用する場合、オリジナルのユーザー権限とカスタム投稿タイプ(+カスタムタクソノミー)を組み合わせることで、運用しやすいダッシュボードを作ることが可能です。
前回はプラグインを用い、コードに疎くても簡単に実装する方法を記載しました。
しかしURLを直接入力するなど方法で、本来ならアクセスして欲しくないページにもアクセスされてしまいます。

今回は、カスタム投稿タイプ毎に権限をきっちりと作り、不要なアクセス(投稿など)が行われないようにします。
※なお、マルチサイトでの検証を行っていませんので、ご了承ください。

目標

カスタム投稿タイプ「report」とカスタムタクソノミー「reportcat」を作成する

前回はプラグインで作成しましたが、今回はfunctions.phpにコードを書いていきます。
(Custom Post Type UIではできない設定項目があります)

カスタム投稿タイプ、カスタムタクソノミーの作成方法や引数についてはCodexをご覧ください

function codex_custom_init() {
	/**
	* カスタムタクソノミー reportcat
	*/
	$reportcat_labels = array(
		'name' => "レポートカテゴリ",
		'singular_name' => "レポートカテゴリ",
		'search_items' => "カテゴリを検索",
		'all_items' => "すべてのカテゴリ",
		'parent_item' => "親カテゴリ",
		'parent_item_colon' => "親:",
		'edit_item' => "カテゴリを編集",
		'update_item' => "カテゴリを更新",
		'add_new_item' => "新規カテゴリ",
		'new_item_name' => "新規カテゴリ名",
		'menu_name' => "レポートカテゴリ",
	);

	register_taxonomy( 'reportcat', array( 'report' ), array(
		'hierarchical' => true,
		'labels' => $reportcat_labels,
		'show_ui' => true,
		'query_var' => true,
		'rewrite' => true,
		'capabilities' => array( 'assign_terms' => 'edit_post_reports' )
	));

	/**
	* カスタム投稿タイプ report
	*/
	$report_labels = array(
		'name' => "レポート",
		'singular_name' => "レポート",
		'add_new' => "新規追加",
		'add_new_item' => "新規レポート追加",
		'edit_item' => "レポートを編集",
		'new_item' => "新規レポート",
		'view_item' => "表示",
		'search_items' => "レポートを検索",
		'not_found' => "見つかりません",
		'not_found_in_trash' =>"ゴミ箱にはありません",
		'parent_item_colon' => '親',
		'menu_name' => 'レポート'
	);
	$report_args = array(
		'labels' => $report_labels,
		'public' => true,
		'publicly_queryable' => true,
		'show_ui' => true,
		'show_in_menu' => true,
		'query_var' => true,
		'rewrite' => true,
		'capability_type' => 'post_report', // 通常はpostだが任意のpost_reportにする
		'has_archive' => true,
		'hierarchical' => false,
		'menu_position' => 5,
		'map_meta_cap' => true,
		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
		'taxonomies' => array( 'reportcat' )
	);
	register_post_type( 'report', $report_args );
}
add_action( 'init', 'codex_custom_init', 0);

カスタム投稿タイプに独自の権限を作成するので 'capability_type' => 'post_report' としています。

また、register_taxonomy で 'capabilities' => array( 'assign_terms' => 'edit_post_reports' ) としています。capabilities は このタクソノミーを操作できる権限の割り当てです。assign_terms はおそらく投稿画面においてタクソノミーを選択できるかどうかの権限です。
デフォルトではedit_postsの権限に含まれており、カスタム投稿タイプの capability_type を post以外にした場合、権限グループによっては投稿画面で選択できなくなりますので edit_post_reports を指定しておきます。

権限を付与していく

さて、独自の権限つきのカスタム投稿タイプを作成できましたが、このままでは管理者であってもダッシュボードにメニューが出てこず投稿すらできませんので、WordPressデフォルトの権限グループとカスタム投稿タイプ「report」にのみ投稿できる「レポート投稿者(report_author)」に権限を付与していきます。
なお、加えるべき権限は $GLOBALS['wp_post_types']['カスタム投稿タイプ名']->cap にオブジェクトとして格納されています。(本家Codexに記載されています)

前述のコードの register_post_type 以降にコードを加えます。

/**
* post_report にかかわる権限の付与
*/
// 新しい権限グループ「report_author」の作成
add_role( 'report_author', 'レポート投稿者', array( 'read' => true ) );

// 権限グループをすべて取得
$roles = new WP_Roles();

// 付与すべき権限をすべて取得
$post_report_caps = $GLOBALS['wp_post_types']['report']->cap;

foreach ($roles->roles as $key => $value ) {
	if ( $key == "subscriber" ) continue; // 購読者はスキップ
	$role = get_role($key);
	if ( $key == "report_author" ) { // レポート投稿者の時
		$role->add_cap( "upload_files" ); // ファイルのアップロード権限付与
	}

	foreach ($post_report_caps as $post_report_cap) {
		if ( $post_report_cap == "read" ) continue; // read は既に登録されているのでスキップ
		if ( $key == "contributor" ) { // 投稿者に必要のない権限はスキップ
			if ( $post_report_cap == "delete_others_post_reports" ) continue;
			if ( $post_report_cap == "delete_private_post_reports" ) continue;
			if ( $post_report_cap == "edit_others_post_reports" ) continue;
			if ( $post_report_cap == "edit_private_post_reports" ) continue;
		} elseif ( $key == "author" ) { // 寄稿者に必要のない権限はスキップ
			if ( $post_report_cap == "delete_others_post_reports" ) continue;
			if ( $post_report_cap == "delete_private_post_reports" ) continue;
			if ( $post_report_cap == "delete_published_post_reports" ) continue;
			if ( $post_report_cap == "edit_others_post_reports" ) continue;
			if ( $post_report_cap == "edit_private_post_reports" ) continue;
			if ( $post_report_cap == "edit_published_post_reports" ) continue;
			if ( $post_report_cap == "publish_post_reports" ) continue;
		} elseif ( $key == "report_author" ) { // レポート投稿者に必要のない権限はスキップ
			if ( $post_report_cap == "delete_others_post_reports" ) continue;
			if ( $post_report_cap == "delete_private_post_reports" ) continue;
			if ( $post_report_cap == "edit_others_post_reports" ) continue;
			if ( $post_report_cap == "edit_private_post_reports" ) continue;
		}

		$role->add_cap( $post_report_cap );
	}
}

まずは新たな権限グループを作成します(66行目)。
使用する関数は add_role( $role, $display_name, $capabilities ) です(削除は remove_role( $role ) です)。

$roleでロールの名前(report_author)、$display_nameで表示名(レポート投稿者)、$capabilitiesで権限の付与を行います。
今回は権限は後でまとめて付与するので指定しなくてもOKです。

※2012.5.25追記:最低でも read 権限を付与しないとログインしてもダッシュボードが表示されませんでした。コードを訂正しておきます。

新しい権限グループが作成されたので、先ほど作ったカスタム投稿タイプにかかわる権限をすべての権限グループに付与していきます。

最初に登録されているすべての権限グループと付与すべき権限を取得します(69行目と72行目)。

74行目から103行目で、取得した権限グループをループで回しながら、処理を行う権限グループを get_role( $role ) で定義し、さらに取得した権限をループで回し add_cap( $role, $cap, $grant ) で付与していきます(削除は remove_cap( $role, $cap ) です)。
その際、特定の権限グループ(投稿者、寄稿者、リポート投稿者)では特定の権限(他者の投稿を編集できる、など)を付与しないようにスキップしています(82〜100行目)。
権限名はオリジナルのものですが、命名規則はデフォルトの権限と同じですので、Codexを参照にして工夫してみてください。

なお、今回のコードを書くにあたり、こちらのブログも参照させていただきました。
参考:SUSH-i LOG「カスタム投稿タイプに独自の権限を与えてみた」

ログイン後の画面遷移

このままでは「レポート投稿者」でログインするとユーザープロフィールに遷移してしまいます。
これは wp-login.php 589行目でユーザーが「edit_posts」権限を持っていないとprofile.phpに遷移するように指定されているためです。
だからといって、「edit_posts」権限を付与しては本末転倒ですので、ダッシュボードに遷移させるために login_redirect のフィルターを使います。

/**
* report_author のログイン後のリダイレクト先を変更
*/
function my_login_redirect( $redirect_to, $request, $user ) {
	// is there a user to check?
	if( !empty( $user->roles ) ) {
		// check for admins
		if( in_array( "report_author", $user->roles ) ) {
			// redirect them to the default place
			return home_url("/wp-admin/index.php");
		} else {
			return home_url("/wp-admin/");
		}
	}
}
add_filter("login_redirect", "my_login_redirect", 10, 3);

※2012.11.19追記:コメント欄で指摘のあったエラーを修正しました。

ずいぶんと長くなってしまいましたが、最後にこれらのコードをプラグイン化し、/wp-content/plugins/ にアップロード、有効化すれば、カスタム投稿タイプと専用のユーザー権限が完成です。

<php
/* Plugin Name: カスタム投稿タイプと専用ユーザー権限
Plugin URI: Description: カスタム投稿タイプ「report」とカスタムタクソノミー「reportcat」を作成し、専用の権限グループ「レポート投稿者(report_author)」を作成します。
Author: Your Name
Version: 1.0
Author URI:
*/
function codex_custom_init() {
	/**
	* カスタムタクソノミー reportcat
	*/
	$reportcat_labels = array(
		'name' => "レポートカテゴリ",
		'singular_name' => "レポートカテゴリ",
		'search_items' => "カテゴリを検索",
		'all_items' => "すべてのカテゴリ",
		'parent_item' => "親カテゴリ",
		'parent_item_colon' => "親:",
		'edit_item' => "カテゴリを編集",
		'update_item' => "カテゴリを更新",
		'add_new_item' => "新規カテゴリ",
		'new_item_name' => "新規カテゴリ名",
		'menu_name' => "レポートカテゴリ",
	);

	register_taxonomy( 'reportcat', array( 'report' ), array(
		'hierarchical' => true,
		'labels' => $reportcat_labels,
		'show_ui' => true,
		'query_var' => true,
		'rewrite' => true,
		'capabilities' => array( 'assign_terms' => 'edit_post_reports' )
	));

	/**
	* カスタム投稿タイプ report
	*/
	$report_labels = array(
		'name' => "レポート",
		'singular_name' => "レポート",
		'add_new' => "新規追加",
		'add_new_item' => "新規レポート追加",
		'edit_item' => "レポートを編集",
		'new_item' => "新規レポート",
		'view_item' => "表示",
		'search_items' => "レポートを検索",
		'not_found' => "見つかりません",
		'not_found_in_trash' =>"ゴミ箱にはありません",
		'parent_item_colon' => '親',
		'menu_name' => 'レポート'
	);
	$report_args = array(
		'labels' => $report_labels,
		'public' => true,
		'publicly_queryable' => true,
		'show_ui' => true,
		'show_in_menu' => true,
		'query_var' => true,
		'rewrite' => true,
		'capability_type' => 'post_report', // 通常はpostだが任意のpost_reportにする
		'has_archive' => true,
		'hierarchical' => false,
		'menu_position' => 5,
		'map_meta_cap' => true,
		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
		'taxonomies' => array( 'reportcat' )
	);
	register_post_type( 'report', $report_args );

	/**
	* post_report にかかわる権限の付与
	*/
	// 新しい権限グループ「report_author」の作成
	add_role( 'report_author', 'レポート投稿者' , array( 'read' => true ) );

	// 権限グループをすべて取得
	$roles = new WP_Roles();

	// 付与すべき権限をすべて取得
	$post_report_caps = $GLOBALS['wp_post_types']['report']->cap;

	foreach ($roles->roles as $key => $value ) {
		if ( $key == "subscriber" ) continue; // 購読者はスキップ

		$role = get_role($key);
		if ( $key == "report_author" ) { // レポート投稿者の時
			$role->add_cap( "upload_files" ); // ファイルのアップロード権限付与
		}
		foreach ($post_report_caps as $post_report_cap) {
			if ( $post_report_cap == "read" ) continue; // read は既に登録されているのでスキップ
			if ( $key == "contributor" ) { // 投稿者に必要のない権限はスキップ
				if ( $post_report_cap == "delete_others_post_reports" ) continue;
				if ( $post_report_cap == "delete_private_post_reports" ) continue;
				if ( $post_report_cap == "edit_others_post_reports" ) continue;
				if ( $post_report_cap == "edit_private_post_reports" ) continue;
			} elseif ( $key == "author" ) { // 寄稿者に必要のない権限はスキップ
				if ( $post_report_cap == "delete_others_post_reports" ) continue;
				if ( $post_report_cap == "delete_private_post_reports" ) continue;
				if ( $post_report_cap == "delete_published_post_reports" ) continue;
				if ( $post_report_cap == "edit_others_post_reports" ) continue;
				if ( $post_report_cap == "edit_private_post_reports" ) continue;
				if ( $post_report_cap == "edit_published_post_reports" ) continue;
				if ( $post_report_cap == "publish_post_reports" ) continue;
			} elseif ( $key == "report_author" ) { // レポート投稿者に必要のない権限はスキップ
				if ( $post_report_cap == "delete_others_post_reports" ) continue;
				if ( $post_report_cap == "delete_private_post_reports" ) continue;
				if ( $post_report_cap == "edit_others_post_reports" ) continue;
				if ( $post_report_cap == "edit_private_post_reports" ) continue;
			}

			$role->add_cap( $post_report_cap );
		}
	}
}
add_action( 'init', 'codex_custom_init', 0);

/**
* report_author のログイン後のリダイレクト先を変更
*/
function my_login_redirect( $redirect_to, $request, $user ) {
	// is there a user to check?
	if( !empty( $user->roles ) ) {
		// check for admins
		if( in_array( "report_author", $user->roles ) ) {
			// redirect them to the default place
			return home_url("/wp-admin/index.php");
		} else {
			return home_url("/wp-admin/");
		}
	}
}
add_filter("login_redirect", "my_login_redirect", 10, 3);

テーマのfunctions.phpに記載しても大丈夫ですが、テーマを切り替えるとカスタム投稿タイプとカスタムタクソノミーが使えなくなってしまいます(ただしデータベース上には残っています)のでご注意ください。

新しい権限グループは投稿や固定ページにアクセスする権限を持たないので、直接URLを入力してもエラー画面が表示されます。

レポート投稿者では投稿を編集できない

また、管理バーもあわせて変更されるので、前回書いた管理バー用のコードも必要ありません。

Codexを調べなから書きましたが、コードに問題点などあれば、ご指摘ください。

※今回はすべて自作コードにしましたが、追加すべき権限が分かっているのなら、前回の記事に書いたプラグインを使っても良いでしょう。

この記事をシェアする