Смена роли пользователя Woocommerce после покупки определённого товара, как сделать?
Здравствуйте, сделать смену роли после покупки определённого товара я смог при помощи вот этого кода:
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_vip' ); function tb_change_role_on_purchase_vip( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 52; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'customer' ); // Add new role $user->add_role( 'pro_mem' ); } } } |
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_vip' ); function tb_change_role_on_purchase_vip( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 52; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'customer' ); // Add new role $user->add_role( 'pro_mem' ); } } }
и для второго товара
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_pro' ); function tb_change_role_on_purchase_pro( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 53; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'customer' ); // Add new role $user->add_role( 'vip_mem' ); } } } |
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_pro' ); function tb_change_role_on_purchase_pro( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 53; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'customer' ); // Add new role $user->add_role( 'vip_mem' ); } } }
Теперь собственно мой вопрос:
Как сделать чтобы после покупки первого товара (id товара 52) когда уже роль стала:
pro_mem
Покупая второй товар (id товара 53) роль pro_mem менялась на следующую роль vip_mem ?
Прописать такой вариант кода, например:
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_vip' ); function tb_change_role_on_purchase_vip( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 53; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'pro_mem' ); // Add new role $user->add_role( 'vip_mem' ); } } } |
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_vip' ); function tb_change_role_on_purchase_vip( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 53; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'pro_mem' ); // Add new role $user->add_role( 'vip_mem' ); } } }
Я правильно сделал?
Или же просто добавить во второй код удаление ещё одной роли:
// Remove old role $user->remove_role( 'pro_mem' ); |
// Remove old role $user->remove_role( 'pro_mem' );
и тогда получится вот так:
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_vip' ); function tb_change_role_on_purchase_vip( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 53; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'customer' ); // Remove old role $user->remove_role( 'pro_mem' ); // Add new role $user->add_role( 'vip_mem' ); } } } |
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_vip' ); function tb_change_role_on_purchase_vip( $order_id ) { // get order object and items $order = new WC_Order( $order_id ); $items = $order->get_items(); $product_id = 53; // Product ID foreach ( $items as $item ) { if( $product_id == $item['product_id'] && $order->user_id ) { $user = new WP_User( $order->user_id ); // Remove old role $user->remove_role( 'customer' ); // Remove old role $user->remove_role( 'pro_mem' ); // Add new role $user->add_role( 'vip_mem' ); } } }
То есть если пользователь только зашёл на сайт и покупает первый товар (id товара 52), то присваивается роль pro_mem а если потом покупает второй товар (id товара 53) роль pro_mem будет удаляться и меняться на vip_mem
Вроде всё правильно сделал. Надо будет проверить )
Дополнительно:
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Делать отдельную функцию и отдельный hook для каждого товара не нужно. Лучше хранить соответствие “ID товара → роль” в массиве и обрабатывать заказ один раз. Так код будет проще поддерживать, и не будет конфликтов, если в заказе несколько подходящих товаров.
Пример:
add_action('woocommerce_order_status_completed', 'change_user_role_by_product'); function change_user_role_by_product($order_id) { $order = wc_get_order($order_id); if (!$order || !$order->get_user_id()) { return; } $role_map = [ 52 => 'pro_mem', 53 => 'vip_mem', ]; $user = new WP_User($order->get_user_id()); foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); $variation_id = $item->get_variation_id(); foreach ([$product_id, $variation_id] as $id) { if (isset($role_map[$id])) { $user->set_role($role_map[$id]); return; } } } }
set_role()заменит текущую роль пользователя на новую. Если нужно не заменить, а добавить роль, используйтеadd_role(). Но у пользователя с несколькими ролями могут быть неожиданные права, поэтому для membership-сценария чаще безопаснее именноset_role().Если товар вариативный, проверяйте не только
product_id, но иvariation_id, как в примере. Иначе роль может не смениться при покупке конкретной вариации.Также подумайте о возвратах и отменах. Если пользователь купил доступ, а заказ потом отменили или вернули, нужно решить, возвращать ли старую роль. Для этого можно добавить обработчики на
cancelled,refundedили хранить старую роль в user meta.Код лучше размещать не в теме, а в маленьком mu-plugin или кастомном плагине, потому что смена роли после покупки — бизнес-логика, она не должна пропадать при смене темы.