Wordpressにて、自分に設定されている権限レベル以下の権限のみを取得して、
新規登録画面で登録出来る権限を制御できるようにしてみた。
権限一覧の取得
1
2
3
4
| function xx(){
global $wp_roles;
$all_roles = $wp_roles->roles;
}
|
出力
1
2
3
4
5
6
7
8
9
10
11
| [(権限名-スラッグ)] => Array
(
[name] => 権限名
[capabilities] => Array
(
[read] => 1
[level_0] => 1
権限内容
)
)
|
シリアライズ
自分に設定されている権限を取得する。
ただし、DBを直接除くとシリアライズされている。
とはいえ、取得は普通にWPの関数で可能。
get_user_meta(ID, 'wp_capabilities', true);
セットは以下のように
update_user_meta($user_id, 'wp_capabilities', ['staff' => 1]);
取得
自分のレベルを取得
1
2
| global $current_user;
$mylevel = $current_user->user_level;
|
これで一見取れているようにみえたが、なぜかレベルの低いユーザーもレベルが10と取得されてしまった。
なので、実際に入っているデータの、level_xx
を見て一致させていく泥臭い手法をとった。
1
2
3
4
5
6
7
8
9
10
11
12
| $uid = wp_get_current_user()->get('ID');
//自分のロール
$my_role = get_user_meta($uid, 'wp_capabilities', true);
$my_role = key($my_role);
$myobj = $wp_roles->role_objects[$my_role]->capabilities;
$mylevel = 0;
for($i = 10; $i>=0; $i--){
if(isset($myobj['level_'.$i]) && $myobj['level_'.$i]){
$mylevel = $i;
break;
}
}
|
アクセス可能な権限をレベルで判別
あとは取得したレベルと、権限の一覧のレベルを比べて、自分の方が大きければ取得していけばよい。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| global $wp_roles;
$aste_user_role = [];
foreach($wp_roles->role_objects as $key=>$role){
$level = 0;
for($i = 10; $i>=0; $i--){
if(isset($role->capabilities['level_'.$i]) && $role->capabilities['level_'.$i]){
$level = $i;
break;
}
}
if($mylevel >= $level){
$aste_user_role[] = [$key, $wp_roles->role_names[$key]];
}
}
|
結果
1
2
3
4
5
6
7
8
9
10
11
12
13
| array (size=8)
0 =>
array (size=2)
0 => string 'administrator' (length=13)
1 => string 'システム管理者' (length=21)
1 =>
array (size=2)
0 => string 'staff' (length=5)
1 => string 'スタッフ' (length=12)
2 =>
array (size=2)
...
...
|
表示
新規登録
新規登録画面への表示は、user_new_form
のフックで行う。
フック内でHTMLを直接書いて対応。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| //ユーザー登録画面
function user_new_form_css() {
?>
<table class="form-table">
<tr>
<th scope="row">権限ロール <span class="description">(必須)</span></th>
<td><select name="user_role">
<?php
$tempo = '';
foreach ($aste_user_role as $val) {
$selected = 'selected';
if($val[0] == 'subscriber'){
$tempo .= '<option value="' . $val[0] . '"' . $selected . '>' . $val[1] . '</option>';
}else{
$tempo .= '<option value="' . $val[0] . '" >' . $val[1] . '</option>';
}
}
echo $tempo;
?>
</select>
</td>
</tr>
</table>
<?php
}
add_action( 'user_new_form', 'user_new_form_css' );
|
編集
編集画面は、personal_options
のフックで対応。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| function add_profile_custom ($profileuser) {
//権限
global $aste_user_role; //自身が参照可能な権限リスト
set_aste_role();
$html = '<tr><th scope="row">権限ロール <span class="description">(必須)</span></th>';
$html .= '<td><select name="user_role">';
//このユーザーの権現を取得
$current_role = get_user_meta($profileuser->ID, 'wp_capabilities', true);
$current_role = key($current_role);
foreach ($aste_user_role as $val) {
$r = $current_role;
$selected = '';
if ($r == $val[0]) {
$selected = ' selected="selected" ';
}
$html .= '<option value="' . $val[0] . '"' . $selected . '>' . $val[1] . '</option>';
}
$html .= '</select></td></tr>';
echo $html;
}
add_action( 'personal_options', 'add_profile_custom');
|
登録処理
登録は新規は、user_register
、更新は、profile_update
。
どちらも処理としては同じ。
$_POST
から取得した値をシリアライズして入れる、のみ。
1
2
3
4
5
6
7
| function save_custom_options_fields( $user_id ) {
//権限ロール
$role_name = $_POST['user_role'];
update_user_meta($user_id, 'wp_capabilities', [$role_name => 1]);
}
add_action( 'profile_update', 'save_custom_options_fields' ); //更新
add_action('user_register', 'save_custom_options_fields'); //新規登録
|
既存のものを非表示に
既存で表示されている権限設定のセレクトボックスを非表示に。
新規登録
上記、新規登録で項目を追加したフックと同じ関数内で実装する。
特定のクラスもIDも振られてないので、x番目と指定して非表示とする。
ただし、これはCSS3となっているので非対応のブラウザだと見えてしまうと思う。
他にいい方法があれば知りたい。
1
2
3
| ?><style type="text/css">
table.form-table tr.form-field:nth-of-type(9)
</style><?php
|
編集
上記、編集で項目を追加したフックと同じ関数内で実装する。
こちらはクラスが振ってあるので、それを指定して非表示とする。
1
2
3
| ?><style type="text/css">
.user-role-wrap, /*権限グループ*/
</style><?php
|
まとめ
これにて完成。
非表示にする箇所がかなり無理矢理だけれども、なんとか見た目は整った。
プラグインなどを使えばこの辺一発で出来たりするのだろうか。
ちなみに、権限の編集にはプラグインを使用した。
WordPress › User Role Editor « WordPress Plugins
参考
security – Getting a List of Currently Available Roles on a WordPress Site? – WordPress Development Stack Exchange
wordpressのユーザ権限を管理画面以外から変更する必要があり、~ – Yahoo!知恵袋