Establezca el código postal de un campo para invitados y clientes en WooCommerce
La idea principal es validar el código postal de un huésped y mostrar diferentes mensajes de acuerdo con él. He usado este hilo para configurar el código de envío: configure el código postal de envío antes de agregarlo al carrito en WooCommerce
Creé una solicitud AJAX en funcionamiento que toma el valor de una entrada en la página de destino.
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");
}
});
})
});
Luego, el valor se pasa a una función PHP que se supone que agrega el postcode
valor a la sesión de invitado 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();
}
También he creado una función de código abreviado para mostrar la sesión del invitado 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
<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' );
El problema es que la función PHP que obtiene la respuesta AJAX no parece establecer la postcode
sesión del invitado customer_data
. Intenté configurar postcode
directamente en el código corto (con el mismo método) y funciona.
¿Podrías ayudarme a averiguar dónde está el problema? También tengo dificultades para depurar, ¿cómo puedo saber si customer_data
se ha cambiado la sesión ?
Gracias.
EDITAR: Envié la sesión del invitado customer data
a la respuesta AJAX y obtuve esto:
array(26) { ["id"]=> string(1) "0" ... ["postcode"]=> int(44500) ... }
Esto significa que los datos se almacenan justo después de la respuesta AJAX. El problema parece que estos datos no se almacenan cuando recargo la página e intento obtener la sesión del invitado customer data
nuevamente.
Respuestas
En su lugar, debe usar los métodos setter y getter disponibles en el WC_Customer
objeto como:
WC()->customer->get_billing_postcode()
oWC()->customer->get_shipping_postcode()
WC()->customer->set_billing_postcode()
oWC()->customer->set_shipping_postcode()
Ahora hay algunos errores en su código. He revisado todo su código de la siguiente manera:
// 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") . '
<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();
}
}
El código va en el archivo functions.php del tema hijo activo (o tema activo). Probado y funciona.