Aggiornare programmaticamente gli attributi personalizzati in WooCommerce
Innanzitutto, grazie per far parte di questa straordinaria comunità che mi ha aiutato migliaia di volte in passato.
Nel mio ambiente WordPress (tema Enfold, plugin WooCommerce) ho creato un sistema che utilizza un sondaggio come input per la creazione automatica di articoli in un front-end. Le risposte del sondaggio vengono incluse nei post generati automaticamente (tipo 'product') insieme agli Attributi Personalizzati di WooCommerce.
Ho scritto query personalizzate che rispondono a trigger in mySQL - inserendo e aggiornando wp_posts, wp_terms, wp_postmeta, wp_term_relationships.
Tutto funziona bene, tranne una cosa: gli attributi personalizzati dei prodotti WooCommerce non vengono visualizzati immediatamente nei filtri dropdown/select del sito. Tuttavia, premendo manualmente "Aggiorna" nella pagina WordPress il problema si risolve.
Sto cercando un modo per replicare esattamente l'azione di premere manualmente "Aggiorna" nel CMS WordPress. Finora, il post stesso viene caricato correttamente nel sito, ma i suoi attributi del prodotto WooCommerce non vengono inizializzati.
Finora ho provato molte soluzioni alternative:
- Impostare programmaticamente lo stato di un post (bozza) e cambiarlo immediatamente in post pubblicato (publish);
- Utilizzare la programmazione integrata di WordPress impostando un orario di pubblicazione;
- Chiamare wp_update_post;
- Usare il plugin Tao Scheduled Updates (https://nl.wordpress.org/plugins/tao-schedule-update/);
- Usare il plugin WordPress PostController (https://github.com/HarriBellThomas/Wordpress_PostController)
Tuttavia, tutti i tentativi aggiornano solo i post in wp_posts, apparentemente non le relazioni/gli attributi personalizzati sottostanti.
La mia unica richiesta sarebbe replicare programmaticamente il click su "Aggiorna" nell'ambiente CMS WordPress. Questo mi aiuterebbe ad automatizzare il processo invece di intervenire manualmente.
Potreste suggerirmi un modo per farlo?
Grazie mille per il vostro tempo!
AGGIORNAMENTO:
Ciao Tom,
Dopo aver approfondito la tua risposta, ancora non capisco.
Le mie query aggiornano/inseriscono tutte le tabelle necessarie. Praticamente seguono tutti i passaggi degli script php a cui ti riferisci.
Quando controllo un prodotto nel CMS, vedo tutti i dati - e soprattutto gli attributi - caricati correttamente. Quando premo Aggiorna manualmente nel CMS e confronto i dati nelle tabelle mySQL prima e dopo l'aggiornamento, non vedo differenze significative. L'unica cosa che noto è il valore per _product_attributes in wp_postmeta che è leggermente diverso (stringa serializzata).
Tuttavia, quando sperimento con questo valore (svuotandolo/modificandolo per il post specifico in wp_postmeta), nulla cambia negli attributi - e tutto continua a funzionare quando filtro.
Questo mi porta alle domande:
- Cosa succede esattamente quando si preme "Aggiorna" manualmente?
- C'è un altro storage oltre alle tabelle mySQL in cui alcune parti sono connesse in qualche modo?
- Sarebbe possibile per me 1) considerare acquisita la procedura "crea prodotto" a cui ti riferisci e saltarla (poiché ho eseguito le mie query) e poi 2) chiamare solo la procedura esatta che viene eseguita quando si preme Aggiorna - per "collegare" tutto senza ricreare tutte le voci del database?
- Se sì, dove troverei questa specifica procedura?
Il tuo aiuto è molto apprezzato. Grazie! Thom

OK, quindi ho avuto una variante dello stesso problema e te lo spiegherò passo dopo passo.
Tutto funziona bene, tranne una cosa: gli attributi personalizzati dei prodotti WooCommerce non vengono visualizzati immediatamente nei menu a discesa/filtri select sul sito web. Tuttavia, premendo manualmente Aggiorna nella pagina di Wordpress il problema si risolve.
Quando WooCommerce visualizza gli attributi, utilizza questa funzione: wc_get_attribute_taxonomies() (http://woocommerce.wp-a2z.org/oik_api/wc_get_attribute_taxonomies/)
Noterai che in quella funzione i dati vengono recuperati da un 'transient' (pensa a dati in cache, vedi http://codex.wordpress.org/Transients_API).
Se stai caricando manualmente i dati nel database, è probabile che tu abbia dimenticato di caricare il transient (che tra l'altro va in wp_options
). Premendo Aggiorna nel pannello di amministrazione di Wordpress, viene eseguita la funzione che aggiorna il transient, ecco perché poi funzionano/si vedono e prima no.
Per far funzionare tutto, devi assicurarti che il tuo aggiornamento manuale del MySQL includa anche l'aggiornamento del transient. Nel mio caso, aggiungendo manualmente attributi dei prodotti in WooCommerce, ho dovuto inserire una riga in wp_options
con options_name
_transient_wc_attribute_taxonomies
e i miei attributi nell'array serializzato nella colonna option_value
(più un ID con autoload impostato su sì). Ma ci sono altri transient, quindi dipende da quale funzione sta causando il problema e cosa stai cercando di visualizzare. Puoi vedere quale ti manca facendo una ricerca MySQL per %transient%
in wp_options
una volta prima di cliccare Aggiorna nel pannello di amministrazione di Wordpress e una dopo, poi confrontando i dati.

Stai aggiornando anche i termini all'interno del prodotto Woocommerce? Sia Wp_term_taxonomy
che wp_woocommerce_attribute_taxonomies
devono essere aggiornati con i tuoi termini di tassonomia per consentire al prodotto Woocommerce di visualizzare i menu a discesa delle variazioni come "Colore" o "Taglia".
Quando crei un prodotto Woocommerce in modo programmatico, le Variazioni Prodotto devono essere inserite e collegate agli attributi esistenti (tassonomie create all'interno di Woocommerce).
Guarda il meta key del post "_product_attributes" che contiene i dati degli attributi. Dovrai comunque associare i termini (attributi) al tuo prodotto (all'interno di wp_term_taxonomy
) ma spero che questo ti dia una direzione in cui muoverti.
Dai anche un'occhiata alle funzioni create_product
(https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L237) e save_variations
(https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L1692) che delineano entrambe come eseguire la creazione del prodotto e delle sue variazioni.

Grazie ancora, Tom. Sì, mi era sfuggito wp_term_taxonomy. Sì, sto inserendo/aggiornando anche quella tabella.
Poiché l'insieme degli attributi non cambia e nessun conteggio è registrato in wp_woocommerce_attribute_taxonomies, cosa esattamente necessita di essere aggiornato lì?
Grazie per quei link. Mi approfondirò e ti farò sapere!
Saluti, Thom

Questa è un'opzione con codice PHP:
function change_price_by_type( $product_id, $price, $price_type) {
update_post_meta( $product_id, '_' . $price_type, $price );
}
function change_price_all_types( $product_id, $price ) {
change_price_by_type( $product_id, $price, 'price' );
change_price_by_type( $product_id, $price, 'sale_price' );
change_price_by_type( $product_id, $price, 'regular_price');
}
function change_product_price( $product_id, $price ) {
change_price_all_types( $product_id, $price );
$product = wc_get_product( $product_id ); // Gestione dei prodotti variabili
if ( $product->is_type( 'variable' ) ) {
// RM: Ottieni le variazioni anche quelle esaurite
$args = array(
'post_type' => 'product_variation',
'post_status' => array( 'private', 'publish' ),
'numberposts' => -1,
'orderby' => 'menu_order',
'order' => 'asc',
'post_parent' => $product_id // $post->ID
);
$variations = get_posts( $args );
foreach ( $variations as $variation ) {
change_price_all_types( $variation->ID, $price );
}
}
}
$args = array( 'post_type' => 'product', 'posts_per_page' => 3000);
$products = get_posts( $args );
foreach($products as $product) {
change_product_price($product->ID, 9.99);
echo $product->ID;
}
exit;
poi vai su phpMyAdmin ed esegui le seguenti query SQL (potresti dover cambiare il nome della tua tabella invece di wp_).
UPDATE `wp_postmeta`
SET `meta_value` = ''
WHERE `meta_key` IN ('_sale_price', '_sale_price_dates_from', '_sale_price_dates_to')
AND `post_id` IN
(SELECT `ID`
FROM `wp_posts`
WHERE `post_type` = 'product'
AND `post_status` = 'publish' );
Svuota la cache:
DELETE
FROM `wp_options`
WHERE (`option_name` LIKE '_transient_wc_var_prices_%'
OR `option_name` LIKE '_transient_timeout_wc_var_prices_%')
Il codice SQL è stato preso da: http://www.technoedu.com/forums/topic/wordpress-solved-copy-woocommerce-products-sale-prices-to-regular-prices-and-reset-sale-prices/
