我有一家WooCommerce商店。我有一个用于用户过期的自定义用户元密钥,需要根据购买特定产品的所有用户的结果进行更新。
不幸的是,我没有在WooCommerce中找到一种方法来获取购买了特定产品的用户列表。因此,我求助于自定义MySQL查询,如下所示:
SELECT
u1.ID,
u1.post_date,
u1.post_type,
u1.post_status,
m2.meta_value AS customer_id, # WooCommerce customer ID from post meta
o3.order_item_name AS item_name, # The WooCommerce Product Item name
e4.meta_value AS expires # A custom user meta field called "expires" formatted as MM/DD/YYYY
FROM wp_posts u1
JOIN wp_postmeta m2 ON (m2.post_id = u1.ID AND m2.meta_key = \'_customer_user\')
JOIN wp_woocommerce_order_items o3 ON (o3.order_id = u1.ID )
JOIN wp_usermeta e4 ON (e4.user_id = m2.meta_value AND e4.meta_key = \'expires\')
WHERE u1.post_type = "shop_order" # WooCommerce orders are custom post type "shop_order"
AND u1.post_status = "wc-completed" # Only dealing with post_status "wc-completed" which is a completed WC order
AND o3.order_item_name = "My Fancy Product" # String value for item name in the WC order item table
AND STR_TO_DATE( e4.meta_value, \'%m/%d/%Y\' ) > STR_TO_DATE( \'01/01/2020\', \'%m/%d/%Y\' ) # Format custom user meta (string) as a date
ORDER BY STR_TO_DATE( e4.meta_value, \'%m/%d/%Y\' ) # Order by custom user meta (string) as a date
对一些人来说,这可能很混乱,但这似乎是我能找到的唯一方法。
该查询是一个获取所有WC已完成订单的连接,其中项目名称为“我的花式产品”(只是问题的占位符),用户元键“expires”大于2020年1月1日(即2020年1月1日,是的,我知道格式为meh,但它就是它)。
我已经用一些识别信息对SQL查询进行了注释,希望这些信息对任何能够回答这个问题的人都有帮助。问题是:
查询可以返回结果集。我需要运行一个更新查询,用一个新值更新“expires”元键,该值是它们的现有值,但2019年为年份。我可能会自己解析当前值并构建日期,但我不知道如何对这个结果集运行更新,因为连接是我搞砸的。
如果您对如何使用MySQL有任何想法,或者如果您有更好的想法,那就太好了!!
最合适的回答,由SO网友:butlerblog 整理而成
我确实想出了一个解决办法。它不是纯MySQL,而是使用了一些WP/PHP向导。因此,这就是我解决问题的方法——但我仍然对更好的解决方案持开放态度(尤其是纯MySQL方法)。
我用了$wpdb->get_results()
对象方法来检索SQL查询的结果。将结果作为数组返回(为返回的结果指定array\\u A)。
然后循环遍历结果,使用PHP的strtotime()
, 减去1年并将结果返回到所需的(是的,meh)m/d/Y格式,最后使用新日期更新用户元update_user_meta()
(SQL结果中的用户ID为“customer\\u ID”)。
就个人而言,但对答案并不重要,我还将结果回显到屏幕上,以便记录更新的记录。但在处理过程中,也可以将其存储为用户元。
为了清晰起见,我对下面的所有代码和MySQL查询进行了注释:
// Use the $wpdb database object class.
global $wpdb;
// MySQL query
$sql = "SELECT
u1.ID,
u1.post_date,
u1.post_type,
u1.post_status,
m2.meta_value AS customer_id, # WooCommerce customer ID from post meta
o3.order_item_name AS item_name, # The WooCommerce Product Item name
e4.meta_value AS expires # A custom user meta field called expires formatted as MM/DD/YYYY
FROM wp_posts u1
JOIN wp_postmeta m2 ON (m2.post_id = u1.ID AND m2.meta_key = \'_customer_user\')
JOIN wp_woocommerce_order_items o3 ON (o3.order_id = u1.ID )
JOIN wp_usermeta e4 ON (e4.user_id = m2.meta_value AND e4.meta_key = \'expires\')
WHERE u1.post_type = \'shop_order\' # WooCommerce orders are custom post type shop_order
AND u1.post_status = \'wc-completed\' # Only dealing with post_status wc-completed which is a completed WC order
AND o3.order_item_name = \'My Fancy Product\' # String value for item name in the WC order item table
AND STR_TO_DATE( e4.meta_value, \'%m/%d/%Y\' ) > STR_TO_DATE( \'01/01/2020\', \'%m/%d/%Y\' ) # Format custom user meta (string) as a date
ORDER BY STR_TO_DATE( e4.meta_value, \'%m/%d/%Y\' ); # Order by custom user meta (string) as a date";
// Get results of $sql query as an array.
$results = $wpdb->get_results( $sql, ARRAY_A );
// Go through results and update user.
foreach( $results as $result ) {
// Take current "expires" and get a value -1 year.
$new_expires = date( \'m/d/Y\', strtotime( $result[\'expires\'] . \' -1 year\' ) );
// Update the "expires" meta with the new value.
update_user_meta( $result[\'customer_id\'], \'expires\', $new_expires );
}