Obtener las categorías principales para un producto
¿Alguien puede ayudarme? Estoy buscando una forma de encontrar la categoría principal padre de un producto de WooCommerce. Por ejemplo, si el producto está marcado bajo Gadgets, pero el padre principal de todos ellos es Electrónica.
Quiero esto para cada entrada, ya que deseo agregar una clase a cada publicación que indique su categoría padre principal product_cat
.
Por favor recuerden que las categorías de productos son taxonomías personalizadas y no se pueden recuperar usando get_category_parents()
. Están listadas como términos.
Gracias de antemano.
// edición:
Este es el código que ya tengo, lo estoy llamando en cada publicación y mis publicaciones se renderizan de manera similar a una página de archivo.
function all_cat_classes($post) {
$cats = "";
$terms = get_the_terms($post->ID, "product_cat");
$count = 0;
$count = count($terms);
$key = 0;
foreach ($terms as $cat) {
$key++;
}
return $cats;
}

solo para ofrecer una solución alternativa que podría ayudar a alguien:
código
function wc_origin_trail_ancestor( $link = false, $trail = false ) {
if (is_product_category()) {
global $wp_query;
$q_obj = $wp_query->get_queried_object();
$cat_id = $q_obj->term_id;
$descendant = get_term_by("id", $cat_id, "product_cat");
$descendant_id = $descendant->term_id;
$ancestors = get_ancestors($cat_id, 'product_cat');
$ancestors = array_reverse($ancestors);
$origin_ancestor = get_term_by("id", $ancestors[0], "product_cat");
$origin_ancestor_id = $origin_ancestor->term_id;
$ac = count($ancestors);
} else if ( is_product() ) {
$descendant = get_the_terms( $post->ID, 'product_cat' );
$descendant = array_reverse($descendant);
$descendant = $descendant[0];
$descendant_id = $descendant->term_id;
$ancestors = array_reverse(get_ancestors($descendant_id, 'product_cat'));
$ac = count($ancestors);
}
$c = 1;
if( $trail == false ){
$origin_ancestor_term = get_term_by("id", $ancestors[0], "product_cat");
$origin_ancestor_link = get_term_link( $origin_ancestor_term->slug, $origin_ancestor_term->taxonomy );
if($link == true)
echo '<a href="'. $origin_ancestor_link .'">';
echo $origin_ancestor_term->name;
if($link == true)
echo '</a>';
}else{
foreach ($ancestors as $ancestor) {
$ancestor_term = get_term_by("id", $ancestor, "product_cat");
$ancestor_link = get_term_link( $ancestor_term->slug, $ancestor_term->taxonomy );
if($c++ == 1)
echo '» ';
else if($c++ != 1 || $c++ != $ac)
echo ' » ';
if($link == true)
echo '<a href="'. $ancestor_link .'">';
echo $ancestor_term->name;
if($link == true)
echo '</a>';
}
$descendant_term = get_term_by("id", $descendant_id, "product_cat");
$descendant_link = get_term_link( $descendant_term->slug, $descendant_term->taxonomy );
echo ' » ';
if($link == true)
echo '<a href="'. $descendant_link .'">';
echo $descendant->name;
if($link == true)
echo '</a>';
}
}
cómo usar
- solo nivel superior, ancestro originario; sin enlace
wc_origin_trail_ancestor();
- solo nivel superior, ancestro originario; con enlace
wc_origin_trail_ancestor(true);
- rastro de ancestros; sin enlace
wc_origin_trail_ancestor(false,true);
- rastro de ancestros; con enlace
wc_origin_trail_ancestor(true,true);
notas
- no funcionará si un producto tiene múltiples categorías principales/de nivel superior, o al menos no las mostrará todas;
- lo mismo debería aplicarse para múltiples subcategorías en el mismo nivel;
- no realicé más pruebas sobre los puntos anteriores, porque la función hace todo lo que necesitaba para ese proyecto;

Escribí mi propia función para recorrer toda la "cadena" hacia arriba. Mi recursividad puede que no sea la mejor implementación que hayas visto, pero funciona.
function get_parent_terms($term) {
if ($term->parent > 0) {
$term = get_term_by("id", $term->parent, "product_cat");
if ($term->parent > 0) {
get_parent_terms($term);
} else return $term;
}
else return $term;
}
# Devuelve todas las categorías de un producto, incluyendo las categorías padre
function all_cat_classes($post) {
$cats = "";
$terms = get_the_terms($post->ID, "product_cat");
$key = 0;
// Por cada product_cat obtiene la categoría principal superior
foreach ($terms as $cat) {
$cat = get_parent_terms($cat);
$cats .= (strpos($cats, $cat->slug) === false ? $cat->slug." " : "");
$key++;
}
return $cats;
}
