netgescon-day0/app/Services/GesconImport/Traits/LegacyScanning.php

327 lines
13 KiB
PHP

<?php
namespace App\Services\GesconImport\Traits;
/**
* Metodi di scansione/preview legacy estratti dal controller gigante per ridurre complessità.
* Non dipendono da stato esterno eccetto chiamate shell e filesystem.
*/
trait LegacyScanning
{
private function scanStabiliFromMasterIndex(string $indexMdbPath, string $legacyBasePath): array
{
$binTables = trim((string)@shell_exec('command -v mdb-tables')) ?: '/usr/bin/mdb-tables';
$binExport = trim((string)@shell_exec('command -v mdb-export')) ?: '/usr/bin/mdb-export';
if (!is_file($indexMdbPath) || !is_readable($indexMdbPath)) return [];
$tableGuess = null;
$tables = @shell_exec(sprintf('%s -1 %s 2>/dev/null', escapeshellarg($binTables), escapeshellarg($indexMdbPath))) ?: '';
if ($tables) {
foreach (preg_split('/\r?\n/', trim($tables)) as $t) {
if ($t === '') continue;
if (preg_match('/(cartelle|stabil|anni)/i', $t)) {
$tableGuess = trim($t);
break;
}
}
}
if (!$tableGuess) {
$lines = array_filter(preg_split('/\r?\n/', trim($tables)));
$tableGuess = $lines ? trim(array_values($lines)[0]) : null;
}
if (!$tableGuess) return [];
$tmp = tempnam(sys_get_temp_dir(), 'mdbcsv_');
$cmd = sprintf(
'%s -D %s -d %s -q %s -R "\\n" %s %s > %s 2>/dev/null',
escapeshellarg($binExport),
escapeshellarg('%Y-%m-%d'),
escapeshellarg('|'),
escapeshellarg('"'),
escapeshellarg($indexMdbPath),
escapeshellarg($tableGuess),
escapeshellarg($tmp)
);
@shell_exec($cmd);
if (!is_file($tmp) || filesize($tmp) === 0) {
@unlink($tmp);
return [];
}
$fh = fopen($tmp, 'r');
if (!$fh) {
@unlink($tmp);
return [];
}
$headers = fgetcsv($fh, 0, '|');
if (!$headers) {
fclose($fh);
@unlink($tmp);
return [];
}
$headers = array_map(fn($h) => strtolower(trim((string)$h)), $headers);
$byCodeYears = [];
$byCodeName = [];
while (($cols = fgetcsv($fh, 0, '|')) !== false) {
if ($cols === [null]) continue;
$cols = array_map(fn($v) => is_string($v) ? trim($v) : $v, $cols);
if (count($cols) < count($headers)) $cols = array_pad($cols, count($headers), null);
if (count($cols) > count($headers)) $cols = array_slice($cols, 0, count($headers));
$row = @array_combine($headers, $cols) ?: [];
if (!$row) continue;
$code = $row['nome_directory'] ?? $row['cod_stabile'] ?? $row['internet_cod_stab'] ?? $row['codice'] ?? null;
$denom = $row['denominazione'] ?? $row['fe_denominazione'] ?? null;
$anno = $row['anno'] ?? $row['year'] ?? null;
if (!$code) continue;
$code = (string)$code;
if (!isset($byCodeYears[$code])) $byCodeYears[$code] = [];
if ($anno && preg_match('/^\d{4}$/', (string)$anno)) $byCodeYears[$code][(string)$anno] = true;
if ($denom) $byCodeName[$code] = (string)$denom;
}
fclose($fh);
@unlink($tmp);
$items = [];
foreach ($byCodeYears as $code => $yearsSet) {
$den = $byCodeName[$code] ?? null;
$years = array_keys($yearsSet);
sort($years, SORT_STRING);
$items[] = ['legacy_code' => $code, 'denominazione' => $den, 'years_count' => count($years), 'years' => $years];
}
if (empty($items)) {
$items = $this->scanLegacyCodesFromDir($legacyBasePath);
$items = $this->enrichLegacyWithArchives($items, $legacyBasePath);
}
usort($items, fn($a, $b) => strnatcasecmp((string)($a['legacy_code'] ?? ''), (string)($b['legacy_code'] ?? '')));
return $items;
}
private function scanStabiliFromMdb(string $mdbPath): array
{
$binTables = trim((string)@shell_exec('command -v mdb-tables')) ?: '/usr/bin/mdb-tables';
$binExport = trim((string)@shell_exec('command -v mdb-export')) ?: '/usr/bin/mdb-export';
$tableGuess = 'Stabili';
$tables = @shell_exec(sprintf('%s -1 %s 2>/dev/null', escapeshellarg($binTables), escapeshellarg($mdbPath))) ?: '';
if ($tables) {
foreach (preg_split('/\r?\n/', trim($tables)) as $t) {
if ($t === "") continue;
if (preg_match('/stabil/i', $t)) {
$tableGuess = trim($t);
break;
}
}
}
$tmp = tempnam(sys_get_temp_dir(), 'mdbcsv_');
$cmd = sprintf(
'%s -D %s -d %s -q %s -R "\\n" %s %s > %s 2>/dev/null',
escapeshellarg($binExport),
escapeshellarg('%Y-%m-%d'),
escapeshellarg('|'),
escapeshellarg('"'),
escapeshellarg($mdbPath),
escapeshellarg($tableGuess),
escapeshellarg($tmp)
);
@shell_exec($cmd);
if (!is_file($tmp) || filesize($tmp) === 0) {
@unlink($tmp);
return [];
}
$fh = fopen($tmp, 'r');
if (!$fh) {
@unlink($tmp);
return [];
}
$headers = fgetcsv($fh, 0, '|');
if (!$headers) {
fclose($fh);
@unlink($tmp);
return [];
}
$headers = array_map(fn($h) => strtolower(trim((string)$h)), $headers);
$items = [];
while (($cols = fgetcsv($fh, 0, '|')) !== false) {
if ($cols === [null] || $cols === false) continue;
$cols = array_map(fn($v) => is_string($v) ? trim($v) : $v, $cols);
$countH = count($headers);
if (count($cols) < $countH) $cols = array_pad($cols, $countH, null);
if (count($cols) > $countH) $cols = array_slice($cols, 0, $countH);
$row = @array_combine($headers, $cols);
if (!$row) continue;
$legacyCode = $row['nome_directory'] ?? ($row['internet_cod_stab'] ?? ($row['cod_stabile'] ?? null));
$denom = $row['denominazione'] ?? ($row['fe_denominazione'] ?? null);
if ($legacyCode) {
$items[] = ['legacy_code' => trim((string)$legacyCode), 'denominazione' => $denom ? trim((string)$denom) : null];
}
}
fclose($fh);
@unlink($tmp);
$byCode = [];
foreach ($items as $it) {
if (!empty($it['legacy_code'])) $byCode[$it['legacy_code']] = $it;
}
ksort($byCode, SORT_NATURAL);
return array_values($byCode);
}
private function sampleStabileFromMdb(string $mdbPath, ?string $legacyCode, int $index = 0): array
{
$binTables = trim((string)@shell_exec('command -v mdb-tables')) ?: '/usr/bin/mdb-tables';
$binExport = trim((string)@shell_exec('command -v mdb-export')) ?: '/usr/bin/mdb-export';
$tableGuess = 'Stabili';
$tables = @shell_exec(sprintf('%s -1 %s 2>/dev/null', escapeshellarg($binTables), escapeshellarg($mdbPath))) ?: '';
if ($tables) {
foreach (preg_split('/\r?\n/', trim($tables)) as $t) {
if ($t === '') continue;
if (preg_match('/stabil/i', $t)) {
$tableGuess = trim($t);
break;
}
}
}
$tmp = tempnam(sys_get_temp_dir(), 'mdbcsv_');
$cmd = sprintf(
'%s -D %s -d %s -q %s -R "\\n" %s %s > %s 2>/dev/null',
escapeshellarg($binExport),
escapeshellarg('%Y-%m-%d'),
escapeshellarg('|'),
escapeshellarg('"'),
escapeshellarg($mdbPath),
escapeshellarg($tableGuess),
escapeshellarg($tmp)
);
@shell_exec($cmd);
if (!is_file($tmp) || filesize($tmp) === 0) {
@unlink($tmp);
return [];
}
$fh = fopen($tmp, 'r');
if (!$fh) {
@unlink($tmp);
return [];
}
$headers = fgetcsv($fh, 0, '|');
if (!$headers) {
fclose($fh);
@unlink($tmp);
return [];
}
$headers = array_map(fn($h) => strtolower(trim((string)$h)), $headers);
$rowData = [];
$i = 0;
while (($cols = fgetcsv($fh, 0, '|')) !== false) {
if ($cols === [null]) continue;
$cols = array_map(fn($v) => is_string($v) ? trim($v) : $v, $cols);
$countH = count($headers);
if (count($cols) < $countH) $cols = array_pad($cols, $countH, null);
if (count($cols) > $countH) $cols = array_slice($cols, 0, $countH);
$row = @array_combine($headers, $cols) ?: [];
$legacyKey = $row['nome_directory'] ?? ($row['internet_cod_stab'] ?? ($row['cod_stabile'] ?? null));
if ($legacyCode) {
if ((string)$legacyKey === (string)$legacyCode) {
$rowData = $row;
break;
}
} else {
if ($i++ >= $index) {
$rowData = $row;
break;
}
}
}
fclose($fh);
@unlink($tmp);
if (empty($rowData)) return [];
$rowData['legacy_key'] = (string)($rowData['nome_directory'] ?? ($rowData['internet_cod_stab'] ?? ($rowData['cod_stabile'] ?? '')));
return $rowData;
}
private function scanLegacyCodesFromDir(string $basePath): array
{
$items = [];
if (!is_dir($basePath)) return $items;
try {
$dh = opendir($basePath);
if ($dh) {
while (($file = readdir($dh)) !== false) {
if ($file === '.' || $file === '..') continue;
$full = rtrim($basePath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file;
if (!is_dir($full)) continue;
$code = null;
if (preg_match('/^(\d{2,5})/', $file, $m)) {
$code = $m[1];
} elseif (preg_match('/(\d{2,5})/', $file, $m)) {
$code = $m[1];
}
$hasGenerale = is_file($full . DIRECTORY_SEPARATOR . 'generale_stabile.mdb');
$hasYears = false;
if (is_dir($full)) {
try {
$sub = opendir($full);
if ($sub) {
while (($yf = readdir($sub)) !== false) {
if ($yf === '.' || $yf === '..') continue;
if (!preg_match('/^\d{4}$/', $yf)) continue;
$ya = $full . DIRECTORY_SEPARATOR . $yf . DIRECTORY_SEPARATOR . 'singolo_anno.mdb';
if (is_file($ya)) {
$hasYears = true;
break;
}
}
closedir($sub);
}
} catch (\Throwable $e) {
}
}
if ($code || $hasGenerale || $hasYears) {
$items[] = ['legacy_code' => $code ?: $file, 'denominazione' => null];
}
}
closedir($dh);
}
} catch (\Throwable $e) { /* ignore */
}
$byCode = [];
foreach ($items as $it) {
$c = (string)($it['legacy_code'] ?? '');
if ($c !== '') {
$byCode[$c] = $it;
}
}
uksort($byCode, 'strnatcasecmp');
return array_values($byCode);
}
private function enrichLegacyWithArchives(array $items, string $basePath): array
{
$enriched = [];
foreach ($items as $it) {
$code = trim((string)($it['legacy_code'] ?? ''));
if ($code === '') {
$enriched[] = $it;
continue;
}
$dir = rtrim($basePath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $code;
$hasGenerale = is_file($dir . DIRECTORY_SEPARATOR . 'generale_stabile.mdb');
$yearsCount = 0;
if (is_dir($dir)) {
try {
$dh = opendir($dir);
if ($dh) {
while (($f = readdir($dh)) !== false) {
if ($f === '.' || $f === '..') continue;
if (!preg_match('/^\d{4}$/', $f)) continue;
$sub = $dir . DIRECTORY_SEPARATOR . $f . DIRECTORY_SEPARATOR . 'singolo_anno.mdb';
if (is_file($sub)) $yearsCount++;
}
closedir($dh);
}
} catch (\Throwable $e) {
}
}
$it['has_generale'] = $hasGenerale;
$it['years_count'] = $yearsCount;
$enriched[] = $it;
}
return $enriched;
}
}