Legen Sie in WooCommerce die Postleitzahl eines Feldes für Gäste und Kunden fest

Jan 14 2021

Die Hauptidee besteht darin, die Postleitzahl eines Gastes zu validieren und verschiedene Nachrichten entsprechend anzuzeigen. Ich habe diesen Thread verwendet, um den Versandcode festzulegen: Legen Sie die Postleitzahl für den Versand frühzeitig fest, bevor Sie sie in WooCommerce in den Warenkorb legen

Ich habe eine funktionierende AJAX-Anforderung erstellt, die den Wert einer Eingabe auf der Zielseite annimmt.

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");
      }
    });
  })
});

Der Wert wird dann an eine PHP-Funktion übergeben, die den postcodeWert zur Gastsitzung hinzufügen soll 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();

}

Ich habe auch eine Shortcode-Funktion erstellt, um die Sitzung des Gastes anzuzeigen 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' );

Das Problem ist, dass die PHP-Funktion, die die AJAX-Antwort erhält postcode, die Sitzung des Gastes nicht festzulegen scheint customer_data. Ich habe versucht, das postcodedirekt in den Shortcode zu setzen (mit der gleichen Methode) und es funktioniert.

Können Sie mir helfen, herauszufinden, wo das Problem liegt? Ich habe auch Schwierigkeiten beim Debuggen - wie kann ich feststellen, dass die Sitzung customer_datageändert wurde?

Vielen Dank.

BEARBEITEN: Ich habe die Sitzung des Gastes customer dataan die AJAX-Antwort gesendet und Folgendes erhalten:

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

Dies bedeutet, dass die Daten unmittelbar nach der AJAX-Antwort gespeichert werden. Das Problem scheint, dass diese Daten nicht gespeichert werden, wenn ich die Seite neu lade und versuche, die Sitzung des Gastes customer dataerneut abzurufen .

Antworten

2 LoicTheAztec Jan 14 2021 at 20:16

Sie müssen stattdessen verfügbare Setter- und Getter-Methoden für das WC_CustomerObjekt verwenden, z. B.:

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

Jetzt gibt es einige Fehler in Ihrem Code. Ich habe Ihren gesamten Code wie folgt überarbeitet:

// 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();
    }
}

Der Code befindet sich in der Datei functions.php des aktiven untergeordneten Themas (oder des aktiven Themas). Getestet und funktioniert.