importar.php Interfaz de importación CSV 1 líneas
1
<?php
// ============================================================
// SIDE - ARC 1.0
// Archivo: importar.php
// ============================================================

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

// --- Validar parent_id ---
if (!isset($_GET['parent_id']) || !is_numeric($_GET['parent_id'])) {
    header('Location: /apps/side-arc/cuadro_clasificacion.php');
    exit;
}

$parent_id = (int) $_GET['parent_id'];

// --- Cargar datos del padre ---
$stmt = mysqli_prepare($conexion,
    "SELECT id, titulo, nivel_descripcion, codigo_referencia
     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);
$padre  = mysqli_fetch_assoc($res);
mysqli_free_result($res);
mysqli_stmt_close($stmt);

if (!$padre) {
    header('Location: /apps/side-arc/cuadro_clasificacion.php');
    exit;
}

// Bloquear si el padre es US
if ($padre['nivel_descripcion'] === 'Unidad Documental Simple') {
    $titulo_pagina = 'Importación bloqueada';
    require_once 'header.php';
    echo '<div class="alerta alerta--error" style="margin-top:2rem;">'
        . 'Las Unidades Documentales Simples no pueden tener subordinados.'
        . ' <a href="/apps/side-arc/ficha.php?id=' . $parent_id . '">Volver</a>.</div>';
    require_once 'footer.php';
    exit;
}

// ============================================================
// GENERAR PLANTILLA CSV (descarga)
// ============================================================
if (isset($_GET['plantilla']) && $_GET['plantilla'] === '1') {
    $columnas = [
        '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',
        'fecha_inicial_filtro','fecha_final_filtro',
    ];

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="plantilla_importacion.csv"');
    header('Cache-Control: no-cache');

    $out = fopen('php://output', 'w');
    fputs($out, "\xEF\xBB\xBF");
    fputcsv($out, $columnas, ',', '"');
    fputcsv($out, [
        'CO-BOG-001-EJ','Título de ejemplo','1990-2000',
        'Serie','5 cajas / papel',
        'Nombre del productor','Historia institucional breve.',
        'Descripción del alcance y contenido.',
        '','','Libre acceso','Sin restricciones',
        'Español','Buen estado',
        '','Notas adicionales.',
        date('Y-m-d'),'2024','Publicado',
        'Archivero Apellido','','',
        'ISAD(G)','','','',
        '1990','2000',
    ], ',', '"');
    fclose($out);
    exit;
}

// --- Recuperar resultado de importación previa ---
$reporte = $_SESSION['importar_reporte'] ?? null;
unset($_SESSION['importar_reporte']);

// Token CSRF
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

$titulo_pagina = 'Importar CSV';
require_once 'header.php';
?>

<nav class="breadcrumb">
    <a href="/apps/side-arc/cuadro_clasificacion.php">Cuadro de Clasificación</a>
    <span class="breadcrumb__sep">›</span>
    <a href="/apps/side-arc/ficha.php?id=<?= $parent_id ?>">
        <?= h($padre['titulo']) ?>
    </a>
    <span class="breadcrumb__sep">›</span>
    <span>Importar CSV</span>
</nav>

<div class="importar-contenedor">

    <div class="importar-encabezado">
        <h1 class="importar-encabezado__titulo">Importación Masiva desde CSV</h1>
        <p class="importar-encabezado__desc">
            Los registros del archivo CSV serán insertados como subordinados de:
            <strong><?= h($padre['titulo']) ?></strong>
            <span class="badge-nivel"><?= h($padre['nivel_descripcion']) ?></span>
        </p>
    </div>

    <?php if ($reporte !== null): ?>
    <div class="importar-reporte">
        <h2 class="importar-reporte__titulo">Resultado de la importación</h2>
        <div class="importar-reporte__stats">
            <div class="stat-card">
                <span class="stat-card__num"><?= $reporte['total'] ?></span>
                <span class="stat-card__label">Filas procesadas</span>
            </div>
            <div class="stat-card stat-card--exito">
                <span class="stat-card__num"><?= $reporte['insertadas'] ?></span>
                <span class="stat-card__label">Insertadas</span>
            </div>
            <div class="stat-card stat-card--error">
                <span class="stat-card__num"><?= $reporte['rechazadas'] ?></span>
                <span class="stat-card__label">Rechazadas</span>
            </div>
        </div>

        <?php if (!empty($reporte['errores'])): ?>
        <div class="importar-reporte__errores">
            <h3 class="importar-reporte__errores-titulo">Detalle de filas rechazadas:</h3>
            <table class="importar-tabla-errores">
                <thead>
                    <tr>
                        <th>Fila CSV</th>
                        <th>Título</th>
                        <th>Motivo del rechazo</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($reporte['errores'] as $err): ?>
                    <tr>
                        <td><?= (int) $err['fila'] ?></td>
                        <td><?= h($err['titulo'] ?? '(sin título)') ?></td>
                        <td><?= h($err['motivo']) ?></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <?php endif; ?>

        <?php if ($reporte['insertadas'] > 0): ?>
        <div style="margin-top:1rem;">
            <a href="/apps/side-arc/subordinados.php?parent_id=<?= $parent_id ?>"
               class="btn btn--primario">
                Ver registros importados
            </a>
        </div>
        <?php endif; ?>
    </div>
    <?php endif; ?>

    <div class="importar-instrucciones">
        <h2 class="importar-instrucciones__titulo">Instrucciones</h2>
        <ol class="importar-instrucciones__lista">
            <li>Descargue la plantilla CSV y ábrala en Excel o LibreOffice Calc.</li>
            <li>Complete los datos respetando los nombres de columna de la primera fila.</li>
            <li>El campo <code>nivel_descripcion</code> debe contener exactamente
                uno de los niveles permitidos para este contexto.</li>
            <li>El campo <code>fecha_ingreso_registro</code> debe tener
                formato <code>AAAA-MM-DD</code>.</li>
            <li>Los campos <code>fecha_inicial_filtro</code> y
                <code>fecha_final_filtro</code> deben ser años numéricos (ej: 1990).</li>
            <li>Guarde el archivo como CSV con codificación <strong>UTF-8</strong>.</li>
            <li>Suba el archivo usando el formulario inferior.</li>
        </ol>
        <a href="/apps/side-arc/importar.php?parent_id=<?= $parent_id ?>&plantilla=1"
           class="btn btn--primario" style="margin-top:0.75rem; display:inline-block;">
            Descargar plantilla CSV
        </a>
    </div>

    <div class="importar-form-contenedor">
        <h2 class="importar-form__titulo">Cargar archivo CSV</h2>
        <form action="/apps/side-arc/procesar_importacion.php"
              method="POST"
              enctype="multipart/form-data"
              class="objeto-form">
            <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
            <input type="hidden" name="parent_id" value="<?= $parent_id ?>">
            <div class="form-grupo">
                <label for="archivo_csv" class="form-label form-label--req">
                    Archivo CSV
                </label>
                <input type="file" id="archivo_csv" name="archivo_csv"
                       class="objeto-file-input" accept=".csv,text/csv" required>
                <p class="objeto-file-hint">
                    Solo archivos .csv · Máximo 5 MB · Codificación UTF-8
                </p>
            </div>
            <div class="form-acciones">
                <button type="submit" class="btn btn--primario btn--guardar">
                    Importar CSV
                </button>
                <a href="/apps/side-arc/ficha.php?id=<?= $parent_id ?>"
                   class="btn btn--cancelar">
                    Cancelar
                </a>
            </div>
        </form>
    </div>

</div>

<?php
mysqli_close($conexion);
require_once 'footer.php';
?>