MoyaSystem

もやしです。

BuddyPressで管理者以外のユーザを管理画面にアクセスさせない制御

そもそも

BuddyPressで会員制サイトを構築させる際、管理者以外のユーザには管理画面を見せたくない。
そのため次の記事を参考にスクリプトを埋め込んでいた。

【WordPress】管理者以外のユーザーが管理画面にアクセスしたらリダイレクトさせる方法

<?php
add_action( 'admin_init', 'disable_admin_pages' );
function disable_admin_pages() {
	if(!current_user_can('administrator')){
		$redirect_url = get_option('home');
		header("Location: ".$redirect_url);
		exit;
	}
}
?>

問題

このスクリプト、単純なWordPressのサイトを運営する分には十分なのですが、BuddyPressに適用させると弊害を生んでしまうのですね。
BuddyPressはプライベートメッセージ機能をはじめ、管理者以外のユーザでもadmin-ajax.phpにリクエストを飛ばして処理する部分が結構ある。
このadmin-ajax.phpを動かす過程でadmin-initのアクションフックが動く!
ということは、このタイミングでリダイレクトさせるとajaxの処理が動かない!
そればかりかajaxの返り値がトップページのHTMLに置き換わるので、画面がカオスなことになる!

ではどうするか

<?php
add_action('admin_init', 'disable_admin_pages' );
function disable_admin_pages() {
	if(!current_user_can('administrator')
		&& strpos($_SERVER['REQUEST_URI'] ,'admin-ajax') === false){
		$redirect_url = get_option('home');
		header("Location: ".$redirect_url);
		exit;
	}
}
?>

wp/wp-adminにアクセスされたときにリダイレクトするにはadmin_initのタイミングで飛ばすしかない。ただしadmin-ajax.phpを動かす処理だけは通したい。ということで条件を追加。
当然、admin-ajaxを含み、かつ管理画面にアクセスするリクエストだとどうにもならないのですが、今のところ無さそうなのでこれでいきます。

追記

以前書いたこの記事、要するにこのリダイレクトが原因だった訳ですね。BuddyPressさんdisってすみませんでした。。
WordPressでは管理者以外AjaxでPHPからの返り値を受け取れないという衝撃の事実 - MoyaSystem