dolibarr  20.0.0-beta
printgcp.modules.php
Go to the documentation of this file.
1 <?php
2 /*
3  * Copyright (C) 2014-2019 Frédéric France <frederic.france@netlogic.fr>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  * or see https://www.gnu.org/
18  */
19 
26 include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php';
27 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
28 
29 use OAuth\Common\Storage\DoliStorage;
30 use OAuth\Common\Consumer\Credentials;
31 
36 {
40  public $name = 'printgcp';
41 
45  public $desc = 'PrintGCPDesc';
46 
50  public $picto = 'printer';
51 
55  public $active = 'PRINTING_PRINTGCP';
56 
60  public $conf = array();
61 
65  public $google_id = '';
66 
70  public $google_secret = '';
71 
75  public $error = '';
76 
80  public $errors = array();
81 
85  public $db;
86 
87  private $OAUTH_SERVICENAME_GOOGLE = 'Google';
88 
89  const LOGIN_URL = 'https://accounts.google.com/o/oauth2/token';
90  const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/search';
91  const PRINTERS_GET_JOBS = 'https://www.google.com/cloudprint/jobs';
92  const PRINT_URL = 'https://www.google.com/cloudprint/submit';
93 
94 
100  public function __construct($db)
101  {
102  global $conf, $langs, $dolibarr_main_url_root;
103 
104  // Define $urlwithroot
105  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
106  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
107  //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
108 
109  $this->db = $db;
110 
111  if (!$conf->oauth->enabled) {
112  $this->conf[] = array(
113  'varname'=>'PRINTGCP_INFO',
114  'info'=>$langs->transnoentitiesnoconv("WarningModuleNotActive", "OAuth"),
115  'type'=>'info',
116  );
117  } else {
118  $keyforprovider = ''; // @FIXME
119 
120  $this->google_id = getDolGlobalString('OAUTH_GOOGLE_ID');
121  $this->google_secret = getDolGlobalString('OAUTH_GOOGLE_SECRET');
122  // Token storage
123  $storage = new DoliStorage($this->db, $conf, $keyforprovider);
124  //$storage->clearToken($this->OAUTH_SERVICENAME_GOOGLE);
125  // Setup the credentials for the requests
126  $credentials = new Credentials(
127  $this->google_id,
128  $this->google_secret,
129  $urlwithroot.'/core/modules/oauth/google_oauthcallback.php'
130  );
131  $access = ($storage->hasAccessToken($this->OAUTH_SERVICENAME_GOOGLE) ? 'HasAccessToken' : 'NoAccessToken');
132  $serviceFactory = new \OAuth\ServiceFactory();
133  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
134  $token_ok = true;
135  try {
136  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
137  } catch (Exception $e) {
138  $this->errors[] = $e->getMessage();
139  $token_ok = false;
140  }
141 
142  $expire = false;
143  // Is token expired or will token expire in the next 30 seconds
144  if ($token_ok) {
145  $expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
146  }
147 
148  // Token expired so we refresh it
149  if ($token_ok && $expire) {
150  try {
151  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
152  $refreshtoken = $token->getRefreshToken();
153  $token = $apiService->refreshAccessToken($token);
154  $token->setRefreshToken($refreshtoken);
155  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
156  } catch (Exception $e) {
157  $this->errors[] = $e->getMessage();
158  }
159  }
160  if ($this->google_id != '' && $this->google_secret != '') {
161  $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthConfigured', 'type'=>'info');
162  $this->conf[] = array(
163  'varname'=>'PRINTGCP_TOKEN_ACCESS',
164  'info'=>$access,
165  'type'=>'info',
166  'renew'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?state=userinfo_email,userinfo_profile,cloud_print&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'),
167  'delete'=>($storage->hasAccessToken($this->OAUTH_SERVICENAME_GOOGLE) ? $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp') : '')
168  );
169  if ($token_ok) {
170  $expiredat = '';
171 
172  $refreshtoken = $token->getRefreshToken();
173 
174  $endoflife = $token->getEndOfLife();
175 
176  if ($endoflife == $token::EOL_NEVER_EXPIRES) {
177  $expiredat = $langs->trans("Never");
178  } elseif ($endoflife == $token::EOL_UNKNOWN) {
179  $expiredat = $langs->trans("Unknown");
180  } else {
181  $expiredat = dol_print_date($endoflife, "dayhour");
182  }
183 
184  $this->conf[] = array('varname'=>'TOKEN_REFRESH', 'info'=>((!empty($refreshtoken)) ? 'Yes' : 'No'), 'type'=>'info');
185  $this->conf[] = array('varname'=>'TOKEN_EXPIRED', 'info'=>($expire ? 'Yes' : 'No'), 'type'=>'info');
186  $this->conf[] = array('varname'=>'TOKEN_EXPIRE_AT', 'info'=>($expiredat), 'type'=>'info');
187  }
188  /*
189  if ($storage->hasAccessToken($this->OAUTH_SERVICENAME_GOOGLE)) {
190  $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
191  $this->conf[] = array('varname'=>'DELETE_TOKEN', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'delete');
192  } else {
193  $this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'authlink');
194  }*/
195  } else {
196  $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthNotConfigured', 'type'=>'info');
197  }
198  }
199  // do not display submit button
200  $this->conf[] = array('enabled'=>0, 'type'=>'submit');
201  }
202 
208  public function listAvailablePrinters()
209  {
210  global $conf, $langs;
211  $error = 0;
212  $langs->load('printing');
213 
214  $html = '<tr class="liste_titre">';
215  $html .= '<td>'.$langs->trans('GCP_Name').'</td>';
216  $html .= '<td>'.$langs->trans('GCP_displayName').'</td>';
217  $html .= '<td>'.$langs->trans('GCP_Id').'</td>';
218  $html .= '<td>'.$langs->trans('GCP_OwnerName').'</td>';
219  $html .= '<td>'.$langs->trans('GCP_State').'</td>';
220  $html .= '<td>'.$langs->trans('GCP_connectionStatus').'</td>';
221  $html .= '<td>'.$langs->trans('GCP_Type').'</td>';
222  $html .= '<td class="center">'.$langs->trans("Select").'</td>';
223  $html .= '</tr>'."\n";
224  $list = $this->getlistAvailablePrinters();
225  //$html.= '<td><pre>'.print_r($list,true).'</pre></td>';
226  foreach ($list['available'] as $printer_det) {
227  $html .= '<tr class="oddeven">';
228  $html .= '<td>'.$printer_det['name'].'</td>';
229  $html .= '<td>'.$printer_det['displayName'].'</td>';
230  $html .= '<td>'.$printer_det['id'].'</td>'; // id to identify printer to use
231  $html .= '<td>'.$printer_det['ownerName'].'</td>';
232  $html .= '<td>'.$printer_det['status'].'</td>';
233  $html .= '<td>'.$langs->trans('STATE_'.$printer_det['connectionStatus']).'</td>';
234  $html .= '<td>'.$langs->trans('TYPE_'.$printer_det['type']).'</td>';
235  // Default
236  $html .= '<td class="center">';
237  if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id']) {
238  $html .= img_picto($langs->trans("Default"), 'on');
239  } else {
240  $html .= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&token='.newToken().'&mode=test&varname=PRINTING_GCP_DEFAULT&driver=printgcp&value='.urlencode($printer_det['id']).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
241  }
242  $html .= '</td>';
243  $html .= '</tr>'."\n";
244  }
245  $this->resprint = $html;
246  return $error;
247  }
248 
249 
255  public function getlistAvailablePrinters()
256  {
257  global $conf;
258  $ret = array();
259 
260  $keyforprovider = ''; // @FIXME
261 
262  // Token storage
263  $storage = new DoliStorage($this->db, $conf, $keyforprovider);
264  // Setup the credentials for the requests
265  $credentials = new Credentials(
266  $this->google_id,
267  $this->google_secret,
268  DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php'
269  );
270  $serviceFactory = new \OAuth\ServiceFactory();
271  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
272  // Check if we have auth token
273  $token_ok = true;
274  try {
275  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
276  } catch (Exception $e) {
277  $this->errors[] = $e->getMessage();
278  $token_ok = false;
279  }
280  $expire = false;
281  // Is token expired or will token expire in the next 30 seconds
282  if ($token_ok) {
283  $expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
284  }
285 
286  // Token expired so we refresh it
287  if ($token_ok && $expire) {
288  try {
289  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
290  $refreshtoken = $token->getRefreshToken();
291  $token = $apiService->refreshAccessToken($token);
292  $token->setRefreshToken($refreshtoken);
293  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
294  } catch (Exception $e) {
295  $this->errors[] = $e->getMessage();
296  }
297  }
298  // Send a request with api
299  try {
300  $response = $apiService->request(self::PRINTERS_SEARCH_URL);
301  } catch (Exception $e) {
302  $this->errors[] = $e->getMessage();
303  print '<pre>'.print_r($e->getMessage(), true).'</pre>';
304  }
305  //print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
306  $responsedata = json_decode($response, true);
307  $printers = $responsedata['printers'];
308  // Check if we have printers?
309  if (is_array($printers) && count($printers) == 0) {
310  // We don't have printers so return blank array
311  $ret['available'] = array();
312  } else {
313  // We have printers so returns printers as array
314  $ret['available'] = $printers;
315  }
316  return $ret;
317  }
318 
327  public function printFile($file, $module, $subdir = '')
328  {
329  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
330 
331  global $conf, $user;
332  $error = 0;
333 
334  $fileprint = $conf->{$module}->dir_output;
335  if ($subdir != '') {
336  $fileprint .= '/'.$subdir;
337  }
338  $fileprint .= '/'.$file;
339  $mimetype = dol_mimetype($fileprint);
340  $printer_id = '';
341  // select printer uri for module order, propal,...
342  $sql = "SELECT rowid, printer_id, copy FROM ".MAIN_DB_PREFIX."printing WHERE module='".$this->db->escape($module)."' AND driver='printgcp' AND userid=".((int) $user->id);
343  $result = $this->db->query($sql);
344  if ($result) {
345  $obj = $this->db->fetch_object($result);
346  if ($obj) {
347  $printer_id = $obj->printer_id;
348  } else {
349  if (getDolGlobalString('PRINTING_GCP_DEFAULT')) {
350  $printer_id = getDolGlobalString('PRINTING_GCP_DEFAULT');
351  } else {
352  $this->errors[] = 'NoDefaultPrinterDefined';
353  $error++;
354  return $error;
355  }
356  }
357  } else {
358  dol_print_error($this->db);
359  }
360 
361  $ret = $this->sendPrintToPrinter($printer_id, $file, $fileprint, $mimetype);
362  $this->error = 'PRINTGCP: '.$ret['errormessage'];
363  if ($ret['status'] != 1) {
364  $error++;
365  }
366  return $error;
367  }
368 
378  public function sendPrintToPrinter($printerid, $printjobtitle, $filepath, $contenttype)
379  {
380  global $conf;
381  // Check if printer id
382  if (empty($printerid)) {
383  return array('status' =>0, 'errorcode' =>'', 'errormessage'=>'No provided printer ID');
384  }
385  // Open the file which needs to be print
386  $handle = fopen($filepath, "rb");
387  if (!$handle) {
388  return array('status' =>0, 'errorcode' =>'', 'errormessage'=>'Could not read the file.');
389  }
390  // Read file content
391  $contents = fread($handle, filesize($filepath));
392  fclose($handle);
393  // Prepare post fields for sending print
394  $post_fields = array(
395  'printerid' => $printerid,
396  'title' => $printjobtitle,
397  'contentTransferEncoding' => 'base64',
398  'content' => base64_encode($contents), // encode file content as base64
399  'contentType' => $contenttype,
400  );
401 
402  $keyforprovider = ''; // @FIXME
403 
404  // Dolibarr Token storage
405  $storage = new DoliStorage($this->db, $conf, $keyforprovider);
406  // Setup the credentials for the requests
407  $credentials = new Credentials(
408  $this->google_id,
409  $this->google_secret,
410  DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php?service=google'
411  );
412  $serviceFactory = new \OAuth\ServiceFactory();
413  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
414 
415  // Check if we have auth token and refresh it
416  $token_ok = true;
417  try {
418  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
419  } catch (Exception $e) {
420  $this->errors[] = $e->getMessage();
421  $token_ok = false;
422  }
423  if ($token_ok) {
424  try {
425  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
426  $refreshtoken = $token->getRefreshToken();
427  $token = $apiService->refreshAccessToken($token);
428  $token->setRefreshToken($refreshtoken);
429  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
430  } catch (Exception $e) {
431  $this->errors[] = $e->getMessage();
432  }
433  }
434 
435  // Send a request with api
436  $response = json_decode($apiService->request(self::PRINT_URL, 'POST', $post_fields), true);
437  //print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
438  return array('status' => $response['success'], 'errorcode' => $response['errorCode'], 'errormessage' => $response['message']);
439  }
440 
441 
447  public function listJobs()
448  {
449  global $conf, $langs;
450 
451  $error = 0;
452  $html = '';
453 
454  $keyforprovider = ''; // @FIXME
455 
456  // Token storage
457  $storage = new DoliStorage($this->db, $conf, $keyforprovider);
458  // Setup the credentials for the requests
459  $credentials = new Credentials(
460  $this->google_id,
461  $this->google_secret,
462  DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php'
463  );
464  $serviceFactory = new \OAuth\ServiceFactory();
465  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
466  // Check if we have auth token
467  $token_ok = true;
468  try {
469  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
470  } catch (Exception $e) {
471  $this->errors[] = $e->getMessage();
472  $token_ok = false;
473  $error++;
474  }
475  $expire = false;
476  // Is token expired or will token expire in the next 30 seconds
477  if ($token_ok) {
478  $expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
479  }
480 
481  // Token expired so we refresh it
482  if ($token_ok && $expire) {
483  try {
484  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
485  $refreshtoken = $token->getRefreshToken();
486  $token = $apiService->refreshAccessToken($token);
487  $token->setRefreshToken($refreshtoken);
488  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
489  } catch (Exception $e) {
490  $this->errors[] = $e->getMessage();
491  $error++;
492  }
493  }
494  // Getting Jobs
495  // Send a request with api
496  try {
497  $response = $apiService->request(self::PRINTERS_GET_JOBS);
498  } catch (Exception $e) {
499  $this->errors[] = $e->getMessage();
500  $error++;
501  }
502  $responsedata = json_decode($response, true);
503  //$html .= '<pre>'.print_r($responsedata,true).'</pre>';
504  $html .= '<div class="div-table-responsive">';
505  $html .= '<table width="100%" class="noborder">';
506  $html .= '<tr class="liste_titre">';
507  $html .= '<td>'.$langs->trans("Id").'</td>';
508  $html .= '<td>'.$langs->trans("Date").'</td>';
509  $html .= '<td>'.$langs->trans("Owner").'</td>';
510  $html .= '<td>'.$langs->trans("Printer").'</td>';
511  $html .= '<td>'.$langs->trans("Filename").'</td>';
512  $html .= '<td>'.$langs->trans("Status").'</td>';
513  $html .= '<td>'.$langs->trans("Cancel").'</td>';
514  $html .= '</tr>'."\n";
515 
516  $jobs = $responsedata['jobs'];
517  //$html .= '<pre>'.print_r($jobs['0'],true).'</pre>';
518  if (is_array($jobs)) {
519  foreach ($jobs as $value) {
520  $html .= '<tr class="oddeven">';
521  $html .= '<td>'.$value['id'].'</td>';
522  $dates = dol_print_date((int) substr($value['createTime'], 0, 10), 'dayhour');
523  $html .= '<td>'.$dates.'</td>';
524  $html .= '<td>'.$value['ownerId'].'</td>';
525  $html .= '<td>'.$value['printerName'].'</td>';
526  $html .= '<td>'.$value['title'].'</td>';
527  $html .= '<td>'.$value['status'].'</td>';
528  $html .= '<td>&nbsp;</td>';
529  $html .= '</tr>';
530  }
531  } else {
532  $html .= '<tr class="oddeven">';
533  $html .= '<td colspan="7" class="opacitymedium">'.$langs->trans("None").'</td>';
534  $html .= '</tr>';
535  }
536  $html .= '</table>';
537  $html .= '</div>';
538 
539  $this->resprint = $html;
540 
541  return $error;
542  }
543 }
Parent class of emailing target selectors modules.
Class to provide printing with Google Cloud Print.
listJobs()
List jobs print.
__construct($db)
Constructor.
listAvailablePrinters()
Return list of available printers.
printFile($file, $module, $subdir='')
Print selected file.
getlistAvailablePrinters()
Return list of available printers.
sendPrintToPrinter($printerid, $printjobtitle, $filepath, $contenttype)
Sends document to the printer.
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition: inc.php:419