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  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
26 // Load Dolibarr environment
27 require '../main.inc.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
31 
32 use OAuth\Common\Storage\DoliStorage;
33 
34 $supportedoauth2array = getSupportedOauth2Array();
35 
36 // Load translation files required by the page
37 $langs->loadLangs(array('admin', 'printing', 'oauth'));
38 
39 $action = GETPOST('action', 'aZ09');
40 $mode = GETPOST('mode', 'alpha');
41 $value = GETPOST('value', 'alpha');
42 $varname = GETPOST('varname', 'alpha');
43 $driver = GETPOST('driver', 'alpha');
44 
45 if (!empty($driver)) {
46  $langs->load($driver);
47 }
48 
49 if (!$mode) {
50  $mode = 'setup';
51 }
52 
53 if (!$user->admin) {
55 }
56 
57 
58 /*
59  * Action
60  */
61 
62 /*if (($mode == 'test' || $mode == 'setup') && empty($driver))
63 {
64  setEventMessages($langs->trans('PleaseSelectaDriverfromList'), null);
65  header("Location: ".$_SERVER['PHP_SELF'].'?mode=config');
66  exit;
67 }*/
68 
69 if ($action == 'setconst' && $user->admin) {
70  $error = 0;
71  $db->begin();
72 
73  $setupconstarray = GETPOST('setupdriver', 'array');
74 
75  foreach ($setupconstarray as $setupconst) {
76  //print '<pre>'.print_r($setupconst, true).'</pre>';
77 
78  $constname = dol_escape_htmltag($setupconst['varname']);
79  $constvalue = dol_escape_htmltag($setupconst['value']);
80  $consttype = dol_escape_htmltag($setupconst['type']);
81  $constnote = dol_escape_htmltag($setupconst['note']);
82 
83  $result = dolibarr_set_const($db, $constname, $constvalue, $consttype, 0, $constnote, $conf->entity);
84  if (!($result > 0)) {
85  $error++;
86  }
87  }
88 
89  if (!$error) {
90  $db->commit();
91  setEventMessages($langs->trans("SetupSaved"), null);
92  } else {
93  $db->rollback();
94  dol_print_error($db);
95  }
96  $action = '';
97 }
98 
99 if ($action == 'setvalue' && $user->admin) {
100  $db->begin();
101 
102  $result = dolibarr_set_const($db, $varname, $value, 'chaine', 0, '', $conf->entity);
103  if (!($result > 0)) {
104  $error++;
105  }
106 
107  if (!$error) {
108  $db->commit();
109  setEventMessages($langs->trans("SetupSaved"), null);
110  } else {
111  $db->rollback();
112  dol_print_error($db);
113  }
114  $action = '';
115 }
116 
117 
118 /*
119  * View
120  */
121 
122 // Define $urlwithroot
123 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
124 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
125 //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
126 
127 $form = new Form($db);
128 
129 $title = $langs->trans("TokenManager");
130 $help_url = 'EN:Module_OAuth|FR:Module_OAuth_FR|ES:Módulo_OAuth_ES';
131 
132 llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-admin page-oauthlogintokens');
133 
134 $linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
135 print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup');
136 
137 $head = oauthadmin_prepare_head();
138 
139 print dol_get_fiche_head($head, 'tokengeneration', '', -1, '');
140 
141 if (GETPOST('error')) {
142  setEventMessages(GETPOST('error'), null, 'errors');
143 }
144 
145 if ($mode == 'setup' && $user->admin) {
146  print '<span class="opacitymedium">'.$langs->trans("OAuthSetupForLogin")."</span><br><br>\n";
147 
148  // Define $listinsetup
149  $listinsetup = array();
150  foreach ($conf->global as $key => $val) {
151  if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
152  $provider = preg_replace('/_ID$/', '', $key);
153  $listinsetup[] = array(
154  $provider.'_NAME',
155  $provider.'_ID',
156  $provider.'_SECRET',
157  $provider.'_URLAUTHORIZE', // For custom oauth links
158  $provider.'_SCOPE' // For custom oauth links
159  );
160  }
161  }
162 
163  $oauthstateanticsrf = bin2hex(random_bytes(128 / 8));
164 
165  // $list is defined into oauth.lib.php to the list of supported OAuth providers.
166  if (!empty($listinsetup)) {
167  foreach ($listinsetup as $key) {
168  $supported = 0;
169  $keyforsupportedoauth2array = $key[0]; // May be OAUTH_GOOGLE_NAME or OAUTH_GOOGLE_xxx_NAME
170  $keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
171  $keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
172  if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
173  $keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
174  $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
175  } else {
176  $keybeforeprovider = $keyforsupportedoauth2array;
177  $keyforprovider = '';
178  }
179  $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
180  $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
181 
182 
183  $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
184 
185  $shortscope = '';
186  if (getDolGlobalString($key[4])) {
187  $shortscope = getDolGlobalString($key[4]);
188  }
189  $state = $shortscope; // TODO USe a better state
190 
191  // Define $urltorenew, $urltodelete, $urltocheckperms
192  if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
193  // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
194  // We pass this param list in to 'state' because we need it before and after the redirect.
195 
196  // Note: github does not accept csrf key inside the state parameter (only known values)
197  $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
198  $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
199  $urltocheckperms = 'https://github.com/settings/applications/';
200  } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
201  // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
202  // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
203  // We pass this key list into the param 'state' because we need it before and after the redirect.
204  $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
205  $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
206  $urltocheckperms = 'https://security.google.com/settings/security/permissions';
207  } elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
208  $urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
209  $urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
210  $urltocheckperms = '';
211  } else {
212  $urltorenew = '';
213  $urltodelete = '';
214  $urltocheckperms = '';
215  }
216 
217  if ($urltorenew) {
218  $urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
219  }
220  if ($urltodelete) {
221  $urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
222  }
223 
224  // Show value of token
225  $tokenobj = null;
226  // Token
227  require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
228  // Dolibarr storage
229  $storage = new DoliStorage($db, $conf, $keyforprovider);
230  try {
231  // $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
232  print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
233  $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
234  //print $storage->token.'<br>';
235  //print $tokenobj->getExtraParams()['id_token'].'<br>';
236  //print $tokenobj->getAccessToken().'<br>';
237  } catch (Exception $e) {
238  // Return an error if token not found
239  //print $e->getMessage();
240  }
241 
242  // Set other properties
243  $refreshtoken = false;
244  $expiredat = '';
245 
246  $expire = false;
247  // Is token expired or will token expire in the next 30 seconds
248  if (is_object($tokenobj)) {
249  $expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
250  }
251  if ($key[1] != '' && $key[2] != '') {
252  if (is_object($tokenobj)) {
253  $refreshtoken = $tokenobj->getRefreshToken();
254 
255  $endoflife = $tokenobj->getEndOfLife();
256  if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) {
257  $expiredat = $langs->trans("Never");
258  } elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
259  $expiredat = $langs->trans("Unknown");
260  } else {
261  $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
262  }
263  }
264  }
265 
266  $submit_enabled = 0;
267 
268  print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&amp;driver='.$driver.'" autocomplete="off">';
269  print '<input type="hidden" name="token" value="'.newToken().'">';
270  print '<input type="hidden" name="action" value="setconst">';
271  print '<input type="hidden" name="page_y" value="">';
272 
273  print '<div class="div-table-responsive-no-min">';
274  print '<table class="noborder centpercent">'."\n";
275 
276  // Api Name
277  $label = $langs->trans($keyforsupportedoauth2array);
278  print '<tr class="liste_titre">';
279  print '<th class="titlefieldcreate">';
280  print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
281  if ($label == $keyforsupportedoauth2array) {
282  print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
283  } else {
284  print $label;
285  }
286  if ($keyforprovider) {
287  print ' (<b>'.$keyforprovider.'</b>)';
288  } else {
289  print ' (<b>'.$langs->trans("NoName").'</b>)';
290  }
291  print '</th>';
292  print '<th></th>';
293  print '<th></th>';
294  print "</tr>\n";
295 
296  print '<tr class="oddeven">';
297  print '<td>';
298  //var_dump($key);
299  print $langs->trans("OAuthIDSecret").'</td>';
300  print '<td>';
301  print '<span class="opacitymedium">'.$langs->trans("SeePreviousTab").'</span>';
302  print '</td>';
303  print '<td>';
304  print '</td>';
305  print '</tr>'."\n";
306 
307  // Scopes
308  print '<tr class="oddeven">';
309  print '<td>'.$langs->trans("Scopes").'</td>';
310  print '<td colspan="2">';
311  $currentscopes = getDolGlobalString($key[4]);
312  print $currentscopes;
313  print '</td></tr>';
314 
315  print '<tr class="oddeven">';
316  print '<td>';
317  //var_dump($key);
318  print $langs->trans("IsTokenGenerated");
319  print '</td>';
320  print '<td>';
321  if ($keyforprovider != 'Login') {
322  if (is_object($tokenobj)) {
323  print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '.dol_print_date($storage->date_modification, 'dayhour').' state='.dol_escape_htmltag($storage->state));
324  } else {
325  print '<span class="opacitymedium">'.$langs->trans("NoAccessToken").'</span>';
326  }
327  } else {
328  print '<span class="opacitymedium">'.$langs->trans("TokenNotRequiredForOAuthLogin").'</span>';
329  }
330  print '</td>';
331  print '<td width="50%">';
332  if ($keyforprovider != 'Login') {
333  // Links to delete/checks token
334  if (is_object($tokenobj)) {
335  //test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
336  if ($urltodelete) {
337  print '<a class="button smallpaddingimp reposition" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
338  } else {
339  print '<span class="opacitymedium">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span><br>';
340  }
341  }
342  // Request remote token
343  if ($urltorenew) {
344  print '<a class="button smallpaddingimp reposition" href="'.$urltorenew.'">'.$langs->trans('GetAccess').'</a>';
345  print $form->textwithpicto('', $langs->trans('RequestAccess'));
346  print '<br>';
347  }
348  // Check remote access
349  if ($urltocheckperms) {
350  print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
351  }
352  }
353  print '</td>';
354  print '</tr>';
355 
356  print '<tr class="oddeven">';
357  print '<td>';
358  //var_dump($key);
359  print $langs->trans("Token").'</td>';
360  print '<td colspan="2">';
361 
362  if (is_object($tokenobj)) {
363  $tokentoshow = $tokenobj->getAccessToken();
364  print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
365  //print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
366  //print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
367  //var_dump($tokenobj->getExtraParams());
368  /*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
369  print ''.join(',',$tokenobj->getExtraParams());
370  print '</textarea>';*/
371  }
372  print '</td>';
373  print '</tr>'."\n";
374 
375  if (is_object($tokenobj)) {
376  // Token refresh
377  print '<tr class="oddeven">';
378  print '<td>';
379  //var_dump($key);
380  print $langs->trans("TOKEN_REFRESH");
381  print '</td>';
382  print '<td colspan="2">';
383  print '<span class="" title="'.dol_escape_htmltag($refreshtoken).'">'.showValueWithClipboardCPButton($refreshtoken, 1, dol_trunc($refreshtoken, 32)).'</span>';
384  print '</td>';
385  print '</tr>';
386 
387  // Token expired
388  print '<tr class="oddeven">';
389  print '<td>';
390  //var_dump($key);
391  print $langs->trans("TOKEN_EXPIRED");
392  print '</td>';
393  print '<td colspan="2">';
394  print yn($expire);
395  print '</td>';
396  print '</tr>';
397 
398  // Token expired at
399  print '<tr class="oddeven">';
400  print '<td>';
401  //var_dump($key);
402  print $langs->trans("TOKEN_EXPIRE_AT");
403  print '</td>';
404  print '<td colspan="2">';
405  print $expiredat;
406  print '</td>';
407  print '</tr>';
408  }
409 
410  print '</table>';
411  print '</div>';
412 
413  if (!empty($driver)) {
414  if ($submit_enabled) {
415  print $form->buttonsSaveCancel("Modify", '');
416  }
417  }
418 
419  print '</form>';
420  print '<br>';
421  }
422  }
423 }
424 
425 if ($mode == 'test' && $user->admin) {
426  print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n";
427 
428  print '<div class="div-table-responsive-no-min">';
429  print '<table class="noborder centpercent">';
430  if (!empty($driver)) {
431  require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
432  $classname = 'printing_'.$driver;
433  $langs->load($driver);
434  $printer = new $classname($db);
435  //print '<pre>'.print_r($printer, true).'</pre>';
436  if (count($printer->getlistAvailablePrinters())) {
437  if ($printer->listAvailablePrinters() == 0) {
438  print $printer->resprint;
439  } else {
440  setEventMessages($printer->error, $printer->errors, 'errors');
441  }
442  } else {
443  print $langs->trans('PleaseConfigureDriverfromList');
444  }
445  }
446 
447  print '</table>';
448  print '</div>';
449 }
450 
451 if ($mode == 'userconf' && $user->admin) {
452  print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
453 
454  print '<div class="div-table-responsive">';
455  print '<table class="noborder centpercent">';
456  print '<tr class="liste_titre">';
457  print '<th>'.$langs->trans("User").'</th>';
458  print '<th>'.$langs->trans("PrintModule").'</th>';
459  print '<th>'.$langs->trans("PrintDriver").'</th>';
460  print '<th>'.$langs->trans("Printer").'</th>';
461  print '<th>'.$langs->trans("PrinterLocation").'</th>';
462  print '<th>'.$langs->trans("PrinterId").'</th>';
463  print '<th>'.$langs->trans("NumberOfCopy").'</th>';
464  print '<th class="center">'.$langs->trans("Delete").'</th>';
465  print "</tr>\n";
466  $sql = "SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login";
467  $sql .= " FROM ".MAIN_DB_PREFIX."printing as p, ".MAIN_DB_PREFIX."user as u WHERE p.userid = u.rowid";
468  $resql = $db->query($sql);
469  while ($obj = $db->fetch_object($resql)) {
470  print '<tr class="oddeven">';
471  print '<td>'.$obj->login.'</td>';
472  print '<td>'.$obj->module.'</td>';
473  print '<td>'.$obj->driver.'</td>';
474  print '<td>'.$obj->printer_name.'</td>';
475  print '<td>'.$obj->printer_location.'</td>';
476  print '<td>'.$obj->printer_id.'</td>';
477  print '<td>'.$obj->copy.'</td>';
478  print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>';
479  print "</tr>\n";
480  }
481  print '</table>';
482  print '</div>';
483 }
484 
485 print dol_get_fiche_end();
486 
487 // End of page
488 llxFooter();
489 $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).
Definition: admin.lib.php:656
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
Class to manage generation of HTML components Only common components must be here.
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:751
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.
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 dolibarr global constant string value.
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.
Definition: oauth.lib.php:279
oauthadmin_prepare_head()
Return array of tabs to used on pages to setup cron module.
Definition: oauth.lib.php:364
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.