NEW The signature is on the good page even if another module add pages

This commit is contained in:
ldestailleur 2025-03-20 12:01:18 +01:00
parent c3f46bd2e0
commit bb3989c9a7
5 changed files with 57 additions and 5 deletions

View file

@ -152,6 +152,7 @@ if ($action == "importSignature") {
if (preg_match('/\.pdf/i', $last_main_doc_file)) {
$ref_pdf = pathinfo($last_main_doc_file, PATHINFO_FILENAME); // Retrieves the name of external or internal PDF
$ref_pdf = preg_replace('/_signed-(\d+)/', '', $ref_pdf);
$newpdffilename = $upload_dir . $ref_pdf . "_signed-" . $date . ".pdf";
$sourcefile = $upload_dir . $ref_pdf . ".pdf";
@ -183,6 +184,8 @@ if ($action == "importSignature") {
$param['online_sign_name'] = $online_sign_name;
$param['pathtoimage'] = $upload_dir . $filename;
$propalsignonspecificpage = getDolGlobalInt("PROPAL_SIGNATURE_ON_SPECIFIC_PAGE");
$s = array(); // Array with size of each page. Example array(w'=>210, 'h'=>297);
for ($i = 1; $i < ($pagecount + 1); $i++) {
try {
@ -190,11 +193,20 @@ if ($action == "importSignature") {
$s = $pdf->getTemplatesize($tppl);
$pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
$pdf->useTemplate($tppl);
$propalsignonspecificpage = getDolGlobalInt("PROPAL_SIGNATURE_ON_SPECIFIC_PAGE");
if ($propalsignonspecificpage < 0) {
$propalsignonspecificpage = $pagecount - abs($propalsignonspecificpage);
}
if (empty($propalsignonspecificpage)) {
// Now we get the metadata keywords from the $sourcefile PDF (by parsing the binary PDF file) and use it to extract
// the page x in PAGESIGN=x into $propalsignonspecificpage
$keywords = pdfExtractMetadata($sourcefile, 'Keywords');
$reg = array();
if (preg_match('/PAGESIGN=(\d+)/', $keywords, $reg)) {
$propalsignonspecificpage = (int) $reg[1];
}
}
if (getDolGlobalString("PROPAL_SIGNATURE_ON_ALL_PAGES") || $propalsignonspecificpage == $i) {
// A signature image file is 720 x 180 (ratio 1/4) but we use only the size into PDF
// TODO Get position of box from PDF template
@ -224,10 +236,9 @@ if ($action == "importSignature") {
}
}
if (!getDolGlobalString("PROPAL_SIGNATURE_ON_ALL_PAGES") && !getDolGlobalInt("PROPAL_SIGNATURE_ON_SPECIFIC_PAGE")) {
if (!getDolGlobalString("PROPAL_SIGNATURE_ON_ALL_PAGES") && !$propalsignonspecificpage) {
// We do not found specific instruction or page for the signature, so we add it now we are on the last page.
// A signature image file is 720 x 180 (ratio 1/4) but we use only the size into PDF
// TODO Get position of box from PDF template
if (getDolGlobalString("PROPAL_SIGNATURE_XFORIMGSTART")) {
$param['xforimgstart'] = getDolGlobalString("PROPAL_SIGNATURE_XFORIMGSTART");
} else {

View file

@ -2783,3 +2783,34 @@ function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails =
}
return 0;
}
/**
* Function to extract metadata from a PDF file by doing a binary parsing of the PDF file
*
* @param string $file Path of file
* @param string $field Key to extract
* @return int|string
*/
function pdfExtractMetadata($file, $field = 'Keywords')
{
if (!dol_is_file($file)) {
return "ERROR: FILE NOT FOUND OR NOT VALID";
}
// Get content of PDF file
$content = file_get_contents(dol_osencode($file));
// Use a regex to capture the metadata
if ($content) {
$matches = array();
// Remove non printablecaracters
$content = preg_replace('/[^(\x20-\x7F)]*/', '', $content);
if (preg_match('/\/' . preg_quote($field, '/') . '\s*\((.*?)\)/', $content, $matches)) {
return trim($matches[1]);
}
return "ERROR: NOT FOUND";
} else {
return "ERROR: FAILED TO READ PDF";
}
}

View file

@ -757,6 +757,10 @@ class pdf_azur extends ModelePDFPropales
// Customer signature area
if (!getDolGlobalString('PROPAL_DISABLE_SIGNATURE')) {
$posy = $this->_signature_area($pdf, $object, $posy, $outputlangs);
// Rewrite keywords to add a tag with the numero of page that contains the signature section
$keywords = $outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name);
$pdf->SetKeyWords($keywords." PAGESIGN=".$pdf->getPage());
}
// Pied de page

View file

@ -879,6 +879,10 @@ class pdf_cyan extends ModelePDFPropales
// Customer signature area
if (!getDolGlobalString('PROPAL_DISABLE_SIGNATURE')) {
$posy = $this->drawSignatureArea($pdf, $object, $posy, $outputlangs);
// Rewrite keywords to add a tag with the numero of page that contains the signature section
$keywords = $outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name);
$pdf->SetKeyWords($keywords." PAGESIGN=".$pdf->getPage());
}
// Add number of pages in footer

View file

@ -420,6 +420,8 @@ if ($source == 'proposal') {
$last_main_doc_file = $object->last_main_doc;
if ($object->status == $object::STATUS_VALIDATED) {
$object->last_main_doc = preg_replace('/_signed-(\d+)/', '', $object->last_main_doc); // We want to be sure to not work on the signed version
if (empty($last_main_doc_file) || !dol_is_file(DOL_DATA_ROOT.'/'.$object->last_main_doc)) {
// It seems document has never been generated, or was generated and then deleted.
// So we try to regenerate it with its default template.
@ -448,7 +450,7 @@ if ($source == 'proposal') {
$datefilesigned = dol_filemtime($last_main_doc_file);
$datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed);
if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) {
if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) { // If file signed is more recent
$directdownloadlink = $object->getLastMainDocLink('proposal');
if ($directdownloadlink) {
print '<br><a href="'.$directdownloadlink.'">';