` de las cartas (grupo Polylang) a * su permalink "bonito" por slug. Necesario cuando se arreglaron los enlaces de * la carta con los artículos en DRAFT: get_permalink() devolvía `?p=`, que * el parser de portada (fea_url_to_post_id, resuelve por slug) NO reconoce → los * artículos no salían en sus secciones. Con los posts ya en publish, get_permalink * da el slug. Solo datos, sin tocar mu-plugins. Dry-run por defecto. * * Uso: CARTA= php prettify_carta_links.php (dry-run) * APPLY=1 CARTA= php prettify_carta_links.php */ require getenv('FEA_WP_LOAD') ?: '/var/www/html/wp-load.php'; $APPLY = getenv('APPLY') === '1'; $CARTA = (int)(getenv('CARTA') ?: 0); if (!$CARTA) { fwrite(STDERR, "Falta CARTA=\n"); exit(1); } $BAK = "/tmp/prettify_carta_bak"; if ($APPLY) @mkdir($BAK, 0777, true); $tot = 0; foreach (pll_get_post_translations($CARTA) as $lang => $pid) { $post = get_post($pid); if (!$post) continue; $chg = 0; $new = preg_replace_callback('~href="([^"]*[?&]p=(\d+)[^"]*)"~i', function($m) use (&$chg) { $id = (int) $m[2]; $url = get_permalink($id); if (!$url || strpos($url, '?p=') !== false) return $m[0]; // sigue feo → dejar $chg++; return 'href="' . esc_url($url) . '"'; }, $post->post_content); echo sprintf("#%d [%s] «%s» — %d enlaces ?p= → slug\n", $pid, $lang, mb_substr($post->post_title,0,28), $chg); $tot += $chg; if ($APPLY && $chg) { file_put_contents("$BAK/$pid.html", $post->post_content); wp_update_post(['ID'=>$pid, 'post_content'=>$new]); clean_post_cache($pid); } } // Invalida los transients de secciones de la portada para que recoja los cambios. if ($APPLY) { global $wpdb; $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_fea_carta_sections_%'"); $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_fea_carta_sections_%'"); } echo ($APPLY ? "APLICADO" : "DRY-RUN") . ": $tot enlaces.\n";