140 lines
4.5 KiB
PHP
140 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Libraries;
|
|
|
|
use Dompdf\Dompdf;
|
|
use Dompdf\Options;
|
|
|
|
/**
|
|
* Renders Medi Assist Portfolio Analysis MIS HTML to PDF via DomPDF.
|
|
*/
|
|
class MediAssistMisPdfService
|
|
{
|
|
/**
|
|
* @param array<string,mixed> $report
|
|
* @return array{status:bool,message?:string,content?:string,filename?:string}
|
|
*/
|
|
public function generateFromReport(array $report, int $policyId): array
|
|
{
|
|
$vm = $report['view_model'] ?? $report;
|
|
$policyNo = trim((string) ($report['header']['policy_number'] ?? (string) $policyId));
|
|
|
|
$html = view('claims_mis_medi_assist', [
|
|
'report' => $report,
|
|
'view_model' => $vm,
|
|
'policy_id' => $policyId,
|
|
'pdf_url' => '',
|
|
'embed' => true,
|
|
]);
|
|
|
|
return $this->generate($html, $policyNo);
|
|
}
|
|
|
|
/**
|
|
* @return array{status:bool,message?:string,content?:string,filename?:string}
|
|
*/
|
|
public function generate(string $html, string $policyNo): array
|
|
{
|
|
$safePolicy = preg_replace('/[^A-Za-z0-9_\-]+/', '_', $policyNo) ?: 'policy';
|
|
$filename = 'MA_MIS_' . $safePolicy . '_' . date('Ymd') . '.pdf';
|
|
|
|
try {
|
|
$options = new Options();
|
|
$options->set('isHtml5ParserEnabled', true);
|
|
$options->set('isRemoteEnabled', true);
|
|
$options->set('isFontSubsettingEnabled', true);
|
|
$options->set('defaultFont', 'DejaVu Sans');
|
|
$options->setChroot([
|
|
rtrim(ROOTPATH, '/\\'),
|
|
rtrim(FCPATH, '/\\'),
|
|
rtrim(WRITEPATH, '/\\'),
|
|
sys_get_temp_dir(),
|
|
]);
|
|
|
|
$dompdf = new Dompdf($options);
|
|
$dompdf->loadHtml($this->prepareHtml($html));
|
|
$dompdf->setPaper('A4', 'landscape');
|
|
$dompdf->render();
|
|
|
|
$content = $dompdf->output();
|
|
if ($content === '' || $content === null) {
|
|
return ['status' => false, 'message' => 'PDF generation failed: empty output.'];
|
|
}
|
|
|
|
return [
|
|
'status' => true,
|
|
'content' => $content,
|
|
'filename' => $filename,
|
|
];
|
|
} catch (\Throwable $e) {
|
|
log_message('error', 'MediAssistMisPdfService::generate failed | ' . $e->getMessage());
|
|
|
|
return ['status' => false, 'message' => 'PDF generation failed: ' . $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
private function prepareHtml(string $html): string
|
|
{
|
|
$html = preg_replace('#<script\b[^>]*>.*?</script>#is', '', $html) ?? $html;
|
|
$html = preg_replace('/[\x{1F300}-\x{1FAFF}]/u', '', $html) ?? $html;
|
|
|
|
$vars = [
|
|
'var(--blue)' => '#1f4e9c',
|
|
'var(--lightblue)' => '#eaf1fb',
|
|
'var(--header-blue)'=> '#dbe7f8',
|
|
'var(--border)' => '#9fb8dd',
|
|
'var(--row-alt)' => '#f4f7fc',
|
|
'var(--red)' => '#e94b5c',
|
|
'var(--text)' => '#222',
|
|
'var(--muted)' => '#555',
|
|
];
|
|
$html = str_replace(array_keys($vars), array_values($vars), $html);
|
|
$html = preg_replace('#:root\s*\{[^}]*\}#is', '', $html) ?? $html;
|
|
|
|
$html = preg_replace_callback(
|
|
'#(<img\b[^>]*\bsrc=["\'])([^"\']+)(["\'][^>]*>)#i',
|
|
function (array $m): string {
|
|
$src = html_entity_decode($m[2], ENT_QUOTES);
|
|
$dataUri = $this->toDataUri($src);
|
|
|
|
return $m[1] . ($dataUri ?: $src) . $m[3];
|
|
},
|
|
$html
|
|
) ?? $html;
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function toDataUri(string $path): ?string
|
|
{
|
|
$path = trim($path);
|
|
if ($path === '' || str_starts_with($path, 'data:')) {
|
|
return null;
|
|
}
|
|
|
|
if (preg_match('#^file://#i', $path)) {
|
|
$path = preg_replace('#^file://#i', '', $path) ?? $path;
|
|
}
|
|
|
|
if (!is_file($path) || !is_readable($path)) {
|
|
return null;
|
|
}
|
|
|
|
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
|
$mime = match ($ext) {
|
|
'png' => 'image/png',
|
|
'jpg', 'jpeg' => 'image/jpeg',
|
|
'gif' => 'image/gif',
|
|
'webp' => 'image/webp',
|
|
default => 'application/octet-stream',
|
|
};
|
|
|
|
$bytes = @file_get_contents($path);
|
|
if ($bytes === false || $bytes === '') {
|
|
return null;
|
|
}
|
|
|
|
return 'data:' . $mime . ';base64,' . base64_encode($bytes);
|
|
}
|
|
}
|