GWM : megre pdf

This commit is contained in:
Gowtham M 2026-05-11 17:51:52 +05:30
parent 840780d3a1
commit a41d390768

View File

@ -13,14 +13,14 @@ if (! defined('MERGED_CLAIM_FILE_TYPE')) {
if (! function_exists('merge_ticket_pdfs')) {
/**
* Merge all active PDF rows in claim_files for a given ticket_master id
* Merge all active PDF/image rows in claim_files for a given ticket_master id
* into one combined PDF and register that PDF as a new claim_files row
* with file_type = MERGED_CLAIM_FILE_TYPE.
*
* Source rows are picked from claim_files where:
* - ticket_id = $ticket_master_id
* - is_active = 1
* - mime_type = 'application/pdf'
* - mime_type IN $opts['include_mime_types'] (default PDF/JPG/PNG)
* - file_type IN $opts['include_file_types'] (default [2, 3])
*
* @param int $ticket_master_id
@ -29,6 +29,7 @@ if (! function_exists('merge_ticket_pdfs')) {
* @var int $created_by Override created_by user id on the inserted row.
* @var int $ticket_type Default 1. Stored on the inserted claim_files row.
* @var array $include_file_types Default [2, 3].
* @var array $include_mime_types Default ['application/pdf', 'image/jpeg', 'image/png'].
* }
* @return array {status, merged_file_id, file_name, pages, source_count, message}
*/
@ -39,6 +40,7 @@ if (! function_exists('merge_ticket_pdfs')) {
'created_by' => null,
'ticket_type' => 1,
'include_file_types' => [2, 3],
'include_mime_types' => ['application/pdf', 'image/jpeg', 'image/png'],
];
$result = [
@ -60,14 +62,14 @@ if (! function_exists('merge_ticket_pdfs')) {
$rows = $claimFiles
->where('ticket_id', $ticket_master_id)
->where('is_active', 1)
->where('mime_type', 'application/pdf')
->whereIn('mime_type', $opts['include_mime_types'])
->whereIn('file_type', $opts['include_file_types'])
->orderBy('id', 'ASC')
->findAll();
if (empty($rows)) {
$result['status'] = true;
$result['message'] = 'No PDF files to merge';
$result['message'] = 'No PDF/image files to merge';
return $result;
}
@ -75,7 +77,7 @@ if (! function_exists('merge_ticket_pdfs')) {
. 'uploads' . DIRECTORY_SEPARATOR
. 'claim_files' . DIRECTORY_SEPARATOR;
$sourcePaths = [];
$sourceFiles = [];
foreach ($rows as $row) {
$name = ! empty($row['url']) ? $row['url'] : ($row['file_name'] ?? '');
if (empty($name)) {
@ -84,18 +86,22 @@ if (! function_exists('merge_ticket_pdfs')) {
// url column may sometimes hold a full URL; we only care about the file basename on disk.
$full = $uploadDir . basename($name);
if (is_file($full) && is_readable($full)) {
$sourcePaths[] = $full;
$sourceFiles[] = [
'path' => $full,
'mime' => strtolower((string) ($row['mime_type'] ?? '')),
'id' => $row['id'] ?? null,
];
} else {
log_message('error', "merge_ticket_pdfs | missing PDF on disk | claim_file_id={$row['id']} | path={$full}");
log_message('error', "merge_ticket_pdfs | missing file on disk | claim_file_id={$row['id']} | path={$full}");
}
}
if (empty($sourcePaths)) {
$result['message'] = 'No readable PDF files on disk';
if (empty($sourceFiles)) {
$result['message'] = 'No readable PDF/image files on disk';
return $result;
}
$result['source_count'] = count($sourcePaths);
$result['source_count'] = count($sourceFiles);
$tempDir = rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'mpdf';
if (! is_dir($tempDir)) {
@ -112,18 +118,24 @@ if (! function_exists('merge_ticket_pdfs')) {
]);
$totalPages = 0;
foreach ($sourcePaths as $src) {
foreach ($sourceFiles as $sourceFile) {
$src = $sourceFile['path'];
try {
$pageCount = $mpdf->setSourceFile($src);
for ($p = 1; $p <= $pageCount; $p++) {
$tplId = $mpdf->importPage($p);
$size = $mpdf->getTemplateSize($tplId);
$mpdf->AddPageByArray([
'orientation' => ($size['width'] > $size['height']) ? 'L' : 'P',
'sheet-size' => [$size['width'], $size['height']],
]);
$mpdf->useTemplate($tplId);
$totalPages++;
if ($sourceFile['mime'] === 'application/pdf') {
$pageCount = $mpdf->setSourceFile($src);
for ($p = 1; $p <= $pageCount; $p++) {
$tplId = $mpdf->importPage($p);
$mpdf->AddPage();
// adjustPageSize=true makes the output page match the imported page.
$mpdf->useTemplate($tplId, 0, 0, null, null, true);
$totalPages++;
}
} elseif (in_array($sourceFile['mime'], ['image/jpeg', 'image/png'], true)) {
if (merge_ticket_pdf_add_image_page($mpdf, $src)) {
$totalPages++;
}
} else {
log_message('error', "merge_ticket_pdfs | unsupported source mime {$sourceFile['mime']} | {$src}");
}
} catch (\Throwable $e) {
log_message('error', "merge_ticket_pdfs | failed to import {$src} | " . $e->getMessage());
@ -131,7 +143,7 @@ if (! function_exists('merge_ticket_pdfs')) {
}
if ($totalPages === 0) {
$result['message'] = 'All source PDFs failed to import';
$result['message'] = 'All source PDF/image files failed to import';
return $result;
}
@ -192,3 +204,48 @@ if (! function_exists('merge_ticket_pdfs')) {
return $result;
}
}
if (! function_exists('merge_ticket_pdf_add_image_page')) {
/**
* Add an uploaded image as a single PDF page, preserving portrait/landscape
* orientation and fitting the image proportionally inside the page.
*/
function merge_ticket_pdf_add_image_page(Mpdf $mpdf, string $imagePath): bool
{
$imageInfo = @getimagesize($imagePath);
if (empty($imageInfo[0]) || empty($imageInfo[1])) {
log_message('error', "merge_ticket_pdfs | invalid image | {$imagePath}");
return false;
}
$imageWidthPx = (int) $imageInfo[0];
$imageHeightPx = (int) $imageInfo[1];
$isLandscape = $imageWidthPx > $imageHeightPx;
$pageWidth = $isLandscape ? 297 : 210;
$pageHeight = $isLandscape ? 210 : 297;
$margin = 0;
$availableWidth = $pageWidth - ($margin * 2);
$availableHeight = $pageHeight - ($margin * 2);
$scale = min($availableWidth / $imageWidthPx, $availableHeight / $imageHeightPx);
$drawWidth = $imageWidthPx * $scale;
$drawHeight = $imageHeightPx * $scale;
$x = ($pageWidth - $drawWidth) / 2;
$y = ($pageHeight - $drawHeight) / 2;
$mpdf->AddPageByArray([
'orientation' => $isLandscape ? 'L' : 'P',
'sheet-size' => 'A4',
'margin-left' => 0,
'margin-right' => 0,
'margin-top' => 0,
'margin-bottom' => 0,
'margin-header' => 0,
'margin-footer' => 0,
]);
$mpdf->Image($imagePath, $x, $y, $drawWidth, $drawHeight);
return true;
}
}