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