diff --git a/htdocs/core/ajax/onlineSign.php b/htdocs/core/ajax/onlineSign.php
index f24ed4e9b36..da25632abdb 100644
--- a/htdocs/core/ajax/onlineSign.php
+++ b/htdocs/core/ajax/onlineSign.php
@@ -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 {
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 5a2ef75c572..40853f107f8 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -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";
+ }
+}
diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
index 6fd9c738929..978ade1f12e 100644
--- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
@@ -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
diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
index 8055b070c8a..0f090cf26a3 100644
--- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
@@ -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
diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php
index b1e96f623d2..2a7c46dee7e 100644
--- a/htdocs/public/onlinesign/newonlinesign.php
+++ b/htdocs/public/onlinesign/newonlinesign.php
@@ -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 '
';