Изменение цен на товары через крючок в WooCommerce 3

В WooCommerce мне нужно умножить цены всех продуктов на число. Поэтому я использовал следующее (через плагин):

add_filter('woocommerce_get_regular_price', array( $this, 'my_custom_price'), 99);
add_filter('woocommerce_get_price', array( $this, 'my_custom_price'), 99);

function my_custom_price( $original_price ) {
  global $post, $woocommerce;

  //Logic for calculating the new price here
  $new_price = $original_price * 2;

  //Return the new price (this is the price that will be used everywhere in the store)
  return $new_price;
 }

Но, что не работает для продуктов вариации. Я пробовал следующие перехватчики без везения:

add_filter('woocommerce_get_variation_regular_price', array( $this, 'my_custom_price'), 99);
add_filter('woocommerce_get_variation_price', array( $this, 'my_custom_price'), 99);

Единственный, который работает на полпути, следующий:

add_filter('woocommerce_variation_prices_price', array( $this, 'my_custom_price'), 99);

Но это просто изменило общую цену, а не выбранную цену вариации. См. Изображение ниже, цена BsF. 200, а общая цена права, 200 x 2 = 400, но вариационная цена при выборе по-прежнему показывает 200:

Примечание. Мне нужно, чтобы это действительно изменилось, поэтому отображать html-крючки не будет.

Variation Price

Есть ли что-то, что я пропущу, или что-то не так?

Ответ 1

Update 4 (September 2019)

  • 2 версии кода для тем и плагинов (работает также в Woocommerce 3.3.x)
  • Кэшированные вариации цен в Woocommerce 3 (обновление и добавление):
    Теперь использование ловушки фильтра woocommerce_get_variation_prices_hash гораздо эффективнее, чем wc_delete_product_transients()… Смотрите эту связанную ветку
  • Добавлены хуки виджетов фильтра цен на товары (см. в конце).

1) Версия плагина с функцией конструктора:

Используемые хуки не поддерживаются в WooCommerce 3+

Чтобы это работало для всех цен на товары, включая изменения цен, вы должны использовать это:

## The following goes inside the constructor ##

// Simple, grouped and external products
add_filter('woocommerce_product_get_price', array( $this, 'custom_price' ), 99, 2 );
add_filter('woocommerce_product_get_regular_price', array( $this, 'custom_price' ), 99, 2 );
// Variations 
add_filter('woocommerce_product_variation_get_regular_price', array( $this, 'custom_price' ), 99, 2 );
add_filter('woocommerce_product_variation_get_price', array( $this, 'custom_price' ), 99, 2 );

// Variable (price range)
add_filter('woocommerce_variation_prices_price', array( $this, 'custom_variable_price' ), 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', array( $this, 'custom_variable_price' ), 99, 3 );

// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'add_price_multiplier_to_variation_prices_hash' ), 99, 1 );


## This goes outside the constructor ##

// Utility function to change the prices with a multiplier (number)
public function get_price_multiplier() {
    return 2; // x2 for testing
}

public function custom_price( $price, $product ) {
    return $price * get_price_multiplier();
}

public function custom_variable_price( $price, $variation, $product ) {
    return $price * get_price_multiplier();
}

public function add_price_multiplier_to_variation_prices_hash( $hash ) {
    $hash[] = get_price_multiplier();
    return $hash;
}

Код протестирован и отлично работает (только) в WooCommerce 3+.


2) Для версии темы: functions.php файл активной дочерней темы (или активной темы):

// Utility function to change the prices with a multiplier (number)
function get_price_multiplier() {
    return 2; // x2 for testing
}

// Simple, grouped and external products
add_filter('woocommerce_product_get_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'custom_price', 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
    return $price * get_price_multiplier();
}

// Variable (price range)
add_filter('woocommerce_variation_prices_price', 'custom_variable_price', 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variable_price', 99, 3 );
function custom_variable_price( $price, $variation, $product ) {
    // Delete product cached price  (if needed)
    // wc_delete_product_transients($variation->get_id());

    return $price * get_price_multiplier();
}

// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', 'add_price_multiplier_to_variation_prices_hash', 99, 1 );
function add_price_multiplier_to_variation_prices_hash( $hash ) {
    $hash[] = get_price_multiplier();
    return $hash;
}

Протестировано и работает на woocommerce 3+


Для продуктов в продаже у вас есть эти крючки:

  • woocommerce_product_get_sale_price (Простые, сгруппированные и внешние продукты)
  • woocommerce_variation_prices_sale_price (Переменные продукты (мин-макс))
  • woocommerce_product_variation_get_sale_price (Варианты продуктов)

Кэшированные цены и woocommerce 3:

Куки с тремя фильтрами, участвующие в изменениях кэшированных цен:

  • woocommerce_variation_prices_price
  • woocommerce_variation_prices_regular_price
  • woocommerce_variation_prices_sale_price

Представленный в Woocommerce 3, ловушка фильтра woocommerce_get_variation_prices_hash позволит обновлять кэшированные цены вариаций гораздо более эффективным способом, не удаляя связанные переходные процессы каждый раз, когда выполняются эти ловушки.

Таким образом, производительность будет расти (благодаря Мэтью Кларку, который указал этот лучший путь)

См.: Кэширование и динамическое ценообразование - предстоящие изменения в методе get_variation_prices


Для фильтрации цен на товары с помощью виджета (минимальная и максимальная цена) используйте следующие крючки:

  • woocommerce_price_filter_widget_min_amount с одним аргументом $price
  • woocommerce_price_filter_widget_max_amount с одним аргументом $price