Un negozio WooCommerce è un WordPress con qualche responsabilità in più: incassa denaro, conserva ordini con dati personali e spesso scambia informazioni con un gestionale, un magazzino e i corrieri. Quando va portato su PHP 8, le parti che possono rompersi sono più numerose e più delicate: il tema con le sue copie dei template del negozio, il plugin del metodo di pagamento, le estensioni che leggono gli ordini direttamente dal database. Un errore nella pagina di pagamento costa vendite fin dal primo minuto.
In questo articolo vediamo cosa richiede oggi WooCommerce, come trovare e riallineare i template sovrascritti dal tema, come gestire i gateway di pagamento nel passaggio a PHP 8 e cos’è HPOS, l’archiviazione degli ordini in tabelle dedicate, con il percorso per attivarla su un negozio esistente senza perdere dati.
Cosa cambia per un negozio
Le regole generali per WordPress valgono anche qui: si lavora su una copia, si aggiorna tutto ciò che funziona sul PHP attuale, poi si cambia interprete e si sale con core ed estensioni, come descritto nell’articolo su WordPress su PHP vecchio. In un negozio si aggiungono quattro punti specifici:
- versione di WooCommerce: le estensioni dichiarano con le intestazioni
WC requires at leasteWC tested up tole versioni con cui funzionano, e un salto di molte versioni va fatto con le estensioni aggiornate insieme; - template sovrascritti dal tema, che restano fermi alla versione in cui sono stati copiati;
- gateway di pagamento, con i loro SDK e le notifiche di ritorno dal servizio di pagamento;
- archiviazione degli ordini: con HPOS gli ordini non sono più post di WordPress, e il codice che li legge come post va adeguato.
I requisiti di WooCommerce oggi
Secondo le raccomandazioni ufficiali per il server, le versioni correnti di WooCommerce richiedono PHP 8.3 o superiore, insieme a MySQL 8.0 o MariaDB 10.6 o successive. PHP 7.4 è indicato come compatibile solo in ambienti legacy, e WordPress dalla versione 7.0 richiede comunque almeno PHP 7.4. Per un negozio che tratta pagamenti, restare sulla soglia minima non è una buona idea: PHP 7.4 è fuori supporto dalla fine del 2022, e gli standard di sicurezza dei pagamenti chiedono di correggere le vulnerabilità note.
Template override: il debito nascosto nel tema
WooCommerce permette al tema di sostituire i propri template copiandoli nella cartella woocommerce del tema, per esempio woocommerce/cart/cart.php o woocommerce/single-product/price.php. È il modo previsto per personalizzare carrello, pagina prodotto ed email. Ogni copia, però, è ferma alla versione da cui è stata presa: quando WooCommerce cambia il template originale, con correzioni o nuovi hook, la copia nel tema non lo sa.
Ogni template di WooCommerce dichiara la propria versione nel commento iniziale, con il tag @version. La pagina WooCommerce, Stato, Stato del sistema confronta le copie del tema con gli originali e segnala quelle superate. Lo stesso controllo si può fare dalla riga di comando:
# Override presenti nel tema attivo e nel tema principale
find wp-content/themes/*/woocommerce -name '*.php' | sort
# Versione dichiarata dall'override e dal template originale
grep -H '@version' wp-content/themes/mio-tema/woocommerce/cart/cart.php
grep -H '@version' wp-content/plugins/woocommerce/templates/cart/cart.php
# Differenze tra la copia nel tema e l'originale aggiornato
diff -u wp-content/plugins/woocommerce/templates/cart/cart.php \
wp-content/themes/mio-tema/woocommerce/cart/cart.php
Per ogni override superato ci sono due strade. Se la personalizzazione è piccola, conviene spesso eliminare la copia e ottenere lo stesso risultato con un hook o una regola CSS, così il problema non si ripresenta. Se è sostanziale, si riparte dal template nuovo e si riapplicano le modifiche. Gli override vanno tenuti in un tema figlio, come spieghiamo nell’articolo su child theme e personalizzazioni, altrimenti il primo aggiornamento del tema li cancella.
Un caso a parte sono carrello e checkout a blocchi. Da WooCommerce 8.3 le nuove installazioni usano i blocchi Carrello e Pagamento, che non passano dai template PHP: le personalizzazioni fatte con override o con gli hook del checkout classico lì non hanno effetto. Un negozio esistente può restare sul checkout classico, ma se passa ai blocchi quelle personalizzazioni vanno rifatte con le estensioni previste per i blocchi.
Gateway di pagamento
Il plugin del metodo di pagamento è il componente da trattare con più cura. Collega il negozio a un servizio esterno tramite un SDK o chiamate dirette alle API, riceve le notifiche di pagamento completato e aggiorna lo stato degli ordini. Un errore qui produce ordini pagati che restano “in attesa”, oppure pagamenti che non partono.
- Gateway ufficiali e mantenuti: si aggiornano all’ultima versione compatibile con il PHP di destinazione. I produttori seguono le versioni di PHP e di WooCommerce, ma è bene leggere le note di rilascio, perché a volte cambiano il modo di configurare le chiavi o i webhook.
- Gateway vecchi o abbandonati: spesso usano SDK fermi da anni, scritti per PHP 5 o 7, e talvolta versioni delle API del servizio di pagamento già dismesse. Di solito conviene sostituirli con il plugin ufficiale del servizio, con le cautele descritte nell’articolo sui plugin WordPress abbandonati.
- Gateway su misura, scritti per una banca o un circuito specifico: vanno rivisti riga per riga, con particolare attenzione alla verifica della firma delle notifiche di ritorno.
- Checkout a blocchi: un gateway che non ha l’integrazione per i blocchi non compare nella pagina di pagamento a blocchi, e WooCommerce lo segnala. Prima di passare ai blocchi bisogna verificare che tutti i metodi di pagamento attivi la abbiano.
I test si fanno con gli ambienti di prova dei servizi di pagamento, sulla copia del negozio raggiungibile da Internet, perché le notifiche di ritorno devono poter arrivare. Vanno provati il pagamento riuscito, quello rifiutato, quello annullato dal cliente e il rimborso dalla bacheca, per ogni metodo attivo.
HPOS: gli ordini in tabelle dedicate
Per molti anni WooCommerce ha salvato gli ordini come post di WordPress, nella tabella wp_posts, con tutti i dettagli nella tabella dei metadati wp_postmeta. Con molti ordini questa struttura diventa lenta, perché ogni ricerca passa da una tabella di metadati generica condivisa con tutti i contenuti del sito. High-Performance Order Storage, in breve HPOS, salva invece gli ordini in tabelle progettate apposta: wc_orders, wc_order_addresses, wc_order_operational_data e wc_orders_meta, con il prefisso del database del sito.
La documentazione per gli sviluppatori indica che HPOS è stabile e attivo di serie per le nuove installazioni da WooCommerce 8.2, uscito a ottobre 2023. I negozi creati prima devono attivarlo, e possono farlo con una modalità di compatibilità che tiene sincronizzati i due archivi durante il passaggio.
Rendere compatibili estensioni e codice su misura
Il codice che usa le API di WooCommerce per leggere e scrivere gli ordini funziona con entrambi gli archivi. Quello che si rompe è il codice che tratta gli ordini come post: get_post_meta() e update_post_meta() su un ordine, WP_Query con il tipo shop_order, query SQL dirette su wp_posts e wp_postmeta. Con HPOS attivo queste chiamate leggono dati vecchi o non trovano nulla.
Il ricettario HPOS per le estensioni descrive le modifiche. Le principali sono due: usare l’oggetto ordine al posto delle funzioni dei post e dichiarare la compatibilità nel file principale del plugin. Finché un’estensione attiva non la dichiara, WooCommerce la considera incompatibile e lo segnala nelle impostazioni.
// Nel file principale del plugin: dichiarazione di compatibilità con HPOS
add_action( 'before_woocommerce_init', function () {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
}
} );
// Prima: l'ordine trattato come un post (non funziona con HPOS attivo)
$codice = get_post_meta( $order_id, '_codice_gestionale', true );
update_post_meta( $order_id, '_codice_gestionale', $nuovo_codice );
// Dopo: l'oggetto ordine, che funziona con entrambi gli archivi
$order = wc_get_order( $order_id );
$codice = $order->get_meta( '_codice_gestionale' );
$order->update_meta_data( '_codice_gestionale', $nuovo_codice );
$order->save();
Per le ricerche si usa wc_get_orders() al posto di WP_Query. Le estensioni che aggiungono riquadri alla pagina dell’ordine devono usare l’identificativo della nuova schermata, che il ricettario indica, e le query SQL scritte a mano vanno riscritte o messe sotto il controllo di OrderUtil::custom_orders_table_usage_is_enabled(), con un ramo per ciascun archivio.
Il passaggio a HPOS passo per passo
Su un negozio esistente il passaggio si fa in fasi, sempre provate prima su una copia. WooCommerce mette a disposizione una serie di comandi WP-CLI nel gruppo wp wc hpos, utili soprattutto quando gli ordini sono molti.
- verificare che tutte le estensioni attive dichiarino la compatibilità con HPOS, aggiornandole, sostituendole o adeguando il codice su misura;
- fare una copia di sicurezza del database;
- attivare la modalità di compatibilità con l’archivio tradizionale ancora principale, e lasciare che WooCommerce copi gli ordini nelle nuove tabelle;
- verificare che i dati coincidano tra i due archivi;
- rendere HPOS l’archivio principale, mantenendo attiva la sincronizzazione;
- dopo un periodo di osservazione con ordini reali, disattivare la sincronizzazione.
# Situazione attuale e ordini ancora da copiare nelle nuove tabelle
wp wc hpos status
wp wc hpos count_unmigrated
# Copia degli ordini dall'archivio attivo all'altro
wp wc hpos sync
# Confronto tra i due archivi; diff mostra le differenze di un ordine
wp wc hpos verify_data
wp wc hpos diff 12345
# HPOS come archivio principale, con la sincronizzazione attiva
wp wc hpos enable --with-sync
Il vantaggio di questo percorso è la reversibilità. Finché la sincronizzazione è attiva, entrambi gli archivi contengono gli stessi ordini, e se un’estensione si comporta male si può tornare all’archivio tradizionale dalle impostazioni senza perdere nulla. La sincronizzazione ha un costo in scrittura, per questo non va lasciata attiva per sempre. Le vecchie copie degli ordini nelle tabelle dei post si eliminano solo alla fine, con wp wc hpos cleanup, quando si è certi di non doverle più usare.
Conviene fare il passaggio a HPOS come fase separata dal cambio di PHP: prima il negozio su PHP 8 con l’archivio tradizionale, poi HPOS. Due cambiamenti alla volta rendono più difficile capire la causa di un problema. Se vuoi pianificare le due fasi per il tuo negozio, scrivici indicando versione di WooCommerce, numero di ordini e metodi di pagamento attivi.
Tirando le somme
Portare WooCommerce su PHP 8 significa occuparsi di quattro cose oltre al core: versione di WooCommerce ed estensioni, template sovrascritti dal tema, gateway di pagamento e archiviazione degli ordini. Le versioni correnti di WooCommerce raccomandano PHP 8.3 o superiore. Gli override nella cartella woocommerce del tema si controllano con il tag @version e vanno riallineati o sostituiti con hook, dentro un tema figlio. I gateway si aggiornano o si sostituiscono con quelli ufficiali e si provano in ambiente di prova con tutti gli esiti possibili, anche sul checkout a blocchi. HPOS, attivo di serie sulle nuove installazioni da WooCommerce 8.2, richiede estensioni che usino l’oggetto ordine e dichiarino la compatibilità, e si attiva per fasi con la sincronizzazione tra i due archivi, che rende il passaggio reversibile.