Creare dei campi personalizzati nel checkout di Woocommerce
L’e-commerce ha pervaso il mercato, in questa situazione sempre più spesso ci si imbatte in personalizzazioni abbastanza “spinte” di WooCommerce. Questo perché ormai si è trasceso il classico invio di merce, infatti trovaresi confrontati e-commerce che gestiscono noleggi, appuntamenti e quant’altro non è più una rarità.
Chiaramente ogniuna di queste attività richiederà delle informazioni addizionali da inserire nel cammino verso il checkout, come ad esempio l’orario di un appuntamento, il piano di consegna, o addirittura interi file.
Quello che mi ha ispirato a buttare giù questi appunti è il progetto che sto seguendo attualmente: un noleggio di mountainbike e e-bike, che nello specifico ha la necessità di sapere, oltre alla filiale di ritiro (gestita con le spedizioni, anche l’orario di ritiro e la conferma che l’utente abbia un’assicurazione RC.
Quello che vedrai in questo articolo:
- Inserire dei campi personalizzati nel checkout
- Gestire eventuali errori di compilazione
- Salvare i dati nel DB di WordPress
- Richiamare i dati personalizzati nella pagina di dettaglio e nella mail [work in progress] Tieni conto innanzitutto che questo sono appunti per me stesso, che ho piacere di condividere con la community 🙂
Inserire dei campi personalizzati nel Checkout
Tutte le modifiche saranno da fare nel file function.php del tema. Ovviamente quello child!
Per aggiungere questo benedetto campo ci appoggeremo alle add_action() e a delle funzioni che conterranno. Nell’esempio, i campi verranno inseriti dopo le note dell’ordine, tramite l’hook woocommerce_after_order_notes, ma è possibile scegliere altre posizioni.
//Aggiungo la funzione all'hook dopo le noste add_action('woocommerce_after_order_notes', 'assicurazione_rc');
//Funzione per la creazione
function assicurazione_rc($checkout) {
//Controlla se nel carrello c'è un prodotto della caregoria noleggio
$categories = array('noleggio');
$has_category = false;
//Loop tra tutti i prodotti
foreach ( WC()->cart->get_cart() as $cart_item ) {
// Controlla la categoria
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
$has_category = true;
break;
}
}
//Se un prodotto ha la categoria, pubblica il campo di input
if ( $has_category ) {
//Riquadro e messaggio personalizzato
echo '<div id="assicurazione-rc"><h2>' . __('Sei intestatario di una assicurazione RC?') . '</h2>';
echo '<p>È <strong>obbligatorio</strong> per tutti gli utilizzatori delle e-bike a noleggio possedere una copertura assicurativa</p>';
echo '<p>Lorem ipsum</p>';
//Creo il campo input usando una funzione dedicada di Woocommerce
//Indico il nome del campo, che ci servirà in seguito per recuperare
//i dati, in seguito l'array con le caratteristiche del campo
woocommerce_form_field(
//Nome del campo
'assicurazione_rc',
//Arry valori dell'input
array(
//Tipo di input
'type' => 'select',
//Eventuali classi
'class' => array(
'assicurazion-rc-box'
),
//Creazione label
'label' =>__(
'Tutti i partecipanti sono coperti da una assicurazione RC'
),
//Un'array con le opzioni per il campo select
'options' => array(
// il campo vuoto serve a dare un'etichetta al campo non
// selezionato.
// L'indice dell'array equivale al campo option del select, il
//valore all'etichetta selezionata
'' => 'Seleziona',
'rc-ok' => 'Si, siamo coperti da una RC'
)
),
//Aggiungo il valore al checkout
$checkout->get_value('assicurazione_rc')
);
echo '</div>';
}
}
A questo punto vi trovere il vostro campo personalizzato ed è recuperabile utilizzando il nome indicato nella funzion woocommerce_form_field, in questo caso sarà $_POST[‘assicurazione_rc’] e lo ritroveremo spesso in questo articolo.
La cattiva notiza che attualmente servirebbe a ben poco, visto che non verrebbe salvato nel DB. Quindi avanti!
Gestire gli errori dei campi personalizzati
Nel mi case study, il campo dell’assicurazione RC è obbligatoria, quindi in qualche modo avrei dovuto intercettare l’errore con un’altra action accompagnata da una funzione.
//Aggiungo il controllo all'hook del processo di checkout
add_action('woocommerce_checkout_process', 'controllo_rc');
function controllo_rc(){
//Controllo ancora che ci siano prodotti nella catagoria noleggio
$categories = array('noleggio');
$has_category = false;
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
$has_category = true;
break;
}
}
//Controllo che assicurazione_rc sia valorizzato, ma nel contempo
//che ci siano effettivamente prodotti a noleggio
if (!$_POST['assicurazione_rc'] && $has_category) {
//Aggiungo il messaggio usando la funzion di WooComemrce
wc_add_notice(
//Scrivo il messaggio
__('<strong>Assicurazione RC</strong> Hai una assicurazione RC? È obbligatoria per il noleggio '),
//Imposto il tipo di messaggio
'error'
);
}
}
Fatto questo, quando l’utente cercherà di finalizzare l’ordine, WooCommerce si occuperà di controllare il campo e, nel caso ci sia un errore, bloccherà il processo mostrando anche un avviso. Comodo, vero?
Ora andiamo alla ciccia! DB e visualizzazione delle informazioni personalizzate nell’ordine…
Salvare i dati personalizzati WooCommerce nel DB di WordPress
Come di consueto ci appoggeremo alle action, ma qui la parte del leone la farà la funzione update_post_meta, che permette di interagire con i campi post_meta, un po’ come con la tabella Option di qui scrivo in questo articolo. Chissà che non scriva un aricolo dedicato al post_meta…
//Aggiungo la funzione all'hook del salvataggio dei dati di WooCommerce dell'ordine
add_action('woocommerce_checkout_update_order_meta','save_controllo_rc');
//Funzione in cui passi il paramerto gl
function save_controllo_rc($order_id) {
//Controllo che effettivamente il campo venga postato
if (!empty($_POST['assicurazione_rc'])) {
//Faccio update dei meta dei post
update_post_meta(
//Numero dell'ordine a cui associare il meta
$order_id,
//Il nome del campo
'_assicurazione_rc',
//
sanitize_text_field($_POST['assicurazione_rc']));
}
}
Vi siete accorti di una particolarità? Per convenzione, il nome di ogni post_meta associato ad un ordine WooCommerce deve inziare con underscore, in questo caso il campo si chiamerà _assicurazione_rc
Ora abbiamo salvato il dato nel DB di WordPress, associato al suo ordine, ora vediamo come visualizzarlo nei dettagli dell’ordine.
Visualizzare i dati personalizzati nella pagina di dettaglio dell’ordine di WooCommerce
Ci siamo quasi! Ora chi gestisce l’e-commerce vorrebbe anche sapere cosa l’utente ha inserito durante il checkout. Dite che ci serivremo di un’altro hook? Ma certo, precisamente di woocommerce_admin_order_data_after_billing_address, che ci permette di appiccicare i dati dopo i dati di fatturazione dell’ordine.
//Colleghiamo la funzione all'hook e diamo una priorità di visualizzazione 10 e la possiblità di prendere in carico un argomento
add_action('woocommerce_admin_order_data_after_billing_address', 'display_controllo_rc', 10, 1);
function display_controllo_rc($order) {
echo '<p><strong>' . __('Assicurazione RC') . ':</strong><br> ' .
//Recupero il post_meta
get_post_meta($order->id, '_assicurazione_rc', true) . '</p>';
}