基于WooCommerce产品购买更新用户元密钥

时间:2018-11-13 作者:butlerblog

我有一家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有任何想法,或者如果您有更好的想法,那就太好了!!

1 个回复
最合适的回答,由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 );
}

结束