Actualizare programatică a Atributelor Personalizate WooCommerce
În primul rând, mulțumesc pentru că faci parte dintr-o comunitate impresionantă care m-a ajutat de mii de ori până acum.
În mediul meu WordPress (tema Enfold, plugin WooCommerce) am creat un sistem care folosește un sondaj ca intrare pentru postări instantanee într-un site front-end. Răspunsurile din sondaj sunt incluse în postările generate automat (tip 'produs') inclusiv Atribute Personalizate WooCommerce.
Am scris interogări personalizate care răspund la trigger-e în mySQL - inserând și actualizând wp_posts, wp_terms, wp_postmeta, wp_term_relationships.
Totul funcționează bine, cu excepția unui lucru: atributele personalizate ale produselor WooCommerce nu sunt afișate instantaneu în filtrele dropdown/select de pe site. Totuși, apăsarea manuală a butonului Update pe pagina WordPress face treaba.
Caut o metodă să replic exact apăsarea manuală a butonului Update în CMS-ul WordPress. Până acum, postarea în sine se încarcă cu succes pe site, dar atributele sale WooCommerce nu sunt instantiate.
Până acum, am încercat multe soluții alternative:
- Setarea programatică a stării unei postări (draft) și schimbarea ei instantaneu în postare publicată (publish);
- Folosirea programării încorporate WordPress prin setarea unei ore la care ar trebui publicată;
- Apelarea wp_update_post;
- Folosirea plugin-ului Tao Scheduled Updates (https://nl.wordpress.org/plugins/tao-schedule-update/);
- Folosirea plugin-ului WordPress PostController (https://github.com/HarriBellThomas/Wordpress_PostController)
Totuși, toate încercările actualizează doar postările în wp_posts, aparent nu și relațiile/atributele personalizate ale produselor.
Singura mea cerință ar fi să replic programatic apăsarea butonului 'Update' din mediul WordPress CMS. Asta m-ar ajuta să automatizez procesul în loc să intervin manual.
Puteți să-mi sugerați o metodă pentru a face asta?
Mulțumesc pentru timpul acordat!
ACTUALIZARE:
Salut Tom,
După ce am analizat răspunsul tău, încă nu înțeleg.
Interogările mele actualizează/inserează toate tabelele necesare. Ele urmează practic toți pașii din scripturile PHP la care te-ai referit.
Când verific un produs în CMS, văd toate datele - și în special atributele - încărcate corect. Când apăs Update manual în CMS și compar datele din tabelele mySQL înainte și după actualizare, nu văd diferențe semnificative. Singurul lucru pe care îl observ este valoarea pentru _product_attributes în wp_postmeta care este ușor diferită (șir serializat).
Totuși, când experimentez cu această valoare (golind/o schimbând pentru postarea specifică în wp_postmeta), nimic nu se schimbă în atribute - și totul funcționează în continuare la filtrare.
Ceea ce mă face să mă întreb:
- Ce se întâmplă exact când apeși 'Update' manual?
- Există o altă locație de stocare în afară de tabelele mySQL unde părți sunt cumva conectate?
- Ar fi posibil pentru mine să: 1) iau procedura 'creare produs' la care te-ai referit ca acceptată și să o omit (deoarece am rulat propriile interogări) și apoi 2) să apelez doar procedura exactă care rulează când apeși Update - pentru a 'lega' totul fără a recrea toate intrările din baza de date?
- Dacă da, unde aș găsi această procedură specifică?
Ajutorul tău este foarte apreciat. Mulțumesc! Thom

OK, deci am avut o variație a aceleiași probleme și o să vă explic pas cu pas.
Totul funcționează bine, cu excepția unui lucru: atributele personalizate ale produselor WooCommerce nu sunt afișate imediat în filtrele dropdown/select de pe site. Totuși, apăsând manual pe Actualizare în pagina WordPress, funcționează.
Când afișează atributele, WooCommerce folosește această funcție: wc_get_attribute_taxonomies() (http://woocommerce.wp-a2z.org/oik_api/wc_get_attribute_taxonomies/)
Veți observa în acea funcție că obține datele dintr-un 'transient' (gândiți-vă la date cache, vedeți http://codex.wordpress.org/Transients_API).
Dacă încărcați manual date în baza de date, este posibil să fi ratat încărcarea transient-ului (care se află în wp_options
, apropo). Apăsând pe Actualizare în panoul de administrare WordPress, rulați funcția care actualizează transient-ul, motiv pentru care atributele funcționează/apar atunci și nu înainte.
Pentru a rezolva, trebuie să vă asigurați că actualizarea manuală a MySQL actualizează și transient-ul. În cazul meu, adăugând manual atribute de produs în WooCommerce, a trebuit să adaug un rând în wp_options
cu options_name
_transient_wc_attribute_taxonomies
și atributele mele în array-ul serializat din coloana option_value
(plus un ID cu autoload setat pe da). Dar există și alte transient-e, deci depinde de funcția care provoacă problema și de ce încercați să afișați. Puteți vedea care lipsește făcând o căutare MySQL pentru %transient%
în wp_options
o dată înainte de a apăsa Actualizare în panoul de administrare WordPress și o dată după, apoi comparând datele.

Actualizezi și termenii din produsul Woocommerce? Atât Wp_term_taxonomy
cât și wp_woocommerce_attribute_taxonomies
trebuie actualizate cu termenii taxonomiei tale pentru a permite produsului Woocommerce să afișeze meniurile derulante pentru variații de "Culoare" sau "Mărime".
Când creezi un produs Woocommerce programatic, variațiile de produs trebuie inserate și asociate cu atributele existente (taxonomii create în cadrul Woocommerce).
Verifică metacheia postului "_product_attributes" care conține datele despre atribute. Va trebui să asociezi termenii (atributele) cu produsul tău (în cadrul wp_term_taxonomy
), dar sperăm că aceasta îți oferă o direcție de urmat.
De asemenea, uită-te la funcțiile create_product
(https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L237) și save_variations
(https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L1692) care descriu cum se realizează crearea produsului și a variațiilor acestuia.

Mulțumesc din nou, Tom. Da, am uitat să menționez wp_term_taxonomy. Da, inserez/actualizez și acel tabel.
Deoarece setul de atribute nu se modifică și nu este înregistrat niciun contor în wp_woocommerce_attribute_taxonomies, ce anume trebuie actualizat acolo?
Mulțumesc pentru link-uri. O să mă apuc să le studiez și o să te anunț!
Toate cele bune, Thom

Aceasta este o opțiune cu cod 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 ); // Prelucrare produse variabile
if ( $product->is_type( 'variable' ) ) {
// RM: Obține variațiile care sunt și ele stoc epuizat
$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;
apoi mergeți în phpMyAdmin și rulați următoarele interogări SQL (poate fi necesar să schimbați numele tabelului în loc de 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' );
Ștergeți cache-ul:
DELETE
FROM `wp_options`
WHERE (`option_name` LIKE '_transient_wc_var_prices_%'
OR `option_name` LIKE '_transient_timeout_wc_var_prices_%')
Codul SQL a fost preluat de la: http://www.technoedu.com/forums/topic/wordpress-solved-copy-woocommerce-products-sale-prices-to-regular-prices-and-reset-sale-prices/
