132 lines
5.4 KiB
PHP
132 lines
5.4 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/lab/submit_formulario.php — Guardar respuesta del cliente (público, sin auth)
|
|
* GET /api/lab/submit_formulario.php?t=TOKEN — Verificar estado del token (público)
|
|
*
|
|
* Body JSON (POST): { token, datos_cliente:{...}, firma_svg? }
|
|
*/
|
|
// No usar _helpers.php porque este endpoint es PÚBLICO (no requiere sesión)
|
|
require_once __DIR__ . '/../../config/config.php';
|
|
require_once __DIR__ . '/../../classes/lab/Formulario.php';
|
|
require_once __DIR__ . '/../../classes/Database.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }
|
|
|
|
function pubOk(array $data = [], string $msg = ''): void {
|
|
$r = ['success' => true];
|
|
if ($msg) $r['message'] = $msg;
|
|
echo json_encode(array_merge($r, $data), JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
function pubErr(string $msg, int $code = 400): void {
|
|
http_response_code($code);
|
|
echo json_encode(['success' => false, 'error' => $msg], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$form = new Formulario();
|
|
|
|
// GET: cargar datos del formulario por token
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
$token = $_GET['t'] ?? '';
|
|
if (!$token) pubErr('Token requerido');
|
|
$envio = $form->obtenerPorToken($token);
|
|
if (!$envio) pubErr('Link inválido o expirado', 404);
|
|
|
|
// Config de diseño: primero override del formulario, luego config global
|
|
$db2 = Database::getInstance();
|
|
$cfgRows = $db2->fetchAll('SELECT clave, valor FROM lab_config ORDER BY clave');
|
|
$gCfg = [];
|
|
foreach ($cfgRows as $r) { $gCfg[$r['clave']] = $r['valor']; }
|
|
$docConfig = [
|
|
'doc_color' => $envio['doc_color'] ?: ($gCfg['doc_color'] ?? '#1565c0'),
|
|
'doc_logo_base64' => $envio['doc_logo_base64'] ?: ($gCfg['doc_logo_base64'] ?? null),
|
|
'doc_encabezado' => $envio['doc_encabezado'] ?: ($gCfg['empresa_nombre'] ?? null),
|
|
'doc_subtitulo' => $envio['doc_subtitulo'] ?: ($gCfg['empresa_subtitulo'] ?? null),
|
|
'doc_pie_pagina' => $envio['doc_pie_pagina'] ?: ($gCfg['doc_pie_pagina'] ?? null),
|
|
];
|
|
|
|
// Estructura que espera form_cliente.php
|
|
pubOk([
|
|
'formulario' => [
|
|
'nombre' => $envio['form_nombre'],
|
|
'descripcion' => $envio['form_descripcion'] ?? '',
|
|
'esquema_decoded'=> $envio['esquema_decoded'],
|
|
'permite_firma' => (bool)($envio['permite_firma'] ?? false),
|
|
'requiere_firma' => (bool)($envio['requiere_firma'] ?? false),
|
|
],
|
|
'envio' => [
|
|
'id' => $envio['id'],
|
|
'estado' => $envio['estado'],
|
|
'firma_svg' => $envio['firma_svg'] ?? null,
|
|
'hash_verificacion'=> $envio['hash_verificacion'] ?? null,
|
|
'completado_en' => $envio['completado_en'] ?? null,
|
|
],
|
|
'prefilled' => $envio['prefilled_decoded'] ?? [],
|
|
'config' => $docConfig,
|
|
]);
|
|
}
|
|
|
|
// POST: guardar respuesta
|
|
$raw = file_get_contents('php://input');
|
|
$datos = json_decode($raw, true) ?? [];
|
|
|
|
$token = $datos['token'] ?? '';
|
|
if (!$token) pubErr('Token requerido');
|
|
|
|
$envio = $form->obtenerPorToken($token);
|
|
if (!$envio) pubErr('Link inválido o expirado', 404);
|
|
|
|
if (in_array($envio['estado'], ['completado', 'firmado'])) {
|
|
// El formulario ya fue guardado (posible reintento tras error de red).
|
|
// Devolvemos éxito con los datos existentes para que el cliente no quede bloqueado.
|
|
$db = Database::getInstance();
|
|
$saved = $db->fetch('SELECT id, hash_verificacion, firma_svg FROM lab_form_envios WHERE token = ?', [$token]);
|
|
pubOk([
|
|
'firmado' => !empty($saved['firma_svg']),
|
|
'hash' => $saved['hash_verificacion'] ?? null,
|
|
'envio_id' => $saved['id'] ?? null,
|
|
'ya_enviado'=> true,
|
|
], 'Formulario enviado correctamente. ¡Gracias!');
|
|
}
|
|
|
|
$datosCliente = $datos['datos_cliente'] ?? [];
|
|
$firmaSvg = $datos['firma_svg'] ?? null;
|
|
$firmaFoto = $datos['firma_foto'] ?? null;
|
|
|
|
// Guardar foto de firma dentro de datos_cliente para no requerir nueva columna
|
|
if ($firmaFoto) {
|
|
$datosCliente['__firma_foto'] = $firmaFoto;
|
|
}
|
|
|
|
// Validar que si requiere firma, venga
|
|
if ($envio['requiere_firma'] && !$firmaSvg) {
|
|
pubErr('La firma es obligatoria para este formulario');
|
|
}
|
|
|
|
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
|
|
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
|
|
|
$ok = $form->guardarRespuesta($token, $datosCliente, $firmaSvg, $ip, $ua);
|
|
if (!$ok) pubErr('No se pudo guardar la respuesta', 500);
|
|
|
|
// Recuperar hash e id para la respuesta
|
|
$db = Database::getInstance();
|
|
$saved = $db->fetch('SELECT id, hash_verificacion FROM lab_form_envios WHERE token = ?', [$token]);
|
|
|
|
pubOk([
|
|
'firmado' => (bool)$firmaSvg,
|
|
'hash' => $saved['hash_verificacion'] ?? null,
|
|
'envio_id' => $saved['id'] ?? null,
|
|
], 'Formulario enviado correctamente. ¡Gracias!');
|
|
|
|
} catch (Exception $e) {
|
|
pubErr($e->getMessage(), 500);
|
|
}
|