Files
feadulta/scripts/fix_numeric_categories.php
T

242 lines
8.4 KiB
PHP

<?php
/**
* fix_numeric_categories.php
*
* Renames 100 WordPress categories that have numeric names (K2 Autor field IDs)
* to their proper author names from the Joomla K2 extra field mapping.
*
* When a named category already exists for the same author, merges both
* (moves posts from numeric → named category, then deletes numeric).
*
* Usage: php fix_numeric_categories.php [--dry-run]
*/
$dry_run = in_array('--dry-run', $argv ?? []);
$db_host = 'wordpress-mysql';
$db_name = 'wordpress_db';
$db_user = 'wordpress_user';
$db_pass = 'wordpress_pass';
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
echo "=== Fix Numeric Author Categories ===\n";
echo $dry_run ? "[DRY RUN]\n\n" : "[LIVE RUN]\n\n";
// -------------------------------------------------------------------------
// Mapping: numeric value → author name (from K2 extra field "Autor")
// -------------------------------------------------------------------------
$autor_map = [
1 => "Fray Marcos",
2 => "José Antonio Pagola",
3 => "Enrique Martínez Lozano",
4 => "José Enrique Galarreta",
5 => "José Arregi",
6 => "Eloy Roy",
7 => "Dolores Aleixandre",
9 => "Florentino Ulibarri",
10 => "Rafael Calvo",
11 => "Julián Mellado",
12 => "Vicente Martínez",
13 => "Matilde Gastalver",
14 => "Koldo Aldai",
15 => "Sandra Hojman",
16 => "Leonardo Boff",
17 => "José M. Castillo",
18 => "Luís Alemán",
19 => "Juan José Tamayo",
20 => "José Ignacio González Faus",
22 => "José Manuel Vidal",
23 => "Isabel Gómez-Acebo",
31 => "Faustino Vilabrille",
32 => "Víctor Daniel Blanco",
33 => "Nuevo Testamento",
36 => "Gabriel Mª Otalora",
38 => "Luís García Orso",
40 => "María Teresa Sánchez Carmona",
41 => "Emma Martínez Ocaña",
45 => "Mari Patxi Ayerra",
49 => "Jesús Bastante",
52 => "J. A. Estrada",
53 => "Rafael Díaz Arias",
58 => "Susana Merino",
69 => "Asociación de teólogos y teólogas Juan XXIII",
73 => "José Ignacio Calleja",
75 => "Autor desconocido",
76 => "Gerardo Villar",
79 => "José Sánchez Luque",
83 => "Mari Paz López Santos",
84 => "Patricia Paz",
87 => "Pedro Casaldáliga",
88 => "Foro «Curas de Madrid»",
92 => "Xavier Pikaza",
96 => "Benjamín Forcano",
97 => "Ima Sanchís",
108 => "Pedro M. Lamet",
114 => "Juan G. Bedoya",
115 => "Juan Masiá",
123 => "Frei Betto",
124 => "Juan Cejudo",
125 => "Miguel Ángel Mesa",
126 => "Carlos F. Barberá",
127 => "Mariá Corbí",
129 => "Rafael Fernando Navarro",
149 => "José María Díez Alegría",
174 => "Carmen Soto",
175 => "Hans Küng",
188 => "Fidel Aizpurúa",
194 => "Pepcastelló",
208 => "Juan Yzuel",
234 => "Maite García Romero",
263 => "Gonzalo Haya",
288 => "Redes Cristianas",
303 => "Víctor Codina",
306 => "José María García-Mauriño",
312 => "Patxi Loidi",
321 => "Jesús Gil García",
323 => "John P. Meier",
325 => "Rogelio Cárdenas",
329 => "Pablo Ordaz",
345 => "Papa Francisco",
347 => "Vicky Irigaray",
357 => "Marco Antonio Velásquez Uribe",
362 => "Fernando Bermúdez López",
374 => "Pablo",
375 => "José Luis Sicre",
376 => "Miguel A. Munárriz Casajús",
382 => "Santiago Agrelo",
392 => "Felix Jiménez Tutor",
396 => "José María Alvarez",
399 => "Hechos",
404 => "Bruno Álvarez",
412 => "Luis Miguel Modino",
418 => "Varios autores",
435 => "Voces cristianas de Sevilla",
437 => "Religión Digital",
443 => "Francisco Bautista",
444 => "Yolanda Chávez",
449 => "Atrio",
450 => "Carolina Abarca",
465 => "Magdalena Bennasar",
516 => "Eclesalia",
520 => "Antonio Aradillas",
529 => "Humanismo Sin credos",
540 => "Juan Zapatero",
557 => "Marifé Ramos González",
566 => "Marta García",
570 => "María Dolores López Guzmán",
583 => "Inma Eibe",
615 => "Íñigo García Blanco",
];
// -------------------------------------------------------------------------
// Fetch all numeric categories from WordPress
// -------------------------------------------------------------------------
$stmt = $pdo->query("
SELECT t.term_id, t.name, t.slug, tt.count
FROM wp_terms t
JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
WHERE tt.taxonomy = 'category' AND t.name REGEXP '^[0-9]+$'
ORDER BY CAST(t.name AS UNSIGNED)
");
$numeric_cats = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Numeric categories found: " . count($numeric_cats) . "\n\n";
$stats = ['renamed' => 0, 'merged' => 0, 'skipped' => 0, 'no_map' => 0];
foreach ($numeric_cats as $cat) {
$num_val = (int)$cat['name'];
$term_id = (int)$cat['term_id'];
$post_count = (int)$cat['count'];
if (!isset($autor_map[$num_val])) {
echo " [SKIP] No mapping for value $num_val (term_id=$term_id, $post_count posts)\n";
$stats['no_map']++;
continue;
}
$new_name = $autor_map[$num_val];
// Check if a category with this name already exists
$existing = $pdo->prepare("
SELECT t.term_id, tt.count
FROM wp_terms t
JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
WHERE tt.taxonomy = 'category' AND t.name = ?
AND t.term_id != ?
");
$existing->execute([$new_name, $term_id]);
$existing_cat = $existing->fetch(PDO::FETCH_ASSOC);
if ($existing_cat) {
// MERGE: move posts from numeric category to the existing named category
$target_term_id = (int)$existing_cat['term_id'];
echo " [MERGE] \"$num_val\" ($post_count posts) \"$new_name\" (term_id=$target_term_id, existing {$existing_cat['count']} posts)\n";
if (!$dry_run) {
// Get term_taxonomy_id for both
$tt_stmt = $pdo->prepare("SELECT term_taxonomy_id FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = 'category'");
$tt_stmt->execute([$term_id]);
$src_tt_id = (int)$tt_stmt->fetchColumn();
$tt_stmt->execute([$target_term_id]);
$dst_tt_id = (int)$tt_stmt->fetchColumn();
// Move post relationships (avoiding duplicates)
$pdo->prepare("
UPDATE IGNORE wp_term_relationships
SET term_taxonomy_id = ?
WHERE term_taxonomy_id = ?
")->execute([$dst_tt_id, $src_tt_id]);
// Delete remaining relationships for source (duplicates that weren't moved)
$pdo->prepare("DELETE FROM wp_term_relationships WHERE term_taxonomy_id = ?")->execute([$src_tt_id]);
// Update count on target
$pdo->prepare("
UPDATE wp_term_taxonomy SET count = (
SELECT COUNT(*) FROM wp_term_relationships WHERE term_taxonomy_id = ?
) WHERE term_taxonomy_id = ?
")->execute([$dst_tt_id, $dst_tt_id]);
// Delete numeric category
$pdo->prepare("DELETE FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = 'category'")->execute([$term_id]);
$pdo->prepare("DELETE FROM wp_terms WHERE term_id = ?")->execute([$term_id]);
}
$stats['merged']++;
} else {
// RENAME: update name and slug
$new_slug = sanitize_slug($new_name);
echo " [RENAME] \"$num_val\" \"$new_name\" (term_id=$term_id, $post_count posts)\n";
if (!$dry_run) {
$pdo->prepare("UPDATE wp_terms SET name = ?, slug = ? WHERE term_id = ?")->execute([$new_name, $new_slug, $term_id]);
}
$stats['renamed']++;
}
}
echo "\n=== Results ===\n";
echo "Renamed: {$stats['renamed']}\n";
echo "Merged: {$stats['merged']}\n";
echo "Skipped (no map): {$stats['no_map']}\n";
echo "\nDone.\n";
// -------------------------------------------------------------------------
function sanitize_slug(string $name): string {
$slug = mb_strtolower($name, 'UTF-8');
$slug = str_replace(
['á','é','í','ó','ú','ü','ñ','ã','â','à','ê','ô','ç','ú','ó','ä','ö'],
['a','e','i','o','u','u','n','a','a','a','e','o','c','u','o','a','o'],
$slug
);
$slug = preg_replace('/[^a-z0-9\s-]/', '', $slug);
$slug = preg_replace('/[\s]+/', '-', trim($slug));
$slug = preg_replace('/-+/', '-', $slug);
return trim($slug, '-');
}