dolibarr 21.0.0-alpha
oauthlogintokens.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2016 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014-2018 Frederic France <frederic.france@netlogic.fr>
4 * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Load Dolibarr environment
28require '../main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
32
33use OAuth\Common\Storage\DoliStorage;
34use OAuth\Common\Consumer\Credentials;
35
36$supportedoauth2array = getSupportedOauth2Array();
37
38// Load translation files required by the page
39$langs->loadLangs(array('admin', 'printing', 'oauth'));
40
41$action = GETPOST('action', 'aZ09');
42$mode = GETPOST('mode', 'alpha');
43$value = GETPOST('value', 'alpha');
44$varname = GETPOST('varname', 'alpha');
45$driver = GETPOST('driver', 'alpha');
46
47if (!empty($driver)) {
48 $langs->load($driver);
49}
50
51if (!$mode) {
52 $mode = 'setup';
53}
54
55if (!$user->admin) {
57}
58
59
60/*
61 * Action
62 */
63
64/*if (($mode == 'test' || $mode == 'setup') && empty($driver))
65{
66 setEventMessages($langs->trans('PleaseSelectaDriverfromList'), null);
67 header("Location: ".$_SERVER['PHP_SELF'].'?mode=config');
68 exit;
69}*/
70
71if ($action == 'setconst' && $user->admin) {
72 $error = 0;
73 $db->begin();
74
75 $setupconstarray = GETPOST('setupdriver', 'array');
76
77 foreach ($setupconstarray as $setupconst) {
78 //print '<pre>'.print_r($setupconst, true).'</pre>';
79
80 $constname = dol_escape_htmltag($setupconst['varname']);
81 $constvalue = dol_escape_htmltag($setupconst['value']);
82 $consttype = dol_escape_htmltag($setupconst['type']);
83 $constnote = dol_escape_htmltag($setupconst['note']);
84
85 $result = dolibarr_set_const($db, $constname, $constvalue, $consttype, 0, $constnote, $conf->entity);
86 if (!($result > 0)) {
87 $error++;
88 }
89 }
90
91 if (!$error) {
92 $db->commit();
93 setEventMessages($langs->trans("SetupSaved"), null);
94 } else {
95 $db->rollback();
96 dol_print_error($db);
97 }
98 $action = '';
99}
100
101if ($action == 'setvalue' && $user->admin) {
102 $db->begin();
103
104 $result = dolibarr_set_const($db, $varname, $value, 'chaine', 0, '', $conf->entity);
105 if (!($result > 0)) {
106 $error++;
107 }
108
109 if (!$error) {
110 $db->commit();
111 setEventMessages($langs->trans("SetupSaved"), null);
112 } else {
113 $db->rollback();
114 dol_print_error($db);
115 }
116 $action = '';
117}
118
119// Test a refresh of a token using the refresh token
120if ($action == 'refreshtoken' && $user->admin) {
121 $keyforprovider = GETPOST('keyforprovider');
122 $OAUTH_SERVICENAME = GETPOST('service');
123
124 // Show value of token
125 $tokenobj = null;
126 // Load OAUth libraries
127 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
128 // Dolibarr storage
129 $storage = new DoliStorage($db, $conf, $keyforprovider);
130 try {
131 // $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
132 print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
133
134 dol_syslog("oauthlogintokens.php: Read token for service ".$OAUTH_SERVICENAME);
135 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
136
137 $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30));
138 // We have to save the refresh token in a memory variable because Google give it only once
139 $refreshtoken = $tokenobj->getRefreshToken();
140 print '<!-- data stored into field token: '.$storage->token.' - expire '.((string) $expire).' -->';
141
142 //print $tokenobj->getExtraParams()['id_token'].'<br>';
143 //print $tokenobj->getAccessToken().'<br>';
144 //print $tokenobj->getRefreshToken().'<br>';
145
146 //var_dump($expire);
147
148 // We do the refresh even if not expired, this is the goal of action.
149 $oauthname = explode('-', $OAUTH_SERVICENAME);
150 $keyforoauthservice = strtoupper($oauthname[0]).(empty($oauthname[1]) ? '' : '-'.$oauthname[1]);
151 $credentials = new Credentials(
152 getDolGlobalString('OAUTH_'.$keyforoauthservice.'_ID'),
153 getDolGlobalString('OAUTH_'.$keyforoauthservice.'_SECRET'),
154 getDolGlobalString('OAUTH_'.$keyforoauthservice.'_URLCALLBACK')
155 );
156
157 $serviceFactory = new \OAuth\ServiceFactory();
158 $httpClient = new \OAuth\Common\Http\Client\CurlClient();
159 // TODO Set options for proxy and timeout
160 // $params=array('CURLXXX'=>value, ...)
161 //$httpClient->setCurlParameters($params);
162 $serviceFactory->setHttpClient($httpClient);
163
164 // ex service is Google-Emails we need only the first part Google
165 $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array());
166
167 if ($apiService instanceof OAuth\OAuth2\Service\AbstractService || $apiService instanceof OAuth\OAuth1\Service\AbstractService) {
168 // ServiceInterface does not provide refreshAccessToekn, AbstractService does
169 dol_syslog("oauthlogintokens.php: call refreshAccessToken to get the new access token");
170 $tokenobj = $apiService->refreshAccessToken($tokenobj); // This call refresh and store the new token (but does not include the refresh token)
171
172 dol_syslog("oauthlogintokens.php: call setRefreshToken");
173 $tokenobj->setRefreshToken($refreshtoken); // Restore the refresh token
174
175 dol_syslog("oauthlogintokens.php: call storeAccessToken to save the new access token + the old refresh token");
176 $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj); // This save the new token including the refresh token
177
178 if ($expire) {
179 setEventMessages($langs->trans("OldTokenWasExpiredItHasBeenRefresh"), null, 'mesgs');
180 } else {
181 setEventMessages($langs->trans("OldTokenWasNotExpiredButItHasBeenRefresh"), null, 'mesgs');
182 }
183 } else {
184 dol_print_error($db, 'apiService is not a correct OAUTH2 Abstract service');
185 }
186
187 dol_syslog("oauthlogintokens.php: Read token again for service ".$OAUTH_SERVICENAME);
188 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
189 } catch (Exception $e) {
190 // Return an error if token not found
191 print $e->getMessage();
192 }
193}
194
195
196/*
197 * View
198 */
199
200// Define $urlwithroot
201$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
202$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
203//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
204
205$form = new Form($db);
206
207$title = $langs->trans("TokenManager");
208$help_url = 'EN:Module_OAuth|FR:Module_OAuth_FR|ES:Módulo_OAuth_ES';
209
210llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-admin page-oauthlogintokens');
211
212$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
213print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup');
214
216
217print dol_get_fiche_head($head, 'tokengeneration', '', -1, '');
218
219if (GETPOST('error')) {
220 setEventMessages(GETPOST('error'), null, 'errors');
221}
222
223if ($mode == 'setup' && $user->admin) {
224 print '<span class="opacitymedium">'.$langs->trans("OAuthSetupForLogin")."</span><br><br>\n";
225
226 // Define $listinsetup
227 $listinsetup = array();
228 foreach ($conf->global as $key => $val) {
229 if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
230 $provider = preg_replace('/_ID$/', '', $key);
231 $listinsetup[] = array(
232 $provider.'_NAME',
233 $provider.'_ID',
234 $provider.'_SECRET',
235 $provider.'_URL', // For custom oauth links
236 $provider.'_SCOPE' // For custom oauth links
237 );
238 }
239 }
240
241 $oauthstateanticsrf = bin2hex(random_bytes(128 / 8));
242
243 // $list is defined into oauth.lib.php to the list of supported OAuth providers.
244 if (!empty($listinsetup)) {
245 foreach ($listinsetup as $key) {
246 $supported = 0;
247 $keyforsupportedoauth2array = $key[0]; // May be OAUTH_GOOGLE_NAME or OAUTH_GOOGLE_xxx_NAME
248 $keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
249 $keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
250 if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
251 $keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
252 $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
253 } else {
254 $keybeforeprovider = $keyforsupportedoauth2array;
255 $keyforprovider = '';
256 }
257 $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
258 $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
259
260
261 $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
262
263 $shortscope = '';
264 if (getDolGlobalString($key[4])) {
265 $shortscope = getDolGlobalString($key[4]);
266 }
267 $state = $shortscope; // TODO USe a better state
268
269 $urltorefresh = $_SERVER["PHP_SELF"].'?action=refreshtoken&token='.newToken();
270
271 // Define $urltorenew, $urltodelete, $urltocheckperms
272 if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
273 // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
274 // We pass this param list in to 'state' because we need it before and after the redirect.
275
276 // Note: github does not accept csrf key inside the state parameter (only known values)
277 $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
278 $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
279 $urltocheckperms = 'https://github.com/settings/applications/';
280 } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
281 // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
282 // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
283 // We pass this key list into the param 'state' because we need it before and after the redirect.
284 $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
285 $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
286 $urltocheckperms = 'https://security.google.com/settings/security/permissions';
287 } elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
288 $urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
289 $urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
290 $urltocheckperms = '';
291 } else {
292 $urltorenew = '';
293 $urltodelete = '';
294 $urltocheckperms = '';
295 }
296
297 if ($urltorenew) {
298 $urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
299 }
300 if ($urltorefresh) {
301 $urltorefresh .= '&keyforprovider='.urlencode($keyforprovider).'&service='.urlencode($OAUTH_SERVICENAME);
302 }
303 if ($urltodelete) {
304 $urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
305 }
306
307 // Show value of token
308 $tokenobj = null;
309 // Token
310 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
311 // Dolibarr storage
312 $storage = new DoliStorage($db, $conf, $keyforprovider);
313 try {
314 // $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
315 print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
316 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
317 print '<!-- data stored into field token: '.$storage->token.' -->';
318 //print $tokenobj->getExtraParams()['id_token'].'<br>';
319 //print $tokenobj->getAccessToken().'<br>';
320 } catch (Exception $e) {
321 // Return an error if token not found
322 //print $e->getMessage();
323 }
324
325 // Set other properties
326 $refreshtoken = false;
327 $expiredat = '';
328
329 $expire = false;
330 // Is token expired or will token expire in the next 30 seconds
331 if (is_object($tokenobj)) {
332 $expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
333 }
334 if ($key[1] != '' && $key[2] != '') {
335 if (is_object($tokenobj)) {
336 $refreshtoken = $tokenobj->getRefreshToken();
337
338 $endoflife = $tokenobj->getEndOfLife();
339 if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) {
340 $expiredat = $langs->trans("Never");
341 } elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
342 $expiredat = $langs->trans("Unknown");
343 } else {
344 $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
345 }
346 }
347 }
348
349 $submit_enabled = 0;
350
351 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&amp;driver='.$driver.'" autocomplete="off">';
352 print '<input type="hidden" name="token" value="'.newToken().'">';
353 print '<input type="hidden" name="action" value="setconst">';
354 print '<input type="hidden" name="page_y" value="">';
355
356 print '<div class="div-table-responsive-no-min">';
357 print '<table class="noborder centpercent">'."\n";
358
359 // Api Name
360 $label = $langs->trans($keyforsupportedoauth2array);
361 print '<tr class="liste_titre">';
362 print '<th class="titlefieldcreate">';
363 print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
364 if ($label == $keyforsupportedoauth2array) {
365 print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
366 } else {
367 print $label;
368 }
369 if ($keyforprovider) {
370 print ' (<b>'.$keyforprovider.'</b>)';
371 } else {
372 print ' (<b>'.$langs->trans("NoName").'</b>)';
373 }
374 print '</th>';
375 print '<th></th>';
376 print '<th></th>';
377 print "</tr>\n";
378
379 print '<tr class="oddeven">';
380 print '<td>';
381 //var_dump($key);
382 print $langs->trans("OAuthIDSecret").'</td>';
383 print '<td>';
384 print '<span class="opacitymedium">'.$langs->trans("SeePreviousTab").'</span>';
385 print '</td>';
386 print '<td>';
387 print '</td>';
388 print '</tr>'."\n";
389
390 // Scopes
391 print '<tr class="oddeven">';
392 print '<td>'.$langs->trans("Scopes").'</td>';
393 print '<td colspan="2">';
394 $currentscopes = getDolGlobalString($key[4]);
395 print $currentscopes;
396 print '</td></tr>';
397
398 print '<tr class="oddeven">';
399 print '<td>';
400 //var_dump($key);
401 print $langs->trans("IsTokenGenerated");
402 print '</td>';
403 print '<td>';
404 if ($keyforprovider != 'Login') {
405 if (is_object($tokenobj)) {
406 print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '.dol_print_date($storage->date_modification, 'dayhour').' state='.dol_escape_htmltag($storage->state));
407 } else {
408 print '<span class="opacitymedium">'.$langs->trans("NoAccessToken").'</span>';
409 }
410 } else {
411 print '<span class="opacitymedium">'.$langs->trans("TokenNotRequiredForOAuthLogin").'</span>';
412 }
413 print '</td>';
414 print '<td width="50%">';
415 if ($keyforprovider != 'Login') {
416 // Links to delete/checks token
417 if (is_object($tokenobj)) {
418 //test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
419 if ($urltodelete) {
420 print '<a class="button button-delete smallpaddingimp reposition marginright" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a>';
421 } else {
422 print '<span class="opacitymedium marginright">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span>';
423 }
424 }
425 // Request remote token
426 if ($urltorenew) {
427 print '<a class="button smallpaddingimp reposition classfortooltip marginright" href="'.$urltorenew.'" title="'.dolPrintHTMLForAttribute($langs->trans('RequestAccess')).'">'.$langs->trans('GetAccess').'</a>';
428 }
429 // Request remote token
430 if ($urltorefresh && $refreshtoken) {
431 print '<a class="button smallpaddingimp reposition classfortooltip marginright" href="'.$urltorefresh.'" title="'.dolPrintHTMLForAttribute($langs->trans('RefreshTokenHelp')).'">'.$langs->trans('RefreshToken').'</a>';
432 }
433
434 // Check remote access
435 if ($urltocheckperms) {
436 print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
437 }
438 }
439 print '</td>';
440 print '</tr>';
441
442 if (is_object($tokenobj)) {
443 print '<tr class="oddeven">';
444 print '<td>';
445 //var_dump($key);
446 print $langs->trans("TokenRawValue").'</td>';
447 print '<td colspan="2">';
448 if (is_object($tokenobj)) {
449 print '<textarea class="quatrevingtpercent small" rows="'.ROWS_4.'">'.var_export($tokenobj, true).'</textarea><br>'."\n";
450 }
451 print '</td>';
452 print '</tr>'."\n";
453
454 print '<tr class="oddeven">';
455 print '<td>';
456 //var_dump($key);
457 print $langs->trans("AccessToken").'</td>';
458 print '<td colspan="2">';
459 $tokentoshow = $tokenobj->getAccessToken();
460 print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span>';
461 //print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
462 //print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
463 //var_dump($tokenobj->getExtraParams());
464 /*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
465 print ''.join(',',$tokenobj->getExtraParams());
466 print '</textarea>';*/
467
468 print '<span class="opacitymedium"> &nbsp; - &nbsp; ';
469 print $langs->trans("ExpirationDate").': ';
470 print '</span>';
471 print $expiredat;
472
473 print $expire ? ' ('.$langs->trans("TokenExpired").')' : ' ('.$langs->trans("TokenNotExpired").')';
474
475 print '</td>';
476 print '</tr>'."\n";
477
478 // Token refresh
479 print '<tr class="oddeven">';
480 print '<td>';
481 //var_dump($key);
482 print $langs->trans("TOKEN_REFRESH");
483 print '</td>';
484 print '<td colspan="2">';
485 print '<span class="" title="'.dol_escape_htmltag($refreshtoken).'">'.showValueWithClipboardCPButton($refreshtoken, 1, dol_trunc($refreshtoken, 32)).'</span>';
486 print '</td>';
487 print '</tr>';
488 }
489
490 print '</table>';
491 print '</div>';
492
493 if (!empty($driver)) {
494 if ($submit_enabled) {
495 print $form->buttonsSaveCancel("Modify", '');
496 }
497 }
498
499 print '</form>';
500 print '<br>';
501 }
502 }
503}
504
505if ($mode == 'test' && $user->admin) {
506 print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n";
507
508 print '<div class="div-table-responsive-no-min">';
509 print '<table class="noborder centpercent">';
510 if (!empty($driver)) {
511 require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
512 $classname = 'printing_'.$driver;
513 $langs->load($driver);
514 $printer = new $classname($db);
515
516 '@phan-var-force PrintingDriver $printer';
517
518 //print '<pre>'.print_r($printer, true).'</pre>';
519 if (count($printer->getlistAvailablePrinters())) {
520 if ($printer->listAvailablePrinters() == 0) {
521 print $printer->resprint;
522 } else {
523 setEventMessages($printer->error, $printer->errors, 'errors');
524 }
525 } else {
526 print $langs->trans('PleaseConfigureDriverfromList');
527 }
528 }
529
530 print '</table>';
531 print '</div>';
532}
533
534if ($mode == 'userconf' && $user->admin) {
535 print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
536
537 print '<div class="div-table-responsive">';
538 print '<table class="noborder centpercent">';
539 print '<tr class="liste_titre">';
540 print '<th>'.$langs->trans("User").'</th>';
541 print '<th>'.$langs->trans("PrintModule").'</th>';
542 print '<th>'.$langs->trans("PrintDriver").'</th>';
543 print '<th>'.$langs->trans("Printer").'</th>';
544 print '<th>'.$langs->trans("PrinterLocation").'</th>';
545 print '<th>'.$langs->trans("PrinterId").'</th>';
546 print '<th>'.$langs->trans("NumberOfCopy").'</th>';
547 print '<th class="center">'.$langs->trans("Delete").'</th>';
548 print "</tr>\n";
549 $sql = "SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login";
550 $sql .= " FROM ".MAIN_DB_PREFIX."printing as p, ".MAIN_DB_PREFIX."user as u WHERE p.userid = u.rowid";
551 $resql = $db->query($sql);
552 while ($obj = $db->fetch_object($resql)) {
553 print '<tr class="oddeven">';
554 print '<td>'.$obj->login.'</td>';
555 print '<td>'.$obj->module.'</td>';
556 print '<td>'.$obj->driver.'</td>';
557 print '<td>'.$obj->printer_name.'</td>';
558 print '<td>'.$obj->printer_location.'</td>';
559 print '<td>'.$obj->printer_id.'</td>';
560 print '<td>'.$obj->copy.'</td>';
561 print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>';
562 print "</tr>\n";
563 }
564 print '</table>';
565 print '</div>';
566}
567
568print dol_get_fiche_end();
569
570// End of page
571llxFooter();
572$db->close();
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:70
Class to manage generation of HTML components Only common components must be here.
llxFooter()
Footer empty.
Definition document.php:107
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dolPrintHTMLForAttribute($s)
Return a string ready to be output on an HTML attribute (alt, title, data-html, .....
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'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getSupportedOauth2Array()
Return array of tabs to used on pages to setup cron module.
oauthadmin_prepare_head()
Return array of tabs to used on pages to setup cron module.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.