Tetapkan kode pos dari bidang untuk tamu dan pelanggan di WooCommerce

Jan 14 2021

Ide utamanya adalah untuk memvalidasi kode pos tamu dan menunjukkan pesan yang berbeda sesuai dengan itu. Saya telah menggunakan utas ini untuk mengatur kode pengiriman: Setel kode pos pengiriman lebih awal sebelum menambahkan ke keranjang di WooCommerce

Saya telah membuat permintaan AJAX yang berfungsi yang mengambil nilai input di halaman arahan.

jQuery(document).ready(function ($) {

  let postcodeField = jQuery("#postcode-field");
  let postcodeVal;

  postcodeField.on("change", function () {
    postcodeVal = postcodeField.val();
  });

  jQuery("#ph_btn").on("click", function () {

    var data = {
      action: 'postcode_handler',
      postcode: postcodeVal
    };

    // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
    // If you need it on a public facing page, uncomment the following line:
    var ajaxurl = ph_script.ajax_url;

    jQuery.ajax({
      type: 'POST',
      url: ajaxurl,
      data: data,
      success: function (result) {
        // console.log(result);
      },
      error: function () {
        console.log("error");
      }
    });
  })
});

Nilai tersebut kemudian diteruskan ke fungsi PHP yang seharusnya menambahkan postcodenilai ke sesi tamu customer_data.

function my_AJAX_processing_function(){

    // Getting the postcode value
    $postcode = intval($_POST['postcode'] ); //Check if the input was a valid integer if ( $postcode == 0 ) {
        echo "Invalid Input";
            wp_die();
    }
    
    //Important: Early enable customer WC_Session 
    add_action( 'init', 'wc_session_enabler' );
    function wc_session_enabler() {
        if ( ! is_admin() && ! WC()->session->has_session() ) {
            WC()->session->set_customer_session_cookie( true );
        }
    }

    // Get an array of the current customer data stored in WC session
    $customer_data = (array) WC()->session->get('customer'); // Change the billing postcode $customer_data['postcode'] = $postcode; // Change the shipping postcode $customer_data['shipping_postcode'] = $postcode; // Save the array of customer WC session data WC()->session->set('customer', $customer_data);

    // Sending a response to the AJAX request
    echo($postcode);
    
    wp_die();

}

Saya juga telah membuat fungsi kode pendek untuk menunjukkan sesi tamu customer_data.

function shortcode_postcode_field(){

  // Getting the customer data from the session
  $customer_data = (array) WC()->session->get('customer');

  // Get the billing postcode
  // if ( isset( $customer_data['postcode'] ) ) $postcode = $customer_data['postcode']; // Showing the customer data for debug reasons var_dump($customer_data);

  return '
  <p class="form-row postcode-field on" id="postcode-field_field" data-priority="">
    <label for="postcode-field" class="">Code postal&nbsp;
      <span class="optional">(facultatif)</span>
    </label>
    <span class="woocommerce-input-wrapper">
      <input type="number" class="input-text" name="postcode" id="postcode-field" placeholder="85000" value="">
    </span>
    <button id="ph_btn" style="color: black">Vérifier son code postal</button>
    <p>Votre code postal est '.$postcode.'</p>
  </p>
  ';
}
add_shortcode( 'postcode-field', 'shortcode_postcode_field' );

Masalahnya adalah bahwa fungsi PHP yang mendapatkan respons AJAX tampaknya tidak menyetel postcodeke sesi tamu customer_data. Saya sudah mencoba mengatur postcodelangsung di shortcode (dengan metode yang sama) dan berhasil.

Bisakah Anda membantu saya mencari tahu di mana letak masalahnya? Saya juga mengalami kesulitan untuk men-debug - bagaimana cara mengetahui bahwa sesi customer_datatelah diubah?

Terima kasih.

EDIT: Saya telah mengirim sesi tamu customer datake tanggapan AJAX dan saya mendapatkan ini:

array(26) { ["id"]=> string(1) "0" ... ["postcode"]=> int(44500) ... }

Ini berarti bahwa data disimpan tepat setelah respons AJAX. Masalahnya tampaknya data ini tidak disimpan saat saya memuat ulang halaman dan mencoba mendapatkan sesi tamu customer datalagi.

Jawaban

2 LoicTheAztec Jan 14 2021 at 20:16

Anda perlu menggunakan metode penyetel dan pengambil yang tersedia di WC_CustomerObjek seperti:

  • WC()->customer->get_billing_postcode() atau WC()->customer->get_shipping_postcode()
  • WC()->customer->set_billing_postcode() atau WC()->customer->set_shipping_postcode()

Sekarang ada beberapa kesalahan dalam kode Anda. Saya telah mengunjungi kembali semua kode Anda sebagai berikut:

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

// Shortcode
add_shortcode( 'postcode-field', 'shortcode_postcode_field' );
function shortcode_postcode_field(){
    return '<p class="form-row postcode-field on" id="postcode-field_field" data-priority="">
        <label for="postcode-field" class="">' . __("Postcode", "woocommerce") . '&nbsp;
            <span class="optional">(optional)</span>
        </label>
        <span class="woocommerce-input-wrapper">
            <input type="number" class="input-text" name="postcode-input" id="postcode-input" placeholder="85000" value="">
        </span>
        <button id="postcode-submit" name="postcode-submit" class="button alt">' . __("Check your postcode", "woocommerce") . '</button>
        <br><div class="postcode-message" style="display:none"></div>
    </p>';
}

// Jquery (Ajax sender)
add_action( 'wp_footer', 'postcode_field_js_script' );
function postcode_field_js_script() {
    ?>
    <script type="text/javascript">
    jQuery( function($) { var postcode = ''; $('#postcode-input').on("input change", function () {
            postcode = $(this).val(); }); $("#postcode-submit").on('click', function () {
            $.ajax({ type: 'POST', url: '<?php echo admin_url('/admin-ajax.php'); ?>', data: { 'action': 'postcode_receiver', 'postcode': postcode }, success: function (response) { $('.postcode-message').html(response).show(300);
                    // console.log(response);
                },
                error: function (error) {
                    $('.postcode-message').html(error).show(300); // console.log(error); } }); }); }); </script> <?php } // Php (Ajax receiver) - Check and set the postcode - return message (notice) add_action('wp_ajax_postcode_receiver', 'postcode_receiver'); add_action('wp_ajax_nopriv_postcode_receiver', 'postcode_receiver' ); function postcode_receiver(){ if( isset($_POST['postcode']) ) {
        $postcode = sanitize_text_field($_POST['postcode']);

        if ( $postcode > 0 ) { WC()->customer->set_shipping_postcode($postcode);
            WC()->customer->set_billing_postcode($postcode); $saved_postcode = WC()->customer->get_shipping_postcode();

            echo sprintf( '<span style="color:green;">' . __("Your postcode %s has been registered successfully.", "woocommerce") . '</span>', '"' . $saved_postcode . '"' );
        } else {
            echo '<span style="color:red;">' . __("Check your postcode input please.", "woocommerce") . '</span>';
        }
        wp_die();
    } else {
        echo '<span style="color:red;">' . __("A problem has occurred, try later.", "woocommerce") . '</span>';
        wp_die();
    }
}

Kode masuk ke file functions.php dari tema anak aktif (atau tema aktif). Teruji dan berhasil.