今日要製作的功能,就是將多重的role加入到我們的使用者之上,我們可以使用簡單的程式碼就可以加入了,而在role的產生,也可以藉由第三方的外掛,或是自己撰寫的擴充來支援,而我們可以基於單純使用的使用wp user來增加role,並且使用is_user_in_role
來當檢查的前哨,我們的is_user_in_role真的是曝光率極高,又非常實用的好東西!
$user_id = 12;
$user = new WP_User( $user_id );
if(false === is_user_in_role($user,'role-1')) $user->add_role( 'role-1' );
if(false === is_user_in_role($user,'role-2')) $user->add_role( 'role-2' );
我們的第一步可以見到,如果只是對於單一情況的增加是非常容易的,而更深入的開發就是要在每一個user之中,將role的欄位從dropdown list轉換成radio button,而我們的使用action主要有三個,編輯新增與顯示,我們只需要將三個要顯示的action加入我們的template來做替換,就可以做到了。
add_action('show_user_profile', 'go_ranger_multiple_role');
add_action('edit_user_profile', 'go_ranger_multiple_role');
add_action('user_new_form', 'go_ranger_multiple_role');
而在回傳的部分,也是將對應的條件回傳回去,每一個回傳的頁面就要有相對應得格式,如同下方:
add_action('personal_options_update', 'go_ranger_multiple_role_save');
add_action('edit_user_profile_update', 'go_ranger_multiple_role_save');
add_action('user_register', 'go_ranger_multiple_role_save');
但是我們三個更新的或是使用者加入的條件,都可以觸發到profile_update
,可以把三行整理成同一個action的recall function來做代替,而我們寫入一個刪除原生role的程式碼,而我們選用的本來是init
,不過在沒辦法確定的生命週期的關係,選擇渲染結束後,開始載入js檔案的admin_enqueue_scripts
。
add_action('admin_enqueue_scripts','enqueue_script_hide_roles');
function enqueue_script_hide_roles(){
wp_enqueue_script( 'go_ranger_hide_role', plugin_dir_url( __FILE__ ) . 'hide_role.js', array(), '1.0' );
}
window.onload = function(){
var target = document.querySelector('selelct[name="role"] tr');
if(typeof target == 'object') target.remove();
}
在刪除之後,我們就可以溫柔地將我們的template加入,與我們之前所說依樣,我們需要一個table來顯示我們的role,而我們第一步就是將我們的role 印出 ,並且製作成簡單的table放上,而為了安全性我們也是加上了nonce來確保沒有權限提升的問題。
function get_roles_list() {
global $wp_roles;
$all_roles = $wp_roles->roles;
$editable_roles = apply_filters('editable_roles', $all_roles);
return $editable_roles;
}
function go_ranger_multiple_role(){
wp_nonce_field( 'go-ranger-update-multiple-roles', 'go_ranger_multile_roles_nonce' );
$roles = get_roles_list();
include(__DIR__.'template/roles_extension.php');
}
//role_extension.php
<h2>多重roles在這</h2>
<table class="form-table">
<tr>
<th class="form-table-title"> Roles</th>
<td>
<?php
$user_roles = ( isset( $user->roles ) ) ? $user->roles : array();
foreach( $roles as $name => $label ){
$id = uniqid();?>
<label for='<?php echo $label.$id ?>'><?php echo $label; ?></label>
<input id='<?php echo $label.$id ?>' type="checkbox" value="<?php echo $name ?>">
<?php
}?>
</td>
</tr>
</table>
這樣我們就可以寫出簡單的陳列了,而我們得把有選過的程式碼加入checked的功能,所以我們在加入片段的程式碼。
<?php
$user_roles = ( isset( $user->roles ) ) ? $user->roles : array();
foreach( $roles as $name => $label ){
$id = uniqid();?>
<label for='<?php echo $label.$id ?>'><?php echo $label; ?></label>
<input id='<?php echo $label.$id ?>' nmae="go_ranger_mroles_array[]" type="checkbox" value="<?php echo $name ?>"
<?php
if( !is_empty( $user_roles)){
if(true === in_array( $name, $user_roles ) ) echo 'checked';
}
?>>
<?php
}?>
在完成模板後,就可以看到變成清單了,而最後就是將我們的程式碼寫入盡我們的DB之中,因為roles本來就是陣列,所以在擴充這個功能上幾乎是沒有遇到什麼大問題,而這邊我們寫上了nonce的街口,並且寫上了不同的post來取得我們回傳的程式碼。
function go_ranger_multiple_role_save($user_id){
if(false === isset( $_POST['go_ranger_multile_roles_nonce']) ||false === wp_verfiy_nonce($_POST['go_ranger_multile_roles_nonce'], 'go-ranger-update-multiple-roles' )) return;
if(false === current_user_can('promote_users')) return;
if( is_array( $_POST [ 'go_ranger_mroles_array' ] ) ) {
$new_roles = $_POST['go_ranger_mroles_array'];
$user = new WP_User( $user_id );
$roles = get_roles_list();
foreach( array_keys($roles) as role) {
$user->remove_role($role);
}
foreach( $new_roles as $role ){
$user->add_role($role);
}
return;
}else return;
}
這樣我們就能確保我們的編輯是可以有多重的roles,如果搭配我們前面的特價來用,你就可以把可以賒帳又五折的客人,與可以賒帳卻多收一成服務費的客人,使用功能性的role來做區別,而明天再將新增的使用者的部分,以及增加role的功能新增上去,來達到完整的多重role使用。
How to Add Custom User Roles on Your WordPress Site
Assign multiple roles to single users
how to Assign Multiple Roles for a user in wordpress?
admin_enqueue_scripts
user role editor