Files
feadulta/scripts/reasign_cats.php
T

71 lines
3.0 KiB
PHP

<?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";