From 70831f13f0d8dd76b13887a002716bb3230b34e1 Mon Sep 17 00:00:00 2001 From: rafa Date: Mon, 22 Jun 2026 15:10:27 -0400 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20#136=20reasignaci=C3=B3n=20de=20c?= =?UTF-8?q?ategor=C3=ADas=20traducidas=20+=20autores=20b=C3=ADblicos=20por?= =?UTF-8?q?=20idioma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - trad_cats.php: traduce categorías estructurales (Nuevo/Antiguo Testamento, etc.) - fix_catnames.php: corrige nombres de términos traducidos - autores_biblicos.php: crea usuarios NT/AT por idioma y reasigna autor de lecturas - reasign_cats.php: reasigna a cada post no-ES las categorías del ES traducidas a su idioma (crea término espejo si falta). Idempotente/resumible (_cats_reasignadas). 7977 posts procesados, 0 con categoría en idioma incorrecto. Co-Authored-By: Claude Opus 4.8 --- scripts/autores_biblicos.php | 40 +++++++++++++++++++++ scripts/fix_catnames.php | 26 ++++++++++++++ scripts/reasign_cats.php | 70 ++++++++++++++++++++++++++++++++++++ scripts/trad_cats.php | 39 ++++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 scripts/autores_biblicos.php create mode 100644 scripts/fix_catnames.php create mode 100644 scripts/reasign_cats.php create mode 100644 scripts/trad_cats.php diff --git a/scripts/autores_biblicos.php b/scripts/autores_biblicos.php new file mode 100644 index 0000000..9722b6c --- /dev/null +++ b/scripts/autores_biblicos.php @@ -0,0 +1,40 @@ + ['en'=>'New Testament','fr'=>'Nouveau Testament','it'=>'Nuovo Testamento','pt'=>'Novo Testamento'], + 409 => ['en'=>'Old Testament','fr'=>'Ancien Testament','it'=>'Antico Testamento','pt'=>'Antigo Testamento'], +]; +$LOGIN = [408=>'nt', 409=>'at']; +// 1) crear/asegurar usuarios por idioma +$uid_map = []; // [es_author][lang] => uid +foreach ($DEF as $es_author => $names) { + foreach ($names as $L => $dn) { + $login = $LOGIN[$es_author].'-'.$L; + $u = get_user_by('login', $login); + if (!$u) { + $id = wp_insert_user(['user_login'=>$login,'user_pass'=>wp_generate_password(20), + 'user_email'=>$login.'@feadulta.local','display_name'=>$dn,'role'=>'author','first_name'=>$dn]); + if (is_wp_error($id)) { echo "ERROR user $login: ".$id->get_error_message()."\n"; continue; } + echo "creado usuario $login (#$id) = $dn\n"; + } else { $id = $u->ID; wp_update_user(['ID'=>$id,'display_name'=>$dn]); echo "existe $login (#$id)\n"; } + $uid_map[$es_author][$L] = $id; + } +} +// 2) reasignar autor de las traducciones según el autor del ES original +$reasig = 0; +foreach ([408,409] as $es_author) { + $posts = get_posts(['author'=>$es_author,'post_type'=>'post','post_status'=>['publish','draft'], + 'posts_per_page'=>-1,'fields'=>'ids','lang'=>'es','no_found_rows'=>true]); + foreach ($posts as $es_id) { + $tr = pll_get_post_translations($es_id); + foreach (['en','fr','it','pt'] as $L) { + if (empty($tr[$L]) || empty($uid_map[$es_author][$L])) continue; + $p = get_post($tr[$L]); + if ($p && (int)$p->post_author !== (int)$uid_map[$es_author][$L]) { + wp_update_post(['ID'=>$tr[$L],'post_author'=>$uid_map[$es_author][$L]]); + $reasig++; + } + } + } + echo "ES autor $es_author: ".count($posts)." posts ES procesados\n"; +} +echo "traducciones reasignadas de autor: $reasig\n"; diff --git a/scripts/fix_catnames.php b/scripts/fix_catnames.php new file mode 100644 index 0000000..0bca84f --- /dev/null +++ b/scripts/fix_catnames.php @@ -0,0 +1,26 @@ + ['en'=>'New Testament','fr'=>'Nouveau Testament','it'=>'Nuovo Testamento','pt'=>'Novo Testamento'], + 411 => ['en'=>'Old Testament','fr'=>'Ancien Testament','it'=>'Antico Testamento','pt'=>'Antigo Testamento'], + 49 => ['en'=>'Advent and Christmas','fr'=>'Avent et Noël','it'=>'Avvento e Natale','pt'=>'Advento e Natal'], + 12 => ['en'=>'In Memoriam','fr'=>'In Memoriam','it'=>'In Memoriam','pt'=>'In Memoriam'], + 1651 => ['en'=>'News','fr'=>'Actualités','it'=>'Notizie','pt'=>'Notícias'], + 61 => ['en'=>'Christian Communities','fr'=>'Communautés chrétiennes','it'=>'Comunità cristiane','pt'=>'Comunidades cristãs'], + 23 => ['en'=>'Letters We Receive','fr'=>'Lettres reçues','it'=>'Lettere che riceviamo','pt'=>'Cartas que recebemos'], + 39 => ['en'=>'Topics','fr'=>'Thèmes','it'=>'Temi','pt'=>'Temas'], + 27 => ['en'=>'Chronological Index','fr'=>'Index chronologique','it'=>'Indice cronologico','pt'=>'Índice cronológico'], + 63 => ['en'=>'EFFA','fr'=>'EFFA','it'=>'EFFA','pt'=>'EFFA'], +]; +$fixed=0; +foreach ($D as $es=>$names) { + foreach ($names as $L=>$correct) { + $t = pll_get_term($es, $L); + if (!$t) { echo " $es/$L sin término\n"; continue; } + $cur = get_term($t)->name; + if ($cur !== $correct) { + wp_update_term($t, 'category', ['name'=>$correct]); + echo " #$t [$L] \"$cur\" → \"$correct\"\n"; $fixed++; + } + } +} +echo "nombres corregidos: $fixed\n"; diff --git a/scripts/reasign_cats.php b/scripts/reasign_cats.php new file mode 100644 index 0000000..a5f0e41 --- /dev/null +++ b/scripts/reasign_cats.php @@ -0,0 +1,70 @@ + term_id + +function translate_or_mirror($c, $lang, &$cache) { + $key = $c . '|' . $lang; + if (isset($cache[$key])) return $cache[$key]; + $t = pll_get_term($c, $lang); + if (!$t) { + $term = get_term($c, 'category'); + if (!$term || is_wp_error($term)) { return $cache[$key] = $c; } + $slug = sanitize_title($term->name) . '-' . $lang . '-' . $c; + $res = wp_insert_term($term->name, 'category', ['slug' => $slug]); + if (is_wp_error($res)) { + $ex = $res->get_error_data(); + if (!$ex) { return $cache[$key] = $c; } + $t = is_array($ex) ? ($ex['term_id'] ?? 0) : (int) $ex; + } else { + $t = $res['term_id']; + } + if ($t) { + pll_set_term_language($t, $lang); + $tr = pll_get_term_translations($c); + $tr[$lang] = $t; + pll_save_term_translations($tr); + } else { + $t = $c; + } + } + return $cache[$key] = (int) $t; +} + +$langs = $only_lang ? [$only_lang] : ['en','fr','it','pt']; +$done = 0; $changed = 0; $mirrors = 0; +$start_mirror_terms = count($mirror_cache); +foreach ($langs as $lang) { + $args = ['lang'=>$lang,'post_type'=>'post','post_status'=>['publish','draft'], + 'fields'=>'ids','posts_per_page'=> $limit ?: -1,'no_found_rows'=>true, + 'meta_query'=>[['key'=>'_cats_reasignadas','compare'=>'NOT EXISTS']]]; + $ids = get_posts($args); + foreach ($ids as $pid) { + // Fuente de verdad = categorías del ES original (las del post traducido + // pueden estar incompletas). Se traducen al idioma del post. + $es = pll_get_post($pid, 'es'); + $source = ($es && $es != $pid) ? wp_get_post_categories($es) : wp_get_post_categories($pid); + $new = []; + foreach ($source as $c) { + $clang = pll_get_term_language($c); + $new[] = ($clang === $lang) ? $c : translate_or_mirror($c, $lang, $mirror_cache); + } + $new = array_values(array_unique($new)); + $cur = wp_get_post_categories($pid); + sort($cur); $cmp = $new; sort($cmp); + if ($cur !== $cmp && $new) { wp_set_post_categories($pid, $new); $changed++; } + update_post_meta($pid, '_cats_reasignadas', 1); + $done++; + } +} +echo "procesados: $done | con cambios: $changed | términos espejo en caché: " . count($mirror_cache) . "\n"; diff --git a/scripts/trad_cats.php b/scripts/trad_cats.php new file mode 100644 index 0000000..a817561 --- /dev/null +++ b/scripts/trad_cats.php @@ -0,0 +1,39 @@ + [en,fr,it,pt]) +$D = [ + 410 => ['Nuevo Testamento', 'New Testament','Nouveau Testament','Nuovo Testamento','Novo Testamento'], + 411 => ['Antiguo Testamento','Old Testament','Ancien Testament','Antico Testamento','Antigo Testamento'], + 49 => ['Adviento y Navidad','Advent and Christmas','Avent et Noël','Avvento e Natale','Advento e Natal'], + 12 => ['In memoriam','In Memoriam','In Memoriam','In Memoriam','In Memoriam'], + 1651 => ['Noticias','News','Actualités','Notizie','Notícias'], + 61 => ['Comunidades cristianas','Christian Communities','Communautés chrétiennes','Comunità cristiane','Comunidades cristãs'], + 23 => ['Cartas que nos llegan','Letters We Receive','Lettres reçues','Lettere che riceviamo','Cartas que recebemos'], + 39 => ['Temas','Topics','Thèmes','Temi','Temas'], + 27 => ['Índice cronológico','Chronological Index','Index chronologique','Indice cronologico','Índice cronológico'], + 63 => ['EFFA','EFFA','EFFA','EFFA','EFFA'], +]; +$LangSlug = ['en'=>'en','fr'=>'fr','it'=>'it','pt'=>'pt']; +$created=0; +foreach ($D as $es_id => $names) { + $es_term = get_term($es_id, 'category'); + if (!$es_term || is_wp_error($es_term)) { echo "skip $es_id (no existe)\n"; continue; } + $existing = pll_get_term_translations($es_id); + $group = $existing; + $i = 1; + foreach (['en','fr','it','pt'] as $L) { + $i++; + if (!empty($existing[$L])) { $group[$L]=$existing[$L]; continue; } + $name = $names[$i-1]; + $slug = sanitize_title($name).'-'.$L; + $res = wp_insert_term($name, 'category', ['slug'=>$slug]); + if (is_wp_error($res)) { echo " $es_id $L ERROR: ".$res->get_error_message()."\n"; continue; } + $tid = $res['term_id']; + pll_set_term_language($tid, $L); + $group[$L] = $tid; + $created++; + } + pll_save_term_translations($group); + echo "#$es_id ".$names[0]." → ".implode(",", array_map(function($k,$v){return $k.":".$v;}, array_keys($group),$group))."\n"; +} +echo "términos traducidos creados: $created\n";