Woocommerce prodotti variabili divenuti improvvisamente semplici

Sto scrivendo questo post per il bene dell’umanità, perché nemmeno il più empio dei bipedi umanoidi del globo terraqueo merita di passare per quello che sono passato io.

Vi dico subito che le soluzioni semplici sono le più efficaci e che se vi trovate nella situazione in cui, di punto in bianco, tutti i prodotti variabili del vostro sito sono divenuti semplici sia da backend che da frontend, allora questo articolo può aiutarvi.
Più precisamente se il vostro prodotto fintamente semplice, quando siete in modifica e cambiate il tipo in variabile, carica delle pre-esistenti variazioni, e salvando bonificate la situazione, allora direi che siete proprio nel posto giusto.

Non sto qui a spiegarvi tutti gli approcci che ho adottato e che sono miseramente falliti, andiamo direttamente al punto spiegando in primis qual era la situazione.

Cosa era successo?

Lo ignoro, ho ereditato questa grana da terzi e senza la possibilità di tornare in uno stato precedente, senza backup e senza informazione.
Ho letto la qualunque sull’internet, per taluni si trattava di un conflitto ( interiore? 😀 ) ma nel mio caso:

  • disattivando tutti i plugin
  • passando al tema ad un tema di default (Twenty twenty three)
  • togliendo la cache dall’equazione
  • assicurandomi che la CDN non rompesse le scatole
  • riavviando il pc (ovviamente questo non l’ho fatto davvero!)

e facendo tutte le altre prove che suggerisce l’intuizione o l’intelligenza artificiale non ho cavato un ragno dal buco. Zero carbonella, come dicono in capitale, nisba, nada … crio.

Con un elenco di più di 500 prodotti affetti dal problema capite bene che andare lì manualmente a editare prodotto per prodotto sarebbe stato un guaio passato.

Pertanto sono andato alla ricerca di fix programmatici, ho scritto plugin, soluzioni che eseguivano operazioni in batch e altre cose anche molto sofisticate, ma sono solo riuscito a sfondare l’archivio prodotti. Tristezza per favore vai via.

Alla fine mi sono messo con calma zen e ho chiesto a chatgpt di farmi uno script che mi consentisse di ottenere un report in json descrittivo del prodotto.

Tale fix sarebbe stato lanciato prima e dopo la modifica manuale del prodotto fintamente semplice in variabile (cosa che come vi ho già detto, aggiustava le cose).

Ho preso il codice php che mi ha suggerito la lattina (povero ChatGPT) e ho creato un file report.php che ho messo nella root di wordpress per poterlo richiamare da browser, eccolo:

<?php
// Assicurati che questo file venga eseguito in un contesto WordPress
require_once('./wp-load.php');

if (!isset($_GET['product_id']) || !is_numeric($_GET['product_id'])) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Missing or invalid product_id parameter.']);
exit;
}

$product_id = intval($_GET['product_id']);
$data = [];

// Recupera dati da wp_posts
$product_post = get_post($product_id);
if ($product_post) {
$data['post'] = [
'ID' => $product_post->ID,
'post_title' => $product_post->post_title,
'post_type' => $product_post->post_type,
'post_status' => $product_post->post_status,
];
} else {
$data['post'] = 'Product not found in wp_posts.';
}

// Recupera dati da wp_postmeta
$postmeta = get_post_meta($product_id);
$data['postmeta'] = $postmeta ?: 'No metadata found for this product.';

// Recupera termini collegati nella tassonomia product_type
$terms = wp_get_object_terms($product_id, 'product_type');
if (!is_wp_error($terms)) {
$data['taxonomy'] = array_map(function ($term) {
return [
'term_id' => $term->term_id,
'name' => $term->name,
'taxonomy' => $term->taxonomy,
];
}, $terms);
} else {
$data['taxonomy'] = 'Error fetching terms: ' . $terms->get_error_message();
}

// Imposta l'intestazione per il JSON
header('Content-Type: application/json');

// Ritorna i dati in formato JSON
echo json_encode($data, JSON_PRETTY_PRINT);

Richiamando la url miosito.it/report.php?product_id=123, ho ottenuto il report relativo al prodotto, quindi ho salvato il prodotto da interfaccia cambiando manualmente il type da simple a variable e ho rigenerato il report.

Dal confronto dei due file è emerso che si era sballata la tassonomia che gestisce il tipo prodotto. Se siete confusi è giusto che sia così, perché sappiate che c’è una tassonomia che gestisce il tipo prodotto …

Tale tassonomia ha vari termini (uno per tipo di prodotto) e ciascuno ha il proprio identificativo (term_id). Il mio termine “variabile” aveva term_id = 842.

Pertanto mi sono detto, perché non fare una bamonda query che prenda tutti i prodotti fintamente semplici e ci metta su, questa cavolo di associazione con il termine giusto?

I prodotti fintamente semplici (e intrinsecamente variabili) erano reperibili verificando che avessero effettivamente almeno un post_parent che gli puntasse (ovvero le variazioni).

Ha funzionato bene, ecco la query:

-- Associare i prodotti fintamente variabili al termine "variable" (term_id 842)
INSERT INTO wpon_term_relationships (object_id, term_taxonomy_id)
SELECT
p.ID AS product_id,
842 AS term_taxonomy_id
FROM
wpon_posts AS p
LEFT JOIN
wpon_posts AS v ON v.post_parent = p.ID AND v.post_type = 'product_variation'
LEFT JOIN
wpon_term_relationships AS tr ON p.ID = tr.object_id
LEFT JOIN
wpon_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN
wpon_terms AS t ON tt.term_id = t.term_id
WHERE
p.post_type = 'product' -- È un prodotto
AND v.ID IS NOT NULL -- Ha variazioni associate
AND (t.term_id IS NULL OR t.term_id != 842) -- Non è già associato a "variable"
GROUP BY
p.ID
ON DUPLICATE KEY UPDATE term_taxonomy_id = VALUES(term_taxonomy_id);

Ovviamente 842 è il mio id, trova il tuo nel database e modifica lo script prima di lanciarlo.

ATTENZIONE: non essere dissennato EFFETTUA UN BACKUP prima di distruggere tutto.

In fine

Questo problema non voglio doverlo risolvere mai più! 🙂

È stato uno stress non indifferente venire a capo dei perché e dei percome, spero torni utile a voi altri.

Change gravatar on product reviews from author email to comment email field using get_avatar wordpress hook

Enhancing user experience in your WordPress store is crucial for standing out and improving customer interaction and reviews area is one of the most used by customers who want to figure out if a certain product fits their needs or not, based on the experience of other users.

By default, WooCommerce products reviews use the avatar associated with the logged-in user, but it can be more beneficial to show the avatar based on the email provided in the comment. Here’s how you can achieve this.

What is Gravatar?

Gravatar (Globally Recognized Avatar) is a service that provides globally unique avatars based on users’ email addresses. When users comment on your site and provide their email, the corresponding Gravatar is displayed, adding a personal touch and increasing the authenticity of the reviews.

WordPress natively integrates Gravatar to grab comment/reviews profile image, as well as in other areas (such as back-end user pages).

Solution implementation

I struggle a little bit to find the right filter to use for my purpose; eventually I bumped into get_avatar.

This filter allows us to intercept and modify the displayed avatar based on the email entered in the comment field rather than the logged-in user e-email. Here’s the code to implement this solution:

<?php
function custom_get_avatar_for_product_review( $avatar, $id_or_email, $args ) {
    // Check if the object is a comment
    if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) {
        $comment = $id_or_email;

        // Check if the comment is associated with a WooCommerce product
        if ( get_post_type( $comment->comment_post_ID ) == 'product' ) {
            // Get the commenter's email from the comment email field
            $commenter_email = get_comment_author_email( $comment->comment_ID );

            // Generate the Gravatar for the commenter's email
            $avatar = get_avatar( $commenter_email, $args['size'], $args['default'], $args['alt'], $args );
        }
    }

    return $avatar;
}
add_filter( 'get_avatar', 'custom_get_avatar_for_product_review', 10, 3 );

NOTE: As you can notice we limited this functionality to product post_type, you can change according to the needs you want to fullfill.

Hope this help people.

Come eliminare tutti i prodotti da woocommerce senza impazzire?

Minimo sforzo massima resa, in questo post spiego come ho fatto a risolvere il problema che un mio cliente aveva generato per errore. Oltre alla soluzione troverete anche l’iter che mi ci ha portato.

A seguito di un’importazione sbagliata, un mio cliente aveva riempito il suo e-commerce (woocommerce) di 2000 prodotti vuoti! Fortunatamente si trattava di un ambiente di pre-produzione e quindi non ha avuto alcun impatto sull’esperienza utente.

Tuttavia si era reso necessario un intervento massivo su tutti i prodotti, in quanto andavano eliminati del tutto dal sito internet.

Il mio cervello ha pensato subito a scrivere un poco di codice per creare uno script da lanciare in batch attraverso di un plugin ad hoc, che avrebbe dovuto esporre una pagina con un pulsante di distruzione di massa, quindi esporre un avviso per chiedere all’utente se fosse sicuro di quello che stava facendo … ma sono troppo pigro, per cui, il secondo pensiero è stato gugolare un poco (anche se in realtà uso perlopiù duckduckgo, ve lo consiglierò prima o poi assieme ad altri tool per la vostra privacy).

Dalla ricerca che ho usato wordpress how to delete all products è venuto fuori (ovviamente) la qualunque … focalizzerò l’attenzione su 2 delle soluzioni che ho trovato.

1. Aumento numero prodotti visualizzati

Parte superiore della pagina prodotti di wordpress/woocommerce

Alcuni consigliano di visualizzare più prodotti sulla stessa pagina e cancellarli massivamente

Ma questa soluzione, mostrando un numero considerevole di prodotti (anche 300), è veramente sconsigliata per tanti motivi:

  • è maledettamente lenta;
  • prevede dei tempi morti perfino lato client (javascript ci mette un po’ a spuntare tutte le checkbox!);
  • anche se il processo di cancellazione massiva viene gestito in batch, ottimizzando l’uso della memoria RAM, vi ritroverete comunque a consumare molte risorse e ad aspettare molto tempo prima che la nuova pagina venga ricaricata e possiate lanciare un altro cancella tutti.

Questa soluzione per me è quindi SCONSIGLIATA. Passiamo alla prossima

2. Query diretta al database che rimuove tutto

Non male come idea. Una bella query, fatta bene che va a togliere non solo i prodotti, ma tutte le sue relazioni con le altre risorse BASE di wordpress.

Quel “BASE” non è maiuscolo per caso. Quello che intendo impropriamente dire con risorse BASE, significa che se per qualche motivo il vostro prodotto è collegato a qualche altra risorsa introdotta da un plugin o da software di terze parti, rischiate seriamente di perdervi pezzi per strada.

Uno screenshot della soluzione così come riportata su Store App org.

Il sito storeapps.org, propone una soluzione basata su questa query:

DELETE relations.*, taxes.*, terms.*
FROM wp_term_relationships AS relations
INNER JOIN wp_term_taxonomy AS taxes
ON relations.term_taxonomy_id=taxes.term_taxonomy_id
INNER JOIN wp_terms AS terms
ON taxes.term_id=terms.term_id
WHERE object_id IN (SELECT ID FROM wp_posts WHERE post_type IN ('product','product_variation'));

DELETE FROM wp_postmeta WHERE post_id IN (SELECT ID FROM wp_posts WHERE post_type IN ('product','product_variation'));
DELETE FROM wp_posts WHERE post_type IN ('product','product_variation');

Ma ad ogni modo, lo stesso autore dopo questa query dice:

However, this is not the best way to bulk delete products

Dal sito storeapps.org

Anche se loro sconsigliano l’approccio query based, perché vogliono vendervi un plugin che fa cose, quella che dicono è una grande verità.

Troppo rischioso lanciare query nel database senza alcuna pietà. Potresti ritrovarvi con più problemi di quando avete iniziato.

Se scegliete questo approccio che io SCONSIGLIO, abbiate almeno il buon cuore di effettuare una copia di backup del database (ho scritto anche io un poco a riguardo).

3. WP CLI

La WP CLI è un software portabile scritto in PHP che vi consentirà di lanciare dei comandi sulla console per ottenere quello che volete.

Non sai di che parlo? Fidati di me, usa il metodo 1.

Il comando che ho lanciato e che ha funzionato come un incantesimo è stato quello suggerito da Ryan Steven sul suo blog.

Provare per credere:

wp post list --field=ID --post_type=product --posts_per_page=2000 | xargs wp post delete --force
Il comando che ho lanciato sul terminale dell’hosting in questione. Come è possibile vedere ho usato direttamente il file .phar.

Se avete il sito su hosting che non ha accesso alla console sappiate che potete usare lo stesso la cli, ma facendo un accrocchio che spero di avere modo di illustrarvi in qualche altro post in futuro.

Conclusioni

Se siete utenti smaliziati, dovete avere a che fare con operazioni ripetitive, containers, orchestratori (tipo kuberneetes), allora vi consiglio di studiare l’uso della CLI (proposta come migliore soluzione, la numero 3).

Se non siete utenti esperti state lontano come la peste dalle query (soluzione 2) e lanciatevi sulla soluzione 1, specie se la cancellazione massiva è da fare una tantum.