netgescon-day0/app/Support/TecnoRepairMdbReader.php

105 lines
2.8 KiB
PHP

<?php
namespace App\Support;
use RuntimeException;
use Symfony\Component\Process\Process;
class TecnoRepairMdbReader
{
/**
* @return array<int,string>
*/
public function listTables(string $mdbPath): array
{
$bin = $this->resolveBinary('mdb-tables');
$process = new Process([$bin, '-1', $mdbPath]);
$process->run();
if (! $process->isSuccessful()) {
throw new RuntimeException(trim($process->getErrorOutput()) ?: 'Impossibile leggere le tabelle MDB.');
}
return array_values(array_filter(array_map('trim', preg_split('/\r\n|\r|\n/', $process->getOutput()) ?: [])));
}
/**
* @return array<int,array<string,string|null>>
*/
public function exportTable(string $mdbPath, string $table): array
{
$bin = $this->resolveBinary('mdb-export');
$process = new Process([$bin, '-D', '%Y-%m-%d %H:%M:%S', '-q', '^', $mdbPath, $table]);
$process->run();
if (! $process->isSuccessful()) {
throw new RuntimeException(trim($process->getErrorOutput()) ?: ('Impossibile esportare la tabella ' . $table));
}
$csv = $process->getOutput();
if (trim($csv) === '') {
return [];
}
return $this->parseCsv($csv);
}
public function resolveBinary(string $name): string
{
$process = new Process(['sh', '-lc', 'command -v ' . escapeshellarg($name)]);
$process->run();
$path = trim($process->getOutput());
if ($path === '') {
throw new RuntimeException($name . ' non trovato. Installa mdbtools sul server Day0.');
}
return $path;
}
/**
* @return array<int,array<string,string|null>>
*/
private function parseCsv(string $csv): array
{
$handle = fopen('php://temp', 'r+');
if ($handle === false) {
throw new RuntimeException('Impossibile creare buffer CSV in memoria.');
}
fwrite($handle, $csv);
rewind($handle);
$headers = fgetcsv($handle, 0, ',', '^');
if (! is_array($headers) || $headers === []) {
fclose($handle);
return [];
}
$headers = array_map(static fn($value): string => trim((string) $value), $headers);
$rows = [];
while (($line = fgetcsv($handle, 0, ',', '^')) !== false) {
if ($line === [null] || $line === []) {
continue;
}
$row = [];
foreach ($headers as $index => $header) {
if ($header === '') {
continue;
}
$value = $line[$index] ?? null;
$row[$header] = is_string($value) ? trim($value) : $value;
}
$rows[] = $row;
}
fclose($handle);
return $rows;
}
}