Files
sam-manage/app/Services/ESign/DocxToPdfConverter.php
2026-02-25 11:45:01 +09:00

89 lines
2.7 KiB
PHP

<?php
namespace App\Services\ESign;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use RuntimeException;
class DocxToPdfConverter
{
/**
* Word 파일이면 PDF로 변환, PDF면 그대로 저장.
*
* @return array{path: string, name: string, hash: string, size: int}
*/
public function convertAndStore(UploadedFile $file, string $storagePath): array
{
if (! $this->isWordFile($file)) {
// PDF는 그대로 저장
$path = $file->store($storagePath, 'local');
return [
'path' => $path,
'name' => $file->getClientOriginalName(),
'hash' => hash_file('sha256', $file->getRealPath()),
'size' => $file->getSize(),
];
}
// Word → PDF 변환
$originalName = $file->getClientOriginalName();
$pdfName = preg_replace('/\.(docx?|DOCX?)$/', '.pdf', $originalName);
$tmpDir = sys_get_temp_dir().'/esign_convert_'.Str::random(16);
mkdir($tmpDir, 0755, true);
try {
$tmpWordPath = $tmpDir.'/'.'source.'.$file->getClientOriginalExtension();
copy($file->getRealPath(), $tmpWordPath);
$command = sprintf(
'HOME=%s libreoffice --headless --convert-to pdf --outdir %s %s 2>&1',
escapeshellarg($tmpDir),
escapeshellarg($tmpDir),
escapeshellarg($tmpWordPath)
);
exec($command, $output, $exitCode);
if ($exitCode !== 0) {
throw new RuntimeException(
'LibreOffice 변환 실패 (exit code: '.$exitCode.'): '.implode("\n", $output)
);
}
$tmpPdfPath = $tmpDir.'/source.pdf';
if (! file_exists($tmpPdfPath)) {
throw new RuntimeException('변환된 PDF 파일을 찾을 수 없습니다.');
}
$hash = hash_file('sha256', $tmpPdfPath);
$size = filesize($tmpPdfPath);
// 최종 저장 경로
$finalPath = $storagePath.'/'.Str::random(40).'.pdf';
Storage::disk('local')->put($finalPath, file_get_contents($tmpPdfPath));
return [
'path' => $finalPath,
'name' => $pdfName,
'hash' => $hash,
'size' => $size,
];
} finally {
// 임시 파일 정리
array_map('unlink', glob($tmpDir.'/*'));
@rmdir($tmpDir);
}
}
public function isWordFile(UploadedFile $file): bool
{
$ext = strtolower($file->getClientOriginalExtension());
return in_array($ext, ['doc', 'docx']);
}
}