get_categories per custom post type con una tassonomia personalizzata allegata
Fondamentalmente ho un custom post type 'products' che ha due tassonomie collegate... la normale 'category' e una tassonomia personalizzata chiamata 'brands'.
Ho una pagina che è specifica per il 'brand'. In questa pagina vorrei elencare tutte le 'categorie' che hanno un 'prodotto' al loro interno con un termine del 'brand' della pagina in cui mi trovo.
Ad esempio, mettiamo che mi trovo nella pagina "Nike". Voglio che elenchi tutte le categorie che hanno un 'prodotto' al loro interno con il 'brand' "Nike" associato.
Il mio pensiero iniziale è di utilizzare get_categories ma non c'è modo di definire una tassonomia specifica o un 'brand'?
// Ottieni le categorie ordinate per nome, profondità 1 e includi anche le categorie vuote
$categories = get_categories('orderby=name&depth=1&hide_empty=0&child_of='.$cat);
Qualcuno ha già fatto qualcosa di simile o conosce un modo per interrogare direttamente il database per ottenere i risultati richiesti?
Ogni aiuto è molto apprezzato, Grazie

Se vuoi elencare tutte le categorie disponibili per un custom post type, questo snippet potrebbe esserti utile.
Basta usare la funzione standard get_categories()
e passare gli $args
relativi alla tassonomia che hai registrato per il tuo CPT. Quindi, se hai definito la tua tassonomia in questo modo:
register_taxonomy( 'the_taxonomy_named_in_your_CPT' );
Allora potresti mostrare la tassonomia agli utenti front end tramite:
$args = array(
'taxonomy' => 'the_taxonomy_named_in_your_CPT',
'orderby' => 'name',
'show_count' => 1,
'pad_counts' => 1,
'hierarchical' => 1,
'echo' => 0
);
$allthecats = get_categories( $args );
echo ( '<pre>' );
print_r( $allthecats );
echo ( '</pre>' );
Vedrai un oggetto che ti aiuterà nel tuo percorso.

Dopo ore e un mal di testa, questa soluzione ha funzionato come necessario. Grazie!! Non c'è una buona documentazione sulla stampa delle categorie dei post type.

Ciao @daveaspi:
Quello che vuoi fare è comune ma non gestito bene nel core di WordPress. Probabilmente ci sono modi per farlo senza SQL personalizzato, ma non credo che scalerebbero bene per un gran numero di articoli. Di seguito trovi una funzione che ho scritto chiamata get_cross_referenced_terms()
che otterrà ciò che desideri, completa di un esempio su come usarla.
Il seguente codice può essere posizionato nella root del tuo sito WordPress in un file test.php
per vederlo funzionare. Puoi poi copiare la funzione get_cross_referenced_terms()
nel file functions.php
del tuo tema o in un file .php
di un plugin su cui stai lavorando:
<?php
include('wp-load.php');
$nike = get_term_by('slug','nike','brand'); // Questo serve solo come esempio
$terms = get_cross_referenced_terms(array(
'post_type' => 'product',
'related_taxonomy' => 'brand',
'term_id' => $nike->term_id,
));
foreach($terms as $term) {
echo "<p>{$term->name}</p>";
}
function get_cross_referenced_terms($args) {
global $wpdb;
$args = wp_parse_args($args,array(
'post_type' => 'post',
'taxonomy' => 'category',
'related_taxonomy' => 'post_tag',
'term_id' => 0,
));
extract($args);
$sql = <<<SQL
SELECT DISTINCT
{$wpdb->terms}.*,
COUNT(*) AS post_count
FROM
{$wpdb->terms}
INNER JOIN {$wpdb->term_taxonomy} ON {$wpdb->terms}.term_id={$wpdb->term_taxonomy}.term_id
INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_taxonomy}.term_taxonomy_id={$wpdb->term_relationships}.term_taxonomy_id
INNER JOIN {$wpdb->posts} ON {$wpdb->term_relationships}.object_id={$wpdb->posts}.ID
INNER JOIN {$wpdb->term_relationships} related_relationship ON {$wpdb->posts}.ID=related_relationship.object_id
INNER JOIN {$wpdb->term_taxonomy} related_term_taxonomy ON related_relationship.term_taxonomy_id=related_term_taxonomy.term_taxonomy_id
INNER JOIN {$wpdb->terms} related_terms ON related_term_taxonomy.term_id=related_terms.term_id
WHERE 1=1
AND (related_term_taxonomy.taxonomy<>{$wpdb->term_taxonomy}.taxonomy OR related_terms.term_id<>{$wpdb->terms}.term_id)
AND {$wpdb->posts}.post_type='%s'
AND {$wpdb->term_taxonomy}.taxonomy='%s'
AND related_term_taxonomy.taxonomy='%s'
AND related_terms.term_id=%d
GROUP BY
{$wpdb->terms}.term_id
SQL;
$sql = $wpdb->prepare($sql,$post_type,$taxonomy,$related_taxonomy,$term_id);
$terms = $wpdb->get_results($sql);
return $terms;
}

Ciao @MikeSchinkel, è esattamente ciò di cui avevo bisogno! Funziona alla perfezione. Grazie mille davvero!

Una piccola domanda, c'è un modo per limitare la 'profondità' a 1? In modo da ottenere solo le categorie di primo livello? :-) Grazie ragazzi

@daveaspi: Aggiungi AND {$wpdb->term_taxonomy}.parent=0
alla clausola where.

@MikeSchinkel, @Bainternet ciao ragazzi, c'è un modo per aggiungere una variabile negli $args per definire sia la categoria che il brand? es. 'post_type' => 'post', 'taxonomy' => 'category', 'related_taxonomy' => 'post_tag', 'term_id' => 0, 'category_id' => $cat

@davesapi - Sembra che questo dovrebbe essere una nuova domanda.

Puoi scrivere una query SQL personalizzata oppure puoi interrogare il tuo post type per quel "brand" specifico, raccogliere le categorie e poi visualizzarle, qualcosa come:
//ottieni tutti i post di quel tipo per il brand specifico
$my_query = new WP_Query();
$my_query->query(array(
'post_type' => 'products',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'brand',
'field' => 'slug',
'terms' => $wp_query->query_vars['brand']
)
)
));
$my_cats = array();
if ($my_query->have_posts()){
//cicla su tutti i post e raccogli le categorie in un array
while ($my_query->have_posts()){
$my_query->the_post();
foreach((get_the_category($post->ID)) as $category) {
if (!in_array($category->cat_ID ,$my_cats)){
$my_cats[] = $category->cat_ID;
}
}
}
}
e qui avrai la lista di tutti gli ID delle categorie nell'array $my_cats. Da cui puoi ottenere tutte le informazioni di cui hai bisogno

Sì, molto più pulito e ottimo per un sito piccolo, ma per un gran numero di articoli potrebbe diventare davvero molto lento.

@MikeSchinkel - sì, richiederebbe un po' di tempo su un sito dove ogni marca ha un sacco di prodotti, ma immagino che il mio "kong SQL fu" non sia forte come il tuo, maestro!

Ah! Non è che l'ho imparato da un giorno all'altro! Ci sono voluti più di 20 anni di lavoro su SQL per arrivare qui. :)
