Verificare se un post è in una qualsiasi sottocategoria di una categoria genitore
In un sito che sto sviluppando, ho la seguente struttura di categorie:
* film (genitore)
* thriller (figlio)
* commedia (figlio)
* dramma (figlio)
Il post corrente è nella categoria commedia. La funzione has_term con i seguenti parametri restituisce true:
has_term( 'commedia', 'category' )
Ma la stessa funzione con i seguenti parametri restituisce false:
has_term( 'film', 'category' )
La mia domanda è: esiste una funzione di WordPress per verificare se il post corrente è in una qualsiasi sottocategoria di una categoria genitore specifica? Se non esiste, come posso effettuare questo controllo?
Grazie in anticipo

Aggiungi il seguente codice al file functions.php del tuo tema:
/**
* Verifica se una delle categorie assegnate a un articolo è discendente delle categorie target
*
* @param int|array $cats Le categorie target. Può essere un ID intero o un array di ID
* @param int|object $_post L'articolo. Ometti per verificare l'articolo corrente nel Loop o nella query principale
* @return bool True se almeno una delle categorie dell'articolo è discendente di una delle categorie target
* @see get_term_by() Puoi ottenere una categoria per nome o slug, poi passare l'ID a questa funzione
* @uses get_term_children() Passa $cats
* @uses in_category() Passa $_post (può essere vuoto)
* @version 2.7
* @link http://codex.wordpress.org/Function_Reference/in_category#Testing_if_a_post_is_in_a_descendant_category
*/
if ( ! function_exists( 'post_is_in_descendant_category' ) ) {
function post_is_in_descendant_category( $cats, $_post = null ) {
foreach ( (array) $cats as $cat ) {
// get_term_children() accetta solo ID interi
$descendants = get_term_children( (int) $cat, 'category' );
if ( $descendants && in_category( $descendants, $_post ) )
return true;
}
return false;
}
}
Utilizza la funzione per verificare l'ID della categoria genitore, non il nome o lo slug. Ad esempio, se l'ID della categoria 'film' è 50:
if ( post_is_in_descendant_category( 50 ) ) {
// fai qualcosa
}
Se non conosci l'ID della categoria 'film', puoi recuperarlo usando get_term_by() e passarlo a post_is_in_descendant_category():
$category_to_check = get_term_by( 'name', 'film', 'category' );
if ( post_is_in_descendant_category( $category_to_check->term_id ) ) {
// fai qualcosa
}

Se vuoi supportare qualsiasi livello di annidamento, usa get_posts
.
/**
* Verifica se il post appartiene a una delle categorie o a una qualsiasi sottocategoria.
*
* @param int|string|array $category_ids (ID singolo di categoria) oppure (stringa separata da virgole o array di ID di categorie).
* @param int $post_id ID del post da verificare. Di default usa `get_the_ID()`.
* @return bool true, se il post appartiene a una qualsiasi categoria o sottocategoria.
*/
function is_post_in_category( $category_ids, $post_id = null ) {
$args = array(
'include' => $post_id ?? get_the_ID(),
'category' => $category_ids,
'fields' => 'ids',
);
return 0 < count( get_posts( $args ) );
}
Puoi espandere questa funzione in molti modi. Ad esempio, passare un array di ID post e filtrare alcuni oppure permettere di affinare la query.

Aggiornamento per l'utilizzo di tassonomie personalizzate:
/**
* Verifica se una delle categorie assegnate a un post è discendente delle categorie target
*
* @param int|array $cats Le categorie target. ID intero o array di ID interi
* @param int|object $_post Il post. Ometti per verificare il post corrente nel Loop o nella query principale
* @param string $target_cat Il nome della tassonomia da interrogare. Ometti per usare la tassonomia predefinita 'category' utilizzata per i post
* @return bool True se almeno 1 delle categorie del post è discendente di una delle categorie target
* @see get_term_by() Puoi ottenere una categoria per nome o slug, poi passare l'ID a questa funzione
* @uses get_term_children() Passa $cats
* @uses in_category() Passa $_post (può essere vuoto)
* @version 2.7
* @link https://developer.wordpress.org/reference/functions/in_category/#comment-4999
*/
if(!function_exists('post_is_in_descendant_category')) {
function post_is_in_descendant_category($cats, $_post = null, $target_cat = 'category') {
foreach((array) $cats as $cat) {
// get_term_children() accetta solo ID intero
$descendants = get_term_children((int) $cat, $target_cat);
if($descendants && has_term($descendants, $target_cat, $_post)) {
return true;
}
}
return false;
}
}
Contesto
in_category
utilizza has_category
che a sua volta chiama has_term( $category, 'category', $post )
con la tassonomia hard-coded 'category'.
Usando direttamente has_term()
possiamo verificare una tassonomia personalizzata come product_cat (WooCommerce) o qualsiasi altra tassonomia.
La funzione usa category come predefinito quindi può essere usata come sostituto diretto.
Utilizzo
Chiama la funzione in questo modo:
if(post_is_in_descendant_category($category_to_check->term_id, $post, 'product_cat')) {
// fai qualcosa
}
