dolibarr  9.0.0
printgcp.modules.php
Go to the documentation of this file.
1 <?php
2 /*
3  * Copyright (C) 2014-2018 Frederic 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 <http://www.gnu.org/licenses/>.
17  * or see http://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 
32 
37 {
38  public $name = 'printgcp';
39  public $desc = 'PrintGCPDesc';
40  public $picto = 'printer';
41  public $active = 'PRINTING_PRINTGCP';
42  public $conf = array();
43  public $google_id = '';
44  public $google_secret = '';
45 
49  public $error = '';
50 
54  public $errors = array();
55 
59  public $db;
60 
61  private $OAUTH_SERVICENAME_GOOGLE = 'Google';
62 
63  const LOGIN_URL = 'https://accounts.google.com/o/oauth2/token';
64  const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/search';
65  const PRINTERS_GET_JOBS = 'https://www.google.com/cloudprint/jobs';
66  const PRINT_URL = 'https://www.google.com/cloudprint/submit';
67 
73  function __construct($db)
74  {
75  global $conf, $langs, $dolibarr_main_url_root;
76 
77  // Define $urlwithroot
78  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
79  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
80  //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
81 
82  $this->db = $db;
83 
84  if (!$conf->oauth->enabled) {
85  $this->conf[] = array(
86  'varname'=>'PRINTGCP_INFO',
87  'info'=>$langs->transnoentitiesnoconv("WarningModuleNotActive", "OAuth"),
88  'type'=>'info',
89  );
90  } else {
91 
92  $this->google_id = $conf->global->OAUTH_GOOGLE_ID;
93  $this->google_secret = $conf->global->OAUTH_GOOGLE_SECRET;
94  // Token storage
95  $storage = new DoliStorage($this->db, $this->conf);
96  //$storage->clearToken($this->OAUTH_SERVICENAME_GOOGLE);
97  // Setup the credentials for the requests
98  $credentials = new Credentials(
99  $this->google_id,
100  $this->google_secret,
101  $urlwithroot.'/core/modules/oauth/google_oauthcallback.php'
102  );
103  $access = ($storage->hasAccessToken($this->OAUTH_SERVICENAME_GOOGLE)?'HasAccessToken':'NoAccessToken');
104  $serviceFactory = new \OAuth\ServiceFactory();
105  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
106  $token_ok=true;
107  try {
108  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
109  } catch (Exception $e) {
110  $this->errors[] = $e->getMessage();
111  $token_ok = false;
112  }
113  //var_dump($this->errors);exit;
114 
115  $expire = false;
116  // Is token expired or will token expire in the next 30 seconds
117  if ($token_ok) {
118  $expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
119  }
120 
121  // Token expired so we refresh it
122  if ($token_ok && $expire) {
123  try {
124  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
125  $refreshtoken = $token->getRefreshToken();
126  $token = $apiService->refreshAccessToken($token);
127  $token->setRefreshToken($refreshtoken);
128  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
129  } catch (Exception $e) {
130  $this->errors[] = $e->getMessage();
131  }
132  }
133  if ($this->google_id != '' && $this->google_secret != '') {
134  $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthConfigured', 'type'=>'info');
135  $this->conf[] = array(
136  'varname'=>'PRINTGCP_TOKEN_ACCESS',
137  'info'=>$access,
138  'type'=>'info',
139  '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'),
140  'delete'=>($storage->hasAccessToken($this->OAUTH_SERVICENAME_GOOGLE)?$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'):'')
141  );
142  if ($token_ok) {
143  $expiredat='';
144 
145  $refreshtoken = $token->getRefreshToken();
146 
147  $endoflife = $token->getEndOfLife();
148 
149  if ($endoflife == $token::EOL_NEVER_EXPIRES)
150  {
151  $expiredat = $langs->trans("Never");
152  }
153  elseif ($endoflife == $token::EOL_UNKNOWN)
154  {
155  $expiredat = $langs->trans("Unknown");
156  }
157  else
158  {
159  $expiredat=dol_print_date($endoflife, "dayhour");
160  }
161 
162  $this->conf[] = array('varname'=>'TOKEN_REFRESH', 'info'=>((! empty($refreshtoken))?'Yes':'No'), 'type'=>'info');
163  $this->conf[] = array('varname'=>'TOKEN_EXPIRED', 'info'=>($expire?'Yes':'No'), 'type'=>'info');
164  $this->conf[] = array('varname'=>'TOKEN_EXPIRE_AT', 'info'=>($expiredat), 'type'=>'info');
165  }
166  /*
167  if ($storage->hasAccessToken($this->OAUTH_SERVICENAME_GOOGLE)) {
168  $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');
169  $this->conf[] = array('varname'=>'DELETE_TOKEN', 'link'=>$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/printing/admin/printing.php?mode=setup&driver=printgcp'), 'type'=>'delete');
170  } else {
171  $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');
172  }*/
173  } else {
174  $this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthNotConfigured', 'type'=>'info');
175  }
176  }
177  // do not display submit button
178  $this->conf[] = array('enabled'=>0, 'type'=>'submit');
179  }
180 
186  public function listAvailablePrinters()
187  {
188  global $conf, $langs;
189  $error = 0;
190  $langs->load('printing');
191 
192  $html = '<tr class="liste_titre">';
193  $html.= '<td>'.$langs->trans('GCP_Name').'</td>';
194  $html.= '<td>'.$langs->trans('GCP_displayName').'</td>';
195  $html.= '<td>'.$langs->trans('GCP_Id').'</td>';
196  $html.= '<td>'.$langs->trans('GCP_OwnerName').'</td>';
197  $html.= '<td>'.$langs->trans('GCP_State').'</td>';
198  $html.= '<td>'.$langs->trans('GCP_connectionStatus').'</td>';
199  $html.= '<td>'.$langs->trans('GCP_Type').'</td>';
200  $html.= '<td align="center">'.$langs->trans("Select").'</td>';
201  $html.= '</tr>'."\n";
202  $list = $this->getlistAvailablePrinters();
203  //$html.= '<td><pre>'.print_r($list,true).'</pre></td>';
204  foreach ($list['available'] as $printer_det)
205  {
206  $html.= '<tr class="oddeven">';
207  $html.= '<td>'.$printer_det['name'].'</td>';
208  $html.= '<td>'.$printer_det['displayName'].'</td>';
209  $html.= '<td>'.$printer_det['id'].'</td>'; // id to identify printer to use
210  $html.= '<td>'.$printer_det['ownerName'].'</td>';
211  $html.= '<td>'.$printer_det['status'].'</td>';
212  $html.= '<td>'.$langs->trans('STATE_'.$printer_det['connectionStatus']).'</td>';
213  $html.= '<td>'.$langs->trans('TYPE_'.$printer_det['type']).'</td>';
214  // Defaut
215  $html.= '<td align="center">';
216  if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id'])
217  {
218  $html.= img_picto($langs->trans("Default"),'on');
219  }
220  else
221  $html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&amp;mode=test&amp;varname=PRINTING_GCP_DEFAULT&amp;driver=printgcp&amp;value='.urlencode($printer_det['id']).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
222  $html.= '</td>';
223  $html.= '</tr>'."\n";
224  }
225  $this->resprint = $html;
226  return $error;
227  }
228 
229 
235  public function getlistAvailablePrinters()
236  {
237  // Token storage
238  $storage = new DoliStorage($this->db, $this->conf);
239  // Setup the credentials for the requests
240  $credentials = new Credentials(
241  $this->google_id,
242  $this->google_secret,
243  DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php'
244  );
245  $serviceFactory = new \OAuth\ServiceFactory();
246  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
247  // Check if we have auth token
248  $token_ok=true;
249  try {
250  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
251  } catch (Exception $e) {
252  $this->errors[] = $e->getMessage();
253  $token_ok = false;
254  }
255  $expire = false;
256  // Is token expired or will token expire in the next 30 seconds
257  if ($token_ok) {
258  $expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
259  }
260 
261  // Token expired so we refresh it
262  if ($token_ok && $expire) {
263  try {
264  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
265  $refreshtoken = $token->getRefreshToken();
266  $token = $apiService->refreshAccessToken($token);
267  $token->setRefreshToken($refreshtoken);
268  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
269  } catch (Exception $e) {
270  $this->errors[] = $e->getMessage();
271  }
272  }
273  // Send a request with api
274  try {
275  $response = $apiService->request(self::PRINTERS_SEARCH_URL);
276  } catch (Exception $e) {
277  $this->errors[] = $e->getMessage();
278  print '<pre>'.print_r($e->getMessage(),true).'</pre>';
279  }
280  //print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
281  $responsedata = json_decode($response, true);
282  $printers = $responsedata['printers'];
283  // Check if we have printers?
284  if(count($printers)==0) {
285  // We dont have printers so return blank array
286  $ret['available'] = array();
287  } else {
288  // We have printers so returns printers as array
289  $ret['available'] = $printers;
290  }
291  return $ret;
292  }
293 
302  public function printFile($file, $module, $subdir='')
303  {
304  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
305 
306  global $conf, $user;
307  $error = 0;
308 
309  $fileprint = $conf->{$module}->dir_output;
310  if ($subdir!='') {
311  $fileprint.='/'.$subdir;
312  }
313  $fileprint.='/'.$file;
314  $mimetype = dol_mimetype($fileprint);
315  // select printer uri for module order, propal,...
316  $sql = "SELECT rowid, printer_id, copy FROM ".MAIN_DB_PREFIX."printing WHERE module='".$module."' AND driver='printgcp' AND userid=".$user->id;
317  $result = $this->db->query($sql);
318  if ($result)
319  {
320  $obj = $this->db->fetch_object($result);
321  if ($obj)
322  {
323  $printer_id = $obj->printer_id;
324  }
325  else
326  {
327  if (! empty($conf->global->PRINTING_GCP_DEFAULT))
328  {
329  $printer_id=$conf->global->PRINTING_GCP_DEFAULT;
330  }
331  else
332  {
333  $this->errors[] = 'NoDefaultPrinterDefined';
334  $error++;
335  return $error;
336  }
337  }
338  }
339  else dol_print_error($this->db);
340 
341  $ret = $this->sendPrintToPrinter($printer_id, $file, $fileprint, $mimetype);
342  $this->error = 'PRINTGCP: '.$ret['errormessage'];
343  if ($ret['status']!=1) {
344  $error++;
345  }
346  return $error;
347  }
348 
358  public function sendPrintToPrinter($printerid, $printjobtitle, $filepath, $contenttype)
359  {
360  // Check if printer id
361  if(empty($printerid)) {
362  return array('status' =>0, 'errorcode' =>'','errormessage'=>'No provided printer ID');
363  }
364  // Open the file which needs to be print
365  $handle = fopen($filepath, "rb");
366  if(!$handle) {
367  return array('status' =>0, 'errorcode' =>'','errormessage'=>'Could not read the file.');
368  }
369  // Read file content
370  $contents = fread($handle, filesize($filepath));
371  fclose($handle);
372  // Prepare post fields for sending print
373  $post_fields = array(
374  'printerid' => $printerid,
375  'title' => $printjobtitle,
376  'contentTransferEncoding' => 'base64',
377  'content' => base64_encode($contents), // encode file content as base64
378  'contentType' => $contenttype,
379  );
380  // Dolibarr Token storage
381  $storage = new DoliStorage($this->db, $this->conf);
382  // Setup the credentials for the requests
383  $credentials = new Credentials(
384  $this->google_id,
385  $this->google_secret,
386  DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php?service=google'
387  );
388  $serviceFactory = new \OAuth\ServiceFactory();
389  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
390 
391  // Check if we have auth token and refresh it
392  $token_ok=true;
393  try {
394  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
395  } catch (Exception $e) {
396  $this->errors[] = $e->getMessage();
397  $token_ok = false;
398  }
399  if ($token_ok) {
400  try {
401  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
402  $refreshtoken = $token->getRefreshToken();
403  $token = $apiService->refreshAccessToken($token);
404  $token->setRefreshToken($refreshtoken);
405  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
406  } catch (Exception $e) {
407  $this->errors[] = $e->getMessage();
408  }
409  }
410 
411  // Send a request with api
412  $response = json_decode($apiService->request(self::PRINT_URL, 'POST', $post_fields), true);
413  //print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
414  return array('status' => $response['success'], 'errorcode' => $response['errorCode'], 'errormessage' => $response['message']);
415  }
416 
417 
423  public function listJobs()
424  {
425  global $conf, $langs;
426 
427  $error = 0;
428  $html = '';
429  // Token storage
430  $storage = new DoliStorage($this->db, $this->conf);
431  // Setup the credentials for the requests
432  $credentials = new Credentials(
433  $this->google_id,
434  $this->google_secret,
435  DOL_MAIN_URL_ROOT.'/core/modules/oauth/google_oauthcallback.php'
436  );
437  $serviceFactory = new \OAuth\ServiceFactory();
438  $apiService = $serviceFactory->createService($this->OAUTH_SERVICENAME_GOOGLE, $credentials, $storage, array());
439  // Check if we have auth token
440  $token_ok=true;
441  try {
442  $token = $storage->retrieveAccessToken($this->OAUTH_SERVICENAME_GOOGLE);
443  } catch (Exception $e) {
444  $this->errors[] = $e->getMessage();
445  $token_ok = false;
446  $error++;
447  }
448  $expire = false;
449  // Is token expired or will token expire in the next 30 seconds
450  if ($token_ok) {
451  $expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
452  }
453 
454  // Token expired so we refresh it
455  if ($token_ok && $expire) {
456  try {
457  // il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
458  $refreshtoken = $token->getRefreshToken();
459  $token = $apiService->refreshAccessToken($token);
460  $token->setRefreshToken($refreshtoken);
461  $storage->storeAccessToken($this->OAUTH_SERVICENAME_GOOGLE, $token);
462  } catch (Exception $e) {
463  $this->errors[] = $e->getMessage();
464  $error++;
465  }
466  }
467  // Getting Jobs
468  // Send a request with api
469  try {
470  $response = $apiService->request(self::PRINTERS_GET_JOBS);
471  } catch (Exception $e) {
472  $this->errors[] = $e->getMessage();
473  $error++;
474  }
475  $responsedata = json_decode($response, true);
476  //$html .= '<pre>'.print_r($responsedata,true).'</pre>';
477  $html .= '<div class="div-table-responsive">';
478  $html .= '<table width="100%" class="noborder">';
479  $html .= '<tr class="liste_titre">';
480  $html .= '<td>'.$langs->trans("Id").'</td>';
481  $html .= '<td>'.$langs->trans("Date").'</td>';
482  $html .= '<td>'.$langs->trans("Owner").'</td>';
483  $html .= '<td>'.$langs->trans("Printer").'</td>';
484  $html .= '<td>'.$langs->trans("Filename").'</td>';
485  $html .= '<td>'.$langs->trans("Status").'</td>';
486  $html .= '<td>'.$langs->trans("Cancel").'</td>';
487  $html .= '</tr>'."\n";
488 
489  $jobs = $responsedata['jobs'];
490  //$html .= '<pre>'.print_r($jobs['0'],true).'</pre>';
491  if (is_array($jobs)) {
492  foreach ($jobs as $value) {
493  $html .= '<tr class="oddeven">';
494  $html .= '<td>'.$value['id'].'</td>';
495  $dates = dol_print_date((int) substr($value['createTime'], 0, 10), 'dayhour');
496  $html .= '<td>'.$dates.'</td>';
497  $html .= '<td>'.$value['ownerId'].'</td>';
498  $html .= '<td>'.$value['printerName'].'</td>';
499  $html .= '<td>'.$value['title'].'</td>';
500  $html .= '<td>'.$value['status'].'</td>';
501  $html .= '<td>&nbsp;</td>';
502  $html .= '</tr>';
503  }
504  }
505  else
506  {
507  $html .= '<tr class="oddeven">';
508  $html .= '<td colspan="7" class="opacitymedium">'.$langs->trans("None").'</td>';
509  $html .= '</tr>';
510  }
511  $html .= '</table>';
512  $html .= '</div>';
513 
514  $this->resprint = $html;
515 
516  return $error;
517  }
518 }
sendPrintToPrinter($printerid, $printjobtitle, $filepath, $contenttype)
Sends document to the printer.
printFile($file, $module, $subdir='')
Print selected file.
print
Draft customers invoices.
Definition: index.php:91
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition: inc.php:292
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return mime type of a file.
listJobs()
List jobs print.
Parent class of emailing target selectors modules.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
listAvailablePrinters()
Return list of available printers.
Class to provide printing with Google Cloud Print.
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
getlistAvailablePrinters()
Return list of available printers.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
__construct($db)
Constructor.