返回

WooCommerce订阅激活自动分配自定义用户角色

php

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());
        }
    }
}

操作步骤:

  1. 将以上代码添加到你的主题的functions.php文件或一个自定义插件中。
  2. 确保"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');

          }
        }
    }




}

操作步骤:

  1. 将代码添加到你的主题的 functions.php 文件或一个自定义插件中。
  2. 确保 "active_production_company" 角色已在你的 WordPress 站点中创建。

代码解释:

  • 通过订单 ID 获取订单对象。
  • 判断是否是订阅订单,如果不是则跳过后续操作
  • 使用$order->get_user_id()获取用户ID.
  • 与方案一类似,对用户ID和用户对象进行了检查,防止重复添加角色

选择合适的方案

方案一更精准地针对订阅状态变化,适合处理各种订阅状态转换的场景。方案二更侧重于付款完成的时机,适合在首期付款后立即赋予角色. 选择哪种方案取决于你的具体业务需求.

安全建议

  • 对任何用户输入进行校验,防止恶意代码注入。
  • 定期更新 WooCommerce 和相关插件,以修复安全漏洞。
  • 使用 HTTPS 保护你的网站和用户数据。