我們在開發的時候總是會想到,人們使用wordpress去做非常多的事情,其實你可以知道有些診所的系統、汽車雜誌、線上教育機構等等,上述這些都有非常多的複雜的商業模式,卻都可以使用wordpress來達成,今天的主題延續昨天的圖書館管理員,寫手可以上傳書本的簡介,但是批准的功能只有編輯可以做到,這邊可以活用出user role的可行範圍!
我們在新增刪除與更新使用者的函式之下(get_users
,wp_insert_user
,wp_update_user
,wp_delete_user
),平常想說直接做設定就好的假設,如果你有下述幾種情況的話,你可以更料姐為何我們那麼需要活用這個函式:
那現在我們操作建立一個我們永遠的地基主Rach來守護我們的圖書館,我們將會有一個而他永遠會在默默的注視著大家,而update與delete其實與其他部分的函式操作是大同小異,你只要拉對正確的user ID,你權限足夠你就可以對其做相對應的操作:
add_action( 'init', 'go_ranger_create_user' );
function go_ranger_create_user() {
if (username_exists( 'Rach' )) return;
$user = wp_insert_user([
'user_login' => 'Rach',
'user_email' => 'Rach@iTaiwan.com.tw',
'user_pass' => 'GGININDER',
'user_url' => 'https://www.rsirstudio.com/',
'display_name' => '你的地基主 Rach',
'role' => 'subscriber',
'description' => '守護靈在此誰敢放肆'
]);
}
我們先前提到的meta_data與使用者資料準備派上用場,我們所回傳的wp_user呢,其實可以在官網中的WP_USER中找到,而我們如果需要有其他欄位其實並不需要去繼承做一個新的class,而是走meta擴增,老話一句,想像力是你的超能力,你要你的使用者靠著更新書籍來補血加攻擊力都是可以的啦。
而我們要使用wp_get_current_user來確定到底是誰在操作,避免到守護靈的干擾,我們操作使用count_user_post來看誰打的多誰就是老大!
add_action( 'save_post', 'go_ranger_add_user_rating' );
function go_ranger_add_user_rating() {
$user = wp_get_current_user();
$level = get_user_meta( $user->ID, 'user_level', true );
if(esc_html($user->user_login) === 'Rach') update_user_meta( $user->ID, 'user_level', 'God' );
$posts = count_user_posts( $user->ID );
$level_list = array(10,50,100,150,300,500,1000);
for ($level_flag = 0; $level_flag <= count($level_list); $level_flag++) {
if($level_list[$level_flag] > $posts) break;
}
switch ($level_flag) {
case 0:
update_user_meta( $user->ID, 'user_level', '初出茅廬' );
break;
case 1:
update_user_meta( $user->ID, 'user_level', '初露鋒芒' );
break;
case 2:
update_user_meta( $user->ID, 'user_level', '精湛演技' );
break;
default:
update_user_meta( $user->ID, 'user_level', '我懶得想' );
}
}
我們上述的meta資料不只是可以這樣,資料的型態也可以由你自己傳入,想要物件或是陣列也可以由自己來做調整,你甚至也可以把三圍傳進去都是非常適合的啦,而操作meta_user也是依樣有三種add
,get
,update
與delete
組成,而我們利用這些資料,將我們館員貢獻的資料,在使用者編及的部分做一個kpa榜單,讓他們競競業業的幫我們新增書本,我知道怪怪的,但我得提到該怎麼用一下edit_user_profile
。
add_action( 'show_user_profile', 'go_ranger_user_collaborate' );
add_action( 'edit_user_profile', 'go_ranger_user_collaborate' );
function go_ranger_user_collaborate( $user ) {
$level = get_user_meta( $user->ID, 'user_level', true );
$posts = get_posts( [ 'numberposts' => -1 ] );
$posts_count = count_user_posts( $user->ID );?>
<h2>貢獻里程碑</h2>
<table class="form-table">
<tr>
<th><label for="go_ranger-favorite-post">等級</label></th>
<td><?php echo esc_html($level) ?></td>
</tr>
<tr>
<th><label for="go_ranger-favorite-post">Favorite Post</label></th>
<td>
<ol>
<?php foreach ( $posts as $post ) {
printf(
'<li>%s</li>',
esc_html( $post->post_title )
);
} ?>
<ol/>
</br>
<span class="description">你已經完成了<?php echo esc_html($posts_count) ?>書本上傳了!</span>
</td>
</tr>
</table>
<?php }
我們在講解options API時,有帶過user role,而在使用之前有個很重要的使用邏輯需要先釐清,role是沒有繼承性的,並不會因為原始邏輯的editor可以admin就可以,雖然在大部分的設定是這樣沒錯,打個比方,administrator是沒有比editor有更高的權限,我們如果有私有的editor的cap,那麼admin沒有被設定到就是不能使用,因為他的設定是權限,每一個能做到的事情都是分離的,我們可能對於比較直觀的想法是有繼承性的,我覺得wordpress也是有這種設計的味道,但事實上,他並沒有。
這就是role與capabilities的原理與關係,role中會有capabiltitis,而capabilities會限制roles是否可以執行,你也可以理解成這樣,capabilities可以看作是user的最小單位,他是一個設定權限的標準,而這個標準的集合就是roles,roles帶入就可以知道誰可以清楚劃分在集合之中,它包含的cap是否可以讓進行這項操作,而user也可以包含著多個role來操作,更詳細的分別可以參考節錄欄位中的介紹。
而我們主要講解的是在我們的role,設定的使用限制,在官網中稱為limiting access
,而wordpress主要分成兩種capabilities來決定你是否有你的admin中,是否有正確的權限可以做到安裝或是更特殊的core function use。
這一個設定是專門設定給特殊的role,以我們集合的邏輯,就是預設值會將role裡頭設定的cap指定給擁有這些role的使用者
這個叫特別是,他並不指定給role,他會將你的user_meta取出,也有可能是你的post或是tax,而這一個meta capabilities會再去對應到primitive capbilities,像是你可以刪除自己的文章,不能刪除別人的文章,這就是由meta caps而來,而admin可以刪你的文章則是來自於prim caps的設定,而我們可以使用map_meta_cap
來確定他回傳的meta cpas陣列中是否有足夠權限的caps來實行。
在這兩個解釋之下,我們先前current_user_can的操作是否更加明瞭了呢?一個能通吃role與caps的傢伙,還不好好用一波?
最後,我們都有自己的人與目標了,那我們要設定一個只限制在我們外掛的使用範圍中,不會去影響到我們其他資訊的role與caps,那我們預計新增兩種管理員與一般會員,而我們的caps則是設定四種讓他們可以創立之類的功能,這樣我們可以幫我們的使用者資訊章節做一個結尾
register_activation_hook( __FILE__, 'go_ranger_setup_role_caps' );
function go_ranger_setup_role_caps() {
$editor = get_role( 'editor' );
$editor->add_cap( 'add_book' );
$editor->add_cap( 'add_book_rating' );
// Add a forum moderator role.
add_role( 'library-manager', '偉大的圖書館管理員們', [
'read' => true,
'add_book' => true,
'add_book_rating' => true
] );
$admin = get_role( 'administrator' );
$admin->add_cap( 'add_book' );
$admin->add_cap( 'add_book_rating' );
$admin->add_cap( 'ultimate_reading' );
$admin->add_cap( 'delete_scumbag' );
add_role( 'library_administrator', 'Your father', [
'read' => true,
'add_book' => true,
'add_book_rating' => true,
'ultimate_reading' => true,
'delete_scumbag' => true
] );
}
度過了漫長的一天,這就是簡單如何實作客製化自己的role與caps的應用,我們可以經由這些設定,讓之後的操作更加有安全性,也可以設定role來當電商的vip等級權限,一註冊會員,輸入邀請碼TK888,馬上送一個魔關羽當地基主,陪你開心新增書籍,最後的範例,也可以加上,在套件關閉要刪除,則可以加入delete_role
來做這些,這些有擴充性的功能,也需要更多的學習,才有辦法讓安全性與效能並存。
下面也有提供人家寫的外掛,可以下載來看看對於role比較擅長的作者所撰寫的程式碼,是如何操作的,而這邊也可以說說比較常被使用的應用,role如果單純來使用,也是可以被當作折扣的等級來用,再搭配woocommerce的套件,可以針對woocommerce_get_variation_prices_hash
進行user_role的折扣,而如果又是部分商品的話,也可以操作各別的Product Id折扣不一定樣在做不一樣的條件設定。
capabilites
wp_get_current_user
WORDPRESS ROLES CAPABILITIES – 帳號角色與功能
WordPress 角色(Role)與權限(capability)簡介 - 資料較舊(2010)
Beginner’s Guide to WordPress User Roles and Permissions
Roles and Capabilities
7 WordPress Plugins To Extend User Roles and Capabilities
Change product prices via a hook in WooCommerce 3