dolibarr 20.0.0
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;
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.
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:420