返回 方案二:使用
WooCommerce订阅激活自动分配自定义用户角色
php
2024-11-11 18:59:29
WooCommerce订阅激活后自动分配自定义用户角色
为用户在WooCommerce订阅激活后自动分配自定义角色,例如"Active Production Company",以便访问特定功能(例如WP Job Manager创建的表单),是一个常见的需求。实现这个功能需要准确地获取用户ID和使用合适的钩子。下面分析几种解决方案以及它们的优缺点。
方案一:优化现有代码
你提供的代码思路是正确的,使用woocommerce_subscription_status_updated
钩子,但在获取用户ID和处理角色分配上可以优化。
add_action( 'woocommerce_subscription_status_updated', 'wc_subscribe_assign_role', 10, 3 );
function wc_subscribe_assign_role( $subscription, $new_status, $old_status ) {
if ( $new_status === 'active' && $old_status !== 'active') { // 避免重复添加角色
$user_id = $subscription->get_customer_id(); // 使用 get_customer_id() 获取用户ID
if( $user_id ){ // 判断用户ID是否存在
$user = get_user_by( 'id', $user_id ); // 更高效地获取用户对象
if ( $user ) { // 确保用户对象存在
if( ! in_array('active_production_company', $user->roles)){
$user->set_role( 'active_production_company' );
}
} else {
// 记录错误:无法获取用户对象
error_log('WC Subscription Role Assignment: Unable to get user object for subscription ' . $subscription->get_id());
}
}else{
error_log('WC Subscription Role Assignment: Invalid User Id from subscription:' . $subscription->get_id());
}
}
}
操作步骤:
- 将以上代码添加到你的主题的
functions.php
文件或一个自定义插件中。 - 确保"active_production_company"角色已在你的WordPress站点中创建。
代码解释:
- 使用
$subscription->get_customer_id()
获取用户ID。这是获取订阅关联用户ID的推荐方法。 - 使用
get_user_by('id', $user_id)
获取WP_User对象, 比new WP_User($user_id)
更高效. - 添加了用户ID和用户对象存在的检查以及错误记录,提高代码的健壮性。
- 添加条件
$old_status !== 'active'
防止在订阅状态由其他激活状态(例如on-hold
重新变为active
)时重复添加角色。 - 检查用户是否已经有目标角色再添加,防止重复调用
set_role()
方案二:使用 woocommerce_payment_complete
钩子
这个钩子在付款成功完成时触发,对于一次性付款和订阅的首期付款都适用。 如果你需要在首期付款完成后立即分配角色,可以使用这个钩子。
add_action( 'woocommerce_payment_complete', 'wc_payment_complete_assign_role' );
function wc_payment_complete_assign_role( $order_id ) {
$order = wc_get_order( $order_id );
if( ! $order) return; // 处理订单不存在的情况
//检查是否是订阅订单,如果不是, 直接返回
$items = $order->get_items();
$has_subscription = false;
foreach($items as $item){
if($item->get_product()->is_type('subscription'))
$has_subscription = true;
}
if(! $has_subscription)
return;
$user_id = $order->get_user_id();
if( $user_id ){ // 判断用户ID是否存在
$user = get_user_by('id',$user_id);
if($user) { //判断用户对象是否存在
if(!in_array('active_production_company',$user->roles)){
$user->set_role('active_production_company');
}
}
}
}
操作步骤:
- 将代码添加到你的主题的
functions.php
文件或一个自定义插件中。 - 确保 "active_production_company" 角色已在你的 WordPress 站点中创建。
代码解释:
- 通过订单 ID 获取订单对象。
- 判断是否是订阅订单,如果不是则跳过后续操作
- 使用
$order->get_user_id()
获取用户ID. - 与方案一类似,对用户ID和用户对象进行了检查,防止重复添加角色
选择合适的方案
方案一更精准地针对订阅状态变化,适合处理各种订阅状态转换的场景。方案二更侧重于付款完成的时机,适合在首期付款后立即赋予角色. 选择哪种方案取决于你的具体业务需求.
安全建议
- 对任何用户输入进行校验,防止恶意代码注入。
- 定期更新 WooCommerce 和相关插件,以修复安全漏洞。
- 使用 HTTPS 保护你的网站和用户数据。