Algoritmo de Darth Vader

Cuando los de Mecus anduvimos por la WordCamp, una de las cosas de las que estuvimos hablando como algo que nos resultaba muy útil infinidad de veces es eso que nosotros llamábamos El algoritmo de Darth Vader: buscar el padre.
Normalmente WordPress nos da las herramientas que necesitamos para encontrar el padre de una página, de un comentario o de una categoría. Pero, ¿qué pasa cuando tenemos que encontrar a su abuelo, o a su bisabuelo?

Aquí WordPress ya no es tan bueno, ya que la información se va segmentando poco a poco y tenemos que hacer algunas operaciones extra, como se puede ver en el ejemplo.


darth_vader

Si tenemos una categoría, $cat, y la hemos obtenido, por ejemplo, con la función get_the_category(), podremos acceder a lo siguiente:

  • $cat->cat_ID: El ID de la categoría
  • $cat->cat_name: El nombre de la categoría
  • $cat->category_nicename: El slug de la categoría
  • $cat->category_description: La descripción de la categoría
  • $cat->category_parent: El ID del padre de la categoría
  • $cat->category_count: La cantidad de artículos o páginas en esta categoría

Es decir, si queremos saber quién es su padre, sólo tenemos que hacer algo del tipo:

$parent_ID = $cat->category_parent

Nuestra categoría incial era un array que guardaba mucha información, pero ahora sólo tenemos el ID de padre, un dato que no nos sirve para repetir la operación. Es decir, no podemos continuar la operación escribiendo:

$abuelo_ID = $parent_ID->category_parent

Por tanto, tenemos que utilizar otro método para conseguir a los abuelos, bisabuelos, etc.

En el desarrollo de Bach hemos necesitado encontrar la categoría raiz de un árbol de categorías, independientemente del nivel en el que nos encontráramos. Se podría decir que es relativamente sencillo. Sólo tenemos buscar una función de wordpress que nos proporcione todos los datos de una categoría a partir de su ID. Y es aquí cuando llega el problema: no hay ninguna función que nos facilite el trabajo. ¿Qué podemos hacer entonces? Crear nuestra propia función y agregarla al archivo functions.php de nuestro tema para poder utilizarla sin problemas.

Podemos hacer una programación concatenada haciendo que recorra el árbol hasta el nivel que queramos, preguntándole si el padre de la categoría que estamos mirando es cero. Si es cero (que simbolizaría la raíz del árbol), nuestra categoría es una categoría de primer nivel.

function get_root_category($category_id){
    $category = $category_id->cat_ID;
    global $wpdb;
    $parent = $wpdb->get_var( “SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = ‘$category'”);
    if ($parent == 0) {
        return $category;
    }
    else{
        $category = $parent;
        $parent = $wpdb->get_var( “SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = ‘$category'”);
        if ($parent == 0) {
            return $category;
        }
        else {
            $category = $parent;
            $parent = $wpdb->get_var( “SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = ‘$category'”);
            if ($parent == 0) {
                return $category;
            }
            else{
                $category = $parent;
                $parent = $wpdb->get_var( “SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = ‘$category'”);
                if ($parent == 0) {
                    […]
                }
            }
        }
    }
}

Aunque siempre podemos hacerlo bonito y elegante para que funcione sea cual sea la profundidad de la categoría:

function get_root_category($category_id){
    $category = $category_id->cat_ID;
global $wpdb;
    $parent = $wpdb->get_var( “SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = ‘$category'”);
        if ($parent == 0) {
            return $category;
        }
        while ($parent != 0){
            $category = $parent;
            $parent = $wpdb->get_var( “SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = ‘$category'”);
            if ($parent == 0) {
                return $category;
            }else{
                $category = $parent;
            }
        }
}

Ahora podremos llamar a nuestra función desde cualquier parte de nuestro tema de WordPress para obtener la categoría raíz llamándolo como:

$raiz = get_root_category($category);

Artículo publicado en Mecus.es. Comentarios y trackbacks allí.