获取用户在 WooCommerce 中定义的日期范围内花费的总金额

问题描述 投票:0回答:1

我一直在努力理解我一直在修改的一些代码,以适应我的目的和需求。简而言之,我想在前端显示用户花费的总金额(基于用户通过使用日期选择器选择的日期范围)。

这是我到目前为止的代码:

   function display_total_amount_spent( $user_id=null ) {
    if ( empty($user_id) ){
        $user_id = get_current_user_id();
    }
    
    $today_year = date( 'Y' );
    $today_month = date( 'm' );
    $day = date( 'd' );
    if ($today_month == '01') {
        $month = '12';
        $year = $today_year - 1;
    } else{
        $month = $today_month - 1;
        $month = sprintf("%02d", $month);
        $year = $today_year - 1;
    }

    $end_date = 'user_selected_date_period';
    $single = true;
    $fetch_end_date = get_user_meta($user_id, $end_date, $single);
    $convert_ed_to_time = strtotime($fetch_end_date);

    $now = strtotime('now');
    $gap_days = $convert_ed_to_time;
    $gap_days_in_seconds = 60*60*24*$gap_days;
    $gap_time = $now - $gap_days_in_seconds;

 $args = array(
    'post_type'   => 'shop_order',
    'post_status' => array( 'wc-completed', 'wc-processing' ),
    'numberposts' => -1,
    'meta_key'    => '_customer_user',
    'meta_value'  => $user_id,
    'date_query' => array(
        'relation' => 'OR',
        array(
            'year' => $today_year,
            'month' => $today_month,
        ),
        array(
            'year' => $year,
            'month' => $month,
        ),
    ),
);

$customer_orders = get_posts( $args );
$count = 0;
$total = 0;
$no_orders_message = __('No orders found the date period', 'hello-world');
if (!empty($customer_orders)) {
    $customer_orders_date = array();
    
    foreach ( $customer_orders as $customer_order ){
        
        $customer_order_date = strtotime($customer_order->post_date);
       
        if ( $customer_order_date > $gap_time ) {
            $customer_order_date;
            $order = new WC_Order( $customer_order->ID );
            $order_items = $order->get_items();
            $total += $order->get_total();
            
            foreach ( $order_items as $order_item ){
               $count++;
            }
        }
    }
    return floatval( preg_replace( '#[^\d.]#', '', $total, $count ) );    
} else {
    return $no_orders_message;         
}
}
add_shortcode( 'user_amount_spent', 'display_total_amount_spent' );

使用上面的代码,我收到“日期期间无订单”消息,而实际上,我已经下了一些测试订单,这些测试订单已标记为“已完成”状态,但查询并未获取这些订单。为什么这不起作用?

任何指示或指导将不胜感激。

php wordpress woocommerce orders date-range
1个回答
0
投票

从 WooCommerce 版本 8.2 开始,默认启用高性能订单存储 (HPOS),并使用自定义数据库表以获得更好的性能,因此 WordPress Post 和 Postmeta 功能无法再与 WooCommerce Orders 一起使用。

您需要将 WordPress

get_posts()
替换为 WooCommerce
wc_get_orders()
,才能查询订单。

现在需要显示2个日期字段,并使用Javascript + Ajax从日期字段中查询订单,以获取花费的金额。

这是完整的代码

// Shortcode function (+Javascript with Ajax)
add_shortcode( 'user_range_spent', 'shortcode_user_date_range_total_spent' );
function shortcode_user_date_range_total_spent( $atts ) {
    extract( shortcode_atts( array(
        'user_id'   => get_current_user_id(),
    ), $atts, 'user_range_spent' ) );

    // Check that user ID is defined
    if ( ! $user_id ) {
        return; // Exit
    }

    // Enqueing Javascript (Jquery + Ajax)
    wc_enqueue_js("$('.date-range-fields button#submit_date').on('click', function(){
        const dateFrom = $('.date-range-fields #from_date').val();
        const dateTo = $('.date-range-fields #to_date').val();
        console.log(dateFrom+' ... '+dateTo);
        
        if( dateFrom && dateTo ) {
            $('.user-total-spent').block({message: null, overlayCSS:{background:\"#fff\",opacity: .6}});
            $.ajax({
                type: 'POST',
                url: '" . admin_url('/admin-ajax.php') . "',
                data: {
                    'action': 'user_total_spent',
                    'user_id': {$user_id},
                    'date_from': dateFrom,
                    'date_to': dateTo
                },
                success: function (response) {
                    $('.user-total-spent').unblock();
                    $('.user-total-spent > .response-message').html(response);
                }
            });
        } else {
            $('.user-total-spent > .response-message').html('" . esc_html__('Select a correct date range please.') . "');
        }
    });");

    // HTML (date range fields)
    return '<div class="user-total-spent">
        <div class="date-range-fields">
            <span id="from_date_field" style="max-width:200px;display:inline-block;">
                <label for="from_date">' . esc_html__('From date', 'woocommerce') . ': </label> 
                <input type="date" class="input-text " name="from_date" id="from_date" value="">
            </span>
            <span id="to_date_field" style="max-width:200px;display:inline-block;">
                <label for="to_date">' . esc_html__('To date', 'woocommerce') . ': </label> 
                <input type="date" class="input-text " name="to_date" id="to_date" value="">
            </span>
            <span id="submit_date_field" style="display:inline-block;">
                <button type="button" class="submit_date" name="submit_date" id="submit_date">' . esc_html__('Submit', 'woocommerce') . '</button>
            </span>
        </div><br>
        <div class="response-message"></div>
    </div>';
}


// PHP AJAX Receiver: Process the ajax request
add_action('wp_ajax_user_total_spent', 'get_user_total_spent_from_date_range');
function get_user_total_spent_from_date_range() {
    if ( isset($_POST['user_id'], $_POST['date_from'], $_POST['date_to']) && $_POST['user_id'] > 0 ) {
        $from_date = $_POST['date_from']; 
        $to_date   = $_POST['date_to'];

        // The WC_Order_Query
        $customer_orders = wc_get_orders( array(
            'type'          => 'shop_order',
            'status'        => wc_get_is_paid_statuses(),
            'limit'         => -1,
            'customer'      => intval($_POST['user_id']),
            'date_created'  => "{$from_date}...{$to_date}", // Date range
        ) );

        $total_spent = 0; // Initialize

        if ( $customer_orders ) {
            // Loop through orders
            foreach ( $customer_orders as $order ) {
                $total_spent += $order->get_total();
            }
        }
        $html = $total_spent > 0 ? 
            sprintf( esc_html__('Total spent: %s', 'woocommerce'), wc_price($total_spent) ) : 
            esc_html__('No orders were found for this date range', 'woocommerce');
    } else {
        $html = esc_html__('Try again please…', 'woocommerce'); // Error
    }
    wp_die($html); // Send back the HTML and end the request silently.
}

代码位于子主题的functions.php 文件中(或插件中)。已测试并有效。

短代码用法:

  • 作为一个简单的简码:
    [user_range_spent]
  • 或者在 PHP 中:
    echo do_shortcode('[user_range_spent]');

此简码有一个可选参数:用户 ID (默认为当前用户 ID)

  • 作为简单的简码(带有用户定义的ID)
    [user_range_spent user_id="123"]
  • 或者在 PHP 中(使用用户定义的 ID)
    echo do_shortcode('[user_range_spent user_id="123"]');

你会得到类似的东西:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.