diff --git a/Admin/.gitkeep b/Admin/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Admin/CustomCSSManager/Domain/ValueObjects/SnippetId.php b/Admin/CustomCSSManager/Domain/ValueObjects/SnippetId.php index 7f0f91a1..615d0e49 100644 --- a/Admin/CustomCSSManager/Domain/ValueObjects/SnippetId.php +++ b/Admin/CustomCSSManager/Domain/ValueObjects/SnippetId.php @@ -8,9 +8,10 @@ use ROITheme\Shared\Domain\Exceptions\ValidationException; /** * Value Object para ID único de snippet CSS * - * Soporta dos formatos: + * Soporta tres formatos: * 1. Generado: css_[timestamp]_[random] (ej: "css_1701432000_a1b2c3") - * 2. Legacy/Migración: kebab-case (ej: "cls-tables-apu", "generic-tables") + * 2. Legacy con prefijo: css_[descriptive]_[number] (ej: "css_tablas_apu_1764624826") + * 3. Legacy kebab-case: (ej: "cls-tables-apu", "generic-tables") * * Esto permite migrar snippets existentes sin romper IDs. */ @@ -18,6 +19,7 @@ final class SnippetId { private const PREFIX = 'css_'; private const PATTERN_GENERATED = '/^css_[0-9]+_[a-z0-9]{6}$/'; + private const PATTERN_LEGACY_PREFIX = '/^css_[a-z0-9_]+$/'; private const PATTERN_LEGACY = '/^[a-z0-9]+(-[a-z0-9]+)*$/'; private function __construct( @@ -47,7 +49,8 @@ final class SnippetId // Validar formato generado (css_*) if (str_starts_with($id, self::PREFIX)) { - if (!preg_match(self::PATTERN_GENERATED, $id)) { + // Acepta formato nuevo (css_timestamp_random) o legacy (css_descriptivo_numero) + if (!preg_match(self::PATTERN_GENERATED, $id) && !preg_match(self::PATTERN_LEGACY_PREFIX, $id)) { throw new ValidationException( sprintf('Formato de ID generado inválido: %s. Esperado: css_[timestamp]_[random]', $id) ); diff --git a/Assets/Css/css-global-generic-tables.css b/Assets/Css/css-global-generic-tables.css index b20888c6..7606226a 100644 --- a/Assets/Css/css-global-generic-tables.css +++ b/Assets/Css/css-global-generic-tables.css @@ -12,7 +12,7 @@ BASE STYLES - Todas las tablas genéricas ======================================== */ -.post-content table:not(.analisis table) { +.post-content table:not(.analisis table):not(.desglose table) { width: 100%; border-collapse: collapse; margin: 2rem auto; @@ -23,9 +23,9 @@ } /* Header styles - VERY OBVIOUS */ -.post-content table:not(.analisis table) thead tr:first-child th, -.post-content table:not(.analisis table) tbody tr:first-child td, -.post-content table:not(.analisis table) tr:first-child td { +.post-content table:not(.analisis table):not(.desglose table) thead tr:first-child th, +.post-content table:not(.analisis table):not(.desglose table) tbody tr:first-child td, +.post-content table:not(.analisis table):not(.desglose table) tr:first-child td { font-weight: 700; text-align: center; padding: 1.25rem 1rem; @@ -34,7 +34,7 @@ } /* Body cells */ -.post-content table:not(.analisis table) tbody tr:not(:first-child) td { +.post-content table:not(.analisis table):not(.desglose table) tbody tr:not(:first-child) td { padding: 0.875rem 1rem; border: 1px solid var(--color-neutral-100); text-align: left; diff --git a/Public/.gitkeep b/Public/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Schemas/.gitkeep b/Schemas/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Shared/Application/.gitkeep b/Shared/Application/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/Shared/Application/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Shared/Application/UseCases/.gitkeep b/Shared/Application/UseCases/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/Shared/Application/UseCases/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Shared/Domain/Contracts/.gitkeep b/Shared/Domain/Contracts/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Shared/Domain/Exceptions/.gitkeep b/Shared/Domain/Exceptions/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Shared/Domain/ValueObjects/.gitkeep b/Shared/Domain/ValueObjects/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Shared/Infrastructure/Api/WordPress/.gitkeep b/Shared/Infrastructure/Api/WordPress/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Shared/Infrastructure/Persistence/WordPress/.gitkeep b/Shared/Infrastructure/Persistence/WordPress/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Shared/Infrastructure/Scripts/find-varied-cases.php b/Shared/Infrastructure/Scripts/find-varied-cases.php deleted file mode 100644 index 75bd0e46..00000000 --- a/Shared/Infrastructure/Scripts/find-varied-cases.php +++ /dev/null @@ -1,94 +0,0 @@ -set_charset("utf8mb4"); - -function detectIssues($html) { - $issues = []; - libxml_use_internal_errors(true); - $doc = new DOMDocument("1.0", "UTF-8"); - $wrapped = '
' . $html . '
'; - $doc->loadHTML('' . $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(); diff --git a/Shared/Infrastructure/Scripts/fix-malformed-lists-dom.php b/Shared/Infrastructure/Scripts/fix-malformed-lists-dom.php deleted file mode 100644 index f13caf0e..00000000 --- a/Shared/Infrastructure/Scripts/fix-malformed-lists-dom.php +++ /dev/null @@ -1,411 +0,0 @@ -/
    conteniendo elementos no-
  1. como hijos directos - * - Listas anidadas que son hermanas en lugar de hijas de
  2. - * - * 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 = '
    ' . $html . '
    '; - $doc->loadHTML('' . $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
  3. - if ($tagName === 'ul' || $tagName === 'ol') { - $changes += wrapInLi($list, $node, $details); - } - // Otros elementos inválidos también se envuelven en
  4. - else { - $changes += wrapInLi($list, $node, $details); - } - } - - return $changes; -} - -/** - * Envolver un nodo en
  5. o moverlo al
  6. anterior - */ -function wrapInLi(DOMElement $list, DOMNode $node, array &$details): int { - $doc = $list->ownerDocument; - $tagName = strtolower($node->nodeName); - - // Buscar el
  7. 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
  8. anterior - $prevLi->appendChild($node); - $details[] = "Movido <$tagName> dentro del
  9. anterior"; - return 1; - } else { - // No hay
  10. anterior, crear uno nuevo - $newLi = $doc->createElement('li'); - $list->insertBefore($newLi, $node); - $newLi->appendChild($node); - $details[] = "Envuelto <$tagName> en nuevo
  11. "; - 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 = '
    ' . $html . '
    '; - $doc->loadHTML('' . $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"; diff --git a/Shared/Infrastructure/Scripts/fix-malformed-lists-wp-posts.php b/Shared/Infrastructure/Scripts/fix-malformed-lists-wp-posts.php deleted file mode 100644 index ce4fdbd1..00000000 --- a/Shared/Infrastructure/Scripts/fix-malformed-lists-wp-posts.php +++ /dev/null @@ -1,322 +0,0 @@ - '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 = '
    ' . $html . '
    '; - $doc->loadHTML('' . $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 = '
    ' . $html . '
    '; - $doc->loadHTML('' . $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
  12. anterior"; - $changes++; - } else { - $newLi = $doc->createElement('li'); - $list->insertBefore($newLi, $node); - $newLi->appendChild($node); - $result['details'][] = "Envuelto <$tagName> en nuevo
  13. "; - $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'], ': $before_ul → $after_ul " . ($before_ul === $after_ul ? "✓" : "⚠️") . "\n"; - echo "Tags
  14. : $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"; diff --git a/Shared/Infrastructure/Scripts/scan-malformed-lists.php b/Shared/Infrastructure/Scripts/scan-malformed-lists.php deleted file mode 100644 index 4db28161..00000000 --- a/Shared/Infrastructure/Scripts/scan-malformed-lists.php +++ /dev/null @@ -1,307 +0,0 @@ - conteniendo