105 lines
4.4 KiB
PHP
105 lines
4.4 KiB
PHP
<?php
|
|
/**
|
|
* Issue #75 — normaliza los enlaces internos de las cartas (ES + traducciones).
|
|
*
|
|
* Bugs que arregla:
|
|
* - Cartas ES con enlaces a http://localhost:8081/<slug>/ (rompen en prod).
|
|
* - Traducciones con enlaces relativos /<slug>/ (rompen en local, falta /fea).
|
|
* - Enlaces que apuntan a un artículo en otro idioma (los re-apunta a la
|
|
* traducción del MISMO idioma de la carta si existe).
|
|
*
|
|
* Para CADA <a href>: si el slug resuelve a un post del sitio, se reescribe al
|
|
* permalink absoluto del post en el idioma de la página (fallback: el que haya).
|
|
* Si el slug NO resuelve a ningún post (legacy .html, externos), se deja intacto.
|
|
*
|
|
* Uso (dentro del contenedor, con WP cargado):
|
|
* php fix_carta_links.php -> DRY-RUN (no escribe nada)
|
|
* APPLY=1 php fix_carta_links.php -> aplica y guarda backup en /tmp/fix_links_bak/
|
|
*/
|
|
if (!defined('ABSPATH')) {
|
|
require getenv('FEA_WP_LOAD') ?: '/var/www/html/wp-load.php';
|
|
}
|
|
global $wpdb;
|
|
|
|
$APPLY = getenv("APPLY") === "1";
|
|
$BAKDIR = "/tmp/fix_links_bak";
|
|
if ($APPLY) @mkdir($BAKDIR, 0777, true);
|
|
|
|
// Conjunto de trabajo: posts ES con localhost:8081 + todas sus traducciones.
|
|
$es_ids = $wpdb->get_col(
|
|
"SELECT ID FROM wp_posts WHERE post_type='post'
|
|
AND post_status IN ('publish','draft')
|
|
AND post_content LIKE '%localhost:8081%'"
|
|
);
|
|
$targets = [];
|
|
foreach ($es_ids as $id) {
|
|
$targets[$id] = true;
|
|
foreach (pll_get_post_translations($id) as $tid) $targets[$tid] = true;
|
|
}
|
|
$targets = array_keys($targets);
|
|
|
|
/** Extrae el slug candidato de un href, o null si no parece interno. */
|
|
function slug_from_href($href) {
|
|
$href = html_entity_decode(trim($href));
|
|
if ($href === '' || $href[0] === '#') return null;
|
|
if (preg_match('~^(mailto:|tel:|javascript:)~i', $href)) return null;
|
|
if (stripos($href, '.html') !== false) return null; // legacy Joomla
|
|
if (stripos($href, 'feadulta.com') !== false) return null; // dominio viejo
|
|
if (strpos($href, '%') !== false) return null; // placeholders [unsubscribe]
|
|
// Quitar querystring / fragment
|
|
$href = preg_replace('~[?#].*$~', '', $href);
|
|
// Quitar esquema+host si los hay
|
|
$path = preg_replace('~^https?://[^/]+~i', '', $href);
|
|
if ($path === '') return null;
|
|
if ($path[0] !== '/') return null; // relativo raro -> no tocar
|
|
if (stripos($path, '/category/') !== false) return null; // categorías, no posts
|
|
if (stripos($path, '/wp-') === 0) return null;
|
|
// Quitar /fea y prefijo de idioma
|
|
$path = preg_replace('~^/fea~', '', $path);
|
|
$path = preg_replace('~^/(en|fr|it|pt|es)(/|$)~', '/', $path);
|
|
$segs = array_values(array_filter(explode('/', $path), 'strlen'));
|
|
if (count($segs) !== 1) return null; // solo /<slug>/ de un nivel
|
|
return $segs[0];
|
|
}
|
|
|
|
$total_posts = 0; $total_links = 0; $samples = 0;
|
|
foreach ($targets as $pid) {
|
|
$post = get_post($pid);
|
|
if (!$post) continue;
|
|
$lang = pll_get_post_language($pid) ?: 'es';
|
|
$content = $post->post_content;
|
|
$changes = 0;
|
|
|
|
$new = preg_replace_callback('~href="([^"]*)"~i', function($m) use ($lang, &$changes, $wpdb) {
|
|
$href = $m[1];
|
|
$slug = slug_from_href($href);
|
|
if ($slug === null) return $m[0];
|
|
$found = $wpdb->get_var($wpdb->prepare(
|
|
"SELECT ID FROM wp_posts WHERE post_name=%s AND post_type='post'
|
|
AND post_status='publish' LIMIT 1", $slug));
|
|
if (!$found) return $m[0]; // no es un post -> intacto
|
|
// Resolver a la traducción del idioma de la página
|
|
$target = pll_get_post((int)$found, $lang);
|
|
if (!$target) $target = (int)$found;
|
|
$url = get_permalink($target);
|
|
if (!$url || $url === $href) return $m[0];
|
|
$changes++;
|
|
return 'href="' . esc_url($url) . '"';
|
|
}, $content);
|
|
|
|
if ($changes > 0) {
|
|
$total_posts++; $total_links += $changes;
|
|
echo sprintf("#%d [%s] «%s» — %d enlace(s) reescrito(s)\n",
|
|
$pid, $lang, mb_substr($post->post_title, 0, 40), $changes);
|
|
if ($APPLY) {
|
|
file_put_contents("$BAKDIR/$pid.html", $content);
|
|
$wpdb->update($wpdb->posts, ['post_content' => $new], ['ID' => $pid]);
|
|
clean_post_cache($pid);
|
|
}
|
|
}
|
|
}
|
|
|
|
echo "\n";
|
|
echo ($APPLY ? "APLICADO" : "DRY-RUN") . ": $total_links enlaces en $total_posts posts.\n";
|
|
if (!$APPLY) echo "Para aplicar: APPLY=1 php fix_carta_links.php (backup en $BAKDIR)\n";
|