Come ordinare il risultato di get_categories
Ho letto la documentazione del codex ma non riesco a ordinare il risultato di get_categories() in modo da avere prima il genitore e poi i figli.
Ho questo tipo di struttura di categorie:
-Eventi
- Musica
- Cultura
- Workshop
- Turismo
-Sport
-Calcio
-Rugby
-Tennis
Voglio che l'output sia:
Eventi, Musica
Ho provato:
echo $product->get_categories();
e il risultato è la stampa di Musica, Eventi (figlio, genitore).
Ho anche provato passando $args come argomento a get_categories():
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'category',
'pad_counts' => false
);
Come posso ordinarlo nel modo che desidero?
Innanzitutto, $product->get_categories()
non funzionerà perché è una funzione di WooCommerce, che sostanzialmente è solo un wrapper per get_the_term_list
, il quale non ha un parametro per l'ordinamento. È sempre utile dare un'occhiata al codice sorgente per sapere con cosa si ha a che fare.
In secondo luogo, get_the_term_list
utilizza get_the_terms
, ma anche questo non ha un parametro per l'ordinamento. Quest'ultimo ottiene i termini dalla cache get_object_term_cache
o direttamente tramite wp_get_object_terms
. La cache molto probabilmente non è utile, perché i termini lì salvati hanno un ordinamento errato, da qui il problema che stai riscontrando. wp_get_object_terms
invece ha - finalmente - la possibilità di definire l'ordinamento.
Dal codex:
Utilizzo
wp_get_object_terms( $object_ids, $taxonomies, $args )
Argomenti Predefiniti
$args = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
Il primo argomento si chiama 'orderby' e ha come valore predefinito 'name'. Altri valori supportati includono 'count', 'slug', 'term_group', 'term_order' e 'term_id'.
Il secondo argomento si chiama 'order' e ha come valore predefinito 'ASC'. L'unico altro valore accettabile è 'DESC'.
Quindi questo potrebbe avvicinarti a ciò che desideri, ma dai un'occhiata tu stesso.
In terzo luogo, potresti semplicemente usare get_ancestors
, che ti restituisce un
Array di antenati dal più basso al più alto nella gerarchia
Il che funziona bene sulla tassonomia delle categorie di prodotti WooCommerce in quanto è gerarchica. Diventa un po' problematico però se assegni più termini per livello gerarchico. Ho scritto una risposta riguardo questo argomento generale, forse ti potrà essere d'aiuto.

Ho scritto questo codice che eseguo dopo get_categories. Questo ordinerà i risultati per categorie genitore e nomi:
$all_categories = get_categories( $args );
$byId = array();
// Creo un array con le categorie per ID
foreach ($all_categories as $cat) {
$byId[$cat->term_id] = $cat;
}
// Aggiungo un nuovo campo path per poter ordinare
foreach ($all_categories as $cat) {
$path = $cat->name;
$parentCat = $cat;
for($n=0;$n<10 && $parentCat->parent > 0;$n++) {
// Limito a 10 livelli (modificare se necessario)
$parentCat = $byId[$parentCat->parent];
$path = $parentCat->name."/".$path;
}
$cat->path = $path;
}
// Infine ordino per il nuovo campo path
function cmp($a, $b) {
return strcmp($a->path,$b->path);
}
usort($all_categories, "cmp");
// $all_categories ora è ordinato per gerarchia e nome

Non ho una configurazione come la tua, quindi proviamo qualcosa. Ti passo il codice, prova tu e fammi sapere se è soddisfacente.
<?php
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'category',
'pad_counts' => false
);
$cats = get_categories( $args );
//var_dump($cat);
foreach( $cats as $cat ){
echo $cat->name .', ';
}
?>

Ho provato:
<?php
$args = array(
'type' => 'product',
'child_of' => 0,
'parent' => '',
'orderby' => 'term_group',
'hide_empty' => false,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'product_cat',
'pad_counts' => false
);
$cats = get_categories( $args );
//var_dump($cat);
foreach( $cats as $cat ){
echo $cat->name.', ';
}
?>
Stampa tutte le categorie raggruppate per gerarchia, nel mio caso:
Eventi, Sport, Musica, Cultura, Workshop, Turismo, Calcio, Rugby, Tennis.
Vorrei solo omettere le categorie non selezionate per il post.
