feat(i18n): #136 reasignación de categorías traducidas + autores bíblicos por idioma
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
$DEF = [
|
||||||
|
408 => ['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";
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
$D = [
|
||||||
|
410 => ['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";
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* reasign_cats.php — #136: reasigna las categorías de los posts traducidos (en/fr/it/pt)
|
||||||
|
* a la versión Polylang de su idioma. Si la categoría no tiene traducción, crea un
|
||||||
|
* término espejo (mismo nombre) en ese idioma y lo asocia. Idempotente y resumible
|
||||||
|
* (marca _cats_reasignadas=1).
|
||||||
|
*
|
||||||
|
* Ejecutar: docker exec wordpress-web wp eval-file /tmp/reasign_cats.php [LANG] [LIMIT] --allow-root
|
||||||
|
* sin args: procesa los 4 idiomas. Con LANG (en/fr/it/pt) y LIMIT acota.
|
||||||
|
*/
|
||||||
|
$only_lang = (isset($argv[1]) && in_array($argv[1], ['en','fr','it','pt'], true)) ? $argv[1] : null;
|
||||||
|
$limit = isset($argv[2]) ? (int) $argv[2] : 0;
|
||||||
|
|
||||||
|
$mirror_cache = []; // "cat_es|lang" => 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";
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
require_once '/var/www/html/wp-load.php';
|
||||||
|
// Categorías estructurales de contenido → traducciones (es_term_id => [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";
|
||||||
Reference in New Issue
Block a user