108 lines
3.4 KiB
PHP
108 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Model\Sdf;
|
|
|
|
use Nette\Utils\FileSystem;
|
|
use Nette\Utils\Json;
|
|
|
|
class SdfCompactExporter
|
|
{
|
|
public function __construct(
|
|
private string $scriptPath,
|
|
private string $sdfPassword
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Přečte SQL Compact .sdf a vrátí tabulky jako pole.
|
|
*
|
|
* @return array{uzivatel: array, zakaznik: array, faktura: array, polozka: array, platba: array, konfigurace: array}
|
|
*/
|
|
public function export(string $sdfPath): array
|
|
{
|
|
if (!is_file($sdfPath)) {
|
|
throw new \RuntimeException('SDF soubor nebyl nalezen.');
|
|
}
|
|
if (!is_file($this->scriptPath)) {
|
|
throw new \RuntimeException('Exportní skript bin/sdf-export.ps1 chybí.');
|
|
}
|
|
|
|
$workDir = dirname($sdfPath) . DIRECTORY_SEPARATOR . 'export-' . bin2hex(random_bytes(4));
|
|
FileSystem::createDir($workDir);
|
|
$outFile = $workDir . DIRECTORY_SEPARATOR . 'export.json';
|
|
|
|
try {
|
|
$this->runPowershell($sdfPath, $outFile);
|
|
$raw = FileSystem::read($outFile);
|
|
$data = Json::decode($raw, forceArrays: true);
|
|
if (!is_array($data)) {
|
|
throw new \RuntimeException('Export SDF nevrátil platná data.');
|
|
}
|
|
|
|
return [
|
|
'uzivatel' => $data['uzivatel'] ?? [],
|
|
'zakaznik' => $data['zakaznik'] ?? [],
|
|
'faktura' => $data['faktura'] ?? [],
|
|
'polozka' => $data['polozka'] ?? [],
|
|
'platba' => $data['platba'] ?? [],
|
|
'konfigurace' => $data['konfigurace'] ?? [],
|
|
];
|
|
} finally {
|
|
FileSystem::delete($workDir);
|
|
}
|
|
}
|
|
|
|
private function runPowershell(string $sdfPath, string $outFile): void
|
|
{
|
|
$powershell = $this->findPowershell();
|
|
$cmd = sprintf(
|
|
'%s -NoProfile -NonInteractive -ExecutionPolicy Bypass -File %s -SdfPath %s -OutFile %s -Password %s',
|
|
$this->winArg($powershell),
|
|
$this->winArg($this->scriptPath),
|
|
$this->winArg($sdfPath),
|
|
$this->winArg($outFile),
|
|
$this->winArg($this->sdfPassword)
|
|
);
|
|
|
|
$descriptor = [
|
|
1 => ['pipe', 'w'],
|
|
2 => ['pipe', 'w'],
|
|
];
|
|
$process = proc_open($cmd, $descriptor, $pipes, null, null, ['bypass_shell' => false]);
|
|
if (!is_resource($process)) {
|
|
throw new \RuntimeException('Nepodařilo se spustit PowerShell pro čtení SDF.');
|
|
}
|
|
|
|
$stdout = stream_get_contents($pipes[1]);
|
|
$stderr = stream_get_contents($pipes[2]);
|
|
fclose($pipes[1]);
|
|
fclose($pipes[2]);
|
|
$code = proc_close($process);
|
|
|
|
if ($code !== 0 || !is_file($outFile)) {
|
|
$detail = trim($stderr . "\n" . $stdout);
|
|
throw new \RuntimeException('Export SDF selhal' . ($detail !== '' ? ': ' . $detail : '.'));
|
|
}
|
|
}
|
|
|
|
private function findPowershell(): string
|
|
{
|
|
$candidates = [
|
|
getenv('SystemRoot') . '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',
|
|
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',
|
|
];
|
|
foreach ($candidates as $path) {
|
|
if ($path && is_file($path)) {
|
|
return $path;
|
|
}
|
|
}
|
|
|
|
return 'powershell.exe';
|
|
}
|
|
|
|
private function winArg(string $value): string
|
|
{
|
|
return '"' . str_replace('"', '\\"', $value) . '"';
|
|
}
|
|
}
|