From 8afd78c111af44ab81e565d076e2fac855eaa50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Wed, 11 Mar 2026 13:37:11 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[hr]=20DomPDF=20setOptions=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=E2=80=94=20chroot=20=EB=8D=AE=EC=96=B4=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=8F=B0=ED=8A=B8=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EC=8B=A4=ED=8C=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - setOptions()가 config의 chroot(base_path)를 new Options()로 전체 교체 → vendor 기본값으로 리셋 - resource_path 폰트 경로가 chroot 밖으로 판정되어 registerFont() false 반환 - setOptions 제거 → config/dompdf.php 설정(font_dir, font_cache, chroot) 그대로 사용 - storage 수동 복사도 제거 → DomPDF가 내부적으로 font_dir에 복사 + .ufm 생성 Co-Authored-By: Claude Opus 4.6 --- app/Services/HR/PayrollService.php | 44 +++++++++--------------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/app/Services/HR/PayrollService.php b/app/Services/HR/PayrollService.php index c9118859..c68ce657 100644 --- a/app/Services/HR/PayrollService.php +++ b/app/Services/HR/PayrollService.php @@ -879,12 +879,7 @@ public function sendPayslip(int $id): ?array // PDF 생성 (한글 폰트를 동일 인스턴스에 등록) $month = str_pad($payslipData['pay_month'], 2, '0', STR_PAD_LEFT); $pdf = Pdf::loadView('emails.payslip', ['payslipData' => $payslipData]) - ->setPaper('a4') - ->setOptions([ - 'font_dir' => storage_path('fonts'), - 'font_cache' => storage_path('fonts'), - 'enable_font_subsetting' => true, - ]); + ->setPaper('a4'); $this->registerKoreanFont($pdf); $pdfContent = $pdf->output(); $fileName = "{$payslipData['pay_year']}년{$month}월_급여명세서_{$payslipData['employee_name']}.pdf"; @@ -905,47 +900,34 @@ public function sendPayslip(int $id): ?array /** * PDF 인스턴스에 한글(Pretendard) 폰트 등록 + * * - render() 전에 동일 DomPDF 인스턴스에 등록해야 적용됨 - * - 폰트 원본은 resources/fonts/에 프로젝트와 함께 배포 + * - resource_path() 원본을 직접 전달 (storage symlink는 chroot 밖이라 차단됨) + * - DomPDF가 내부적으로 font_dir에 복사 + .ufm 메트릭 생성 */ private function registerKoreanFont(\Barryvdh\DomPDF\PDF $pdf): void { - $fontDir = storage_path('fonts'); - if (! is_dir($fontDir)) { - mkdir($fontDir, 0755, true); - } - - // 프로젝트에 포함된 폰트 (Git으로 배포됨) - $fontSources = [ - 'normal' => resource_path('fonts/Pretendard-Regular.ttf'), - 'bold' => resource_path('fonts/Pretendard-Bold.ttf'), - ]; - - if (! file_exists($fontSources['normal'])) { + $normalFont = resource_path('fonts/Pretendard-Regular.ttf'); + if (! file_exists($normalFont)) { return; } - // storage/fonts/에 복사 - foreach ($fontSources as $weight => $src) { - $dst = $fontDir.'/'.basename($src); - if (! file_exists($dst)) { - copy($src, $dst); - } - } - - // 동일 DomPDF 인스턴스에 폰트 등록 (핵심: $pdf->getDomPDF()) $dompdf = $pdf->getDomPDF(); $fm = $dompdf->getFontMetrics(); + $fm->registerFont( ['family' => 'pretendard', 'style' => 'normal', 'weight' => 'normal'], - $fontDir.'/Pretendard-Regular.ttf' + $normalFont ); - if (file_exists($fontDir.'/Pretendard-Bold.ttf')) { + + $boldFont = resource_path('fonts/Pretendard-Bold.ttf'); + if (file_exists($boldFont)) { $fm->registerFont( ['family' => 'pretendard', 'style' => 'normal', 'weight' => 'bold'], - $fontDir.'/Pretendard-Bold.ttf' + $boldFont ); } + $fm->saveFontFamilies(); }