Caso práctico: Cambiar entrada a Custom Post Type según una categoría

Mejora la estructura de datos, y ten mayor control, separando el contenido en Custom Post Type, mediante SQL.

desarrollo, sql, WordPress

En varias ocasiones, quizá demasiadas, me he encontrado en WordPress que las entradas tienen noticias, ebooks, webinars, videos, opiniones, etc… separadas/identificadas por categorías, o subcategorías, y el problema está en separarlo eficazmente para dar estilos, gestión.

Esa forma de trabajar puede ser la más rápida, pero según van creciendo los contenidos se hace más compleja su gestión, y la estructura de datos no es la más deseable.

En esta ocasión vamos a crear un Custom Post Type, y a este le vamos a transferir unas entradas/contenidos específicos a una determinada categoría.

El Custom Post Type se puede generar a través de GenerateWP para que os genere un PHP, e integrarlo en vuestro tema. Os dejo unas referencias más abajo sobre Custom Post Type.

Antes de empezar, os aconsejo realizar una copia de seguridad de la base de datos, ya que vamos a modificarla, y así, si comentemos un error, tendremos opción de restaurarla.

Seleccionando las entradas de una categoría.

Ahora vamos a seleccionar cuantas entradas existen en la categoría que necesitamos mover al Custom Post Type, que, a partir de ahora, nos referiremos a él como CPT.

Accedemos a la base de datos del servidor, por ejemplo mediante phpMyAdmin, o a través del plugin WP phpMyAdmin (que es una maravilla), y comprobamos que tenemos el mismo número de entradas en la categoría del panel de WordPress, con la siguiente sentencia SQL:

SELECT COUNT(*) FROM wp_posts 
    LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
    LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
    wp_posts.post_type = 'post' AND
    wp_term_taxonomy.taxonomy = 'category' AND
    wp_term_taxonomy.term_id = 40

Donde; ‘post‘ es el tipo de CPT que vamos a buscar. ‘category‘ es la taxonomía a la que pertenece la categoría que vamos a buscar, y ’40’ es el ID de la categoría a buscar. En este momento habría que cambiar ‘wp_‘ por el prefijo que tengan configuradas vuestras tablas de la base de datos de WordPress.

Número de entradas en WordPress y resultado de la sentencia SQL

Con esta sentencia se mostrarían las 5 primeras entradas de esa categoría, para comprobar que son correctas:

SELECT wp_posts.post_title FROM wp_posts 
    LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
    LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
    wp_posts.post_type = 'post' AND
    wp_term_taxonomy.taxonomy = 'category' AND
    wp_term_taxonomy.term_id = 40 ORDER BY ID DESC LIMIT 5

Pasando una Entrada a un nuevo CPT y a una categoría concreta

Antes de mover todas las entradas, vamos a mover solo una para ver si se hace correctamente. Retomando lo que comentaba al principio, tenemos un nuevo CPT llamado ‘opinion‘, una taxonomía llamada ‘opinion-cat‘ y una categoría llamada editorial con el ID:50 que es dónde moveremos la primera entrada.

En esta ocasión vamos a utilizar variables de mySql para las sentencias que vamos a realizar, y de esta forma lo veremos todo más claro. Cambiando el valor de esas variables, puestas al inicio del código variaremos fácilmente la consulta.

SET @term_id = 211716; # Id Categoría Opinión (Editorial)
SET @post_id = 520172; # Id de la Entrada
SET @term_id_post = 50; # Id categoría Entrada (Editorial)

# Guardamos en una variable el ID y el número de opiniones de la categoría indicada de opinión.
# @var_name := value
SELECT @taxonomy_id := term_taxonomy_id, @taxonomy_count := count
FROM wp_term_taxonomy
WHERE term_id = @term_id
LIMIT 1;


# Pasamos la Entrada al CPT opinión y le indicamos a que categoría de opinión le asignamos.
UPDATE
    wp_posts
    LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
    LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
SET
    wp_posts.post_type = 'opinion',
    wp_term_relationships.term_taxonomy_id = @taxonomy_id 
WHERE
    wp_posts.post_type = 'post' AND
    wp_posts.ID = @post_id AND
    wp_term_taxonomy.taxonomy = 'category' AND
    wp_term_taxonomy.term_id = @term_id_post;

# Actualizamos el número de opiniones
UPDATE
    wp_term_taxonomy
SET 
    count = @taxonomy_count + 1
WHERE term_id = @term_id;

Pasando todas las Entradas a CPT

Una vez que hayamos verificado que funciona correctamente, procedemos a hacerlo con el resto de entradas con las siguientes sentencias:

SET @term_id = 211717; # Id Categoría Opinión (La columna)
SET @term_id_post = 37; # Id categoría Entrada (La columna)

# Guardamos en una variable el ID de la categoría indicada de opinión.
SELECT @taxonomy_id := term_taxonomy_id
FROM wp_term_taxonomy
WHERE term_id = @term_id
LIMIT 1;


# Pasamos la Entrada al CPT opinión y le indicamos a que categoría de opinión le asignamos.
UPDATE
    wp_posts
    LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
    LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
SET
    wp_posts.post_type = 'opinion',
    wp_term_relationships.term_taxonomy_id = @taxonomy_id 
WHERE
    wp_posts.post_type = 'post' AND
    wp_term_taxonomy.taxonomy = 'category' AND
    wp_term_taxonomy.term_id = @term_id_post;

# Guardamos en una variable el número de opiniones de la categoría indicada de opinión.
SELECT @taxonomy_count := COUNT(*) FROM wp_posts 
    LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
    LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
    wp_posts.post_type = 'opinion' AND
    wp_term_taxonomy.taxonomy = 'punto-de-vista' AND
    wp_term_taxonomy.term_id = @term_id;

# Actualizamos el número de opiniones
UPDATE
    wp_term_taxonomy
SET 
    count = @taxonomy_count
WHERE term_id = @term_id;

Probablemente se puedan mejorar las sentencias, pero no le quería añadir mas complejidad.

Conclusión

Quizá haciéndolo de este modo nos estemos complicando un poco mas «la vida» que si lo hiciéramos mediante plugin, pero así tenemos mayor control.

Y por ahora esto es todo, nos vemos en el próximo…

Referencias