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