Script para aplicar categorías automáticamente a posts en WordPress
Traigo una maravilla (al menos para mi), con ayuda de nuestro amigo ChatGPT hemos resuelto en menos de media hora un problema grande.
El reto era recuperar el contenido de un blog de WordPress antiguo, unos 20000 posts desde el año 2013, muchas horas de trabajo de redacción.
El problema
El problema por el que necesitamos un script para aplicar categorías automáticamente a posts en WordPress es que los posts no tienen cateogrías, hemos conseguido recuperar la totalidad del contenido sin tener la base de datos ni ninguna copia de seguridad porque el equipo de WordPress de Pango Studio es la hostia (si te interesa recuperar algo así escríbenos), pero sin categorías ni etiquetas; lo positivo es que casi todos los posts tienen dentro del post_content un texto como este: «Publicado en: Actualidad, Internet, Tecnología», siendo «Actualidad», «Internet»y «Tecnología» las categorías a las que pertenece el post, así que podemos resolver el problema con algo que recorra todos los posts y le añada a cada post sus categorías correspondientes.
Lo mismo pasa con las etiquetas, pero tiene un texto diferente, por ejemplo:
Con este objetivo hemos desarrollado el script, y posteriormente lo hemos ejecutado, página a página, actualizando 100 posts en cada tacada. Ha sido sorprendentemente rápido. De hecho, he tardado más en escribir esto que en el proceso total de desarrollar el script, subirlo y ejecutarlo.
El Script
Aquí el script para aplicar categorías y etiquetas automáticamente a posts en WordPress para que hagas con él lo que quieras.
<?php
// Incluye los archivos de WordPress
require_once('wp-load.php');
global $wpdb;
// Definir el número de posts por página
$posts_per_page = 100;
// Obtener el número total de posts
$total_posts = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}posts WHERE post_type = 'post' AND post_status = 'publish'");
$total_pages = ceil($total_posts / $posts_per_page);
// Obtener el número de página actual desde la URL, si no está definido, usar la página 1
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$offset = ($page - 1) * $posts_per_page;
// Consulta para obtener los posts de la página actual
$posts = $wpdb->get_results($wpdb->prepare(
"SELECT ID, post_content FROM {$wpdb->prefix}posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT %d OFFSET %d",
$posts_per_page, $offset
));
foreach ($posts as $post) {
$post_id = $post->ID;
$post_content = $post->post_content;
// Procesar Categorías
if (preg_match('/Publicado en:\s*(.*?)(<\/p>|<br>|$)/i', $post_content, $matches)) {
$categories = explode(',', $matches[1]);
// Limpia los nombres de las categorías
$categories = array_map('trim', $categories);
// Array para almacenar los IDs de las categorías
$category_ids = [];
foreach ($categories as $category_name) {
// Verifica si la categoría ya existe
$category = get_term_by('name', $category_name, 'category');
if (!$category) {
// Crea la categoría si no existe
$category_id = wp_create_category($category_name);
} else {
// Usa el ID de la categoría existente
$category_id = $category->term_id;
}
$category_ids[] = $category_id;
}
// Asocia las categorías con el post
wp_set_post_categories($post_id, $category_ids);
}
// Procesar Etiquetas
if (preg_match('/Etiquetas:\s*(.*?)(<\/p>|<br>|$)/i', $post_content, $matches)) {
$tags = explode(',', $matches[1]);
// Limpia los nombres de las etiquetas
$tags = array_map('trim', $tags);
// Array para almacenar los nombres de las etiquetas
$tag_names = [];
foreach ($tags as $tag_name) {
// Añade la etiqueta al array de nombres de etiquetas
$tag_names[] = $tag_name;
}
// Asocia las etiquetas con el post
wp_set_post_tags($post_id, $tag_names, true);
}
}
// Mostrar navegación de páginas
if ($page > 1) {
echo '<a href="?page=' . ($page - 1) . '">Página Anterior</a> | ';
}
if ($page < $total_pages) {
echo '<a href="?page=' . ($page + 1) . '">Página Siguiente</a>';
}
echo '<p>Página ' . $page . ' de ' . $total_pages . '</p>';
?>
Explicación del script
Esto es lo que hace, modifícalo a tu gusto para tu caso particular. Seguramente no te sirvan las mismas expresiones regulares, por poner un ejemplo.
- Línea 4: Incluye los archivos de WordPress para tener acceso a sus funciones.
- Línea 7: Define el número de posts por página.
- Línea 10: Obtiene el número total de posts publicados.
- Línea 11: Calcula el número total de páginas.
- Línea 14-16: Obtiene el número de página actual desde la URL, y calcula el offset para la consulta SQL.
- Línea 19-21: Consulta los posts de la página actual.
- Línea 23-41: Procesa cada post, encuentra las categorías en el contenido, las crea si no existen y las asocia al post.
- Línea 44-51: Muestra enlaces de navegación para ir a la página anterior o siguiente.
Instrucciones para ejecutar el script
- Haz una copia de seguridad de tu base de datos. No la vayas a liar.
- Coloca el script en el directorio raíz de tu instalación de WordPress: Guárdalo como un archivo PHP, por ejemplo,
asignar_categorias_pag.php
. (lo puedes llamar como quieras) - Ejecuta el script: Accede al script a través de tu navegador visitando
https://pangostudio.com/asignar_categorias_pag.php?page=1
.
Si hubiera un museo de WordPress, este script debería estar
Aquí vemos como (ya en la página 8) han ido apareciendo las categorías:
Aquí en la página 180:
Es un problema poco común, porque pocas veces se recupera tanto contenido, con este script hemos tardado menos de media hora en hacerlo todo, ¿Cuánto hubiéramos tardado a mano?