netgescon-master/netgescon-laravel/app/Http/Controllers/SuperAdmin/ArchiviSistemaController.php

446 lines
13 KiB
PHP

<?php
namespace App\Http\Controllers\SuperAdmin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use ZipArchive;
use Carbon\Carbon;
class ArchiviSistemaController extends Controller
{
/**
* Mostra la dashboard di gestione archivi di sistema
*/
public function index()
{
// Statistiche archivi
$stats = [
'comuni_count' => DB::table('comuni_italiani')->count(),
'last_import' => DB::table('import_logs')
->where('tipo', 'comuni_italiani')
->latest()
->value('created_at'),
'storage_size' => $this->getArchiveStorageSize(),
'available_archives' => $this->getAvailableArchives()
];
return view('superadmin.archivi.index', compact('stats'));
}
/**
* Gestione archivio comuni italiani
*/
public function comuniItaliani(Request $request)
{
$query = DB::table('comuni_italiani');
// Filtri di ricerca
if ($request->filled('search_nome')) {
$query->where('denominazione', 'like', '%' . $request->search_nome . '%');
}
if ($request->filled('search_provincia')) {
$query->where('provincia_codice', 'like', '%' . $request->search_provincia . '%');
}
if ($request->filled('search_regione')) {
$query->where('regione_denominazione', 'like', '%' . $request->search_regione . '%');
}
if ($request->filled('search_cap')) {
$query->where('cap', 'like', '%' . $request->search_cap . '%');
}
// Export CSV
if ($request->get('export') === 'csv') {
return $this->exportComuniCSV($query);
}
$comuni = $query->orderBy('denominazione')->paginate(50);
return view('superadmin.archivi.comuni', compact('comuni'));
}
/**
* Export comuni in formato CSV
*/
private function exportComuniCSV($query)
{
$comuni = $query->get();
$filename = 'comuni_italiani_' . date('Y-m-d_H-i') . '.csv';
$headers = [
'Content-Type' => 'text/csv',
'Content-Disposition' => "attachment; filename=\"{$filename}\"",
];
$callback = function() use ($comuni) {
$file = fopen('php://output', 'w');
// Header CSV
fputcsv($file, [
'Codice ISTAT',
'Denominazione',
'Denominazione Straniera',
'Codice Catastale',
'CAP',
'Provincia Codice',
'Provincia Denominazione',
'Regione Codice',
'Regione Denominazione'
], ';');
// Dati
foreach ($comuni as $comune) {
fputcsv($file, [
$comune->codice_istat,
$comune->denominazione,
$comune->denominazione_straniera,
$comune->codice_catastale,
$comune->cap,
$comune->provincia_codice,
$comune->provincia_denominazione,
$comune->regione_codice,
$comune->regione_denominazione
], ';');
}
fclose($file);
};
return response()->stream($callback, 200, $headers);
}
/**
* Import ZIP con dati JSON
*/
public function importZip(Request $request)
{
$request->validate([
'zip_file' => 'required|file|mimes:zip|max:51200', // 50MB max
'tipo_archivio' => 'required|string|in:comuni_italiani,province,regioni'
]);
try {
$zipFile = $request->file('zip_file');
$tipoArchivio = $request->input('tipo_archivio');
// Salva il file ZIP temporaneamente
$zipPath = $zipFile->storeAs('temp', 'import_' . time() . '.zip');
$fullZipPath = storage_path('app/' . $zipPath);
// Estrai e processa il ZIP
$result = $this->processZipImport($fullZipPath, $tipoArchivio);
// Cancella il file ZIP dopo l'importazione
Storage::delete($zipPath);
// Log dell'operazione
DB::table('import_logs')->insert([
'tipo' => $tipoArchivio,
'file_originale' => $zipFile->getClientOriginalName(),
'records_importati' => $result['imported'],
'errori' => $result['errors'],
'user_id' => auth()->id(),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
return response()->json([
'success' => true,
'message' => "Importazione completata. {$result['imported']} record importati.",
'data' => $result
]);
} catch (\Exception $e) {
Log::error('Errore import ZIP: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'Errore durante l\'importazione: ' . $e->getMessage()
], 500);
}
}
/**
* Processa il file ZIP e importa i dati
*/
private function processZipImport($zipPath, $tipo)
{
$zip = new ZipArchive;
$imported = 0;
$errors = [];
if ($zip->open($zipPath) === TRUE) {
// Estrai in una cartella temporanea
$extractPath = storage_path('app/temp/extract_' . time());
$zip->extractTo($extractPath);
$zip->close();
// Cerca file JSON nella cartella estratta
$jsonFiles = glob($extractPath . '/*.json');
foreach ($jsonFiles as $jsonFile) {
$jsonData = json_decode(file_get_contents($jsonFile), true);
if ($jsonData) {
$result = $this->importJsonData($jsonData, $tipo);
$imported += $result['imported'];
$errors = array_merge($errors, $result['errors']);
}
}
// Pulisci la cartella estratta
$this->deleteDirectory($extractPath);
} else {
throw new \Exception('Impossibile aprire il file ZIP');
}
return [
'imported' => $imported,
'errors' => $errors
];
}
/**
* Importa i dati JSON nel database
*/
private function importJsonData($data, $tipo)
{
$imported = 0;
$errors = [];
DB::beginTransaction();
try {
switch ($tipo) {
case 'comuni_italiani':
$imported = $this->importComuniItaliani($data);
break;
case 'province':
$imported = $this->importProvince($data);
break;
case 'regioni':
$imported = $this->importRegioni($data);
break;
default:
throw new \Exception("Tipo archivio non supportato: {$tipo}");
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
$errors[] = $e->getMessage();
}
return [
'imported' => $imported,
'errors' => $errors
];
}
/**
* Importa i comuni italiani
*/
private function importComuniItaliani($data)
{
// Se necessario, svuota la tabella esistente
DB::table('comuni_italiani')->truncate();
$imported = 0;
$chunk = [];
foreach ($data as $record) {
$chunk[] = [
'codice_istat' => $record['codice_istat'] ?? null,
'denominazione' => $record['denominazione'] ?? null,
'denominazione_straniera' => $record['denominazione_straniera'] ?? null,
'codice_catastale' => $record['codice_catastale'] ?? null,
'cap' => $record['cap'] ?? null,
'provincia_codice' => $record['provincia_codice'] ?? null,
'provincia_denominazione' => $record['provincia_denominazione'] ?? null,
'regione_codice' => $record['regione_codice'] ?? null,
'regione_denominazione' => $record['regione_denominazione'] ?? null,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
];
// Inserisci a blocchi di 500 record
if (count($chunk) >= 500) {
DB::table('comuni_italiani')->insert($chunk);
$imported += count($chunk);
$chunk = [];
}
}
// Inserisci il resto
if (!empty($chunk)) {
DB::table('comuni_italiani')->insert($chunk);
$imported += count($chunk);
}
return $imported;
}
/**
* Importa le province
*/
private function importProvince($data)
{
DB::table('province')->truncate();
$imported = 0;
foreach ($data as $record) {
DB::table('province')->insert([
'codice' => $record['codice'] ?? null,
'denominazione' => $record['denominazione'] ?? null,
'sigla' => $record['sigla'] ?? null,
'regione_codice' => $record['regione_codice'] ?? null,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
$imported++;
}
return $imported;
}
/**
* Importa le regioni
*/
private function importRegioni($data)
{
DB::table('regioni')->truncate();
$imported = 0;
foreach ($data as $record) {
DB::table('regioni')->insert([
'codice' => $record['codice'] ?? null,
'denominazione' => $record['denominazione'] ?? null,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
$imported++;
}
return $imported;
}
/**
* Calcola la dimensione dello storage archivi
*/
private function getArchiveStorageSize()
{
$size = 0;
$directories = ['archives', 'temp'];
foreach ($directories as $dir) {
$path = storage_path("app/{$dir}");
if (is_dir($path)) {
$size += $this->getDirectorySize($path);
}
}
return $this->formatBytes($size);
}
/**
* Ottiene gli archivi disponibili
*/
private function getAvailableArchives()
{
return [
'comuni_italiani' => [
'nome' => 'Comuni Italiani',
'descrizione' => 'Archivio completo dei comuni italiani con codici ISTAT',
'ultima_sincronizzazione' => DB::table('import_logs')
->where('tipo', 'comuni_italiani')
->latest()
->value('created_at')
],
'province' => [
'nome' => 'Province Italiane',
'descrizione' => 'Elenco delle province italiane',
'ultima_sincronizzazione' => null
],
'regioni' => [
'nome' => 'Regioni Italiane',
'descrizione' => 'Elenco delle regioni italiane',
'ultima_sincronizzazione' => null
]
];
}
/**
* Cancella ricorsivamente una directory
*/
private function deleteDirectory($dir)
{
if (!is_dir($dir)) return;
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
$path = $dir . DIRECTORY_SEPARATOR . $file;
is_dir($path) ? $this->deleteDirectory($path) : unlink($path);
}
rmdir($dir);
}
/**
* Calcola la dimensione di una directory
*/
private function getDirectorySize($path)
{
$size = 0;
if (is_dir($path)) {
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
$size += $file->getSize();
}
}
return $size;
}
/**
* Formatta i byte in formato leggibile
*/
private function formatBytes($size, $precision = 2)
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $size > 1024 && $i < count($units) - 1; $i++) {
$size /= 1024;
}
return round($size, $precision) . ' ' . $units[$i];
}
/**
* Sincronizzazione futura con ISTAT
*/
public function sincronizzaIstat()
{
// Placeholder per sincronizzazione automatica con ISTAT
return response()->json([
'success' => false,
'message' => 'Sincronizzazione automatica con ISTAT in sviluppo'
]);
}
}