Aggiornare programmaticamente gli attributi personalizzati in WooCommerce

17 nov 2015, 11:54:55
Visualizzazioni: 18.8K
Voti: 2

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:

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

2
Commenti

Stai aggiungendo prodotti al database tramite i tuoi "trigger personalizzati" oppure i trigger MySQL rispondono quando inserisci dati nel database tramite WordPress? O stai inserendo manualmente dati di WordPress (prodotti?) nel database e questi compaiono nell'admin? Se puoi darmi un po' di chiarezza, credo di poterti aiutare.

Tom Tom
17 nov 2015 13:08:38

Grazie per la tua rapida risposta, Tom. Funziona così: - L'utente completa un sondaggio nella tabella wp_fsq_data - Il trigger notifica l'inserimento in questa tabella sondaggio ed esegue la query 1: legge una stringa serializzata in una tabella 'conv1' - Il trigger notifica l'inserimento in questa tabella conv1 ed esegue la query 2: etichetta valori numerici come stringhe in una tabella temporanea 'conv2' - Il trigger notifica l'inserimento in questa tabella conv2 ed esegue la query 3: inserisce/aggiorna tutti i dati nella struttura WP (wp_posts, wp_terms, wp_postmeta, wp_relationships) - Il post appare nel front-end senza attributi nei dropdown/selector.

Thom Rommens Thom Rommens
17 nov 2015 13:30:44
Tutte le risposte alla domanda 3
1

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.

1 apr 2016 18:29:15
Commenti

I transient sono esattamente il problema, ed è per questo che non si aggiornano sul front-end. Maledetti transient!

Solomon Closson Solomon Closson
9 set 2016 18:28:34
2

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.

17 nov 2015 13:46:42
Commenti

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

Thom Rommens Thom Rommens
17 nov 2015 15:02:01

Thom, ha funzionato per te?

Tom Tom
18 ott 2017 15:35:46
0
-1

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/

12 set 2017 16:10:03