> */ public static function operations(): array { $rows = Settings::get( 'ops', array() ); $out = array(); if ( is_array( $rows ) ) { foreach ( $rows as $row ) { if ( ! is_array( $row ) ) { continue; } $finalidad = trim( (string) ( $row['finalidad'] ?? '' ) ); if ( '' === $finalidad ) { continue; } $out[] = array( 'name' => trim( (string) ( $row['name'] ?? $finalidad ) ), 'finalidad' => $finalidad, 'datos' => trim( (string) ( $row['datos'] ?? '' ) ), 'titulares' => trim( (string) ( $row['titulares'] ?? '' ) ), 'base' => trim( (string) ( $row['base'] ?? '' ) ), 'destinos' => trim( (string) ( $row['destinos'] ?? '' ) ), 'transfiere' => ! empty( $row['transfiere'] ) ? 'si' : 'no', 'pais' => trim( (string) ( $row['pais'] ?? '' ) ), 'plazo' => trim( (string) ( $row['plazo'] ?? '' ) ), 'fuente' => trim( (string) ( $row['fuente'] ?? '' ) ), 'perfilado' => ! empty( $row['perfilado'] ) ? 'si' : 'no', 'sensibles' => ! empty( $row['sensibles'] ) ? 'si' : 'no', ); } } if ( ! $out ) { $out = self::suggested(); } return $out; } /** * Registro sugerido a partir de la propia configuración del sitio (punto de * partida editable; nunca se publica sin que el administrador lo revise). * * @return array> */ public static function suggested(): array { $out = array(); $months = max( 1, (int) Settings::get( 'log_retention_months', 24 ) ); $out[] = array( 'name' => __( 'Aviso y consentimiento de privacidad del sitio web', 'cumpleconsent' ), 'finalidad' => __( 'Informar y recoger el consentimiento sobre cookies, tecnologías similares y finalidades del sitio; conservar la prueba de la decisión', 'cumpleconsent' ), 'datos' => __( 'Identificador seudónimo del visitante, decisión por finalidad, fecha y hora, hash de IP (opcional), versión y huella del aviso informado', 'cumpleconsent' ), 'titulares' => __( 'Visitantes del sitio web', 'cumpleconsent' ), 'base' => __( 'Consentimiento (art. 12) y cumplimiento de deberes legales (art. 13 b)', 'cumpleconsent' ), 'destinos' => __( 'Proveedor de hosting y de caché/CDN', 'cumpleconsent' ), 'transfiere' => 'si', 'pais' => '', 'plazo' => sprintf( /* translators: %d: meses */ __( '%d meses desde la decisión; luego se elimina automáticamente', 'cumpleconsent' ), $months ), 'fuente' => __( 'Del propio titular, al navegar el sitio', 'cumpleconsent' ), 'perfilado' => 'no', 'sensibles' => 'no', ); foreach ( Purposes::active() as $key => $purpose ) { if ( ! empty( $purpose['required'] ) ) { continue; } $out[] = array( 'name' => sprintf( /* translators: %s: finalidad */ __( 'Cookies y tecnologías con finalidad de %s', 'cumpleconsent' ), Purposes::lower( (string) $purpose['label'] ) ), 'finalidad' => (string) $purpose['desc'], 'datos' => __( 'Identificadores en línea, dirección IP, páginas visitadas, datos de dispositivo', 'cumpleconsent' ), 'titulares' => __( 'Visitantes del sitio web', 'cumpleconsent' ), 'base' => 'necesarias' === $key ? __( 'Ejecución del servicio solicitado (art. 13 c)', 'cumpleconsent' ) : __( 'Consentimiento (art. 12)', 'cumpleconsent' ), 'destinos' => __( 'Proveedores del servicio correspondiente', 'cumpleconsent' ), 'transfiere' => in_array( $key, array( 'analiticas', 'publicidad', 'embeds' ), true ) ? 'si' : 'no', 'pais' => '', 'plazo' => __( 'Según la vigencia de la cookie y el plazo informado en la política', 'cumpleconsent' ), 'fuente' => __( 'Del propio titular, al navegar el sitio', 'cumpleconsent' ), 'perfilado' => 'publicidad' === $key ? 'si' : 'no', 'sensibles' => 'no', ); } $diag = Settings::get( 'diag_data', array() ); if ( is_array( $diag ) && ! empty( $diag['forms'] ) ) { $out[] = array( 'name' => __( 'Formularios de contacto y solicitudes del sitio', 'cumpleconsent' ), 'finalidad' => __( 'Atender consultas y solicitudes enviadas por los formularios del sitio', 'cumpleconsent' ), 'datos' => __( 'Nombre, correo electrónico, teléfono y contenido del mensaje', 'cumpleconsent' ), 'titulares' => __( 'Personas que envían un formulario', 'cumpleconsent' ), 'base' => __( 'Consentimiento (art. 12) o ejecución de medidas precontractuales (art. 13 c)', 'cumpleconsent' ), 'destinos' => __( 'Proveedor de correo y de hosting', 'cumpleconsent' ), 'transfiere' => 'si', 'pais' => '', 'plazo' => sprintf( /* translators: %d: meses */ __( '%d meses desde la última interacción', 'cumpleconsent' ), $months ), 'fuente' => __( 'Del propio titular, en el formulario', 'cumpleconsent' ), 'perfilado' => 'no', 'sensibles' => 'no', ); } return $out; } /** * Saneamiento de las filas del formulario de administración. * * @param mixed $rows Filas crudas. * @return array> */ public static function sanitize_rows( $rows ): array { $out = array(); if ( ! is_array( $rows ) ) { return $out; } $text = array( 'name', 'finalidad', 'datos', 'titulares', 'base', 'destinos', 'pais', 'plazo', 'fuente' ); foreach ( $rows as $row ) { if ( ! is_array( $row ) ) { continue; } $clean = array(); foreach ( $text as $key ) { $clean[ $key ] = substr( sanitize_text_field( (string) ( $row[ $key ] ?? '' ) ), 0, 300 ); } if ( '' === $clean['finalidad'] && '' === $clean['name'] ) { continue; } $clean['transfiere'] = ! empty( $row['transfiere'] ) ? 'si' : 'no'; $clean['perfilado'] = ! empty( $row['perfilado'] ) ? 'si' : 'no'; $clean['sensibles'] = ! empty( $row['sensibles'] ) ? 'si' : 'no'; $out[] = $clean; } return $out; } /** * Registro de actividades de tratamiento (art. 3 d), contenidos i a xi). * * @return string HTML. */ public static function register_html(): string { $s = Settings::all(); $ops = self::operations(); $transfers = Transfers::rows(); $territorio = __( 'Chile (el sitio web es accesible desde cualquier país; los datos de los formularios se reciben en Chile).', 'cumpleconsent' ); $h = array(); $h[] = '

' . esc_html__( 'Registro de actividades de tratamiento (sitio web)', 'cumpleconsent' ) . '

'; $h[] = '

' . sprintf( /* translators: 1: fecha, 2: versión */ esc_html__( 'Generado el %1$s con CumpleConsent. Versión del aviso: %2$s.', 'cumpleconsent' ), esc_html( date_i18n( 'j \d\e F \d\e Y' ) ), esc_html( Policy::version() ) ) . '

'; // a) Individualización del responsable. $h[] = '

' . esc_html__( '1. Responsable y representante legal (art. 3 a) del reglamento)', 'cumpleconsent' ) . '

'; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = '
' . esc_html__( 'Responsable', 'cumpleconsent' ) . '' . esc_html( (string) $s['owner_name'] ) . '
' . esc_html__( 'RUT', 'cumpleconsent' ) . '' . esc_html( (string) $s['owner_legal_id'] ) . '
' . esc_html__( 'Representante legal', 'cumpleconsent' ) . '' . esc_html( (string) $s['owner_rep'] . ( $s['owner_rep_id'] ? ' — ' . (string) $s['owner_rep_id'] : '' ) ) . '
' . esc_html__( 'Encargado de prevención / delegado', 'cumpleconsent' ) . '' . esc_html( (string) $s['dpo_name'] . ( $s['dpo_email'] ? ' — ' . (string) $s['dpo_email'] : '' ) ) . '
' . esc_html__( 'Contacto para titulares', 'cumpleconsent' ) . '' . esc_html( Rights::channel_email() ) . '
' . esc_html__( 'Domicilio', 'cumpleconsent' ) . '' . esc_html( (string) $s['owner_address'] ) . '
'; // d) Caracterización de operaciones. $h[] = '

' . esc_html__( '2. Caracterización de las operaciones de tratamiento (art. 3 d))', 'cumpleconsent' ) . '

'; $h[] = '

' . esc_html( sprintf( /* translators: %s: ámbito territorial */ __( 'Ámbito territorial (ii): %s', 'cumpleconsent' ), $territorio ) ) . '

'; foreach ( $ops as $index => $op ) { $h[] = '

' . esc_html( sprintf( '%d. %s', $index + 1, $op['name'] ? $op['name'] : $op['finalidad'] ) ) . '

'; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = '
' . esc_html__( 'v. Fines del tratamiento', 'cumpleconsent' ) . '' . esc_html( $op['finalidad'] ) . '
' . esc_html__( 'i. Tipo de datos (¿incluye sensibles o categorías especiales?)', 'cumpleconsent' ) . '' . esc_html( $op['datos'] ) . ' — ' . esc_html( 'si' === $op['sensibles'] ? __( 'Incluye datos sensibles.', 'cumpleconsent' ) : __( 'No incluye datos sensibles.', 'cumpleconsent' ) ) . '
' . esc_html__( 'iii. Categorías de bases de datos', 'cumpleconsent' ) . '' . esc_html__( 'Base de datos del sitio web (almacenamiento local del sitio)', 'cumpleconsent' ) . '
' . esc_html__( 'iv. Categorías de titulares', 'cumpleconsent' ) . '' . esc_html( $op['titulares'] ) . '
' . esc_html__( 'vi. Fuente de los datos', 'cumpleconsent' ) . '' . esc_html( $op['fuente'] ) . '
' . esc_html__( 'vii. Base de licitud', 'cumpleconsent' ) . '' . esc_html( $op['base'] ) . '
' . esc_html__( 'viii. Categorías de terceros destinatarios', 'cumpleconsent' ) . '' . esc_html( $op['destinos'] ) . '
' . esc_html__( 'ix. Transferencia internacional', 'cumpleconsent' ) . '' . esc_html( 'si' === $op['transfiere'] ? __( 'Sí', 'cumpleconsent' ) . ( '' !== $op['pais'] ? ' — ' . $op['pais'] : '' ) : __( 'No', 'cumpleconsent' ) ) . '
' . esc_html__( 'x. Plazo de supresión', 'cumpleconsent' ) . '' . esc_html( $op['plazo'] ) . '
' . esc_html__( 'xi. Decisiones automatizadas o elaboración de perfiles', 'cumpleconsent' ) . '' . esc_html( 'si' === $op['perfilado'] ? __( 'Sí — describir la lógica y las consecuencias en la política (art. 14 ter l).', 'cumpleconsent' ) : __( 'No.', 'cumpleconsent' ) ) . '
'; } if ( $transfers ) { $h[] = '

' . esc_html__( '3. Transferencias internacionales declaradas (art. 27 de la ley)', 'cumpleconsent' ) . '

'; $h[] = Transfers::shortcode( array() ); } return implode( '', $h ); } /** * Matriz de riesgos (art. 3 e) del reglamento), graduada según la ley. * * La probabilidad y el impacto se estiman con señales observables del sitio * (datos sensibles, transferencias, perfilado, volumen de finalidades). El * nivel no es una medición estadística: es una priorización de trabajo. * * @return array> */ public static function risk_matrix(): array { $rows = array(); foreach ( self::operations() as $op ) { $prob = 2; $imp = 2; $nota = array(); if ( 'si' === $op['sensibles'] ) { $imp += 2; $nota[] = __( 'trata datos sensibles (art. 2 g y 16)', 'cumpleconsent' ); } if ( 'si' === $op['transfiere'] ) { $prob += 1; $imp += 1; $nota[] = __( 'transferencia internacional (art. 27)', 'cumpleconsent' ); } if ( 'si' === $op['perfilado'] ) { $imp += 2; $nota[] = __( 'perfilado o publicidad comportamental (art. 14 ter l)', 'cumpleconsent' ); } if ( false !== stripos( $op['datos'], 'navegación' ) || false !== stripos( $op['datos'], 'identificadores' ) ) { $prob += 1; $nota[] = __( 'tratamiento de navegación sin interacción directa del titular', 'cumpleconsent' ); } $prob = min( 3, $prob ); $imp = min( 3, $imp ); $score = $prob * $imp; if ( $score >= 7 ) { $nivel = 'alto'; $grav = __( 'Grave / gravísima (art. 34 ter y 34 quáter)', 'cumpleconsent' ); $accion = __( 'Revisar base de licitud y aviso antes de cada cambio; mantener evidencia de consentimiento y EIPD si aplica (art. 15 ter).', 'cumpleconsent' ); } elseif ( $score >= 4 ) { $nivel = 'medio'; $grav = __( 'Grave (art. 34 ter)', 'cumpleconsent' ); $accion = __( 'Verificar que el aviso mencione esta finalidad y que el bloqueo previo esté funcionando.', 'cumpleconsent' ); } else { $nivel = 'bajo'; $grav = __( 'Leve (art. 34 bis)', 'cumpleconsent' ); $accion = __( 'Mantener el registro y revisar una vez al año.', 'cumpleconsent' ); } $rows[] = array( 'operacion' => $op['name'] ? $op['name'] : $op['finalidad'], 'prob' => (string) $prob, 'impacto' => (string) $imp, 'nivel' => $nivel, 'sancion' => $grav, 'controles' => self::controls_for( $op ), 'accion' => $accion, 'nota' => implode( '; ', $nota ), ); } return $rows; } /** * Controles que el sitio tiene implementados HOY para esa operación * (se listan solo los que el plugin puede acreditar). * * @param array $op Operación. * @return string */ public static function controls_for( array $op ): string { $c = array(); if ( Settings::is_ready() ) { $c[] = __( 'Aviso con elección por finalidad y registro de la decisión (art. 12)', 'cumpleconsent' ); } if ( Script_Blocker::MODE_STRICT === Script_Blocker::mode() ) { $c[] = __( 'Bloqueo de rastreadores antes del consentimiento (art. 14 quáter)', 'cumpleconsent' ); } else { $c[] = __( 'Carga sin cookies gobernada por Consent Mode v2 hasta el consentimiento (art. 14 quáter)', 'cumpleconsent' ); } if ( Settings::get( 'block_iframes', true ) ) { $c[] = __( 'Contenido incrustado con carga diferida hasta el consentimiento', 'cumpleconsent' ); } if ( Settings::get( 'log_enabled', true ) ) { $c[] = sprintf( /* translators: %d: meses */ __( 'Prueba de consentimiento con huella del aviso informado y purga automática a los %d meses', 'cumpleconsent' ), max( 1, (int) Settings::get( 'log_retention_months', 24 ) ) ); } if ( Settings::get( 'log_ip_hash', true ) ) { $c[] = __( 'Minimización: IP solo como hash con sal, sin dato en claro', 'cumpleconsent' ); } if ( Settings::get( 'rights_enabled', false ) ) { $c[] = __( 'Canal de derechos con plazos legales vigilados (art. 11)', 'cumpleconsent' ); } return $c ? implode( '; ', $c ) : __( 'Sin controles acreditados por el plugin. Define medidas antes de cerrar esta matriz.', 'cumpleconsent' ); } /** Matriz de riesgos en HTML. */ public static function matrix_html(): string { $rows = self::risk_matrix(); $h = array(); $h[] = '

' . esc_html__( 'Matriz de riesgos del tratamiento en el sitio web (art. 3 e) del reglamento)', 'cumpleconsent' ) . '

'; $h[] = '

' . esc_html__( 'Probabilidad e impacto se estiman en escala 1–3 a partir de señales observables del sitio; el nivel es una priorización de trabajo, no una medición estadística. La graduación de la sanción sigue los artículos 34 bis, 34 ter y 34 quáter de la ley.', 'cumpleconsent' ) . '

'; $h[] = ''; foreach ( array( __( 'Operación', 'cumpleconsent' ), __( 'Prob.', 'cumpleconsent' ), __( 'Impacto', 'cumpleconsent' ), __( 'Nivel', 'cumpleconsent' ), __( 'Graduación', 'cumpleconsent' ), __( 'Controles vigentes', 'cumpleconsent' ), __( 'Acción', 'cumpleconsent' ) ) as $th ) { $h[] = ''; } $h[] = ''; foreach ( $rows as $row ) { $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; $h[] = ''; } $h[] = '
' . esc_html( $th ) . '
' . esc_html( $row['operacion'] ) . ( '' !== $row['nota'] ? '
' . esc_html( $row['nota'] ) . '' : '' ) . '
' . esc_html( $row['prob'] ) . '' . esc_html( $row['impacto'] ) . '' . esc_html( ucfirst( $row['nivel'] ) ) . '' . esc_html( $row['sancion'] ) . '' . esc_html( $row['controles'] ) . '' . esc_html( $row['accion'] ) . '
'; return implode( '', $h ); } /** Protocolos y reglas específicas (art. 3 f) del reglamento). */ public static function protocols_html(): string { $s = Settings::all(); $months = max( 1, (int) $s['log_retention_months'] ); $weeks = 30; $h = array(); $h[] = '

' . esc_html__( 'Protocolos, reglas y procedimientos (art. 3 f) del reglamento)', 'cumpleconsent' ) . '

'; $h[] = '

' . esc_html__( 'Protocolo 1 · Aviso y captación del consentimiento', 'cumpleconsent' ) . '

'; $h[] = '
    '; $h[] = '
  • ' . esc_html__( 'El aviso se muestra antes de cualquier tratamiento no necesario; ninguna casilla viene premarcada y “rechazar” tiene el mismo peso que “aceptar”.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . sprintf( /* translators: %s: versión */ esc_html__( 'La versión vigente del aviso es la %s; su contenido informado se registra con una huella criptográfica junto a cada decisión.', 'cumpleconsent' ), esc_html( Policy::version() ) ) . '
  • '; $h[] = '
  • ' . sprintf( /* translators: %d: meses */ esc_html__( 'La decisión del visitante se conserva %d meses y luego se le vuelve a preguntar; la revocación está disponible en todo momento desde el pie del sitio.', 'cumpleconsent' ), max( 1, (int) $s['consent_months'] ) ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Cambiar el fondo del aviso (nuevas finalidades, nuevos destinatarios) obliga a subir la versión: al hacerlo, todos los consentimientos anteriores se consideran vencidos y el sitio vuelve a preguntar.', 'cumpleconsent' ) . '
  • '; $h[] = '
'; $h[] = '

' . esc_html__( 'Protocolo 2 · Cookies, rastreadores y contenido de terceros', 'cumpleconsent' ) . '

'; $h[] = '
    '; $h[] = '
  • ' . esc_html__( 'Categorías de proveedores y de scripts: bloqueo en el HTML servido (no depende de la caché) y reactivación en el navegador según la decisión real de cada visitante.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Contenido incrustado (videos, mapas, redes): se muestra un aviso y el contenido se carga solo si el visitante acepta esa finalidad.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Al agregar un script, plugin o servicio nuevo, se revisa si instala cookies o envía datos a terceros; si lo hace, se clasifica en una finalidad y se declara el destinatario y el país.', 'cumpleconsent' ) . '
  • '; $h[] = '
'; $h[] = '

' . esc_html__( 'Protocolo 3 · Atención de derechos (art. 11)', 'cumpleconsent' ) . '

'; $h[] = '
    '; $h[] = '
  • ' . esc_html__( 'Toda solicitud se ingresa con su fecha y calcula sus plazos: 30 días corridos, prorrogables una sola vez por otros 30 días corridos; 2 días hábiles si se pide bloqueo temporal, y mientras no se resuelva no se tratan los datos comprendidos.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . sprintf( /* translators: %d: días */ esc_html__( 'Se emite acuse de recibo y se guarda la respuesta íntegra, su fecha y el canal de envío como respaldo (el módulo de derechos lo registra y alerta %d días antes del vencimiento).', 'cumpleconsent' ), $weeks ) . '
  • '; $h[] = '
  • ' . esc_html__( 'En caso de denegación se funda la decisión, se indican los antecedentes y se informa que el titular puede reclamar ante la Agencia dentro de 30 días hábiles.', 'cumpleconsent' ) . '
  • '; $h[] = '
'; $h[] = '

' . esc_html__( 'Protocolo 4 · Conservación y supresión', 'cumpleconsent' ) . '

'; $h[] = '
    '; $h[] = '
  • ' . sprintf( /* translators: %d: meses */ esc_html__( 'El registro de consentimiento se purga automáticamente a los %d meses (tarea programada diaria). El plazo declarado en la política y el implementado son el mismo dato de configuración.', 'cumpleconsent' ), $months ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Las cookies de consentimiento caducan al plazo configurado y obligan a un nuevo aviso.', 'cumpleconsent' ) . '
  • '; $h[] = '
'; $h[] = '

' . esc_html__( 'Protocolo 5 · Incidentes y reporte interno (art. 3 g) del reglamento)', 'cumpleconsent' ) . '

'; $h[] = '
    '; $h[] = '
  • ' . esc_html__( 'Canal interno: cualquier persona de la organización reporta accesos, filtraciones o pérdidas al encargado de prevención por el canal definido por el responsable.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'El responsable evalúa el riesgo para los derechos de los titulares y, si es razonable, reporta a la Agencia por los medios más expeditos y sin dilaciones indebidas (art. 14 sexies), con la naturaleza de la vulneración, sus efectos, categorías y número aproximado de titulares y las medidas adoptadas.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Si el incidente afecta datos sensibles, datos de niños y niñas menores de 14 años o datos financieros, se comunica además a cada titular afectado en lenguaje claro y sencillo.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Se evalúa la autodenuncia del art. 36 N° 4 cuando corresponda.', 'cumpleconsent' ) . '
  • '; $h[] = '
'; return implode( '', $h ); } /** * Expediente completo (HTML imprimible) para anexar al programa de cumplimiento. * * Es un documento autónomo (se descarga o se archiva y se imprime tal cual): sus * estilos se declaran con wp_add_inline_style() y los imprime el núcleo, para que el * anexo se vea igual fuera del sitio y sin conexión. */ /** * Estilos del expediente impreso (una sola cadena: es un documento autónomo). */ private static function expediente_css(): string { return 'body{font:14px/1.55 -apple-system,"Segoe UI",Roboto,Arial,sans-serif;max-width:1100px;margin:32px auto;padding:0 24px;color:#1a1a1a}h1{font-size:24px}h2{font-size:19px;margin-top:32px;border-bottom:2px solid #0b6e4f;padding-bottom:6px}h3{font-size:16px;margin-top:22px}table{border-collapse:collapse;width:100%;margin:10px 0 18px}th,td{border:1px solid #d5d5d5;padding:7px 9px;text-align:left;vertical-align:top;font-size:13px}th{background:#f4f6f5}.ccn-doc-meta{color:#555;font-size:12px}ul{margin:6px 0 14px 20px}li{margin:4px 0}.ccn-alcance{background:#fbf6e6;border-left:4px solid #d9a900;padding:10px 14px;font-size:13px}'; } public static function expediente_html(): string { $h = array(); $h[] = '' . esc_html__( 'Expediente de consentimiento y tratamiento en el sitio web', 'cumpleconsent' ) . ''; // Los estilos se declaran con la API de WordPress y los imprime el núcleo dentro // del documento. Así el anexo sigue siendo autónomo —se archiva y se imprime igual // sin conexión— sin que el plugin escriba etiquetas de estilo a mano. wp_register_style( 'cumpleconsent-expediente', false, array(), CUMPLECONSENT_VERSION ); wp_add_inline_style( 'cumpleconsent-expediente', self::expediente_css() ); ob_start(); wp_print_styles( 'cumpleconsent-expediente' ); $h[] = (string) ob_get_clean(); $h[] = ''; $h[] = '

' . esc_html__( 'Expediente de consentimiento y tratamiento de datos — sitio web', 'cumpleconsent' ) . '

'; $h[] = '

' . esc_html( (string) Settings::get( 'owner_name' ) ) . ' · ' . esc_html( home_url() ) . ' · ' . esc_html( date_i18n( 'j \d\e F \d\e Y' ) ) . '

'; $h[] = '

' . esc_html__( 'Alcance de este documento:', 'cumpleconsent' ) . ' ' . esc_html__( 'aporta elementos documentales para las letras a), d), e), f) y g) del art. 3 del reglamento D.S. 662, referidos al tratamiento que ocurre en este sitio web. No constituye por sí solo un programa de cumplimiento, no designa delegado de protección de datos, no certifica y no cubre las operaciones de la organización fuera del sitio. El delegado lo designa el responsable y el programa debe ser aprobado e implementado por él.', 'cumpleconsent' ) . '

'; $h[] = self::register_html(); $h[] = self::matrix_html(); $h[] = self::protocols_html(); $h[] = '

' . esc_html__( 'Anexo · Evidencia técnica disponible', 'cumpleconsent' ) . '

'; $h[] = '

' . esc_html__( 'El sitio mantiene, en su propia base de datos, los siguientes registros auditables y configurables:', 'cumpleconsent' ) . '

'; $h[] = '
    '; $h[] = '
  • ' . esc_html__( 'Registro de decisiones de consentimiento (fecha y hora UTC, seudónimo, evento, finalidades aceptadas y rechazadas, versión y huella del aviso informado, hash de IP opcional, HMAC de integridad), exportable a CSV.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Expediente de solicitudes de derechos con fecha de ingreso, plazos calculados, respuesta íntegra y hash de evidencia, exportable a CSV.', 'cumpleconsent' ) . '
  • '; $h[] = '
  • ' . esc_html__( 'Informe de diagnóstico del sitio (terceros detectados, formularios, cobertura del art. 14 ter e inconsistencias), con fecha de generación.', 'cumpleconsent' ) . '
  • '; $h[] = '
'; $h[] = ''; return implode( "\n", $h ); } /** Entrega el expediente como archivo HTML descargable. */ public function download(): void { $html = self::expediente_html(); nocache_headers(); header( 'Content-Type: text/html; charset=utf-8' ); header( 'Content-Disposition: attachment; filename=cumpleconsent-expediente-' . gmdate( 'Ymd' ) . '.html' ); echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- documento ya escapado campo por campo. exit; } }