grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026 * (devuelve el JSONL crudo; el token evita que cualquiera lea opiniones). */ declare(strict_types=1); // ================= CONFIG ================= // Mapa de locales (PENDIENTE Jorge: nombres reales, sincronizar con /var/www/html/satisfaccion/config.php del 85) $LOCALES = [1 => 'Local 1', 2 => 'Local 2', 3 => 'Local 3']; // Guardado: archivo JSONL (default, no requiere MySQL) $DATA_DIR = __DIR__ . '/data'; $DATA_FILE = $DATA_DIR . '/opiniones.jsonl'; // Token secreto del endpoint de export (debe coincidir con el del sync en el 85) $EXPORT_TOKEN = '8476d0b2698d42c957b21c8fda522b81'; // reCAPTCHA v3 (Google). Claves del sitio Bagno. $RC_SITE = '6LeZdXgtAAAAAHaKuEuoer5_V-zyVeV7ondjRI9O'; $RC_SECRET = '6LeZdXgtAAAAAOWo4VbDczAPJ0F4IYXBvFe0wNyn'; $RC_MIN_SCORE = 0.5; // score minimo para aceptar (0.0-1.0); 0.5 es el default recomendado // MySQL opcional del host publico: si $DB_HOST no esta vacio, ademas del JSONL inserta aca. $DB_HOST = ''; // ej: '127.0.0.1' si el host publico tiene MySQL propio $DB_USER = ''; $DB_PASS = ''; $DB_NAME = 'satisfaccion'; $DB_TABLE = 'opiniones'; // ========================================== function e(?string $s): string { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } // ---- Endpoint de export para el sync (solo con token valido) ---- if (isset($_GET['export'])) { if (($_GET['export'] ?? '') !== '1' || !isset($_GET['token']) || !hash_equals($EXPORT_TOKEN, (string)$_GET['token'])) { http_response_code(403); exit('forbidden'); } if (!is_file($DATA_FILE)) { http_response_code(404); exit('no data'); } header('Content-Type: text/plain; charset=utf-8'); readfile($DATA_FILE); exit; } $local = isset($_GET['local']) ? (int)$_GET['local'] : 0; $localOk = isset($LOCALES[$local]); $ok = false; $err = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!$localOk) { $err = 'URL invalida. Verifica que tenga ?local=1, 2 o 3.'; } elseif (!empty($_POST['website'])) { // honeypot anti-spam (debe quedar vacio) $ok = true; // simula exito, no guarda nada } else { // ---- reCAPTCHA v3: verificar token con Google ---- $rcToken = (string)($_POST['g-recaptcha-response'] ?? ''); $rcOk = false; if ($rcToken !== '') { $rcResp = @file_get_contents( 'https://www.google.com/recaptcha/api/siteverify' . '?secret=' . rawurlencode($RC_SECRET) . '&response=' . rawurlencode($rcToken) . '&remoteip=' . rawurlencode($_SERVER['REMOTE_ADDR'] ?? '') ); $rcJson = $rcResp ? json_decode($rcResp, true) : null; $rcOk = is_array($rcJson) && !empty($rcJson['success']) && ($rcJson['score'] ?? 0) >= $RC_MIN_SCORE; } if (!$rcOk) { $err = 'No pudimos verificar que sos humano. Recargá e intentá de nuevo.'; } else { $comentario = trim((string)($_POST['comentario'] ?? '')); $nombre = trim((string)($_POST['nombre'] ?? '')); $telefono = trim((string)($_POST['telefono'] ?? '')); if (mb_strlen($comentario) < 5) { $err = 'Escribí tu comentario (mínimo 5 caracteres).'; } else { $fila = [ 'id' => uniqid(), // 13 hex, UNIQUE en la tabla opiniones 'local' => $local, 'local_nombre' => $LOCALES[$local], 'fecha' => date('Y-m-d H:i:s'), 'ip' => $_SERVER['REMOTE_ADDR'] ?? '', 'nombre' => mb_substr($nombre, 0, 80), 'telefono' => mb_substr($telefono, 0, 20), 'comentario' => mb_substr($comentario, 0, 2000), ]; try { if (!is_dir($DATA_DIR)) { @mkdir($DATA_DIR, 0750, true); } $linea = json_encode($fila, JSON_UNESCAPED_UNICODE) . "\n"; if (@file_put_contents($DATA_FILE, $linea, FILE_APPEND | LOCK_EX) === false) { throw new RuntimeException('No se pudo guardar la opinion.'); } if ($DB_HOST !== '') { try { $pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8mb4", $DB_USER, $DB_PASS); $st = $pdo->prepare("INSERT INTO $DB_TABLE (uuid, id_local, nombre, telefono, comentario, fecha) VALUES (?,?,?,?,?,?)"); $st->execute([$fila['id'], $local, $fila['nombre'], $fila['telefono'], $fila['comentario'], $fila['fecha']]); } catch (Throwable $t) { /* JSONL ya quedo; el error MySQL no bloquea */ } } $ok = true; } catch (Throwable $t) { $err = 'Ups, no pudimos guardar tu opinión. Intentalo de nuevo.'; } } } } } ?> Tu opinión nos ayuda | Bagno

¡Gracias por tu opinión!

La recibimos y nos ayuda a mejorar todos los días.
✔ Comentario enviado

¿Cómo fue tu atención?

Contanos tu experiencia en . Tu comentario va directo a nuestro equipo.
URL inválida: falta ?local=1, 2 o 3.