要根据当前产品获取订单,您不必每次都查询所有订单。尤其是订单多的时候,占用资源太多。
从Get all Orders IDs from a product ID in Woocommerce 回答代码,您可以使用函数get_orders_ids_by_product_id() 获取来自特定产品ID 的所有订单(您必须在其中设置所需的订单状态)。
然后您可以使用这个其他函数计算每个产品(简单或变体)的平均价格基于产品 ID。
// calculate the average price based on the product id using the query within the "get_orders_ids_by_product_id()" function
function calculates_average_price_based_on_product_id( $product_id ) {
$orders = get_orders_ids_by_product_id( $product_id );
$count = count( $orders );
if ( $count <= 0 ) {
return; // set the return value in case there are no orders for this product
}
$prices = 0;
foreach ( $orders as $order_id ) {
$order = wc_get_order( $order_id );
if ( $order ) {
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( $product_id == $product->get_id() ) {
$qty = $item->get_quantity();
$total = $item->get_total();
$prices += $total / $qty;
}
}
}
}
return $prices / $count;
}
它是如何工作的
- 如果产品是变量:
- 计算平均价格仅在已购买的产品变体之间
- 如果未购买任何变体,则计算当前设置的净价之间的平均价格
- 如果产品简单:
-
根据包含此产品的所有订单的售价计算平均价格
- 如果产品从未购买过,显示当前设置的净价
短代码
最后是显示基于当前页面产品的平均价格的简码。 如果产品是可变的,则会计算并显示所有变体之间的平均价格。
[average_price_product] 短代码仅适用于产品页面。
// create a shortcode showing the average price of the product
add_shortcode( 'average_price_product', 'shortcode_average_price_product' );
function shortcode_average_price_product() {
global $product;
// initialize prices
$avg_price = 0;
$current_avg_price = 0;
// initializes the number of variations that have been purchased at least once
$count = 0;
// if the product is variable it calculates the average price of all the variations
if ( $product->is_type( 'variable' ) ) {
$variation_ids = $product->get_children();
// gets the total number of variations
$total_variations = count( $variation_ids );
foreach ( $variation_ids as $variation_id ) {
$variation = wc_get_product( $variation_id );
// gets the average price of each single variation
$avg_price_variation = calculates_average_price_based_on_product_id( $variation_id );
// if the average price of the current product variation is greater than zero, it updates the price and count
if ( $avg_price_variation > 0 ) {
$avg_price += $avg_price_variation;
$count++;
}
// sum the current price of each single variation (in case no variation has ever been purchased)
$current_avg_price += $variation->get_price();
}
// if no variation has been purchased, I display the average price between the current net prices
if ( $avg_price == 0 ) {
$avg_price = $current_avg_price / $total_variations;
} else {
$avg_price /= $count;
}
// if the product is simple
} else {
// gets the average price of the product
$avg_price = calculates_average_price_based_on_product_id( $product->get_id() );
// if the simple product has never been ordered, I will display the current price
if ( $avg_price == 0 ) {
$avg_price = $product->get_price();
}
}
// creates the HTML content to display on the product page
$html = '<div class="sales-price-number"><span class="sales-price-text">Average Sale Price </span><span class="sales-price-value">' . wc_price( $avg_price ) . ' </span></div>';
return $html;
}
挂钩
作为短代码的替代方案,您可以使用 woocommerce_before_add_to_cart_form 钩子在产品页面上添加平均价格,具有以下功能:
// shows the average price on the product page
add_action( 'woocommerce_before_add_to_cart_form', 'shows_average_price_on_the_product_page', 10 );
function shows_average_price_on_the_product_page() {
global $product;
// initialize prices
$avg_price = 0;
$current_avg_price = 0;
// initializes the number of variations that have been purchased at least once
$count = 0;
// if the product is variable it calculates the average price of all the variations
if ( $product->is_type( 'variable' ) ) {
$variation_ids = $product->get_children();
// gets the total number of variations
$total_variations = count( $variation_ids );
foreach ( $variation_ids as $variation_id ) {
$variation = wc_get_product( $variation_id );
// gets the average price of each single variation
$avg_price_variation = calculates_average_price_based_on_product_id( $variation_id );
// if the average price of the current product variation is greater than zero, it updates the price and count
if ( $avg_price_variation > 0 ) {
$avg_price += $avg_price_variation;
$count++;
}
// sum the current price of each single variation (in case no variation has ever been purchased)
$current_avg_price += $variation->get_price();
}
// if no variation has been purchased, I display the average price between the current net prices
if ( $avg_price == 0 ) {
$avg_price = $current_avg_price / $total_variations;
} else {
$avg_price /= $count;
}
// if the product is simple
} else {
// gets the average price of the product
$avg_price = calculates_average_price_based_on_product_id( $product->get_id() );
// if the simple product has never been ordered, I will display the current price
if ( $avg_price == 0 ) {
$avg_price = $product->get_price();
}
}
// creates the HTML content to display on the product page
$html = '<div class="sales-price-number"><span class="sales-price-text">Average Sale Price </span><span class="sales-price-value">' . wc_price( $avg_price ) . ' </span></div>';
echo $html;
}
代码已经过测试并且可以运行。将其添加到活动主题的 functions.php 中。
建议
虽然上面的代码可以正常工作,但这并不是获得产品平均价格的最佳方法。
每当每个订单的状态发生变化时,您都可以为每个产品创建和更新自定义元数据,例如“wc-completed”。
您只需要该产品的订单数量和根据最后完成的订单计算的平均价格的计数器。
当新订单进入完成状态时,您将更新相应的字段。