/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; } }