chore: purgar archivos no utilizados (plan 101 fase 1)
- eliminar carpetas vacias admin/herosection y bootstrapicons - eliminar 7 scripts legacy con credenciales hardcodeadas - eliminar formbuilder duplicado en shared/infrastructure/ui - eliminar 11 archivos .gitkeep en carpetas con contenido 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Busca casos variados de problemas de listas para validación exhaustiva
|
||||
*/
|
||||
|
||||
$conn = new mysqli("localhost", "preciosunitarios_seo", "ACl%EEFd=V-Yvb??", "preciosunitarios_seo");
|
||||
$conn->set_charset("utf8mb4");
|
||||
|
||||
function detectIssues($html) {
|
||||
$issues = [];
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument("1.0", "UTF-8");
|
||||
$wrapped = '<div id="wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$validChildren = ["li", "script", "template"];
|
||||
foreach (["ul", "ol"] as $tag) {
|
||||
foreach ($doc->getElementsByTagName($tag) as $list) {
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$childTag = strtolower($child->nodeName);
|
||||
if (!in_array($childTag, $validChildren)) {
|
||||
$issues[] = ["parent" => $tag, "child" => $childTag];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $issues;
|
||||
}
|
||||
|
||||
echo "BUSCANDO CASOS VARIADOS...\n\n";
|
||||
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina WHERE html IS NOT NULL AND html != '' ORDER BY id";
|
||||
$result = $conn->query($query);
|
||||
|
||||
if (!$result) {
|
||||
die("Error en query: " . $conn->error);
|
||||
}
|
||||
|
||||
$cases = [
|
||||
"many_issues" => [],
|
||||
"ol_issues" => [],
|
||||
"mixed_issues" => [],
|
||||
"few_issues" => []
|
||||
];
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row["html"]);
|
||||
if (empty($issues)) continue;
|
||||
|
||||
$count = count($issues);
|
||||
$hasOl = false;
|
||||
$hasUl = false;
|
||||
|
||||
foreach ($issues as $issue) {
|
||||
if ($issue["parent"] === "ol") $hasOl = true;
|
||||
if ($issue["parent"] === "ul") $hasUl = true;
|
||||
}
|
||||
|
||||
if ($count > 10 && count($cases["many_issues"]) < 3) {
|
||||
$cases["many_issues"][] = ["id" => $row["id"], "url" => $row["page"], "count" => $count, "issues" => $issues];
|
||||
}
|
||||
if ($hasOl && !$hasUl && count($cases["ol_issues"]) < 3) {
|
||||
$cases["ol_issues"][] = ["id" => $row["id"], "url" => $row["page"], "count" => $count, "issues" => $issues];
|
||||
}
|
||||
if ($hasOl && $hasUl && count($cases["mixed_issues"]) < 3) {
|
||||
$cases["mixed_issues"][] = ["id" => $row["id"], "url" => $row["page"], "count" => $count, "issues" => $issues];
|
||||
}
|
||||
if ($count <= 2 && count($cases["few_issues"]) < 3) {
|
||||
$cases["few_issues"][] = ["id" => $row["id"], "url" => $row["page"], "count" => $count, "issues" => $issues];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($cases as $type => $posts) {
|
||||
echo "=== " . strtoupper($type) . " ===\n";
|
||||
if (empty($posts)) {
|
||||
echo " (ninguno encontrado)\n\n";
|
||||
continue;
|
||||
}
|
||||
foreach ($posts as $post) {
|
||||
echo "ID: {$post["id"]} - {$post["count"]} problemas\n";
|
||||
echo "URL: {$post["url"]}\n";
|
||||
echo "Tipos: ";
|
||||
$types = [];
|
||||
foreach ($post["issues"] as $i) {
|
||||
$types[] = "<{$i["parent"]}> contiene <{$i["child"]}>";
|
||||
}
|
||||
echo implode(", ", array_unique($types)) . "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
@@ -1,411 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Corrector de Listas HTML Mal Formadas usando DOMDocument
|
||||
*
|
||||
* PROPÓSITO: Detectar y corregir listas con estructura inválida
|
||||
* - <ul>/<ol> conteniendo elementos no-<li> como hijos directos
|
||||
* - Listas anidadas que son hermanas en lugar de hijas de <li>
|
||||
*
|
||||
* USO:
|
||||
* php fix-malformed-lists-dom.php --mode=scan # Solo escanear
|
||||
* php fix-malformed-lists-dom.php --mode=test # Probar corrección (1 post)
|
||||
* php fix-malformed-lists-dom.php --mode=fix # Aplicar correcciones
|
||||
*
|
||||
* @package ROI_Theme
|
||||
* @since Phase 4.4 Accessibility
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('memory_limit', '512M');
|
||||
set_time_limit(600);
|
||||
|
||||
// Configuración
|
||||
$db_config = [
|
||||
'host' => 'localhost',
|
||||
'database' => 'preciosunitarios_seo',
|
||||
'username' => 'preciosunitarios_seo',
|
||||
'password' => 'ACl%EEFd=V-Yvb??',
|
||||
'charset' => 'utf8mb4'
|
||||
];
|
||||
|
||||
// Parsear argumentos
|
||||
$mode = 'scan';
|
||||
foreach ($argv as $arg) {
|
||||
if (strpos($arg, '--mode=') === 0) {
|
||||
$mode = substr($arg, 7);
|
||||
}
|
||||
}
|
||||
|
||||
echo "==============================================\n";
|
||||
echo " CORRECTOR DE LISTAS - DOMDocument\n";
|
||||
echo " Modo: $mode\n";
|
||||
echo " Fecha: " . date('Y-m-d H:i:s') . "\n";
|
||||
echo "==============================================\n\n";
|
||||
|
||||
/**
|
||||
* Conectar a la base de datos
|
||||
*/
|
||||
function connectDatabase(array $config): ?mysqli {
|
||||
$conn = new mysqli(
|
||||
$config['host'],
|
||||
$config['username'],
|
||||
$config['password'],
|
||||
$config['database']
|
||||
);
|
||||
if ($conn->connect_error) {
|
||||
echo "Error de conexión: " . $conn->connect_error . "\n";
|
||||
return null;
|
||||
}
|
||||
$conn->set_charset($config['charset']);
|
||||
return $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Corregir listas mal formadas usando DOMDocument
|
||||
*/
|
||||
function fixMalformedLists(string $html): array {
|
||||
$result = [
|
||||
'fixed' => false,
|
||||
'html' => $html,
|
||||
'changes' => 0,
|
||||
'details' => []
|
||||
];
|
||||
|
||||
// Suprimir errores de HTML mal formado
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
$doc = new DOMDocument('1.0', 'UTF-8');
|
||||
|
||||
// Envolver en contenedor para preservar estructura
|
||||
$wrapped = '<div id="temp-wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
libxml_clear_errors();
|
||||
|
||||
// Procesar todas las listas (ul y ol)
|
||||
$lists = [];
|
||||
foreach ($doc->getElementsByTagName('ul') as $ul) {
|
||||
$lists[] = $ul;
|
||||
}
|
||||
foreach ($doc->getElementsByTagName('ol') as $ol) {
|
||||
$lists[] = $ol;
|
||||
}
|
||||
|
||||
$changes = 0;
|
||||
|
||||
foreach ($lists as $list) {
|
||||
$changes += fixListChildren($list, $result['details']);
|
||||
}
|
||||
|
||||
if ($changes > 0) {
|
||||
// Extraer HTML corregido
|
||||
$wrapper = $doc->getElementById('temp-wrapper');
|
||||
if ($wrapper) {
|
||||
$innerHTML = '';
|
||||
foreach ($wrapper->childNodes as $child) {
|
||||
$innerHTML .= $doc->saveHTML($child);
|
||||
}
|
||||
$result['html'] = $innerHTML;
|
||||
$result['fixed'] = true;
|
||||
$result['changes'] = $changes;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Corregir hijos de una lista (solo debe contener li, script, template)
|
||||
*/
|
||||
function fixListChildren(DOMElement $list, array &$details): int {
|
||||
$changes = 0;
|
||||
$validChildren = ['li', 'script', 'template'];
|
||||
$nodesToProcess = [];
|
||||
|
||||
// Recopilar nodos que necesitan corrección
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$nodesToProcess[] = $child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Procesar cada nodo inválido
|
||||
foreach ($nodesToProcess as $node) {
|
||||
$tagName = strtolower($node->nodeName);
|
||||
|
||||
// Si es una lista anidada (ul/ol), envolverla en <li>
|
||||
if ($tagName === 'ul' || $tagName === 'ol') {
|
||||
$changes += wrapInLi($list, $node, $details);
|
||||
}
|
||||
// Otros elementos inválidos también se envuelven en <li>
|
||||
else {
|
||||
$changes += wrapInLi($list, $node, $details);
|
||||
}
|
||||
}
|
||||
|
||||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Envolver un nodo en <li> o moverlo al <li> anterior
|
||||
*/
|
||||
function wrapInLi(DOMElement $list, DOMNode $node, array &$details): int {
|
||||
$doc = $list->ownerDocument;
|
||||
$tagName = strtolower($node->nodeName);
|
||||
|
||||
// Buscar el <li> hermano anterior
|
||||
$prevLi = null;
|
||||
$prev = $node->previousSibling;
|
||||
while ($prev) {
|
||||
if ($prev->nodeType === XML_ELEMENT_NODE && strtolower($prev->nodeName) === 'li') {
|
||||
$prevLi = $prev;
|
||||
break;
|
||||
}
|
||||
$prev = $prev->previousSibling;
|
||||
}
|
||||
|
||||
if ($prevLi) {
|
||||
// Mover el nodo al final del <li> anterior
|
||||
$prevLi->appendChild($node);
|
||||
$details[] = "Movido <$tagName> dentro del <li> anterior";
|
||||
return 1;
|
||||
} else {
|
||||
// No hay <li> anterior, crear uno nuevo
|
||||
$newLi = $doc->createElement('li');
|
||||
$list->insertBefore($newLi, $node);
|
||||
$newLi->appendChild($node);
|
||||
$details[] = "Envuelto <$tagName> en nuevo <li>";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detectar problemas en HTML sin corregir
|
||||
*/
|
||||
function detectIssues(string $html): array {
|
||||
$issues = [];
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument('1.0', 'UTF-8');
|
||||
$wrapped = '<div id="temp-wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$validChildren = ['li', 'script', 'template'];
|
||||
|
||||
// Revisar ul
|
||||
foreach ($doc->getElementsByTagName('ul') as $ul) {
|
||||
foreach ($ul->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$issues[] = [
|
||||
'list_type' => 'ul',
|
||||
'invalid_child' => $tagName,
|
||||
'context' => getNodeContext($child)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Revisar ol
|
||||
foreach ($doc->getElementsByTagName('ol') as $ol) {
|
||||
foreach ($ol->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$issues[] = [
|
||||
'list_type' => 'ol',
|
||||
'invalid_child' => $tagName,
|
||||
'context' => getNodeContext($child)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener contexto de un nodo para debug
|
||||
*/
|
||||
function getNodeContext(DOMNode $node): string {
|
||||
$doc = $node->ownerDocument;
|
||||
$html = $doc->saveHTML($node);
|
||||
return substr($html, 0, 100) . (strlen($html) > 100 ? '...' : '');
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// EJECUCIÓN PRINCIPAL
|
||||
// ============================================
|
||||
|
||||
$conn = connectDatabase($db_config);
|
||||
if (!$conn) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ Conexión establecida\n\n";
|
||||
|
||||
// Contar registros
|
||||
$result = $conn->query("SELECT COUNT(*) as total FROM datos_seo_pagina WHERE html IS NOT NULL AND html != ''");
|
||||
$total = $result->fetch_assoc()['total'];
|
||||
echo "Total de registros: $total\n\n";
|
||||
|
||||
if ($mode === 'scan') {
|
||||
// MODO SCAN: Solo detectar problemas
|
||||
echo "MODO: ESCANEO (solo detección)\n";
|
||||
echo "─────────────────────────────────\n\n";
|
||||
|
||||
$batch_size = 100;
|
||||
$offset = 0;
|
||||
$affected = 0;
|
||||
$total_issues = 0;
|
||||
|
||||
while ($offset < $total) {
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina
|
||||
WHERE html IS NOT NULL AND html != ''
|
||||
ORDER BY id LIMIT $batch_size OFFSET $offset";
|
||||
$result = $conn->query($query);
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['html']);
|
||||
if (!empty($issues)) {
|
||||
$affected++;
|
||||
$total_issues += count($issues);
|
||||
|
||||
if ($affected <= 20) {
|
||||
echo "[ID: {$row['id']}] " . count($issues) . " problema(s)\n";
|
||||
echo "URL: {$row['page']}\n";
|
||||
foreach (array_slice($issues, 0, 2) as $issue) {
|
||||
echo " - <{$issue['list_type']}> contiene <{$issue['invalid_child']}>\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$offset += $batch_size;
|
||||
|
||||
if ($offset % 1000 == 0) {
|
||||
echo "Procesados: $offset/$total...\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "─────────────────────────────────\n";
|
||||
echo "RESUMEN:\n";
|
||||
echo " Posts afectados: $affected\n";
|
||||
echo " Total incidencias: $total_issues\n";
|
||||
|
||||
} elseif ($mode === 'test') {
|
||||
// MODO TEST: Probar corrección en 1 post
|
||||
echo "MODO: PRUEBA (sin guardar)\n";
|
||||
echo "─────────────────────────────────\n\n";
|
||||
|
||||
// Buscar primer post con problemas
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina
|
||||
WHERE html IS NOT NULL AND html != ''
|
||||
ORDER BY id LIMIT 100";
|
||||
$result = $conn->query($query);
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['html']);
|
||||
if (!empty($issues)) {
|
||||
echo "POST ID: {$row['id']}\n";
|
||||
echo "URL: {$row['page']}\n";
|
||||
echo "Problemas detectados: " . count($issues) . "\n\n";
|
||||
|
||||
echo "ANTES (problemas):\n";
|
||||
foreach (array_slice($issues, 0, 3) as $issue) {
|
||||
echo " - <{$issue['list_type']}> contiene <{$issue['invalid_child']}>\n";
|
||||
echo " Contexto: " . htmlspecialchars(substr($issue['context'], 0, 80)) . "\n";
|
||||
}
|
||||
|
||||
// Aplicar corrección
|
||||
$fixResult = fixMalformedLists($row['html']);
|
||||
|
||||
echo "\nDESPUÉS (corrección):\n";
|
||||
echo " Cambios realizados: {$fixResult['changes']}\n";
|
||||
foreach ($fixResult['details'] as $detail) {
|
||||
echo " - $detail\n";
|
||||
}
|
||||
|
||||
// Verificar que no quedan problemas
|
||||
$issuesAfter = detectIssues($fixResult['html']);
|
||||
echo "\nVERIFICACIÓN:\n";
|
||||
echo " Problemas antes: " . count($issues) . "\n";
|
||||
echo " Problemas después: " . count($issuesAfter) . "\n";
|
||||
|
||||
if (count($issuesAfter) < count($issues)) {
|
||||
echo " ✓ Reducción de problemas\n";
|
||||
}
|
||||
|
||||
// Mostrar fragmento del HTML corregido
|
||||
if ($fixResult['fixed']) {
|
||||
echo "\nMUESTRA HTML CORREGIDO (primeros 500 chars):\n";
|
||||
echo "─────────────────────────────────\n";
|
||||
echo htmlspecialchars(substr($fixResult['html'], 0, 500)) . "...\n";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($mode === 'fix') {
|
||||
// MODO FIX: Aplicar correcciones
|
||||
echo "MODO: CORRECCIÓN (GUARDANDO CAMBIOS)\n";
|
||||
echo "─────────────────────────────────\n\n";
|
||||
|
||||
$batch_size = 50;
|
||||
$offset = 0;
|
||||
$fixed_count = 0;
|
||||
$error_count = 0;
|
||||
|
||||
while ($offset < $total) {
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina
|
||||
WHERE html IS NOT NULL AND html != ''
|
||||
ORDER BY id LIMIT $batch_size OFFSET $offset";
|
||||
$result = $conn->query($query);
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['html']);
|
||||
|
||||
if (!empty($issues)) {
|
||||
$fixResult = fixMalformedLists($row['html']);
|
||||
|
||||
if ($fixResult['fixed']) {
|
||||
// Guardar HTML corregido
|
||||
$stmt = $conn->prepare("UPDATE datos_seo_pagina SET html = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $fixResult['html'], $row['id']);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$fixed_count++;
|
||||
echo "[ID: {$row['id']}] ✓ Corregido ({$fixResult['changes']} cambios)\n";
|
||||
} else {
|
||||
$error_count++;
|
||||
echo "[ID: {$row['id']}] ✗ Error al guardar\n";
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$offset += $batch_size;
|
||||
|
||||
if ($offset % 500 == 0) {
|
||||
echo "Procesados: $offset/$total (corregidos: $fixed_count)\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n─────────────────────────────────\n";
|
||||
echo "RESUMEN:\n";
|
||||
echo " Posts corregidos: $fixed_count\n";
|
||||
echo " Errores: $error_count\n";
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
echo "\n✓ Proceso completado.\n";
|
||||
@@ -1,322 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Corrector de Listas HTML Mal Formadas - WordPress Posts
|
||||
*
|
||||
* BASE DE DATOS: preciosunitarios_wp
|
||||
* TABLA: wp_posts
|
||||
* CAMPO: post_content
|
||||
*
|
||||
* USO:
|
||||
* php fix-malformed-lists-wp-posts.php --mode=scan
|
||||
* php fix-malformed-lists-wp-posts.php --mode=test
|
||||
* php fix-malformed-lists-wp-posts.php --mode=fix
|
||||
*
|
||||
* @package ROI_Theme
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('memory_limit', '512M');
|
||||
set_time_limit(600);
|
||||
|
||||
$db_config = [
|
||||
'host' => 'localhost',
|
||||
'database' => 'preciosunitarios_wp',
|
||||
'username' => 'preciosunitarios_wp',
|
||||
'password' => 'Kq#Gk%yEt+PWpVe&HZ',
|
||||
'charset' => 'utf8mb4'
|
||||
];
|
||||
|
||||
$mode = 'scan';
|
||||
foreach ($argv as $arg) {
|
||||
if (strpos($arg, '--mode=') === 0) {
|
||||
$mode = substr($arg, 7);
|
||||
}
|
||||
}
|
||||
|
||||
echo "==============================================\n";
|
||||
echo " CORRECTOR DE LISTAS - WordPress Posts\n";
|
||||
echo " Base de datos: {$db_config['database']}\n";
|
||||
echo " Tabla: wp_posts (post_content)\n";
|
||||
echo " Modo: $mode\n";
|
||||
echo " Fecha: " . date('Y-m-d H:i:s') . "\n";
|
||||
echo "==============================================\n\n";
|
||||
|
||||
function connectDatabase(array $config): ?mysqli {
|
||||
$conn = new mysqli($config['host'], $config['username'], $config['password'], $config['database']);
|
||||
if ($conn->connect_error) {
|
||||
echo "Error de conexión: " . $conn->connect_error . "\n";
|
||||
return null;
|
||||
}
|
||||
$conn->set_charset($config['charset']);
|
||||
return $conn;
|
||||
}
|
||||
|
||||
function detectIssues(string $html): array {
|
||||
$issues = [];
|
||||
if (empty(trim($html))) return $issues;
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument('1.0', 'UTF-8');
|
||||
$wrapped = '<div id="temp-wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$validChildren = ['li', 'script', 'template'];
|
||||
|
||||
foreach (['ul', 'ol'] as $listTag) {
|
||||
foreach ($doc->getElementsByTagName($listTag) as $list) {
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$issues[] = [
|
||||
'list_type' => $listTag,
|
||||
'invalid_child' => $tagName
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
function fixMalformedLists(string $html): array {
|
||||
$result = ['fixed' => false, 'html' => $html, 'changes' => 0, 'details' => []];
|
||||
|
||||
if (empty(trim($html))) return $result;
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument('1.0', 'UTF-8');
|
||||
$wrapped = '<div id="temp-wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$lists = [];
|
||||
foreach ($doc->getElementsByTagName('ul') as $ul) { $lists[] = $ul; }
|
||||
foreach ($doc->getElementsByTagName('ol') as $ol) { $lists[] = $ol; }
|
||||
|
||||
$changes = 0;
|
||||
$validChildren = ['li', 'script', 'template'];
|
||||
|
||||
foreach ($lists as $list) {
|
||||
$nodesToProcess = [];
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$nodesToProcess[] = $child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($nodesToProcess as $node) {
|
||||
$tagName = strtolower($node->nodeName);
|
||||
$prevLi = null;
|
||||
$prev = $node->previousSibling;
|
||||
|
||||
while ($prev) {
|
||||
if ($prev->nodeType === XML_ELEMENT_NODE && strtolower($prev->nodeName) === 'li') {
|
||||
$prevLi = $prev;
|
||||
break;
|
||||
}
|
||||
$prev = $prev->previousSibling;
|
||||
}
|
||||
|
||||
if ($prevLi) {
|
||||
$prevLi->appendChild($node);
|
||||
$result['details'][] = "Movido <$tagName> dentro del <li> anterior";
|
||||
$changes++;
|
||||
} else {
|
||||
$newLi = $doc->createElement('li');
|
||||
$list->insertBefore($newLi, $node);
|
||||
$newLi->appendChild($node);
|
||||
$result['details'][] = "Envuelto <$tagName> en nuevo <li>";
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($changes > 0) {
|
||||
$wrapper = $doc->getElementById('temp-wrapper');
|
||||
if ($wrapper) {
|
||||
$innerHTML = '';
|
||||
foreach ($wrapper->childNodes as $child) {
|
||||
$innerHTML .= $doc->saveHTML($child);
|
||||
}
|
||||
$result['html'] = $innerHTML;
|
||||
$result['fixed'] = true;
|
||||
$result['changes'] = $changes;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// EJECUCIÓN PRINCIPAL
|
||||
$conn = connectDatabase($db_config);
|
||||
if (!$conn) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ Conexión establecida\n\n";
|
||||
|
||||
// Solo posts publicados con contenido
|
||||
$countQuery = "SELECT COUNT(*) as total FROM wp_posts
|
||||
WHERE post_status = 'publish'
|
||||
AND post_type IN ('post', 'page')
|
||||
AND post_content IS NOT NULL
|
||||
AND post_content != ''";
|
||||
$result = $conn->query($countQuery);
|
||||
$total = $result->fetch_assoc()['total'];
|
||||
echo "Total de posts/páginas publicados: $total\n\n";
|
||||
|
||||
if ($mode === 'scan') {
|
||||
echo "MODO: ESCANEO (solo detección)\n";
|
||||
echo "─────────────────────────────────\n\n";
|
||||
|
||||
$batch_size = 100;
|
||||
$offset = 0;
|
||||
$affected = 0;
|
||||
$total_issues = 0;
|
||||
|
||||
while ($offset < $total) {
|
||||
$query = "SELECT ID, post_title, post_content, guid FROM wp_posts
|
||||
WHERE post_status = 'publish'
|
||||
AND post_type IN ('post', 'page')
|
||||
AND post_content IS NOT NULL
|
||||
AND post_content != ''
|
||||
ORDER BY ID LIMIT $batch_size OFFSET $offset";
|
||||
$result = $conn->query($query);
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['post_content']);
|
||||
if (!empty($issues)) {
|
||||
$affected++;
|
||||
$total_issues += count($issues);
|
||||
|
||||
if ($affected <= 20) {
|
||||
echo "[ID: {$row['ID']}] " . count($issues) . " problema(s)\n";
|
||||
echo "Título: " . substr($row['post_title'], 0, 60) . "\n";
|
||||
foreach (array_slice($issues, 0, 2) as $issue) {
|
||||
echo " - <{$issue['list_type']}> contiene <{$issue['invalid_child']}>\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$offset += $batch_size;
|
||||
|
||||
if ($offset % 1000 == 0) {
|
||||
echo "Procesados: $offset/$total...\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "─────────────────────────────────\n";
|
||||
echo "RESUMEN:\n";
|
||||
echo " Posts afectados: $affected\n";
|
||||
echo " Total incidencias: $total_issues\n";
|
||||
|
||||
} elseif ($mode === 'test') {
|
||||
echo "MODO: PRUEBA (sin guardar)\n";
|
||||
echo "─────────────────────────────────\n\n";
|
||||
|
||||
$query = "SELECT ID, post_title, post_content FROM wp_posts
|
||||
WHERE post_status = 'publish'
|
||||
AND post_type IN ('post', 'page')
|
||||
AND post_content IS NOT NULL
|
||||
AND post_content != ''
|
||||
ORDER BY ID LIMIT 200";
|
||||
$result = $conn->query($query);
|
||||
|
||||
$tested = 0;
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['post_content']);
|
||||
if (!empty($issues) && $tested < 5) {
|
||||
$tested++;
|
||||
echo "POST ID: {$row['ID']}\n";
|
||||
echo "Título: {$row['post_title']}\n";
|
||||
echo "Problemas detectados: " . count($issues) . "\n\n";
|
||||
|
||||
$fixResult = fixMalformedLists($row['post_content']);
|
||||
$issuesAfter = detectIssues($fixResult['html']);
|
||||
|
||||
echo "ANTES: " . count($issues) . " problemas\n";
|
||||
echo "DESPUÉS: " . count($issuesAfter) . " problemas\n";
|
||||
echo "Cambios: {$fixResult['changes']}\n";
|
||||
|
||||
// Verificar integridad
|
||||
$before_ul = substr_count($row['post_content'], '<ul');
|
||||
$after_ul = substr_count($fixResult['html'], '<ul');
|
||||
$before_li = substr_count($row['post_content'], '<li');
|
||||
$after_li = substr_count($fixResult['html'], '<li');
|
||||
|
||||
echo "Tags <ul>: $before_ul → $after_ul " . ($before_ul === $after_ul ? "✓" : "⚠️") . "\n";
|
||||
echo "Tags <li>: $before_li → $after_li " . ($before_li === $after_li ? "✓" : "⚠️") . "\n";
|
||||
|
||||
if (count($issuesAfter) === 0) {
|
||||
echo "✅ CORRECCIÓN EXITOSA\n";
|
||||
} else {
|
||||
echo "⚠️ REQUIERE REVISIÓN\n";
|
||||
}
|
||||
echo "─────────────────────────────────\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($mode === 'fix') {
|
||||
echo "MODO: CORRECCIÓN (GUARDANDO CAMBIOS)\n";
|
||||
echo "─────────────────────────────────\n\n";
|
||||
|
||||
$batch_size = 50;
|
||||
$offset = 0;
|
||||
$fixed_count = 0;
|
||||
$error_count = 0;
|
||||
|
||||
while ($offset < $total) {
|
||||
$query = "SELECT ID, post_content FROM wp_posts
|
||||
WHERE post_status = 'publish'
|
||||
AND post_type IN ('post', 'page')
|
||||
AND post_content IS NOT NULL
|
||||
AND post_content != ''
|
||||
ORDER BY ID LIMIT $batch_size OFFSET $offset";
|
||||
$result = $conn->query($query);
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['post_content']);
|
||||
|
||||
if (!empty($issues)) {
|
||||
$fixResult = fixMalformedLists($row['post_content']);
|
||||
|
||||
if ($fixResult['fixed']) {
|
||||
$stmt = $conn->prepare("UPDATE wp_posts SET post_content = ? WHERE ID = ?");
|
||||
$stmt->bind_param("si", $fixResult['html'], $row['ID']);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$fixed_count++;
|
||||
echo "[ID: {$row['ID']}] ✓ Corregido ({$fixResult['changes']} cambios)\n";
|
||||
} else {
|
||||
$error_count++;
|
||||
echo "[ID: {$row['ID']}] ✗ Error al guardar\n";
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$offset += $batch_size;
|
||||
|
||||
if ($offset % 500 == 0) {
|
||||
echo "Procesados: $offset/$total (corregidos: $fixed_count)\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n─────────────────────────────────\n";
|
||||
echo "RESUMEN:\n";
|
||||
echo " Posts corregidos: $fixed_count\n";
|
||||
echo " Errores: $error_count\n";
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
echo "\n✓ Proceso completado.\n";
|
||||
@@ -1,307 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Script de Diagnóstico: Listas HTML Mal Formadas
|
||||
*
|
||||
* PROPÓSITO: Identificar posts con estructura de listas inválida
|
||||
* - <ul> conteniendo <ul> como hijo directo (en lugar de dentro de <li>)
|
||||
* - <ol> conteniendo <ol> como hijo directo
|
||||
*
|
||||
* BASE DE DATOS: preciosunitarios_seo
|
||||
* TABLA: datos_seo_pagina
|
||||
* CAMPO: html
|
||||
*
|
||||
* IMPORTANTE: Este script SOLO LEE, no modifica ningún dato.
|
||||
*
|
||||
* @package ROI_Theme
|
||||
* @since Phase 4.4 Accessibility
|
||||
*/
|
||||
|
||||
// Configuración de errores para debugging
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('memory_limit', '512M');
|
||||
set_time_limit(300); // 5 minutos máximo
|
||||
|
||||
// Credenciales de base de datos (ajustar según servidor)
|
||||
$db_config = [
|
||||
'host' => 'localhost',
|
||||
'database' => 'preciosunitarios_seo',
|
||||
'username' => 'root', // Cambiar en producción
|
||||
'password' => '', // Cambiar en producción
|
||||
'charset' => 'utf8mb4'
|
||||
];
|
||||
|
||||
// Patrones regex para detectar listas mal formadas
|
||||
$malformed_patterns = [
|
||||
// <ul> seguido directamente de <ul> (sin estar dentro de <li>)
|
||||
'ul_direct_ul' => '/<ul[^>]*>\s*(?:<li[^>]*>.*?<\/li>\s*)*<ul/is',
|
||||
|
||||
// Patrón más específico: </li> seguido de <ul> (hermanos en lugar de anidados)
|
||||
'li_sibling_ul' => '/<\/li>\s*<ul[^>]*>/is',
|
||||
|
||||
// <ol> seguido directamente de <ol>
|
||||
'ol_direct_ol' => '/<ol[^>]*>\s*(?:<li[^>]*>.*?<\/li>\s*)*<ol/is',
|
||||
|
||||
// </li> seguido de <ol> (hermanos)
|
||||
'li_sibling_ol' => '/<\/li>\s*<ol[^>]*>/is',
|
||||
];
|
||||
|
||||
/**
|
||||
* Conectar a la base de datos
|
||||
*/
|
||||
function connectDatabase(array $config): ?mysqli {
|
||||
$conn = new mysqli(
|
||||
$config['host'],
|
||||
$config['username'],
|
||||
$config['password'],
|
||||
$config['database']
|
||||
);
|
||||
|
||||
if ($conn->connect_error) {
|
||||
echo "Error de conexión: " . $conn->connect_error . "\n";
|
||||
return null;
|
||||
}
|
||||
|
||||
$conn->set_charset($config['charset']);
|
||||
return $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analizar HTML en busca de listas mal formadas
|
||||
*/
|
||||
function analyzeMalformedLists(string $html, array $patterns): array {
|
||||
$issues = [];
|
||||
|
||||
foreach ($patterns as $pattern_name => $pattern) {
|
||||
if (preg_match_all($pattern, $html, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($matches[0] as $match) {
|
||||
$position = $match[1];
|
||||
$context = getContextAroundPosition($html, $position, 100);
|
||||
|
||||
$issues[] = [
|
||||
'type' => $pattern_name,
|
||||
'position' => $position,
|
||||
'context' => $context
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener contexto alrededor de una posición
|
||||
*/
|
||||
function getContextAroundPosition(string $html, int $position, int $length = 100): string {
|
||||
$start = max(0, $position - $length);
|
||||
$end = min(strlen($html), $position + $length);
|
||||
|
||||
$context = substr($html, $start, $end - $start);
|
||||
|
||||
// Limpiar para mostrar
|
||||
$context = preg_replace('/\s+/', ' ', $context);
|
||||
$context = htmlspecialchars($context);
|
||||
|
||||
if ($start > 0) {
|
||||
$context = '...' . $context;
|
||||
}
|
||||
if ($end < strlen($html)) {
|
||||
$context .= '...';
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contar total de listas en el HTML
|
||||
*/
|
||||
function countListElements(string $html): array {
|
||||
$ul_count = preg_match_all('/<ul[^>]*>/i', $html);
|
||||
$ol_count = preg_match_all('/<ol[^>]*>/i', $html);
|
||||
$li_count = preg_match_all('/<li[^>]*>/i', $html);
|
||||
|
||||
return [
|
||||
'ul' => $ul_count,
|
||||
'ol' => $ol_count,
|
||||
'li' => $li_count
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// EJECUCIÓN PRINCIPAL
|
||||
// ============================================
|
||||
|
||||
echo "==============================================\n";
|
||||
echo " DIAGNÓSTICO: Listas HTML Mal Formadas\n";
|
||||
echo " Base de datos: {$db_config['database']}\n";
|
||||
echo " Tabla: datos_seo_pagina\n";
|
||||
echo " Fecha: " . date('Y-m-d H:i:s') . "\n";
|
||||
echo "==============================================\n\n";
|
||||
|
||||
// Conectar
|
||||
$conn = connectDatabase($db_config);
|
||||
if (!$conn) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ Conexión establecida\n\n";
|
||||
|
||||
// Obtener estructura de la tabla
|
||||
echo "Verificando estructura de tabla...\n";
|
||||
$result = $conn->query("DESCRIBE datos_seo_pagina");
|
||||
if ($result) {
|
||||
echo "Columnas encontradas:\n";
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
echo " - {$row['Field']} ({$row['Type']})\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
// Contar registros totales
|
||||
$result = $conn->query("SELECT COUNT(*) as total FROM datos_seo_pagina WHERE html IS NOT NULL AND html != ''");
|
||||
$total = $result->fetch_assoc()['total'];
|
||||
echo "Total de registros con HTML: {$total}\n\n";
|
||||
|
||||
// Procesar en lotes
|
||||
$batch_size = 100;
|
||||
$offset = 0;
|
||||
$affected_posts = [];
|
||||
$total_issues = 0;
|
||||
$processed = 0;
|
||||
|
||||
echo "Iniciando análisis...\n";
|
||||
echo "─────────────────────────────────────────────\n";
|
||||
|
||||
while ($offset < $total) {
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina
|
||||
WHERE html IS NOT NULL AND html != ''
|
||||
ORDER BY id
|
||||
LIMIT {$batch_size} OFFSET {$offset}";
|
||||
|
||||
$result = $conn->query($query);
|
||||
|
||||
if (!$result) {
|
||||
echo "Error en consulta: " . $conn->error . "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$processed++;
|
||||
$id = $row['id'];
|
||||
$url = $row['page'] ?? 'N/A';
|
||||
$html = $row['html'];
|
||||
|
||||
$issues = analyzeMalformedLists($html, $malformed_patterns);
|
||||
|
||||
if (!empty($issues)) {
|
||||
$list_counts = countListElements($html);
|
||||
|
||||
$affected_posts[] = [
|
||||
'id' => $id,
|
||||
'url' => $url,
|
||||
'issues' => $issues,
|
||||
'list_counts' => $list_counts
|
||||
];
|
||||
|
||||
$total_issues += count($issues);
|
||||
|
||||
// Mostrar progreso para posts afectados
|
||||
echo "\n[ID: {$id}] " . count($issues) . " problema(s) encontrado(s)\n";
|
||||
echo "URL: {$url}\n";
|
||||
echo "Listas: UL={$list_counts['ul']}, OL={$list_counts['ol']}, LI={$list_counts['li']}\n";
|
||||
|
||||
foreach ($issues as $idx => $issue) {
|
||||
echo " Problema " . ($idx + 1) . ": {$issue['type']} (pos: {$issue['position']})\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Mostrar progreso cada 500 registros
|
||||
if ($processed % 500 == 0) {
|
||||
echo "\rProcesados: {$processed}/{$total}...";
|
||||
}
|
||||
}
|
||||
|
||||
$offset += $batch_size;
|
||||
}
|
||||
|
||||
echo "\n\n";
|
||||
echo "==============================================\n";
|
||||
echo " RESUMEN DEL ANÁLISIS\n";
|
||||
echo "==============================================\n\n";
|
||||
|
||||
echo "Registros analizados: {$processed}\n";
|
||||
echo "Posts con problemas: " . count($affected_posts) . "\n";
|
||||
echo "Total de incidencias: {$total_issues}\n\n";
|
||||
|
||||
if (count($affected_posts) > 0) {
|
||||
echo "─────────────────────────────────────────────\n";
|
||||
echo "DETALLE DE POSTS AFECTADOS\n";
|
||||
echo "─────────────────────────────────────────────\n\n";
|
||||
|
||||
// Agrupar por tipo de problema
|
||||
$by_type = [];
|
||||
foreach ($affected_posts as $post) {
|
||||
foreach ($post['issues'] as $issue) {
|
||||
$type = $issue['type'];
|
||||
if (!isset($by_type[$type])) {
|
||||
$by_type[$type] = [];
|
||||
}
|
||||
$by_type[$type][] = $post['id'];
|
||||
}
|
||||
}
|
||||
|
||||
echo "Por tipo de problema:\n";
|
||||
foreach ($by_type as $type => $ids) {
|
||||
$unique_ids = array_unique($ids);
|
||||
echo " - {$type}: " . count($unique_ids) . " posts\n";
|
||||
}
|
||||
|
||||
echo "\n─────────────────────────────────────────────\n";
|
||||
echo "LISTA DE IDs AFECTADOS (para revisión manual)\n";
|
||||
echo "─────────────────────────────────────────────\n\n";
|
||||
|
||||
$ids_list = array_column($affected_posts, 'id');
|
||||
echo "IDs: " . implode(', ', $ids_list) . "\n";
|
||||
|
||||
// Generar archivo de reporte
|
||||
$report_file = __DIR__ . '/malformed-lists-report-' . date('Ymd-His') . '.json';
|
||||
$report_data = [
|
||||
'generated_at' => date('Y-m-d H:i:s'),
|
||||
'database' => $db_config['database'],
|
||||
'table' => 'datos_seo_pagina',
|
||||
'total_analyzed' => $processed,
|
||||
'total_affected' => count($affected_posts),
|
||||
'total_issues' => $total_issues,
|
||||
'by_type' => array_map(function($ids) {
|
||||
return array_values(array_unique($ids));
|
||||
}, $by_type),
|
||||
'affected_posts' => $affected_posts
|
||||
];
|
||||
|
||||
if (file_put_contents($report_file, json_encode($report_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE))) {
|
||||
echo "\n✓ Reporte JSON guardado en:\n {$report_file}\n";
|
||||
}
|
||||
|
||||
// Muestra de contexto para análisis
|
||||
echo "\n─────────────────────────────────────────────\n";
|
||||
echo "MUESTRA DE CONTEXTO (primeros 3 posts)\n";
|
||||
echo "─────────────────────────────────────────────\n\n";
|
||||
|
||||
$sample = array_slice($affected_posts, 0, 3);
|
||||
foreach ($sample as $post) {
|
||||
echo "POST ID: {$post['id']}\n";
|
||||
echo "URL: {$post['url']}\n";
|
||||
foreach ($post['issues'] as $idx => $issue) {
|
||||
echo " [{$issue['type']}]\n";
|
||||
echo " Contexto: {$issue['context']}\n\n";
|
||||
}
|
||||
echo "───────────────────────\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "✓ No se encontraron listas mal formadas.\n";
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
echo "\n✓ Análisis completado.\n";
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Script de PRUEBA - Muestra corrección propuesta sin aplicarla
|
||||
*
|
||||
* IMPORTANTE: Este script SOLO MUESTRA, no modifica nada.
|
||||
*/
|
||||
|
||||
$conn = new mysqli("localhost", "preciosunitarios_seo", "ACl%EEFd=V-Yvb??", "preciosunitarios_seo");
|
||||
$conn->set_charset("utf8mb4");
|
||||
|
||||
echo "========================================\n";
|
||||
echo "ANÁLISIS DE CORRECCIÓN PROPUESTA\n";
|
||||
echo "========================================\n\n";
|
||||
|
||||
// Patrón que encuentra: </li></ul><li>TEXTO</li><ul>
|
||||
// Este patrón captura:
|
||||
// - $1: </li> inicial (con espacios)
|
||||
// - $2: espacios entre </ul> y <li>
|
||||
// - $3: contenido del <li> (ej: <strong>Texto</strong>)
|
||||
// - $4: espacios entre </li> y <ul>
|
||||
|
||||
$pattern = '#(</li>\s*)</ul>(\s*)<li>(.*?)</li>(\s*)<ul>#is';
|
||||
$replacement = '$1<li>$3$4<ul>';
|
||||
|
||||
echo "PATRÓN A BUSCAR:\n";
|
||||
echo " </li>\\s*</ul>\\s*<li>CONTENIDO</li>\\s*<ul>\n\n";
|
||||
|
||||
echo "REEMPLAZO:\n";
|
||||
echo " </li><li>CONTENIDO<ul>\n\n";
|
||||
|
||||
// Obtener HTML del post ID 3
|
||||
$result = $conn->query("SELECT id, page, html FROM datos_seo_pagina WHERE id = 3");
|
||||
$row = $result->fetch_assoc();
|
||||
$html = $row["html"];
|
||||
$page = $row["page"];
|
||||
|
||||
echo "PROBANDO CON POST ID 3:\n";
|
||||
echo "URL: $page\n";
|
||||
echo "────────────────────────────\n\n";
|
||||
|
||||
// Encontrar todas las ocurrencias
|
||||
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||
|
||||
echo "Ocurrencias encontradas: " . count($matches) . "\n\n";
|
||||
|
||||
// Mostrar cada ocurrencia y su corrección propuesta
|
||||
foreach (array_slice($matches, 0, 3) as $idx => $match) {
|
||||
$full_match = $match[0][0];
|
||||
$position = $match[0][1];
|
||||
|
||||
echo "[$idx] Posición: $position\n";
|
||||
echo "ANTES:\n";
|
||||
echo htmlspecialchars($full_match) . "\n\n";
|
||||
|
||||
$fixed = preg_replace($pattern, $replacement, $full_match);
|
||||
echo "DESPUÉS:\n";
|
||||
echo htmlspecialchars($fixed) . "\n";
|
||||
echo "────────────────────────────\n\n";
|
||||
}
|
||||
|
||||
// Aplicar corrección en memoria y contar diferencia
|
||||
$html_fixed = preg_replace($pattern, $replacement, $html);
|
||||
|
||||
$before = preg_match_all($pattern, $html);
|
||||
$after = preg_match_all($pattern, $html_fixed);
|
||||
|
||||
echo "========================================\n";
|
||||
echo "RESUMEN DE CORRECCIÓN (sin aplicar):\n";
|
||||
echo "========================================\n";
|
||||
echo "Ocurrencias ANTES: $before\n";
|
||||
echo "Ocurrencias DESPUÉS: $after\n";
|
||||
echo "Reducción: " . ($before - $after) . "\n\n";
|
||||
|
||||
// Verificar que la estructura es válida después de la corrección
|
||||
$ul_count_before = substr_count($html, '<ul');
|
||||
$ul_count_after = substr_count($html_fixed, '<ul');
|
||||
echo "Tags <ul> antes: $ul_count_before\n";
|
||||
echo "Tags <ul> después: $ul_count_after\n";
|
||||
|
||||
$li_count_before = substr_count($html, '<li');
|
||||
$li_count_after = substr_count($html_fixed, '<li');
|
||||
echo "Tags <li> antes: $li_count_before\n";
|
||||
echo "Tags <li> después: $li_count_after\n";
|
||||
|
||||
echo "\n========================================\n";
|
||||
echo "NOTA: Este patrón elimina el </ul> prematuro\n";
|
||||
echo "pero NO agrega el </li> faltante al final.\n";
|
||||
echo "Se necesita un segundo paso para balancear.\n";
|
||||
echo "========================================\n";
|
||||
|
||||
$conn->close();
|
||||
@@ -1,187 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Prueba corrección en casos específicos variados
|
||||
*/
|
||||
|
||||
$conn = new mysqli("localhost", "preciosunitarios_seo", "ACl%EEFd=V-Yvb??", "preciosunitarios_seo");
|
||||
$conn->set_charset("utf8mb4");
|
||||
|
||||
// IDs a probar (casos variados)
|
||||
$test_ids = [20, 23, 65, 377, 98, 107, 144];
|
||||
|
||||
function detectIssues($html) {
|
||||
$issues = [];
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument("1.0", "UTF-8");
|
||||
$doc->loadHTML('<?xml encoding="UTF-8"><div id="w">' . $html . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$validChildren = ["li", "script", "template"];
|
||||
foreach (["ul", "ol"] as $tag) {
|
||||
foreach ($doc->getElementsByTagName($tag) as $list) {
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$childTag = strtolower($child->nodeName);
|
||||
if (!in_array($childTag, $validChildren)) {
|
||||
$issues[] = "<$tag> contiene <$childTag>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $issues;
|
||||
}
|
||||
|
||||
function fixMalformedLists($html) {
|
||||
$result = ['fixed' => false, 'html' => $html, 'changes' => 0];
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument("1.0", "UTF-8");
|
||||
$doc->loadHTML('<?xml encoding="UTF-8"><div id="w">' . $html . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$lists = [];
|
||||
foreach ($doc->getElementsByTagName('ul') as $ul) { $lists[] = $ul; }
|
||||
foreach ($doc->getElementsByTagName('ol') as $ol) { $lists[] = $ol; }
|
||||
|
||||
$changes = 0;
|
||||
$validChildren = ["li", "script", "template"];
|
||||
|
||||
foreach ($lists as $list) {
|
||||
$nodesToProcess = [];
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$nodesToProcess[] = $child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($nodesToProcess as $node) {
|
||||
$tagName = strtolower($node->nodeName);
|
||||
$prevLi = null;
|
||||
$prev = $node->previousSibling;
|
||||
|
||||
while ($prev) {
|
||||
if ($prev->nodeType === XML_ELEMENT_NODE && strtolower($prev->nodeName) === 'li') {
|
||||
$prevLi = $prev;
|
||||
break;
|
||||
}
|
||||
$prev = $prev->previousSibling;
|
||||
}
|
||||
|
||||
if ($prevLi) {
|
||||
$prevLi->appendChild($node);
|
||||
$changes++;
|
||||
} else {
|
||||
$newLi = $doc->createElement('li');
|
||||
$list->insertBefore($newLi, $node);
|
||||
$newLi->appendChild($node);
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($changes > 0) {
|
||||
$wrapper = $doc->getElementById('w');
|
||||
if ($wrapper) {
|
||||
$innerHTML = '';
|
||||
foreach ($wrapper->childNodes as $child) {
|
||||
$innerHTML .= $doc->saveHTML($child);
|
||||
}
|
||||
$result['html'] = $innerHTML;
|
||||
$result['fixed'] = true;
|
||||
$result['changes'] = $changes;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
echo "=====================================================\n";
|
||||
echo " PRUEBA DE CORRECCIÓN EN CASOS VARIADOS\n";
|
||||
echo "=====================================================\n\n";
|
||||
|
||||
$ids_str = implode(',', $test_ids);
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina WHERE id IN ($ids_str)";
|
||||
$result = $conn->query($query);
|
||||
|
||||
$all_passed = true;
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$id = $row['id'];
|
||||
$url = $row['page'];
|
||||
$html = $row['html'];
|
||||
|
||||
echo "─────────────────────────────────────────────────\n";
|
||||
echo "POST ID: $id\n";
|
||||
echo "URL: $url\n\n";
|
||||
|
||||
// Detectar problemas antes
|
||||
$issues_before = detectIssues($html);
|
||||
echo "ANTES:\n";
|
||||
echo " Problemas: " . count($issues_before) . "\n";
|
||||
$unique_types = array_unique($issues_before);
|
||||
foreach ($unique_types as $type) {
|
||||
echo " - $type\n";
|
||||
}
|
||||
|
||||
// Aplicar corrección
|
||||
$fixResult = fixMalformedLists($html);
|
||||
|
||||
// Detectar problemas después
|
||||
$issues_after = detectIssues($fixResult['html']);
|
||||
|
||||
echo "\nDESPUÉS:\n";
|
||||
echo " Cambios aplicados: {$fixResult['changes']}\n";
|
||||
echo " Problemas restantes: " . count($issues_after) . "\n";
|
||||
|
||||
if (count($issues_after) > 0) {
|
||||
echo " ⚠️ Problemas NO resueltos:\n";
|
||||
foreach (array_unique($issues_after) as $type) {
|
||||
echo " - $type\n";
|
||||
}
|
||||
$all_passed = false;
|
||||
}
|
||||
|
||||
// Verificar integridad del HTML
|
||||
$tags_before = [
|
||||
'ul' => substr_count($html, '<ul'),
|
||||
'ol' => substr_count($html, '<ol'),
|
||||
'li' => substr_count($html, '<li'),
|
||||
];
|
||||
$tags_after = [
|
||||
'ul' => substr_count($fixResult['html'], '<ul'),
|
||||
'ol' => substr_count($fixResult['html'], '<ol'),
|
||||
'li' => substr_count($fixResult['html'], '<li'),
|
||||
];
|
||||
|
||||
echo "\nINTEGRIDAD DE TAGS:\n";
|
||||
echo " <ul>: {$tags_before['ul']} → {$tags_after['ul']} ";
|
||||
echo ($tags_before['ul'] === $tags_after['ul'] ? "✓" : "⚠️ CAMBIÓ") . "\n";
|
||||
echo " <ol>: {$tags_before['ol']} → {$tags_after['ol']} ";
|
||||
echo ($tags_before['ol'] === $tags_after['ol'] ? "✓" : "⚠️ CAMBIÓ") . "\n";
|
||||
echo " <li>: {$tags_before['li']} → {$tags_after['li']} ";
|
||||
echo ($tags_before['li'] === $tags_after['li'] ? "✓" : "⚠️ CAMBIÓ") . "\n";
|
||||
|
||||
// Resultado
|
||||
if (count($issues_after) === 0 &&
|
||||
$tags_before['ul'] === $tags_after['ul'] &&
|
||||
$tags_before['ol'] === $tags_after['ol']) {
|
||||
echo "\n✅ RESULTADO: CORRECCIÓN EXITOSA\n";
|
||||
} else {
|
||||
echo "\n❌ RESULTADO: REQUIERE REVISIÓN\n";
|
||||
$all_passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n=====================================================\n";
|
||||
if ($all_passed) {
|
||||
echo "✅ TODOS LOS CASOS PASARON LA PRUEBA\n";
|
||||
} else {
|
||||
echo "⚠️ ALGUNOS CASOS REQUIEREN REVISIÓN\n";
|
||||
}
|
||||
echo "=====================================================\n";
|
||||
|
||||
$conn->close();
|
||||
@@ -1,347 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Validador de Correcciones - Genera archivos HTML para revisión visual
|
||||
*
|
||||
* PROPÓSITO: Crear archivos comparativos ANTES/DESPUÉS para validar
|
||||
* que la corrección no rompe el contenido.
|
||||
*
|
||||
* USO: php validate-fix-lists.php
|
||||
*
|
||||
* GENERA:
|
||||
* /tmp/list-fix-validation/
|
||||
* ├── post_ID_before.html
|
||||
* ├── post_ID_after.html
|
||||
* └── comparison_report.html
|
||||
*
|
||||
* @package ROI_Theme
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('memory_limit', '256M');
|
||||
|
||||
$db_config = [
|
||||
'host' => 'localhost',
|
||||
'database' => 'preciosunitarios_seo',
|
||||
'username' => 'preciosunitarios_seo',
|
||||
'password' => 'ACl%EEFd=V-Yvb??',
|
||||
'charset' => 'utf8mb4'
|
||||
];
|
||||
|
||||
$output_dir = '/tmp/list-fix-validation';
|
||||
$sample_size = 5;
|
||||
|
||||
echo "==============================================\n";
|
||||
echo " VALIDADOR DE CORRECCIONES\n";
|
||||
echo " Fecha: " . date('Y-m-d H:i:s') . "\n";
|
||||
echo "==============================================\n\n";
|
||||
|
||||
// Crear directorio de salida
|
||||
if (!is_dir($output_dir)) {
|
||||
mkdir($output_dir, 0755, true);
|
||||
}
|
||||
|
||||
// Limpiar archivos anteriores
|
||||
array_map('unlink', glob("$output_dir/*.html"));
|
||||
|
||||
/**
|
||||
* Detectar problemas en HTML
|
||||
*/
|
||||
function detectIssues(string $html): array {
|
||||
$issues = [];
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
$doc = new DOMDocument('1.0', 'UTF-8');
|
||||
$wrapped = '<div id="temp-wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$validChildren = ['li', 'script', 'template'];
|
||||
|
||||
foreach (['ul', 'ol'] as $listTag) {
|
||||
foreach ($doc->getElementsByTagName($listTag) as $list) {
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$issues[] = "<$listTag> contiene <$tagName>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Corregir listas mal formadas
|
||||
*/
|
||||
function fixMalformedLists(string $html): array {
|
||||
$result = ['fixed' => false, 'html' => $html, 'changes' => 0, 'details' => []];
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
$doc = new DOMDocument('1.0', 'UTF-8');
|
||||
$wrapped = '<div id="temp-wrapper">' . $html . '</div>';
|
||||
$doc->loadHTML('<?xml encoding="UTF-8">' . $wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
libxml_clear_errors();
|
||||
|
||||
$lists = [];
|
||||
foreach ($doc->getElementsByTagName('ul') as $ul) { $lists[] = $ul; }
|
||||
foreach ($doc->getElementsByTagName('ol') as $ol) { $lists[] = $ol; }
|
||||
|
||||
$changes = 0;
|
||||
$validChildren = ['li', 'script', 'template'];
|
||||
|
||||
foreach ($lists as $list) {
|
||||
$nodesToProcess = [];
|
||||
foreach ($list->childNodes as $child) {
|
||||
if ($child->nodeType === XML_ELEMENT_NODE) {
|
||||
$tagName = strtolower($child->nodeName);
|
||||
if (!in_array($tagName, $validChildren)) {
|
||||
$nodesToProcess[] = $child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($nodesToProcess as $node) {
|
||||
$tagName = strtolower($node->nodeName);
|
||||
$prevLi = null;
|
||||
$prev = $node->previousSibling;
|
||||
|
||||
while ($prev) {
|
||||
if ($prev->nodeType === XML_ELEMENT_NODE && strtolower($prev->nodeName) === 'li') {
|
||||
$prevLi = $prev;
|
||||
break;
|
||||
}
|
||||
$prev = $prev->previousSibling;
|
||||
}
|
||||
|
||||
if ($prevLi) {
|
||||
$prevLi->appendChild($node);
|
||||
$result['details'][] = "Movido <$tagName> dentro del <li> anterior";
|
||||
$changes++;
|
||||
} else {
|
||||
$newLi = $doc->createElement('li');
|
||||
$list->insertBefore($newLi, $node);
|
||||
$newLi->appendChild($node);
|
||||
$result['details'][] = "Envuelto <$tagName> en nuevo <li>";
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($changes > 0) {
|
||||
$wrapper = $doc->getElementById('temp-wrapper');
|
||||
if ($wrapper) {
|
||||
$innerHTML = '';
|
||||
foreach ($wrapper->childNodes as $child) {
|
||||
$innerHTML .= $doc->saveHTML($child);
|
||||
}
|
||||
$result['html'] = $innerHTML;
|
||||
$result['fixed'] = true;
|
||||
$result['changes'] = $changes;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar HTML wrapper para visualización
|
||||
*/
|
||||
function wrapForVisualization(string $content, string $title, string $status): string {
|
||||
$statusColor = $status === 'error' ? '#dc3545' : '#28a745';
|
||||
return <<<HTML
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>$title</title>
|
||||
<style>
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 20px; line-height: 1.6; }
|
||||
.status { padding: 10px 20px; background: $statusColor; color: white; border-radius: 4px; margin-bottom: 20px; }
|
||||
.content { border: 1px solid #ddd; padding: 20px; border-radius: 4px; background: #fafafa; }
|
||||
ul, ol { background: #fff3cd; padding: 15px 15px 15px 35px; border-left: 4px solid #ffc107; margin: 10px 0; }
|
||||
li { background: #d4edda; padding: 5px 10px; margin: 5px 0; border-left: 3px solid #28a745; }
|
||||
h1, h2, h3, h4, h5, h6 { color: #333; }
|
||||
p { color: #555; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="status">$status</div>
|
||||
<div class="content">
|
||||
$content
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
}
|
||||
|
||||
// Conectar a DB
|
||||
$conn = new mysqli($db_config['host'], $db_config['username'], $db_config['password'], $db_config['database']);
|
||||
$conn->set_charset($db_config['charset']);
|
||||
|
||||
if ($conn->connect_error) {
|
||||
die("Error de conexión: " . $conn->connect_error);
|
||||
}
|
||||
|
||||
echo "✓ Conexión establecida\n\n";
|
||||
|
||||
// Buscar posts con problemas
|
||||
$query = "SELECT id, page, html FROM datos_seo_pagina WHERE html IS NOT NULL AND html != '' ORDER BY id LIMIT 500";
|
||||
$result = $conn->query($query);
|
||||
|
||||
$samples = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$issues = detectIssues($row['html']);
|
||||
if (!empty($issues) && count($samples) < $sample_size) {
|
||||
$samples[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Encontrados " . count($samples) . " posts con problemas para validar\n\n";
|
||||
|
||||
$comparison_data = [];
|
||||
|
||||
foreach ($samples as $idx => $post) {
|
||||
$id = $post['id'];
|
||||
$url = $post['page'];
|
||||
$html_before = $post['html'];
|
||||
|
||||
echo "─────────────────────────────────\n";
|
||||
echo "POST $id: $url\n";
|
||||
|
||||
// Detectar problemas antes
|
||||
$issues_before = detectIssues($html_before);
|
||||
echo " Problemas ANTES: " . count($issues_before) . "\n";
|
||||
|
||||
// Aplicar corrección
|
||||
$fixResult = fixMalformedLists($html_before);
|
||||
$html_after = $fixResult['html'];
|
||||
|
||||
// Detectar problemas después
|
||||
$issues_after = detectIssues($html_after);
|
||||
echo " Problemas DESPUÉS: " . count($issues_after) . "\n";
|
||||
echo " Cambios aplicados: " . $fixResult['changes'] . "\n";
|
||||
|
||||
// Guardar archivos HTML
|
||||
$file_before = "$output_dir/post_{$id}_BEFORE.html";
|
||||
$file_after = "$output_dir/post_{$id}_AFTER.html";
|
||||
|
||||
file_put_contents($file_before, wrapForVisualization(
|
||||
$html_before,
|
||||
"Post $id - ANTES (con errores)",
|
||||
"ANTES: " . count($issues_before) . " problemas de listas"
|
||||
));
|
||||
|
||||
file_put_contents($file_after, wrapForVisualization(
|
||||
$html_after,
|
||||
"Post $id - DESPUÉS (corregido)",
|
||||
"DESPUÉS: " . count($issues_after) . " problemas - " . $fixResult['changes'] . " correcciones aplicadas"
|
||||
));
|
||||
|
||||
echo " ✓ Archivos generados:\n";
|
||||
echo " - $file_before\n";
|
||||
echo " - $file_after\n";
|
||||
|
||||
// Guardar datos para reporte
|
||||
$comparison_data[] = [
|
||||
'id' => $id,
|
||||
'url' => $url,
|
||||
'issues_before' => count($issues_before),
|
||||
'issues_after' => count($issues_after),
|
||||
'changes' => $fixResult['changes'],
|
||||
'file_before' => "post_{$id}_BEFORE.html",
|
||||
'file_after' => "post_{$id}_AFTER.html"
|
||||
];
|
||||
}
|
||||
|
||||
// Generar reporte comparativo
|
||||
$report_html = <<<HTML
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Reporte de Validación - Corrección de Listas</title>
|
||||
<style>
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 20px; }
|
||||
h1 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }
|
||||
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
|
||||
th, td { padding: 12px; text-align: left; border: 1px solid #ddd; }
|
||||
th { background: #007bff; color: white; }
|
||||
tr:nth-child(even) { background: #f8f9fa; }
|
||||
.success { color: #28a745; font-weight: bold; }
|
||||
.warning { color: #ffc107; font-weight: bold; }
|
||||
.error { color: #dc3545; font-weight: bold; }
|
||||
a { color: #007bff; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
.instructions { background: #e7f3ff; padding: 15px; border-radius: 4px; margin: 20px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Reporte de Validación - Corrección de Listas HTML</h1>
|
||||
|
||||
<div class="instructions">
|
||||
<strong>Instrucciones:</strong>
|
||||
<ol>
|
||||
<li>Abre cada par de archivos (ANTES/DESPUÉS) en el navegador</li>
|
||||
<li>Verifica que el contenido se muestre correctamente</li>
|
||||
<li>Las listas (fondo amarillo) deben contener solo items (fondo verde)</li>
|
||||
<li>Si todo se ve bien, la corrección es segura</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>URL</th>
|
||||
<th>Problemas Antes</th>
|
||||
<th>Problemas Después</th>
|
||||
<th>Cambios</th>
|
||||
<th>Archivos</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
HTML;
|
||||
|
||||
foreach ($comparison_data as $data) {
|
||||
$status_class = $data['issues_after'] == 0 ? 'success' : ($data['issues_after'] < $data['issues_before'] ? 'warning' : 'error');
|
||||
|
||||
$report_html .= <<<HTML
|
||||
<tr>
|
||||
<td>{$data['id']}</td>
|
||||
<td><a href="{$data['url']}" target="_blank">{$data['url']}</a></td>
|
||||
<td class="error">{$data['issues_before']}</td>
|
||||
<td class="$status_class">{$data['issues_after']}</td>
|
||||
<td>{$data['changes']}</td>
|
||||
<td>
|
||||
<a href="{$data['file_before']}" target="_blank">ANTES</a> |
|
||||
<a href="{$data['file_after']}" target="_blank">DESPUÉS</a>
|
||||
</td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
|
||||
$report_html .= <<<HTML
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><strong>Generado:</strong> {$_SERVER['REQUEST_TIME_FLOAT']}</p>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
||||
$report_file = "$output_dir/comparison_report.html";
|
||||
file_put_contents($report_file, $report_html);
|
||||
|
||||
echo "\n─────────────────────────────────\n";
|
||||
echo "REPORTE GENERADO:\n";
|
||||
echo " $report_file\n\n";
|
||||
echo "Para revisar, descarga el directorio:\n";
|
||||
echo " scp -r VPSContabo:$output_dir ./validation/\n\n";
|
||||
|
||||
$conn->close();
|
||||
echo "✓ Validación completada.\n";
|
||||
Reference in New Issue
Block a user