drm16022 2018-02-17 03:23
浏览 97

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

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

The problem is using the WC_Order_Query inside filter, because when I comment it then works. 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);
  • 写回答

1条回答 默认 最新

  • dongya1228 2018-02-17 05:29
    关注

    What fails is '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.

    You can make a more complex SQL query using WPDB in your code, calling 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". It will replace in your code the 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. So it should works with your custom product type 'lottery'.

    评论

报告相同问题?

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向