• Никакой политики на форуме. Иначе - бан!
  • Вопрос без рабочей ссылки на проблему считается риторическим. Без ссылки и скриншота - провокацией!
  • Темы озаглавленные с маленькой буквы или капсом удаляются без предупреждения!

Смена роли пользователя Woocommerce после покупки товара

dim70

Опытный
Здравствуйте, сделать смену роли после покупки определённого товара я смог при помощи вот этого кода:
PHP:
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' );
        }
    }
}

и для второго товара

PHP:
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 ?

Прописать такой вариант кода, например:
PHP:
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' );
        }
    }
}

Я правильно сделал?

Или же просто добавить во второй код удаление ещё одной роли:

PHP:
/ Remove old role
            $user->remove_role( 'pro_mem' );

и тогда получится вот так:

PHP:
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
Вроде всё правильно сделал?
 

joy66

Опытный
Манипуляция с ролями должна соответствовать вашей задумке, которая осталась скрыта от нас ))
Второй товар это очередность или другой определенный (53)?
Вы же потом на основании роли будете принимать какие-то правила к клиенту?
Может ли клиент сразу купить 53 и стать vip и потом купить 52 товар и стать pro?
Ролей у одного пользователя может быть сколько угодно, так что удаление/назначение ролей между собой связаны только логикой задачи
 

dim70

Опытный
Манипуляция с ролями должна соответствовать вашей задумке, которая осталась скрыта от нас ))
Второй товар это очередность или другой определенный (53)?
Вы же потом на основании роли будете принимать какие-то правила к клиенту?
Может ли клиент сразу купить 53 и стать vip и потом купить 52 товар и стать pro?
Ролей у одного пользователя может быть сколько угодно, так что удаление/назначение ролей между собой связаны только логикой задачи
Да, Вы правы я изложил мало информации. Суть в следующем. При помощи кода представленного ниже для каждой роли даётся определённое кол-во "фантиков"

PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    foreach ( $user->roles as $role) {
      if ( $role === 'start_mem' ) {
        return 10000;
      }
      if ( $role === 'baza_mem' ) {
        return 100000;
      }
      if ( $role === 'pro_mem' ) {
        return 1000000;
      }
      if ( $role === 'vip_mem' ) {
        return 10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
тарифы - это отдельные товары и при покупке товара пользователю присваивается соответствующая роль купленному тарифу, вот этот код
PHP:
/*vip для 354*/
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 = 354; // 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( 'start_mem' );
            // Remove old role
            $user->remove_role( 'baza_mem' );
            // Remove old role
            $user->remove_role( 'pro_mem' );

            // Add new role
            $user->add_role( 'vip_mem' );
        }
    }
}
/*pro для 353*/
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 = 353; // 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( 'start_mem' );
            // Remove old role
            $user->remove_role( 'baza_mem' );
            // Remove old role
            $user->remove_role( 'vip_mem' );

            // Add new role
            $user->add_role( 'pro_mem' );
        }
    }
}
/*baza для 352*/
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase_baza' );

function tb_change_role_on_purchase_baza( $order_id ) {

// get order object and items
    $order = new WC_Order( $order_id );
    $items = $order->get_items();

    $product_id = 352; // 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( 'start_mem' );
            // Remove old role
            $user->remove_role( 'vip_mem' );
            // Remove old role
            $user->remove_role( 'pro_mem' );

            // Add new role
            $user->add_role( 'baza_mem' );
        }
    }
}
/*start для 348*/
add_action( 'woocommerce_order_status_completed', 'tb_change_role_on_purchase' );

function tb_change_role_on_purchase( $order_id ) {

// get order object and items
    $order = new WC_Order( $order_id );
    $items = $order->get_items();

    $product_id = 348; // 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( 'vip_mem' );
            // Remove old role
            $user->remove_role( 'baza_mem' );
            // Remove old role
            $user->remove_role( 'pro_mem' );

            // Add new role
            $user->add_role( 'start_mem' );
        }
    }
}
Всё работает, если после израсходования купленных "фантиков" купить другой тариф, но вот если подряд купить один и тот же тариф, то не происходит суммирования "фантиков".
Подскажите пожалуйста, как реализовать так чтобы "фантики" суммировались и быть может мой код можно сделать более элегантным и простым?
 

joy66

Опытный
Вариантов решения задачи тут несколько (Если я правильно все понял ))) . И не обязательно с ролями. Но раз завязались на роли то можно и так ))
Так как ролей может быть несколько, то проверяем есть ли такая роль у пользователя и если есть , суммируем фантики.
Возвращаем либо сумму фантиков, либо $credits
Код:
/*token role*/
add_filter( 'mwai_stats_credits', function ($credits, $userId ) {
  $user = get_userdata( $userId );

  if ( !empty( $user->roles) && is_array( $user->roles ) ) {

$fantiki=0;
$user_roles=$user->roles;
  if( in_array('start_mem', $user_roles )) {
        $fantiki+= 10000;
      }
    
if in_array('baza_mem', $user_roles )) {
        $fantiki+= 100000;
      }
    if (in_array('pro_mem', $user_roles )) {
        $fantiki+= 1000000;
      }
      if (in_array('vip_mem', $user_roles )) {{
         $fantiki+= 10000000;
      }
    }

 
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $fantiki >0 ? $fantiki : $credits;
}, 10, 2);

А вот во второй функции надо определиться когда удалять ту или иную роль ,а когда нет
 

dim70

Опытный
Вариантов решения задачи тут несколько (Если я правильно все понял ))) . И не обязательно с ролями. Но раз завязались на роли то можно и так ))
Так как ролей может быть несколько, то проверяем есть ли такая роль у пользователя и если есть , суммируем фантики.
Возвращаем либо сумму фантиков, либо $credits
...
Спасибо большое попробую. С фантиками я это конечно погорячился, так сказать литературно обозвал просто ) Сейчас попробую Ваш пример под $credits переделать, а Вы посмотрите пожалуйста правильно я сделал или нет:


PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    

$credits=0;
$user_roles=$user->roles;

  if( in_array('start_mem', $user_roles )) {
        $credits+= 10000;
      }

     
if in_array('baza_mem', $user_roles )) {
        $credits+= 100000;
      }

      
if (in_array('pro_mem', $user_roles )) {
        $credits+= 1000000;
      }

 if (in_array('vip_mem', $user_roles )) {{
         $credits+= 10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);

и здесь я не понял как правильно написать код:


PHP:
// This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $fantiki >0 ? $fantiki : $credits;
}, 10, 2);
 

joy66

Опытный
Смотрите, у вас в функцию первым параметром передается $credits.
Поэтому надо понять в какое место навешана эта функция. И решить обнулять $credits или нет ( строка $credits=0;)
То есть сейчас получается так. при каждом вызове функции
Если у юзера есть хоть какая-то роль, $credits обнуляется, потом по результатам проверки на роль что-то может суммироваться
и результат возвращается . И он будет либо 0 , либо +10000 +100000 ....
То есть непонятно зачем этот параметр передается.

Нижний код return $fantiki >0 ? $fantiki : $credits; не нужен
 

dim70

Опытный
Смотрите, у вас в функцию первым параметром передается $credits.
Поэтому надо понять в какое место навешана эта функция. И решить обнулять $credits или нет ( строка $credits=0;)
То есть сейчас получается так. при каждом вызове функции
Если у юзера есть хоть какая-то роль, $credits обнуляется, потом по результатам проверки на роль что-то может суммироваться
и результат возвращается . И он будет либо 0 , либо +10000 +100000 ....
То есть непонятно зачем этот параметр передается.

Нижний код return $fantiki >0 ? $fantiki : $credits; не нужен
это дополнительные роли, что указаны у меня в коде, а есть ещё две роли которые управляются непосредственно из плагина. Первая роль это Guests и он получает своё количество кредитов, вторая роль это Users где пользователь после регистрации получает своё кол-во кредитов.
Представленный мною код, вот этот
PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    foreach ( $user->roles as $role) {
      if ( $role === 'start_mem' ) {
        return 10000;
      }
      if ( $role === 'baza_mem' ) {
        return 100000;
      }
      if ( $role === 'pro_mem' ) {
        return 1000000;
      }
      if ( $role === 'vip_mem' ) {
        return 10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
- это расширение ролей предложенное самими разработчиками плагина. Но дальше этого кода они ничего не дают, хоть плагин и платный(
 

joy66

Опытный
это дополнительные роли, что указаны у меня в коде, а есть ещё две роли которые управляются непосредственно из плагина. Первая роль это Guests и он получает своё количество кредитов, вторая роль это Users где пользователь после регистрации получает своё кол-во кредитов.
Прочитайте еще раз мое сообщение. Вопрос не в ролях. С ними все понятно. Вопрос в значении $credits
Рассмотрите разные ситуации и скажите что должно происходить с этим значение после выполнения функции
Сейчас будет так как я написал выше. Повторю.
1 Если у юзера есть хоть какая-то роль, любая , то значение credits первым делом обнулится
2 Если роль одна из тех где даются "фантики", к нулю последовательно просуммируются соответ. фантики
3 Если роли никакой нет вовсе , вернется credits без изменений.
 

dim70

Опытный
1 Если у юзера есть хоть какая-то роль, любая , то значение credits первым делом обнулится
речь ведь идёт не о всех юзерах которые уже зарегистрированы на сайте, а лишь о том который решит купить любой из тарифов (где после покупки присвоится роль согласно выше описанным моим кодам) ?
 

joy66

Опытный
речь ведь идёт не о всех юзерах которые уже зарегистрированы на сайте, а лишь о том который решит купить любой из тарифов (где после покупки присвоится роль согласно выше описанным моим кодам) ?
Любая, это значит любая. Хоть Читатель.
вот кусок кода, который это сделает
Код:
if ( !empty( $user->roles) && is_array( $user->roles ) ) {
$credits=0;
 

dim70

Опытный
Вариантов решения задачи тут несколько (Если я правильно все понял ))) . И не обязательно с ролями. Но раз завязались на роли то можно и так ))
Так как ролей может быть несколько, то проверяем есть ли такая роль у пользователя и если есть , суммируем фантики.
Возвращаем либо сумму фантиков, либо $credits
Код:
/*token role*/
add_filter( 'mwai_stats_credits', function ($credits, $userId ) {
  $user = get_userdata( $userId );

  if ( !empty( $user->roles) && is_array( $user->roles ) ) {

$fantiki=0;
$user_roles=$user->roles;
  if( in_array('start_mem', $user_roles )) {
        $fantiki+= 10000;
      }
   
if in_array('baza_mem', $user_roles )) {
        $fantiki+= 100000;
      }
    if (in_array('pro_mem', $user_roles )) {
        $fantiki+= 1000000;
      }
      if (in_array('vip_mem', $user_roles )) {{
         $fantiki+= 10000000;
      }
    }


  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $fantiki >0 ? $fantiki : $credits;
}, 10, 2);

А вот во второй функции надо определиться когда удалять ту или иную роль ,а когда нет
Создал копию своего сайта для тестирования. Установил код
PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    

$credits=0;
$user_roles=$user->roles;

  if( in_array('start_mem', $user_roles )) {
        $credits+= 10000;
      }

    
if in_array('baza_mem', $user_roles )) {
        $credits+= 100000;
      }

      
if (in_array('pro_mem', $user_roles )) {
        $credits+= 1000000;
      }

 if (in_array('vip_mem', $user_roles )) {{
         $credits+= 10000000;
      }
    }
 
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);

сайт выдаёт ошибку вот такую
1705140676024.png
 

dim70

Опытный
Создал копию своего сайта для тестирования. Установил код
PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
   

$credits=0;
$user_roles=$user->roles;

  if( in_array('start_mem', $user_roles )) {
        $credits+= 10000;
      }

   
if in_array('baza_mem', $user_roles )) {
        $credits+= 100000;
      }

     
if (in_array('pro_mem', $user_roles )) {
        $credits+= 1000000;
      }

if (in_array('vip_mem', $user_roles )) {{
         $credits+= 10000000;
      }
    }

  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);

сайт выдаёт ошибку вот такую
Посмотреть вложение 6044
так одну ошибку нашёл ) скобка не была указана вот здесь,
1705140926821.png

поправил, но всё равно ошибка. Теперь вот на эту строку ругается:
1705141022291.png
1705140997809.png
 

dim70

Опытный
так одну ошибку нашёл ) скобка не была указана вот здесь,
Посмотреть вложение 6045

поправил, но всё равно ошибка. Теперь вот на эту строку ругается:
Посмотреть вложение 6047
Посмотреть вложение 6046
Заработало! Код во всяком случаи не выдаёт ошибку))) Сейчас проверю на сколько он выполняет свои функции, ошибка была вот здесь
1705142013892.png
не было скобки. Вот полностью рабочий код

PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    

$credits=0;
$user_roles=$user->roles;

  if( in_array('start_mem', $user_roles )) {
        $credits+= 10000;
      }

    
if (in_array('baza_mem', $user_roles )) {
        $credits+= 100000;
      }

      
if (in_array('pro_mem', $user_roles )) {
        $credits+= 1000000;
      }

 if (in_array('vip_mem', $user_roles )) {{
         $credits+= 10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
 

dim70

Опытный
Заработало! Код во всяком случаи не выдаёт ошибку))) Сейчас проверю на сколько он выполняет свои функции, ошибка была вот здесь
Посмотреть вложение 6048
не было скобки. Вот полностью рабочий код

PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
   

$credits=0;
$user_roles=$user->roles;

  if( in_array('start_mem', $user_roles )) {
        $credits+= 10000;
      }

   
if (in_array('baza_mem', $user_roles )) {
        $credits+= 100000;
      }

     
if (in_array('pro_mem', $user_roles )) {
        $credits+= 1000000;
      }

if (in_array('vip_mem', $user_roles )) {{
         $credits+= 10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
Был куплен тариф VIP (роль vip_mem) добавились кредиты в размере 10000000
далее купил из под этого же аккаунта тариф START и роль изменилась на 'start_mem и количество кредитов стало 10000
Суммирования не произошло (((
 

joy66

Опытный
Что ж вы меня не слушаете то. ))) удалите вот эту строчку
$credits=0;
 

dim70

Опытный
я к сожалению не так хорошо как Вы в этом разбираюсь ((( поэтому наверное и неслышу, не понимаю очевидных для Вас вещей (((
Сейчас попробую...
 

dim70

Опытный
удалил, протестировал. Происходит просто смена роли и тарифа - суммирования не происходит (
 

dim70

Опытный
Было так
1705146607422.png

стало так

1705146635819.png
код такой сейчас

PHP:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
   

$user_roles=$user->roles;

  if( in_array('start_mem', $user_roles )) {
        $credits+= 10000;
      }

   
if (in_array('baza_mem', $user_roles )) {
        $credits+= 100000;
      }

     
if (in_array('pro_mem', $user_roles )) {
        $credits+= 1000000;
      }

if (in_array('vip_mem', $user_roles )) {{
         $credits+= 10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
 

joy66

Опытный
Ок. Продолжаем дальше гадать )) Попробуйте так
Код:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    foreach ( $user->roles as $role) {
      if ( $role === 'start_mem' ) {
        return $credits+10000;
      }
      if ( $role === 'baza_mem' ) {
        return $credits+100000;
      }
      if ( $role === 'pro_mem' ) {
        return $credits+1000000;
      }
      if ( $role === 'vip_mem' ) {
        return $credits+10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
 

dim70

Опытный
Ок. Продолжаем дальше гадать )) Попробуйте так
Код:
/*token role*/
add_filter( 'mwai_stats_credits', function ( $credits, $userId ) {
  $user = get_userdata( $userId );
  if ( !empty( $user->roles) && is_array( $user->roles ) ) {
    foreach ( $user->roles as $role) {
      if ( $role === 'start_mem' ) {
        return $credits+10000;
      }
      if ( $role === 'baza_mem' ) {
        return $credits+100000;
      }
      if ( $role === 'pro_mem' ) {
        return $credits+1000000;
      }
      if ( $role === 'vip_mem' ) {
        return $credits+10000000;
      }
    }
  }
  // This will be basically the default value set in the plugin settings
  // for logged-in users.
  return $credits;
}, 10, 2);
спасибо большое за участие)
Сейчас попробую...

Нет, суммирования не происходит. Идёт смена тарифа и роли.
 
Сверху Снизу