Woocommerce 循环中每个订单项的总数
Total count for each order item in a loop on Woocommerce
嗨,我正在同时学习 PHP 和 Woocommerce!
我正在尝试获取所有具有处理状态的订单和每个订单的总数,并将其显示在页面上。
到目前为止,我可以遍历所有订单并获取每个订单的名称和数量。
但由于我不知道哪个产品会出现在列表中,所以我不确定如何比较名称然后添加数量。
我目前的输出是这样的:
prod1 - v1 x 1
Prod2 - v3 x 1
prod2 - v3 x 1
prod3 - v2 x 11
prod3 - v2 x 1
我想要的是:
prod1 - v1 x 1
Prod2 - v3 x 2
prod3 - v2 x 12
目前的代码是:
<?php
/*
Template Name: Print Supplier Order
*/
if (!is_user_logged_in() || !current_user_can('manage_options')) wp_die('This page is private.');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><?php _e('Processing Orders'); ?></title>
<style>
body { background:white; color:black; width: 95%; margin: 0 auto; }
</style>
</head>
<body>
<header>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h1 class="title"><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php endwhile; endif; ?>
</header>
<section>
<?php
global $woocommerce;
$args = array( 'post_type' => 'shop_order', 'post_status' => 'wc-processing', 'posts_per_page' => -1 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
$product_details = array();
$order_items = $order->get_items();
foreach( $order_items as $product ) {
echo $product['name']." x ".$product['qty'];
echo '<br>';
}
?>
<?php endwhile; ?>
</section>
</body>
</html>
方法一
有几种不同的方法可以解决这个问题,但如果我们只想稍微调整您的代码,那么我们可以通过将产品循环中的产品添加到自定义数组来实现,使用产品名称作为一个键,然后遍历该数组。
这是一个例子:
global $woocommerce;
//custom array to list products:
$products_array = array();
//start wp query
$args = array(
'post_type' => 'shop_order',
'post_status' => 'wc-processing',
'posts_per_page'=> -1
);
$loop = new WP_Query( $args );
//loop through orders
while ( $loop->have_posts() ) {
$loop->the_post();
//vars
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
$product_details = array();
$order_items = $order->get_items();
//loop through products
foreach( $order_items as $product ) {
//if product has been captured to custom array before, increment value, else add it.
if (array_key_exists($product['name'], $products_array)) {
$products_array[$product['name']] += $product['qty'];
} else {
$products_array[$product['name']] = $product['qty'];
}
}
}
//end wp_query
wp_reset_postdata();
//display list:
foreach ($products_array as $title => $quantity) {
echo $title.' x '.$quantity;
}
方法二
遍历所有产品,而不是所有订单(一段时间后,假设商店成功,订单可能会比产品多很多,所以这种方法可能会更快 运行).每个产品都将其总销售额存储为元值,因此访问它非常简单:
//WP Query args
$args = array(
'post_type' => 'product',
'posts_per_page'=> -1,
'meta_key' => 'total_sales',
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array( //make sure we only grab items that have actually sold
array(
'key' => 'total_sales',
'value' => 0,
'compare' => '>'
)
)
);
$query = new WP_Query($args);
//loop through products
if($query->have_posts()) {
while($query->have_posts()) {
$query->the_post();
//use built in Wordpress functions for get_the_title() and get_post_meta()
echo get_the_title().' x '.get_post_meta(get_the_ID(), 'total_sales', true);
}
}
//end wp query
wp_reset_postdata();
Updated (Now the SQL query gives also the product name, make it even lighter)
与其使用 WP_Query
和一些繁重的代码来进行计算,不如使用 更轻便和有效的版本代码 ,使用 WPDB
Class(SQL 查询):
global $wpdb;
$results = $wpdb->get_results( "
SELECT DISTINCT woim2.meta_value as id, SUM(woim.meta_value) as count, woi.order_item_name as name
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woi.order_item_id = woim.order_item_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim2 ON woi.order_item_id = woim2.order_item_id
INNER JOIN {$wpdb->prefix}posts as p ON p.ID = woi.order_id
WHERE p.post_status IN ('wc-processing','wc-on-hold')
AND woim.meta_key LIKE '_qty'
AND woim2.meta_key LIKE '_product_id'
GROUP BY woim2.meta_value
" );
foreach( $results as $result ){
echo $result->name . ' (' . $result->id . ') x ' . $result->count . '<br>';
}
产品数量将仅基于处理订单状态而不是产品总销售额。
经过测试并可以正常工作。
改为获取产品变体 (如评论中所述)
如评论中要求获取订单中的产品变体,您将替换行:
AND woim2.meta_key LIKE '_product_id'
通过以下行:
AND woim2.meta_key LIKE '_variation_id'
获取所有产品和变体(可变产品除外)
要获取包括产品变体但不包括可变产品的所有产品,请使用:
global $wpdb;
$results = $wpdb->get_results( "
SELECT DISTINCT woim2.meta_value as id, SUM(woim.meta_value) as count, woi.order_item_name as name
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woi.order_item_id = woim.order_item_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim2 ON woi.order_item_id = woim2.order_item_id
INNER JOIN {$wpdb->prefix}posts as p ON p.ID = woi.order_id
WHERE p.post_status IN ('wc-processing','wc-on-hold')
AND woim.meta_key LIKE '_qty'
AND ((woim2.meta_key LIKE '_variation_id' AND woim2.meta_value > 0)
OR (woim2.meta_key LIKE '_product_id'
AND woim2.meta_value NOT IN (SELECT DISTINCT post_parent FROM {$wpdb->prefix}posts WHERE post_type LIKE 'product_variation')))
GROUP BY woim2.meta_value
" );
foreach( $results as $result ){
echo $result->name . ' (' . $result->id . ') x ' . $result->count . '<br>';
}
经过测试并可以正常工作。
全部获取(甚至产品变体和可变产品):
global $wpdb;
$results = $wpdb->get_results( "
SELECT DISTINCT woim2.meta_value as id, SUM(woim.meta_value) as count, woi.order_item_name as name
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woi.order_item_id = woim.order_item_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim2 ON woi.order_item_id = woim2.order_item_id
INNER JOIN {$wpdb->prefix}posts as p ON p.ID = woi.order_id
WHERE p.post_status IN ('wc-processing','wc-on-hold')
AND woim.meta_key LIKE '_qty'
AND ((woim2.meta_key LIKE '_variation_id' AND woim2.meta_value > 0)
OR woim2.meta_key LIKE '_product_id' )
GROUP BY woim2.meta_value
" );
foreach( $results as $result ){
echo $result->name . ' (' . $result->id . ') x ' . $result->count . '<br>';
}
经过测试并可以正常工作。
嗨,我正在同时学习 PHP 和 Woocommerce! 我正在尝试获取所有具有处理状态的订单和每个订单的总数,并将其显示在页面上。
到目前为止,我可以遍历所有订单并获取每个订单的名称和数量。
但由于我不知道哪个产品会出现在列表中,所以我不确定如何比较名称然后添加数量。
我目前的输出是这样的:
prod1 - v1 x 1
Prod2 - v3 x 1
prod2 - v3 x 1
prod3 - v2 x 11
prod3 - v2 x 1
我想要的是:
prod1 - v1 x 1
Prod2 - v3 x 2
prod3 - v2 x 12
目前的代码是:
<?php
/*
Template Name: Print Supplier Order
*/
if (!is_user_logged_in() || !current_user_can('manage_options')) wp_die('This page is private.');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><?php _e('Processing Orders'); ?></title>
<style>
body { background:white; color:black; width: 95%; margin: 0 auto; }
</style>
</head>
<body>
<header>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h1 class="title"><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php endwhile; endif; ?>
</header>
<section>
<?php
global $woocommerce;
$args = array( 'post_type' => 'shop_order', 'post_status' => 'wc-processing', 'posts_per_page' => -1 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
$product_details = array();
$order_items = $order->get_items();
foreach( $order_items as $product ) {
echo $product['name']." x ".$product['qty'];
echo '<br>';
}
?>
<?php endwhile; ?>
</section>
</body>
</html>
方法一
有几种不同的方法可以解决这个问题,但如果我们只想稍微调整您的代码,那么我们可以通过将产品循环中的产品添加到自定义数组来实现,使用产品名称作为一个键,然后遍历该数组。
这是一个例子:
global $woocommerce;
//custom array to list products:
$products_array = array();
//start wp query
$args = array(
'post_type' => 'shop_order',
'post_status' => 'wc-processing',
'posts_per_page'=> -1
);
$loop = new WP_Query( $args );
//loop through orders
while ( $loop->have_posts() ) {
$loop->the_post();
//vars
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
$product_details = array();
$order_items = $order->get_items();
//loop through products
foreach( $order_items as $product ) {
//if product has been captured to custom array before, increment value, else add it.
if (array_key_exists($product['name'], $products_array)) {
$products_array[$product['name']] += $product['qty'];
} else {
$products_array[$product['name']] = $product['qty'];
}
}
}
//end wp_query
wp_reset_postdata();
//display list:
foreach ($products_array as $title => $quantity) {
echo $title.' x '.$quantity;
}
方法二
遍历所有产品,而不是所有订单(一段时间后,假设商店成功,订单可能会比产品多很多,所以这种方法可能会更快 运行).每个产品都将其总销售额存储为元值,因此访问它非常简单:
//WP Query args
$args = array(
'post_type' => 'product',
'posts_per_page'=> -1,
'meta_key' => 'total_sales',
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array( //make sure we only grab items that have actually sold
array(
'key' => 'total_sales',
'value' => 0,
'compare' => '>'
)
)
);
$query = new WP_Query($args);
//loop through products
if($query->have_posts()) {
while($query->have_posts()) {
$query->the_post();
//use built in Wordpress functions for get_the_title() and get_post_meta()
echo get_the_title().' x '.get_post_meta(get_the_ID(), 'total_sales', true);
}
}
//end wp query
wp_reset_postdata();
Updated (Now the SQL query gives also the product name, make it even lighter)
与其使用 WP_Query
和一些繁重的代码来进行计算,不如使用 更轻便和有效的版本代码 ,使用 WPDB
Class(SQL 查询):
global $wpdb;
$results = $wpdb->get_results( "
SELECT DISTINCT woim2.meta_value as id, SUM(woim.meta_value) as count, woi.order_item_name as name
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woi.order_item_id = woim.order_item_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim2 ON woi.order_item_id = woim2.order_item_id
INNER JOIN {$wpdb->prefix}posts as p ON p.ID = woi.order_id
WHERE p.post_status IN ('wc-processing','wc-on-hold')
AND woim.meta_key LIKE '_qty'
AND woim2.meta_key LIKE '_product_id'
GROUP BY woim2.meta_value
" );
foreach( $results as $result ){
echo $result->name . ' (' . $result->id . ') x ' . $result->count . '<br>';
}
产品数量将仅基于处理订单状态而不是产品总销售额。
经过测试并可以正常工作。
改为获取产品变体 (如评论中所述)
如评论中要求获取订单中的产品变体,您将替换行:
AND woim2.meta_key LIKE '_product_id'
通过以下行:
AND woim2.meta_key LIKE '_variation_id'
获取所有产品和变体(可变产品除外)
要获取包括产品变体但不包括可变产品的所有产品,请使用:
global $wpdb;
$results = $wpdb->get_results( "
SELECT DISTINCT woim2.meta_value as id, SUM(woim.meta_value) as count, woi.order_item_name as name
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woi.order_item_id = woim.order_item_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim2 ON woi.order_item_id = woim2.order_item_id
INNER JOIN {$wpdb->prefix}posts as p ON p.ID = woi.order_id
WHERE p.post_status IN ('wc-processing','wc-on-hold')
AND woim.meta_key LIKE '_qty'
AND ((woim2.meta_key LIKE '_variation_id' AND woim2.meta_value > 0)
OR (woim2.meta_key LIKE '_product_id'
AND woim2.meta_value NOT IN (SELECT DISTINCT post_parent FROM {$wpdb->prefix}posts WHERE post_type LIKE 'product_variation')))
GROUP BY woim2.meta_value
" );
foreach( $results as $result ){
echo $result->name . ' (' . $result->id . ') x ' . $result->count . '<br>';
}
经过测试并可以正常工作。
全部获取(甚至产品变体和可变产品):
global $wpdb;
$results = $wpdb->get_results( "
SELECT DISTINCT woim2.meta_value as id, SUM(woim.meta_value) as count, woi.order_item_name as name
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woi.order_item_id = woim.order_item_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim2 ON woi.order_item_id = woim2.order_item_id
INNER JOIN {$wpdb->prefix}posts as p ON p.ID = woi.order_id
WHERE p.post_status IN ('wc-processing','wc-on-hold')
AND woim.meta_key LIKE '_qty'
AND ((woim2.meta_key LIKE '_variation_id' AND woim2.meta_value > 0)
OR woim2.meta_key LIKE '_product_id' )
GROUP BY woim2.meta_value
" );
foreach( $results as $result ){
echo $result->name . ' (' . $result->id . ') x ' . $result->count . '<br>';
}
经过测试并可以正常工作。