procesar_ingreso.php Controlador de ingreso (INSERT) 1 líneas
1
<?php
// ============================================================
// SIDE - ARC 1.0
// Archivo: procesar_ingreso.php
// Propósito: Recibe el POST de ingreso.php, valida la matriz
//            de niveles, sanea los datos e inserta en BD.
//            No genera HTML: solo redirige.
// ============================================================

require_once 'conexion.php';
require_once 'helpers.php';
requerir_admin();

// --- Solo POST ---
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: /apps/side-arc/index.php');
    exit;
}

// --- Validar CSRF ---
if (
    empty($_POST['csrf_token']) ||
    empty($_SESSION['csrf_token']) ||
    !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])
) {
    $_SESSION['form_error'] = 'Solicitud inválida. Intente de nuevo.';
    header('Location: /apps/side-arc/ingreso.php');
    exit;
}
unset($_SESSION['csrf_token']);

// ============================================================
// FUNCIÓN DE SANEAMIENTO
// ============================================================
function limpiar(?string $valor): ?string {
    if ($valor === null || trim($valor) === '') {
        return null;
    }
    return trim($valor);
}

// ============================================================
// RECOGER Y SANEAR TODOS LOS CAMPOS
// ============================================================
$parent_id = isset($_POST['parent_id']) && is_numeric($_POST['parent_id'])
    ? (int) $_POST['parent_id']
    : null;

$nivel_descripcion  = limpiar($_POST['nivel_descripcion'] ?? null);
$codigo_referencia  = limpiar($_POST['codigo_referencia'] ?? null);
$titulo             = limpiar($_POST['titulo'] ?? null);

// Campos opcionales
$fechas                  = limpiar($_POST['fechas']                  ?? null);
$volumen_soporte         = limpiar($_POST['volumen_soporte']         ?? null);
$nombre_productor        = limpiar($_POST['nombre_productor']        ?? null);
$historia_institucional  = limpiar($_POST['historia_institucional']  ?? null);
$alcance_contenido       = limpiar($_POST['alcance_contenido']       ?? null);
$valoracion_eliminacion  = limpiar($_POST['valoracion_eliminacion']  ?? null);
$organizacion            = limpiar($_POST['organizacion']            ?? null);
$condiciones_acceso      = limpiar($_POST['condiciones_acceso']      ?? null);
$condiciones_reproduccion= limpiar($_POST['condiciones_reproduccion']?? null);
$lengua_escritura        = limpiar($_POST['lengua_escritura']        ?? null);
$caracteristicas_fisicas = limpiar($_POST['caracteristicas_fisicas'] ?? null);
$unidades_relacionadas   = limpiar($_POST['unidades_relacionadas']   ?? null);
$notas                   = limpiar($_POST['notas']                   ?? null);
$fechas_descripciones    = limpiar($_POST['fechas_descripciones']    ?? null);
$estado                  = limpiar($_POST['estado']                  ?? null);
$nombre_descriptor       = limpiar($_POST['nombre_descriptor']       ?? null);
$nota_archivero          = limpiar($_POST['nota_archivero']          ?? null);
$fecha_creacion_revision = limpiar($_POST['fecha_creacion_revision'] ?? null);
$reglas_normas           = limpiar($_POST['reglas_normas']           ?? null);
$pa_nombre               = limpiar($_POST['pa_nombre']               ?? null);
$pa_geografico           = limpiar($_POST['pa_geografico']           ?? null);
$pam_materia             = limpiar($_POST['pam_materia']             ?? null);
$objeto_digital = limpiar($_POST['objeto_digital'] ?? null);

// Fecha de ingreso (DATE)
$fecha_ingreso_registro = limpiar($_POST['fecha_ingreso_registro'] ?? null);
if ($fecha_ingreso_registro !== null &&
    !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha_ingreso_registro)) {
    $fecha_ingreso_registro = null;
}

// Años numéricos para filtros
$fecha_inicial_filtro = isset($_POST['fecha_inicial_filtro']) &&
    is_numeric($_POST['fecha_inicial_filtro'])
    ? (int) $_POST['fecha_inicial_filtro'] : null;

$fecha_final_filtro = isset($_POST['fecha_final_filtro']) &&
    is_numeric($_POST['fecha_final_filtro'])
    ? (int) $_POST['fecha_final_filtro'] : null;

// ============================================================
// VALIDACIONES OBLIGATORIAS
// ============================================================
function redirigir_error(string $msg, ?int $parent_id): never {
    $_SESSION['form_error'] = $msg;
    // Guardar datos para repoblar el formulario
    $_SESSION['form_data']  = $_POST;
    $url = '/apps/side-arc/ingreso.php';
    if ($parent_id !== null) {
        $url .= '?parent_id=' . $parent_id;
    }
    header('Location: ' . $url);
    exit;
}

if (empty($titulo)) {
    redirigir_error('El campo Título es obligatorio.', $parent_id);
}

if (empty($codigo_referencia)) {
    redirigir_error('El campo Código de referencia es obligatorio.', $parent_id);
}

if (empty($nivel_descripcion)) {
    redirigir_error('Debe seleccionar un Nivel de descripción.', $parent_id);
}

// Obtener nivel del padre desde la BD para validación server-side
$nivel_padre_real = null;
if ($parent_id !== null) {
    $stmt = mysqli_prepare(
        $conexion,
        "SELECT nivel_descripcion FROM descripcion_isadg WHERE id = ? LIMIT 1"
    );
    mysqli_stmt_bind_param($stmt, 'i', $parent_id);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $fila_padre = mysqli_fetch_assoc($res);
    mysqli_stmt_close($stmt);

    if (!$fila_padre) {
        redirigir_error('El registro padre especificado no existe.', null);
    }
    $nivel_padre_real = $fila_padre['nivel_descripcion'];
}

$niveles_validos = niveles_permitidos_bajo($nivel_padre_real);

if (!in_array($nivel_descripcion, $niveles_validos, true)) {
    redirigir_error(
        'El nivel de descripción "' . $nivel_descripcion .
        '" no es válido para este registro padre. Operación bloqueada.',
        $parent_id
    );
}

// Validar rango de fechas
if ($fecha_inicial_filtro !== null &&
    $fecha_final_filtro   !== null &&
    $fecha_inicial_filtro > $fecha_final_filtro) {
    redirigir_error(
        'El año inicial no puede ser mayor que el año final.',
        $parent_id
    );
}

// ============================================================
// INSERTAR EN LA BASE DE DATOS
// ============================================================
$sql = "INSERT INTO descripcion_isadg (
    parent_id, codigo_referencia, titulo, fechas,
    nivel_descripcion, volumen_soporte, nombre_productor,
    historia_institucional, alcance_contenido, valoracion_eliminacion,
    organizacion, condiciones_acceso, condiciones_reproduccion,
    lengua_escritura, caracteristicas_fisicas, unidades_relacionadas,
    notas, fecha_ingreso_registro, fechas_descripciones, estado,
    nombre_descriptor, nota_archivero, fecha_creacion_revision,
    reglas_normas, pa_nombre, pa_geografico, pam_materia,
    objeto_digital, fecha_inicial_filtro, fecha_final_filtro
) VALUES (
    ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
)";

$stmt = mysqli_prepare($conexion, $sql);

if (!$stmt) {
    redirigir_error(
        'Error interno al preparar la consulta: ' . mysqli_error($conexion),
        $parent_id
    );
}

mysqli_stmt_bind_param(
    $stmt,
    'isssssssssssssssssssssssssssii',
    $parent_id,
    $codigo_referencia,
    $titulo,
    $fechas,
    $nivel_descripcion,
    $volumen_soporte,
    $nombre_productor,
    $historia_institucional,
    $alcance_contenido,
    $valoracion_eliminacion,
    $organizacion,
    $condiciones_acceso,
    $condiciones_reproduccion,
    $lengua_escritura,
    $caracteristicas_fisicas,
    $unidades_relacionadas,
    $notas,
    $fecha_ingreso_registro,
    $fechas_descripciones,
    $estado,
    $nombre_descriptor,
    $nota_archivero,
    $fecha_creacion_revision,
    $reglas_normas,
    $pa_nombre,
    $pa_geografico,
    $pam_materia,
    $objeto_digital,
    $fecha_inicial_filtro,
    $fecha_final_filtro
);

if (!mysqli_stmt_execute($stmt)) {
    $err = mysqli_stmt_error($stmt);
    mysqli_stmt_close($stmt);
    redirigir_error('Error al guardar el registro: ' . $err, $parent_id);
}

$nuevo_id = mysqli_insert_id($conexion);
mysqli_stmt_close($stmt);
mysqli_close($conexion);

// Redirigir a la ficha del registro recién creado
header('Location: /apps/side-arc/ficha.php?id=' . $nuevo_id . '&nuevo=1');
exit;