3

对于预订网站,我已激活“时区”。应显示访问者的当地时间。在预订表格中,一切正常。使用以下功能时,购物车数据($start_time、$end_time)未正确显示。

add_filter( 'woocommerce_get_item_data', 'display_cart_data_wc_bookings', 10, 2 );
function display_cart_data_wc_bookings( $item_data, $cart_item ){

    if ( ! empty( $cart_item['booking'] ) ) {

        $date_format = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
        $time_format = apply_filters( 'woocommerce_bookings_time_format', wc_time_format() );
        $start_date = apply_filters( 'woocommerce_bookings_get_start_date_with_time', date_i18n(  $date_format, $cart_item['booking']['_start_date'] ) );
        $start_time = apply_filters( 'woocommerce_bookings_get_start_date_with_time', date_i18n(  $time_format, $cart_item['booking']['_start_date'] ) );
        $end_time = apply_filters( 'woocommerce_bookings_get_end_date_with_time', date_i18n(  $time_format, $cart_item['booking']['_end_date'] ) );
        $persons = $cart_item['booking']['_persons'];
        $ID = $cart_item['booking']['_booking_id'];

        echo '<dt class="titel datum">' . __('Date', 'woocommerce') . '</dt><dd class="data datum">' . esc_html( $start_date ) . '</dd>';
        echo '<dt class="titel tijdvak">' . __('Time', 'woocommerce') . '</dt><dd class="data tijdvak">' . esc_html( $start_time ) . ' - ' . esc_html( $end_time ) . '</dd>';
        foreach($persons as $person){
            echo '<dt class="titel personen">' . __('Persons', 'woocommerce') . '</dt><dd class="data personen">' . esc_html( $person) . '</dd>';
        }
        echo '<dt class="titel booking_id">' . __('Booking #', 'woocommerce') . '</dt><dd class="data booking_id">' . esc_html( $ID) . '</dd>';

    }
}

$start_time 和 $end_time 的输出应该以访问者的本地时间显示。我怎样才能做到这一点?

4

3 回答 3

2

要启用用户时区,需要 jQuery 和 ajax。以下是以下步骤:

  1. 早期启用用户 WooCommerce 会话(WC Session)
  2. 获取用户浏览器时区(来自用户计算机或设备的时区)
  3. 通过ajax将该时区发送到php,
  4. 在用户 WC Session 中获取该时区,
  5. 然后在你的代码中使用日期和时间 php 函数作为date(), date_i18n(), time()...</li>

一旦用户时区保存在 WC Session 中,所有相关代码将被自动禁用(不再需要)

编码:

// Early enable customer WC_Session (if not done)
add_action( 'init', 'wc_session_enabler' );
function wc_session_enabler() {
    if ( isset(WC()->session) && ! WC()->session->has_session() ) {
        WC()->session->set_customer_session_cookie( true );
    }
}

// Get the browser user timezone and send it to php (Ajax)
add_action( 'wp_head', 'user_timmezone_js' );
function user_timmezone_js() {
    if( ! WC()->session->get('time-zone') ) :
    ?>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>
    <script type="text/javascript">
    jQuery( function($){
        if (typeof woocommerce_params === 'undefined') 
            return false;

        var tz = jstz.determine();

        $.ajax({
            type: "POST",
            url: woocommerce_params.ajax_url,
            data: ({
                'action': 'time_zone',
                'timezone': tz.name()
            }),
            success: function(response) {
                console.log('Success: '+response);
            }
        });
    });
    </script>
    <?php
    endif;
}

// function that gets the Ajax data and save it to user WC Session
add_action( 'wp_ajax_time_zone', 'set_session_timezone' );
add_action( 'wp_ajax_nopriv_time_zone', 'set_session_timezone' );
function set_session_timezone() {
    if ( isset($_POST['timezone']) && ! empty($_POST['timezone']) ){
        WC()->session->set('time-zone', esc_attr($_POST['timezone']) );
        echo  WC()->session->get('time-zone');
    }
    die();
}

代码位于您的活动子主题(或活动主题)的 function.php 文件中。

然后您将包括以下内容以获取和设置时区:

if( $timezone = WC()->session->get('time-zone') ) {
    date_default_timezone_set($timezone);
}

更新:

现在你的代码在使用时不正确,woocommerce_get_item_data因为它是一个过滤器钩子,需要返回过滤后的内容(而不是回显 html) ......</p>

请尝试以下方法(未经测试)

add_filter( 'woocommerce_get_item_data', 'display_cart_data_wc_bookings', 10, 2 );
function display_cart_data_wc_bookings( $item_data, $cart_item ){
    if ( isset($cart_item['booking']) && ! empty($cart_item['booking']) && ! is_admin() ) {
        // Get and set the user time zone
        if( $timezone = WC()->session->get('time-zone') ) {
            date_default_timezone_set($timezone);
        }
        $booking_data = $cart_item['booking'];
        $date_format  = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
        $time_format  = apply_filters( 'woocommerce_bookings_time_format', wc_time_format() );
        $start_date   = apply_filters( 'woocommerce_bookings_get_start_date_with_time', date_i18n(  $date_format, $booking_data['_start_date'] ) );
        $start_time   = apply_filters( 'woocommerce_bookings_get_start_date_with_time', date_i18n(  $time_format, $booking_data['_start_date'] ) );
        $end_time     = apply_filters( 'woocommerce_bookings_get_end_date_with_time', date_i18n(  $time_format, $booking_data['_end_date'] ) );
        $persons      = $booking_data['_persons'];
        $booking_id   = $booking_data['_booking_id'];
        
        $item_data[] = array(
            'key'       => __('Date', 'woocommerce'),
            'value'     => esc_html( $start_date ),
            'display'   => esc_html( $start_date ),
        );
        
        $item_data[] = array(
            'key'       => __('Time', 'woocommerce'),
            'value'     => esc_html( $start_time ),
            'display'   => esc_html( $start_time ),
        );
        
        $count = 1;
        
        foreach($persons as $person){
            $item_data[] = array(
                'key'       => __('Person', 'woocommerce') . $count,
                'value'     => esc_html( $person ),
                'display'   => esc_html( $person ),
            );
            $count++;
        }
        
        $item_data[] = array(
            'key'       => __('Booking #', 'woocommerce'),
            'value'     => esc_html( $booking_id ),
            'display'   => esc_html( $booking_id ),
        );
    }
    return $item_data;
}

部分基于:如何检测用户的时区?

于 2019-04-28T07:53:00.233 回答
1

它有点棘手,我们可以做的总是在后端处理 UTC 时间格式,并从前端将 UTC 时间转换为本地时间

转换本地时间你可以在这里找到帮助,希望这样你可以存档你的目标

于 2019-04-26T11:12:54.810 回答
0

@LoicTheAztec:感谢您的更新。还是行不通。我已经根据文件“class-wc-booking-cart-manager.php”更新了代码:

add_filter( 'woocommerce_get_item_data', 'display_cart_data_wc_bookings', 10, 2 );
function display_cart_data_wc_bookings( $item_data, $cart_item ){
    if ( isset($cart_item['booking']) && ! empty($cart_item['booking']) ) {

        // Get and set the user time zone
        $booking_data = $cart_item['booking'];
        if ( ! empty( $booking_data['_booking_id'] ) ) {
            $booking = get_wc_booking( $booking_data['_booking_id'] );
            if ( wc_should_convert_timezone( $booking ) ) {
                $timezone_data = array(
                    'name'    => get_wc_booking_data_label( 'timezone', $cart_item['data'] ),
                    'value'   => str_replace( '_', ' ', $booking->get_local_timezone() ),
                    'display' => '',
                );
            }
        }

        $date_format    = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
        $time_format    = apply_filters( 'woocommerce_bookings_time_format', wc_time_format() );
        $start_date     = date_i18n( get_option( 'date_format' ), $booking->get_start( 'view', true ) );
        $start_time     = date_i18n( get_option( 'time_format' ), $booking->get_start( 'view', true ) );
        $end_time       = date_i18n( get_option( 'time_format' ), $booking->get_end( 'view', true ) );
        $persons        = $booking_data['_persons'];
        $booking_id     = $booking_data['_booking_id']; 

        $item_data[] = array(
            'key'       => __('Booking #', 'woocommerce'),
            'value'     => esc_html( $booking_id ),
            'display'   => esc_html( $booking_id ),
        );

        $item_data[] = array(
            'key'       => __('Date', 'woocommerce'),
            'value'     => esc_html( $start_date ),
            'display'   => esc_html( $start_date ),
        );

        $item_data[] = array(
            'key'       => __('Start time', 'woocommerce'),
            'value'     => esc_html( $start_time ),
            'display'   => esc_html( $start_time ),
        );

        $item_data[] = array(
            'key'       => __('End time', 'woocommerce'),
            'value'     => esc_html( $end_time ),
            'display'   => esc_html( $end_time ),
        );

        $count = 1;

        foreach($persons as $person){
            $item_data[] = array(
                'key'       => __('Person(s)', 'woocommerce') . $count,
                'value'     => esc_html( $person ),
                'display'   => esc_html( $person ),
            );
            $count++;
        }

        if ( ! empty( $timezone_data ) ) {
            // Add timezone to the end.
            $item_data[] = $timezone_data;
        }
    }

    return $item_data;

使用此代码,您的第一条评论中的第 1 步到第 4 步是不必要的。经过测试,它可以工作!

于 2019-05-02T13:45:48.193 回答