咳咳,各位观众,晚上好!我是今晚的特邀码农讲师,江湖人称“代码挖掘机”。今天咱们要聊的是WordPress权限管理的骨架——Roles
和Capabilities
,重点深入add_role()
和add_cap()
这两个函数的底层运作机制。
为了避免大家听着犯困,我会尽量用轻松幽默的方式,把这些看似高深的代码逻辑掰开了、揉碎了,喂到你们嘴里。准备好了吗?Let’s dive in!
第一幕:Role与Capability——权限世界的基石
首先,咱们得明确一下,什么是Role,什么是Capability?
- Role (角色): 顾名思义,就是一种身份,比如管理员 (Administrator)、编辑 (Editor)、作者 (Author)、投稿人 (Contributor) 和订阅者 (Subscriber)。每种角色代表着一组特定的权限。你可以理解成一个预设好的权限模板。
- Capability (权限): 这才是真正干活的。Capability代表着对某个动作的许可,比如
edit_posts
(编辑文章)、delete_posts
(删除文章)、manage_options
(管理选项)等等。
Role和Capability的关系就像是:Role是套装,Capability是套装里的单品。一个Role包含了若干个Capability。
第二幕:add_role()
函数——创造角色的魔法棒
add_role()
函数的作用是创建一个新的Role。它的原型如下:
function add_role( string $role, string $display_name, array $capabilities = array() ): WP_Role|false {
global $wp_roles;
if ( isset( $wp_roles->roles[ $role ] ) ) {
return false;
}
$wp_roles->add_role( $role, $display_name, $capabilities );
return $wp_roles->get_role( $role );
}
是不是感觉有点懵?别怕,咱们逐行解读:
-
global $wp_roles;
: 声明$wp_roles
为全局变量。$wp_roles
是一个WP_Roles
类的实例,它负责管理所有的Roles。 -
if ( isset( $wp_roles->roles[ $role ] ) ) { return false; }
: 这段代码判断要添加的Role是否已经存在。如果存在,直接返回false
,防止重复添加。 -
$wp_roles->add_role( $role, $display_name, $capabilities );
: 这才是真正添加Role的地方。它调用$wp_roles
对象的add_role()
方法来完成添加操作。注意,这里是调用 WP_Roles 类的方法,而不是全局的 add_role() 函数本身! -
return $wp_roles->get_role( $role );
: 添加成功后,返回新创建的WP_Role
对象。
看到这里,你可能会问:全局函数add_role()
只是个壳子,真正的添加逻辑在 WP_Roles 类里?Bingo!答对了!
深入WP_Roles类的add_role()
方法
让我们看看 WP_Roles 类的 add_role()
方法的实现:
public function add_role( string $role, string $name, array $capabilities = array() ): void {
if ( isset( $this->roles[ $role ] ) ) {
return;
}
$this->roles[ $role ] = array(
'name' => $name,
'capabilities' => $capabilities,
);
$this->role_names[ $role ] = $name;
$this->set_role( $role );
/**
* Fires after a role is added.
*
* @since 2.0.0
*
* @param string $role Role name.
*/
do_action( 'add_role', $role );
}
-
if ( isset( $this->roles[ $role ] ) ) { return; }
: 再次检查Role是否已存在,这次是在$this->roles
数组中检查。 -
$this->roles[ $role ] = array( 'name' => $name, 'capabilities' => $capabilities, );
: 将Role的信息(包括名称和权限)存储到$this->roles
数组中。$this->roles
是 WP_Roles 类的一个成员变量,它是一个关联数组,存储了所有已注册的Roles的信息。 -
$this->role_names[ $role ] = $name;
: 将Role的名称存储到$this->role_names
数组中。这个数组主要用于快速查找Role的名称。 -
$this->set_role( $role );
: 这个方法至关重要!它负责将Role的信息持久化到数据库中。稍后我们会详细分析。 -
do_action( 'add_role', $role );
: 触发add_role
action hook,允许其他插件或主题在Role添加后执行自定义操作。
揭秘set_role()
方法——持久化的关键
set_role()
方法负责将Role的信息存储到WordPress的 wp_options
表中。让我们看看它的实现:
private function set_role( string $role ): void {
if ( empty( $this->roles ) ) {
return;
}
update_option( 'wp_user_roles', $this->roles );
$this->reinit_role( $role );
}
-
if ( empty( $this->roles ) ) { return; }
: 如果$this->roles
数组为空,直接返回。 -
update_option( 'wp_user_roles', $this->roles );
: 使用update_option()
函数将$this->roles
数组存储到wp_options
表中,option name为wp_user_roles
。这意味着所有的Roles信息都序列化后存储在一个option里。 -
$this->reinit_role( $role );
: 重新初始化指定的Role。
reinit_role()
方法
private function reinit_role(string $role): void
{
if (isset($this->roles[$role])) {
$this->roles[$role] = (object)$this->roles[$role];
}
}
这个方法将指定role从数组转换为对象。
第三幕:add_cap()
函数——赋予角色的神力
add_cap()
函数的作用是给指定的Role添加Capability。它的原型如下:
function add_cap( string $role, string $cap, bool $grant = true ): void {
global $wp_roles;
if ( ! is_object( $wp_roles ) ) {
$wp_roles = new WP_Roles();
}
$wp_roles->add_cap( $role, $cap, $grant );
}
和 add_role()
类似,全局函数 add_cap()
也是一个壳子,真正的添加逻辑在 WP_Roles 类中。
-
global $wp_roles;
: 声明$wp_roles
为全局变量。 -
if ( ! is_object( $wp_roles ) ) { $wp_roles = new WP_Roles(); }
: 确保$wp_roles
是一个WP_Roles
类的实例。 -
$wp_roles->add_cap( $role, $cap, $grant );
: 调用$wp_roles
对象的add_cap()
方法来完成添加操作。
深入WP_Roles类的add_cap()
方法
让我们看看 WP_Roles 类的 add_cap()
方法的实现:
public function add_cap( string $role, string $cap, bool $grant = true ): void {
if ( isset( $this->roles[ $role ] ) ) {
$this->roles[ $role ]['capabilities'][ $cap ] = $grant;
$this->update_role( $role );
}
}
-
if ( isset( $this->roles[ $role ] ) ) { ... }
: 检查指定的Role是否存在。 -
$this->roles[ $role ]['capabilities'][ $cap ] = $grant;
: 将指定的Capability添加到Role的capabilities
数组中。$grant
参数指定是否授予该权限(true
表示授予,false
表示拒绝)。 -
$this->update_role( $role );
: 更新Role的信息到数据库中。
update_role()
方法
private function update_role( string $role ): void {
update_option( 'wp_user_roles', $this->roles );
}
update_role()
方法非常简单,它只是调用 update_option()
函数将 $this->roles
数组更新到 wp_options
表中,option name 仍然是 wp_user_roles
。
第四幕:案例分析——实战演练
假设我们要创建一个新的Role,叫做 "Content Manager"(内容管理员),并赋予其 edit_posts
(编辑文章)和 publish_posts
(发布文章)的权限。我们可以这样做:
// 创建名为 "content_manager" 的Role,显示名称为 "Content Manager"
add_role( 'content_manager', 'Content Manager', array(
'edit_posts' => true, // 允许编辑文章
'publish_posts' => true, // 允许发布文章
));
// 或者,先创建Role,再添加Capability
add_role( 'content_manager', 'Content Manager' );
$role = get_role( 'content_manager' ); // 获取 WP_Role 对象
$role->add_cap( 'edit_posts' );
$role->add_cap( 'publish_posts' );
第五幕:总结与思考
今天我们深入剖析了 WordPress 的 add_role()
和 add_cap()
函数的底层实现。总结一下几个要点:
add_role()
和add_cap()
函数都是全局函数,但它们只是 WP_Roles 类相应方法的代理。- WP_Roles 类负责管理所有的Roles和Capabilities。
- Role的信息(包括名称和权限)存储在 WP_Roles 类的
$roles
数组中。 - Role的信息最终会被序列化后存储到
wp_options
表中,option name为wp_user_roles
。 update_option()
函数是持久化Role信息的关键。
思考题:
- WordPress是如何判断用户是否有某个Capability的?提示:想想
current_user_can()
函数。 - 如果直接修改
wp_options
表中的wp_user_roles
option,会发生什么?有什么需要注意的? - 你能否写一个函数,用于删除指定的Role?
希望今天的讲座对大家有所帮助。记住,代码的世界充满了乐趣,只要你敢于挖掘,就能发现更多精彩! 下次再见!