php - WooCommerce 产品级别的简单票务系统
问题描述
我正在使用 WordPress 和 WooCommerce 并有一个 SQL 查询来调用特定产品类型的元标记。
function get_last_order_id_from_product( $product_id ) {
global $wpdb;
return $wpdb->get_col( $wpdb->prepare( "
SELECT oi.order_id
FROM {$wpdb->prefix}woocommerce_order_items as oi
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as oim
ON oi.order_item_id = oim.order_item_id
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as oim2
ON oi.order_item_id = oim2.order_item_id
LEFT JOIN {$wpdb->posts} AS p
ON oi.order_id = p.ID
WHERE p.post_type = 'shop_order'
AND oi.order_item_type = 'line_item'
AND oim.meta_key = '_product_id'
AND oim.meta_value = '%d'
AND oim2.meta_key = 'Ticket Number'
ORDER BY SUBSTRING_INDEX(oim2.meta_value, ' ', 10) DESC
LIMIT 1
", $product_id ) );
}
上面的代码采用产品 id 并输出元标记,当我意识到当用户购买多个单一数量时,它为“票号”键创建的元值是“10 11”,mysql 将其视为单个字符串。如上所示,我尝试使用 SUBSTRING_INDEX 将其拆分,但它不会查看第一个订单之后的任何订单。
我需要它将数字视为单个数字,因此如果用户购买了 10 个商品,它可以将最后一个数字识别为最高的数字(例如 21 22 23 24),而下一个购买此产品的用户 sql 查询将识别 24从字符串中作为最高数字,并使新项目元为 25。
如果它有任何用途,这也是我的函数,它当前运行但仅从元值 1 工作,但是购买了许多产品:
add_action('woocommerce_order_status_processing', 'action_woocommerce_order_status_completed');
function action_woocommerce_order_status_completed($order_id) {
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach ($items as $key => $value) {
$get_last_order = get_last_order_id_from_product( 10 );
if ($get_last_order == null){
$gen_id_1 = "0";
} else {
$get_order_id = implode($get_last_order);
$lastorder = wc_get_order($get_order_id);
$lastitem = $lastorder->get_items();
foreach ($lastitem as $key2 => $value2) {
$custom_thing = $value2->get_meta('Ticket Number');
}
$gen_ids = explode(' ', $custom_thing);
$gen_id_1 = end($gen_ids);
}
$qua = $value->get_quantity();
for ($x = 1; $x <= $qua; $x++) {
$gen_id_1++;
$gen_id_2 .= " $gen_id_1";
};
$value->add_meta_data( "Ticket Number", $gen_id_2);
$value->save();
}
}
解决方案
有一种不同的方法,更容易和更有效地完成这项工作。
当订单更改为处理状态时:
首先,对于每个订单项目,我增加售出的门票数量(项目数量) 作为产品级别的索引(保存/更新为自定义产品元数据)。
然后对于每个订单项目,我根据项目数量从相关产品索引(更新之前)生成票号,并将其保存为自定义订单项目元数据。
最后,对于每个订单项目,我更新相关产品“索引”,将销售数量添加到当前“索引”值。
代码(注释):
add_action( 'woocommerce_order_status_processing', 'action_woocommerce_order_status_processing', 10, 2 );
function action_woocommerce_order_status_processing( $order_id, $order ) {
// Loop through order items
foreach ($order->get_items() as $item_id => $item ) {
// Check that tickets numbers haven't been generated yet for this item
if( $item->get_meta( "_tickets_number") )
continue;
$product = $item->get_product(); // Get the WC_Produt Object
$quantity = (int) $item->get_quantity(); // Get item quantity
// Get last ticket sold index from product meta data
$now_index = (int) $product->get_meta('_tickets_sold');
$tickets_ids = array(); // Initializing
// Generate an array of the customer tickets Ids from the product registered index (last ticket ID)
for ($i = 1; $i <= $quantity; $i++) {
$tickets_ids[] = $now_index + $i;
};
// Save the tickets numbers as order item custom meta data
$item->update_meta_data( "Tickets numbers", implode(' ', $tickets_ids) ); // Displayed string of tickets numbers on customer orders and emails
$item->update_meta_data( "_tickets_number", $tickets_ids ); // (Optional) Array of the ticket numbers (Not displayed to the customer)
$item->save(); // Save item meta data
// Update the Ticket index for the product (custom meta data)
$product->update_meta_data('_tickets_sold', $now_index + $quantity );
$product->save(); // Save product data
}
$order->save(); // Save all order data
}
代码在您的活动子主题(活动主题)的functions.php 文件中。测试和工作。
隐藏的
_tickets_number
自定义订单项目元数据是可选的,允许您获取票证数组,而不是使用以下命令获取票证字符串:$item->get_meta('_tickets_number');
如果您想要一个全球票务系统(不在产品级别),您将使用以下内容:
add_action( 'woocommerce_order_status_processing', 'action_woocommerce_order_status_processing', 10, 2 );
function action_woocommerce_order_status_processing( $order_id, $order ) {
// Loop through order items
foreach ($order->get_items() as $item_id => $item ) {
$now_index = (int) get_option( "wc_tickets_number_index"); // Get last ticket number sold (globally)
$quantity = (int) $item->get_quantity(); // Get item quantity
$tickets_ids = array(); // Initializing
// Generate an array of the customer tickets Ids from the tickets index
for ($i = 1; $i <= $quantity; $i++) {
$tickets_ids[] = $now_index + $i;
};
// Save the tickets numbers as order item custom meta data
$item->update_meta_data( "Tickets numbers", implode(' ', $tickets_ids) ); // Displayed string of tickets numbers on customer orders and emails
$item->update_meta_data( "_tickets_number", $tickets_ids ); // (Optional) Array of the ticket numbers (Not displayed to the customer)
$item->save(); // Save item meta data
// Update last ticket number sold (globally)
update_option( 'wc_tickets_number_index', $now_index + $quantity );
}
$order->save(); // Save all order data
}
代码在您的活动子主题(活动主题)的functions.php 文件中。它应该工作。
推荐阅读
- docker - 使用depends_on不会启动所需的容器,而是根据它启动容器
- django - 检索访问令牌时出错:b'{\n "error": "redirect_uri_mismatch",\n "error_description": "Bad Request"\n}'
- javascript - 关闭编译警告:[JSC_POSSIBLE_INEXISTENT_PROPERTY] 属性 TextEncoder 从未定义过?
- javascript - 将 promise.all 中的值添加到数组
- sql - 翻译包含逗号分隔代码的列
- java - 无法从文件名中有空格的天蓝色下载和读取文件
- python-3.x - 使用 Python 请求模块获取 VPN 后面的 URL
- cytoscape - 如何让 Cytoscape 将边缘列识别为布局的权重
- excel - 包含在 Excel VBA 代码中的假日逻辑
- python - 获取链接 ng href selenium