简体   繁体   English

将WC_Order_Query与自定义产品类型和日期范围一起使用

[英]Use WC_Order_Query with a custom product type and a date range

I have to change the product price (only in single product page) depending on orders made in a date range, and if user has a membership. 我必须根据日期范围内的订单以及用户是否具有会员身份来更改产品价格(仅在单个产品页面中)。 This is fine, but the problems is that something fails when I use WC_Order_Query inside the woocommerce_get_price_html filter 很好,但是问题是当我在woocommerce_get_price_html过滤器内使用WC_Order_Query时,某些操作失败

The problem is using the WC_Order_Query inside filter, because when I comment it then works. 问题是在过滤器内部使用了WC_Order_Query,因为当我发表评论时它就起作用了。 What can I use for that query? 该查询可以用来做什么? Or I have to change of filter, hook? 还是我必须更换过滤器,吊钩?

function change_price( $price ) {   
    global $product;

    if($product->get_type() != "lottery") return $price;

    $user_id = get_current_user_id();
    $membresias = wc_memberships_get_user_memberships($user_id); // Get the memberships of user, returning an array

    if(!$membresias) return;

    foreach ($membresias as $value) {
        if ($value->status == "wcm-free_trial" || $value->status == "wcm-active") {
            $currentDayOfWeek = date("N");

            $start = date('Y-m-d', strtotime('-'.(intval($currentDayOfWeek )-1).' days'));
            $end = date('Y-m-d', strtotime('+'.(7 - intval($currentDayOfWeek )).' days'));


            $query = new WC_Order_Query(
                array(
                    'limit' => 10,
                    'orderby' => 'date',
                    'order' => 'DESC',
                    'return' => 'ids',
                    'customer_id' => $user_id,
                    'date_paid' => $start."...".$end, //'2018-02-01...2018-02-28',
                    'meta_key' => '_lottery',
                )
            );

            $orders = $query->get_orders(); // If I comment this page loads well.

        /* Also fails
        $orders = wc_get_orders(
            array(
                'limit' => 10,
                'orderby' => 'date',
                'order' => 'DESC',
                'return' => 'ids',
                'customer_id' => $user_id,
                'date_paid' => $start."...".$end,  //'2018-02-01...2018-02-28',
                'meta_key' => '_lottery',
            )
        );
        */

            $sorteosJugadosCount = 0;
            foreach ($orders as $order) {
                $order = wc_get_order($order);

                foreach ($order->get_items() as $item_id => $item_data) {
                    $product = $item_data->get_product();
                    $item_quantity = $item_data->get_quantity(); // Get the item quantity
                    $sorteosJugadosCount += $item_quantity; 
                }
            }   

            if ( $sorteosJugadosCount < 7 )
                return "0€ (Free lottery)";

        }
    }

    return $price;
} 

add_filter( 'woocommerce_get_price_html', 'sv_change_product_price_display', 10, 2);

What fails is 'meta_key' => '_lottery' . 失败的是'meta_key' => '_lottery'

Why? 为什么?
Because you are querying Orders but NOT products meta data (order items) . 因为您要查询的是订单不是产品元数据(订单项)
As "lottery" is a custom product type that has nothing to do with the order meta data, it fails. 由于“彩票”是与订单元数据无关的自定义产品类型,因此失败。
The WC_Order_Query is limited. WC_Order_Query是受限制的。

You can make a more complex SQL query using WPDB in your code, calling global $wpdb; 您可以在代码中使用WPDB进行更复杂的SQL查询,调用global $wpdb; obbject, where you will be able to target specific product types in order items. 对象,您将可以在其中定位订单商品中的特定产品类型。

So the following query will output an array of orders IDs, based on "date paid" range and order item custom product type "lottery". 因此,以下查询将基于“付款日期”范围和订单项自定义产品类型“彩票”输出订单ID数组。 It will replace in your code the WC_Order_Query : 它将在您的代码中替换WC_Order_Query

global $wpdb;

$product_type = 'lottery'; // <== The product type to target

// Dates
$currentDayOfWeek = date("N");
$time_start = strtotime(date('Y-m-d', strtotime('-'.(intval($currentDayOfWeek )-1).' days')));
$time_end = strtotime(date('Y-m-d', strtotime('+'.(7 - intval($currentDayOfWeek )).' days')));

// The SQL query
$order_ids = $wpdb->get_col( "
    SELECT DISTINCT pm.post_id
    FROM {$wpdb->prefix}postmeta as pm
    INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON pm.post_id = woi.order_id
    INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta as woim ON woi.order_item_id = woim.order_item_id
    INNER JOIN {$wpdb->prefix}term_relationships as tr ON woim.meta_value = tr.object_id
    INNER JOIN {$wpdb->prefix}term_taxonomy as tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
    INNER JOIN {$wpdb->prefix}terms as t ON tt.term_id = t.term_id
    WHERE pm.meta_key LIKE '_date_paid'
    AND pm.meta_value BETWEEN '$time_start' AND '$time_end'
    AND woi.order_item_type LIKE 'line_item'
    AND woim.meta_key LIKE '_product_id'
    AND tt.taxonomy LIKE 'product_type'
    AND t.slug LIKE '$product_type'
    ORDER BY pm.meta_value DESC
" );

// Raw output display (testing)
echo '<pre>'; print_r($order_ids); echo '</pre>';

This code is tested with normal woocommerce product types as "simple" for example and works. 例如,此代码使用普通的woocommerce产品类型(例如“简单”)进行了测试并可以工作。 So it should works with your custom product type 'lottery'. 因此,它应与您的自定义产品类型“彩票”一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM