dolibarr  16.0.5
onlineSign.php
Go to the documentation of this file.
1 <?php
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <https://www.gnu.org/licenses/>.
15  */
16 
22 if (!defined('NOTOKENRENEWAL')) {
23  define('NOTOKENRENEWAL', '1'); // Disables token renewal
24 }
25 if (!defined('NOREQUIREHTML')) {
26  define('NOREQUIREHTML', '1');
27 }
28 if (!defined('NOREQUIREAJAX')) {
29  define('NOREQUIREAJAX', '1');
30 }
31 // Needed for create other object with workflow
32 /*if (!defined('NOREQUIRESOC')) {
33  define('NOREQUIRESOC', '1');
34 }*/
35 if (!defined('NOCSRFCHECK')) {
36  define('NOCSRFCHECK', '1');
37 }
38 // Do not check anti CSRF attack test
39 if (!defined('NOREQUIREMENU')) {
40  define('NOREQUIREMENU', '1');
41 }
42 // If there is no need to load and show top and left menu
43 if (!defined("NOLOGIN")) {
44  define("NOLOGIN", '1');
45 }
46 if (!defined('NOIPCHECK')) {
47  define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
48 }
49 if (!defined('NOBROWSERNOTIF')) {
50  define('NOBROWSERNOTIF', '1');
51 }
52 $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
53 if (is_numeric($entity)) {
54  define("DOLENTITY", $entity);
55 }
56 include '../../main.inc.php';
57 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
58 
59 $action = GETPOST('action', 'aZ09');
60 
61 $signature = GETPOST('signaturebase64');
62 $ref = GETPOST('ref', 'aZ09');
63 $mode = GETPOST('mode', 'aZ09');
64 $SECUREKEY = GETPOST("securekey"); // Secure key
65 
66 $error = 0;
67 $response = "";
68 
69 $type = $mode;
70 
71 // Check securitykey
72 $securekeyseed = '';
73 if ($type == 'proposal') {
74  $securekeyseed = getDolGlobalString('PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN');
75 }
76 
77 if (empty($SECUREKEY) || !dol_verifyHash($securekeyseed.$type.$ref.(empty($conf->multicompany->enabled) ? '' : $entity), $SECUREKEY, '0')) {
78  http_response_code(403);
79  print 'Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref);
80  exit(-1);
81 }
82 
83 
84 /*
85  * Actions
86  */
87 
88 // None
89 
90 
91 /*
92  * View
93  */
94 
95 if ($action == "importSignature") {
96  if (!empty($signature) && $signature[0] == "image/png;base64") {
97  $signature = $signature[1];
98  $data = base64_decode($signature);
99 
100  if ($mode == "propale" || $mode == 'proposal') {
101  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
102  require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
103  $object = new Propal($db);
104  $object->fetch(0, $ref);
105 
106  $upload_dir = !empty($conf->propal->multidir_output[$object->entity])?$conf->propal->multidir_output[$object->entity]:$conf->propal->dir_output;
107  $upload_dir .= '/'.dol_sanitizeFileName($object->ref).'/';
108 
109  $date = dol_print_date(dol_now(), "%Y%m%d%H%M%S");
110  $filename = "signatures/".$date."_signature.png";
111  if (!is_dir($upload_dir."signatures/")) {
112  if (!dol_mkdir($upload_dir."signatures/")) {
113  $response ="Error mkdir. Failed to create dir ".$upload_dir."signatures/";
114  $error++;
115  }
116  }
117 
118  if (!$error) {
119  $return = file_put_contents($upload_dir.$filename, $data);
120  if ($return == false) {
121  $error++;
122  $response = 'Error file_put_content: failed to create signature file.';
123  }
124  }
125 
126  if (!$error) {
127  // Defined modele of doc
128  $last_main_doc_file = $object->last_main_doc;
129  $directdownloadlink = $object->getLastMainDocLink('proposal'); // url to download the $object->last_main_doc
130 
131  if (preg_match('/\.pdf/i', $last_main_doc_file)) {
132  // TODO Use the $last_main_doc_file to defined the $newpdffilename and $sourcefile
133  $newpdffilename = $upload_dir.$ref."_signed-".$date.".pdf";
134  $sourcefile = $upload_dir.$ref.".pdf";
135 
136  if (dol_is_file($sourcefile)) {
137  // We build the new PDF
138  $pdf = pdf_getInstance();
139  if (class_exists('TCPDF')) {
140  $pdf->setPrintHeader(false);
141  $pdf->setPrintFooter(false);
142  }
143  $pdf->SetFont(pdf_getPDFFont($langs));
144 
145  if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
146  $pdf->SetCompression(false);
147  }
148 
149 
150  //$pdf->Open();
151  $pagecount = $pdf->setSourceFile($sourcefile); // original PDF
152 
153  $s = array(); // Array with size of each page. Exemple array(w'=>210, 'h'=>297);
154  for ($i=1; $i<($pagecount+1); $i++) {
155  try {
156  $tppl = $pdf->importPage($i);
157  $s = $pdf->getTemplatesize($tppl);
158  $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
159  $pdf->useTemplate($tppl);
160  } catch (Exception $e) {
161  dol_syslog("Error when manipulating some PDF by onlineSign: ".$e->getMessage(), LOG_ERR);
162  $response = $e->getMessage();
163  $error++;
164  }
165  }
166 
167  // A signature image file is 720 x 180 (ratio 1/4) but we use only the size into PDF
168  // TODO Get position of box from PDF template
169  $xforimgstart = (empty($s['w']) ? 120 : round($s['w'] / 2) + 15);
170  $yforimgstart = (empty($s['h']) ? 240 : $s['h'] - 60);
171  $wforimg = $s['w'] - 20 - $xforimgstart;
172 
173  $pdf->Image($upload_dir.$filename, $xforimgstart, $yforimgstart, $wforimg, round($wforimg / 4));
174  //$pdf->Close();
175  $pdf->Output($newpdffilename, "F");
176 
177  // Index the new file and update the last_main_doc property of object.
178  $object->indexFile($newpdffilename, 1);
179  }
180  } elseif (preg_match('/\.odt/i', $last_main_doc_file)) {
181  // Adding signature on .ODT not yet supported
182  // TODO
183  } else {
184  // Document format not supported to insert online signature.
185  // We should just create an image file with the signature.
186  }
187  }
188 
189  if (!$error) {
190  $db->begin();
191 
192  $online_sign_ip = getUserRemoteIP();
193  $online_sign_name = ''; // TODO Ask name on form to sign
194 
195  $sql = "UPDATE ".MAIN_DB_PREFIX."propal";
196  $sql .= " SET fk_statut = ".((int) $object::STATUS_SIGNED).", note_private = '".$db->escape($object->note_private)."',";
197  $sql .= " date_signature = '".$db->idate(dol_now())."',";
198  $sql .= " online_sign_ip = '".$db->escape($online_sign_ip)."'";
199  if ($online_sign_name) {
200  $sql .= ", online_sign_name = '".$db->escape($online_sign_name)."'";
201  }
202  $sql .= " WHERE rowid = ".((int) $object->id);
203 
204  dol_syslog(__METHOD__, LOG_DEBUG);
205  $resql = $db->query($sql);
206  if (!$resql) {
207  $error++;
208  } else {
209  $num = $db->affected_rows($resql);
210  }
211 
212  if (!$error) {
213  $db->commit();
214  $response = "success";
215  setEventMessages("PropalSigned", null, 'warnings');
216  if (method_exists($object, 'call_trigger')) {
217  //customer is not a user !?! so could we use same user as validation ?
218  $user = new User($db);
219  $user->fetch($object->user_valid_id);
220  $result = $object->call_trigger('PROPAL_CLOSE_SIGNED', $user);
221  if ($result < 0) {
222  $error++;
223  }
224  }
225  } else {
226  $db->rollback();
227  $error++;
228  $response = "error sql";
229  }
230  }
231  }
232  } else {
233  $error++;
234  $response = 'error signature_not_found';
235  }
236 }
237 
238 if ($error) {
239  http_response_code(501);
240 }
241 
242 echo $response;
dol_escape_htmltag
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
Definition: functions.lib.php:1468
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:484
pdf_getInstance
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition: pdf.lib.php:126
dol_verifyHash
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...
Definition: security.lib.php:151
pdf_getPDFFont
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition: pdf.lib.php:265
dol_is_file
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:477
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2514
Exception
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1603
getDolGlobalString
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:80
User
Class to manage Dolibarr users.
Definition: user.class.php:44
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2845
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8137
Propal
Class to manage proposals.
Definition: propal.class.php:52
dol_mkdir
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
Definition: functions.lib.php:6603
getUserRemoteIP
getUserRemoteIP()
Return the IP of remote user.
Definition: functions.lib.php:3515