Merge branch '17.0' of git@github.com:Dolibarr/dolibarr.git into 17.0
This commit is contained in:
commit
bda65d0d9b
33
ChangeLog
33
ChangeLog
@ -3,15 +3,6 @@ English Dolibarr ChangeLog
|
|||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
***** ChangeLog for 18.0.0 compared to 17.0.0 *****
|
|
||||||
|
|
||||||
WARNING:
|
|
||||||
|
|
||||||
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
|
|
||||||
* The deprecated method escapeunderscore() of database handlers has been removed. You must use escapeforlike instead.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
***** ChangeLog for 17.0.0 compared to 16.0.0 *****
|
***** ChangeLog for 17.0.0 compared to 16.0.0 *****
|
||||||
|
|
||||||
@ -218,27 +209,41 @@ Following changes may create regressions for some external modules, but were nec
|
|||||||
* Tables llx_prelevement_facture and llx_prelevement_facture_demande have been renamed into llx_prelevement and llx_prelevement_demande.
|
* Tables llx_prelevement_facture and llx_prelevement_facture_demande have been renamed into llx_prelevement and llx_prelevement_demande.
|
||||||
* Rename MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and rename MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES
|
* Rename MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and rename MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES
|
||||||
* Rename the substitution for "project label" instead of "project title" in substitution variables
|
* Rename the substitution for "project label" instead of "project title" in substitution variables
|
||||||
|
* You must use "$objectoffield" to manipulate the current object inside the formulare of computed custom extrafields instead of $obj/$object.
|
||||||
|
* Making a global search is sending the parameter using always the name search_all (instead of sometimes sall and search_all)
|
||||||
|
|
||||||
|
***** ChangeLog for 16.0.4 compared to 16.0.3 *****
|
||||||
***** ChangeLog for 16.0.4 compared to 16.0.2 *****
|
|
||||||
|
|
||||||
FIX: Amount of localtax1 and 2 not correctly save on purchase order (the rate was saved instead)
|
FIX: Amount of localtax1 and 2 not correctly save on purchase order (the rate was saved instead)
|
||||||
FIX: #20415
|
FIX: #20415
|
||||||
FIX: #21280
|
FIX: #21280
|
||||||
FIX: #23008
|
FIX: #23008
|
||||||
FIX: #22271
|
FIX: #22271
|
||||||
|
FIX: #22524
|
||||||
FIX: #22837
|
FIX: #22837
|
||||||
|
FIX: #22964
|
||||||
|
FIX: #23012
|
||||||
FIX: #23019 Impossible to add task times to an existing draft invoice
|
FIX: #23019 Impossible to add task times to an existing draft invoice
|
||||||
FIX: #23072
|
FIX: #23072
|
||||||
FIX: #23087
|
FIX: #23087
|
||||||
FIX: #23115
|
FIX: #23115
|
||||||
FIX: #23116
|
FIX: #23116
|
||||||
FIX: #23281
|
FIX: #23281
|
||||||
|
FIX: #23420 : wrong check on $search_categ value causing FATAL ERROR
|
||||||
|
FIX: Accountancy - Quadra export
|
||||||
|
FIX: add border left on image product when conf activated
|
||||||
|
FIX: Add missing token when deleting template inn order_supplier admin menu
|
||||||
|
FIX: Amount of localtax1 and 2 not correctly save on purchase order (the
|
||||||
|
FIX: API access for deactivated users
|
||||||
FIX: bad selection of barcode numbering module
|
FIX: bad selection of barcode numbering module
|
||||||
FIX: Can't see all time spent by all user
|
FIX: Can't see all time spent by all user
|
||||||
FIX: CI
|
FIX: CI
|
||||||
FIX: CommonObject - showOptionals - Display blank td when MAIN_VIEW_LINE_NUMBER is enabled and action is confirm_valid
|
FIX: CommonObject - showOptionals - Display blank td when MAIN_VIEW_LINE_NUMBER is enabled and action is confirm_valid
|
||||||
FIX: Documents API inconsistency
|
FIX: Documents API inconsistency
|
||||||
|
FIX: Empty FormSetup emailTemplate type IF empty fieldvalue
|
||||||
|
FIX: Errors Handling for CreateFrom Hooks
|
||||||
|
FIX: error with dol_banner_tab, ref is needed
|
||||||
|
FIX: ExpenseReport card was not reloaded after addline
|
||||||
FIX: #23075
|
FIX: #23075
|
||||||
FIX: #23117
|
FIX: #23117
|
||||||
FIX: get multicurrency infos of propal when create order from propal with "WORKFLOW_PROPAL_AUTOCREATE_ORDER" conf
|
FIX: get multicurrency infos of propal when create order from propal with "WORKFLOW_PROPAL_AUTOCREATE_ORDER" conf
|
||||||
@ -246,12 +251,16 @@ FIX: Give predictable order to inventory lines
|
|||||||
FIX: include class multicurrency
|
FIX: include class multicurrency
|
||||||
FIX: methods declaration (backport fix 67b9a7dc07d708231d12b5e58800334d4a01ef98)
|
FIX: methods declaration (backport fix 67b9a7dc07d708231d12b5e58800334d4a01ef98)
|
||||||
FIX: multicurrency_tx and not currency_tx
|
FIX: multicurrency_tx and not currency_tx
|
||||||
FIX: PGSQL Integer type does not have a free length
|
FIX: on public ticket list, only the page 1 was accessible. Other pages were 404 error.
|
||||||
|
FIX: PGSQL Integer type does not have a free lenght
|
||||||
|
FIX: PGSQL Int type does not have a free lenght
|
||||||
FIX: Product list in setup.php in new Module
|
FIX: Product list in setup.php in new Module
|
||||||
FIX: propal and order stats broken on Tag+User(retricted customer list)
|
FIX: propal and order stats broken on Tag+User(retricted customer list)
|
||||||
FIX: saving of numbering module for jobs
|
FIX: saving of numbering module for jobs
|
||||||
FIX: Stickler
|
FIX: Stickler
|
||||||
FIX: travis
|
FIX: travis
|
||||||
|
FIX: wrong check on $search_categ value causing fatal error
|
||||||
|
FIX: wrong stock list with multicompany and without stock sharing
|
||||||
|
|
||||||
***** ChangeLog for 16.0.3 compared to 16.0.2 *****
|
***** ChangeLog for 16.0.3 compared to 16.0.2 *****
|
||||||
|
|
||||||
|
|||||||
@ -107,6 +107,7 @@ $permissiondellink = $user->admin; // Used by the include of actions_dellink.inc
|
|||||||
$permissiontoadd = $user->admin; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
|
$permissiontoadd = $user->admin; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
|
||||||
|
|
||||||
$debuginfo = '';
|
$debuginfo = '';
|
||||||
|
$error = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -121,8 +122,6 @@ if ($reshook < 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($reshook)) {
|
if (empty($reshook)) {
|
||||||
$error = 0;
|
|
||||||
|
|
||||||
$permissiontoadd = 1;
|
$permissiontoadd = 1;
|
||||||
$permissiontodelete = 1;
|
$permissiontodelete = 1;
|
||||||
if (empty($backtopage)) {
|
if (empty($backtopage)) {
|
||||||
@ -397,104 +396,128 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
|
|||||||
$connectstringsource = '';
|
$connectstringsource = '';
|
||||||
$connectstringtarget = '';
|
$connectstringtarget = '';
|
||||||
|
|
||||||
if (function_exists('imap_open')) {
|
// Note: $object->host has been loaded by the fetch
|
||||||
// Note: $object->host has been loaded by the fetch
|
$usessl = 1;
|
||||||
$usessl = 1;
|
|
||||||
|
|
||||||
$connectstringserver = $object->getConnectStringIMAP($usessl);
|
$connectstringserver = $object->getConnectStringIMAP($usessl);
|
||||||
|
|
||||||
if ($action == 'scan') {
|
if ($action == 'scan') {
|
||||||
if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) {
|
if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) {
|
||||||
if ($object->acces_type == 1) {
|
if ($object->acces_type == 1) {
|
||||||
// Mode OAUth2 with PHP-IMAP
|
// Mode OAUth2 with PHP-IMAP
|
||||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array
|
||||||
$keyforsupportedoauth2array = $object->oauth_service;
|
$keyforsupportedoauth2array = $object->oauth_service;
|
||||||
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
||||||
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
||||||
} else {
|
|
||||||
$keyforprovider = '';
|
|
||||||
}
|
|
||||||
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
|
||||||
$keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
|
|
||||||
|
|
||||||
$OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
|
|
||||||
|
|
||||||
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
|
||||||
//$debugtext = "Host: ".$this->host."<br>Port: ".$this->port."<br>Login: ".$this->login."<br>Password: ".$this->password."<br>access type: ".$this->acces_type."<br>oauth service: ".$this->oauth_service."<br>Max email per collect: ".$this->maxemailpercollect;
|
|
||||||
//dol_syslog($debugtext);
|
|
||||||
|
|
||||||
$storage = new DoliStorage($db, $conf);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
|
||||||
$expire = true;
|
|
||||||
// Is token expired or will token expire in the next 30 seconds
|
|
||||||
// if (is_object($tokenobj)) {
|
|
||||||
// $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30));
|
|
||||||
// }
|
|
||||||
// Token expired so we refresh it
|
|
||||||
if (is_object($tokenobj) && $expire) {
|
|
||||||
$credentials = new Credentials(
|
|
||||||
getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'),
|
|
||||||
getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'),
|
|
||||||
getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE')
|
|
||||||
);
|
|
||||||
$serviceFactory = new \OAuth\ServiceFactory();
|
|
||||||
$oauthname = explode('-', $OAUTH_SERVICENAME);
|
|
||||||
// ex service is Google-Emails we need only the first part Google
|
|
||||||
$apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array());
|
|
||||||
// We have to save the token because Google give it only once
|
|
||||||
$refreshtoken = $tokenobj->getRefreshToken();
|
|
||||||
$tokenobj = $apiService->refreshAccessToken($tokenobj);
|
|
||||||
$tokenobj->setRefreshToken($refreshtoken);
|
|
||||||
$storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj);
|
|
||||||
}
|
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
|
||||||
if (is_object($tokenobj)) {
|
|
||||||
$token = $tokenobj->getAccessToken();
|
|
||||||
} else {
|
|
||||||
$object->error = "Token not found";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
print $e->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
$cm = new ClientManager();
|
|
||||||
$client = $cm->make([
|
|
||||||
'host' => $object->host,
|
|
||||||
'port' => $object->port,
|
|
||||||
'encryption' => 'ssl',
|
|
||||||
'validate_cert' => true,
|
|
||||||
'protocol' => 'imap',
|
|
||||||
'username' => $object->login,
|
|
||||||
'password' => $token,
|
|
||||||
'authentication' => "oauth",
|
|
||||||
]);
|
|
||||||
} else {
|
} else {
|
||||||
// Mode login/pass with PHP-IMAP
|
$keyforprovider = '';
|
||||||
$cm = new ClientManager();
|
|
||||||
$client = $cm->make([
|
|
||||||
'host' => $object->host,
|
|
||||||
'port' => $object->port,
|
|
||||||
'encryption' => 'ssl',
|
|
||||||
'validate_cert' => true,
|
|
||||||
'protocol' => 'imap',
|
|
||||||
'username' => $object->login,
|
|
||||||
'password' => $object->password,
|
|
||||||
'authentication' => "login",
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||||
|
$keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
|
||||||
|
|
||||||
|
$OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
|
||||||
|
|
||||||
|
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||||
|
//$debugtext = "Host: ".$this->host."<br>Port: ".$this->port."<br>Login: ".$this->login."<br>Password: ".$this->password."<br>access type: ".$this->acces_type."<br>oauth service: ".$this->oauth_service."<br>Max email per collect: ".$this->maxemailpercollect;
|
||||||
|
//dol_syslog($debugtext);
|
||||||
|
|
||||||
|
$token = '';
|
||||||
|
|
||||||
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$client->connect();
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||||
} catch (ConnectionFailedException $e) {
|
|
||||||
print $e->getMessage();
|
$expire = true;
|
||||||
|
// Is token expired or will token expire in the next 30 seconds
|
||||||
|
// if (is_object($tokenobj)) {
|
||||||
|
// $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30));
|
||||||
|
// }
|
||||||
|
// Token expired so we refresh it
|
||||||
|
if (is_object($tokenobj) && $expire) {
|
||||||
|
$credentials = new Credentials(
|
||||||
|
getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'),
|
||||||
|
getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'),
|
||||||
|
getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE')
|
||||||
|
);
|
||||||
|
$serviceFactory = new \OAuth\ServiceFactory();
|
||||||
|
$oauthname = explode('-', $OAUTH_SERVICENAME);
|
||||||
|
|
||||||
|
// ex service is Google-Emails we need only the first part Google
|
||||||
|
$apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array());
|
||||||
|
|
||||||
|
// We have to save the token because Google give it only once
|
||||||
|
$refreshtoken = $tokenobj->getRefreshToken();
|
||||||
|
//var_dump($tokenobj);
|
||||||
|
$tokenobj = $apiService->refreshAccessToken($tokenobj);
|
||||||
|
|
||||||
|
$tokenobj->setRefreshToken($refreshtoken);
|
||||||
|
$storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj);
|
||||||
|
}
|
||||||
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||||
|
if (is_object($tokenobj)) {
|
||||||
|
$token = $tokenobj->getAccessToken();
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
$morehtml .= "Token not found";
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error++;
|
||||||
|
$morehtml .= $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$f = $client->getFolders(false, $object->source_directory);
|
if (empty($object->login)) {
|
||||||
$nbemail = $f[0]->examine()["exists"];
|
$error++;
|
||||||
$morehtml .= $nbemail;
|
$morehtml .= 'Error: Login is empty. Must be email owner when using MAIN_IMAP_USE_PHPIMAP and OAuth.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$cm = new ClientManager();
|
||||||
|
$client = $cm->make([
|
||||||
|
'host' => $object->host,
|
||||||
|
'port' => $object->port,
|
||||||
|
'encryption' => 'ssl',
|
||||||
|
'validate_cert' => true,
|
||||||
|
'protocol' => 'imap',
|
||||||
|
'username' => $object->login,
|
||||||
|
'password' => $token,
|
||||||
|
'authentication' => "oauth",
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
|
// Mode login/pass with PHP-IMAP
|
||||||
|
$cm = new ClientManager();
|
||||||
|
$client = $cm->make([
|
||||||
|
'host' => $object->host,
|
||||||
|
'port' => $object->port,
|
||||||
|
'encryption' => 'ssl',
|
||||||
|
'validate_cert' => true,
|
||||||
|
'protocol' => 'imap',
|
||||||
|
'username' => $object->login,
|
||||||
|
'password' => $object->password,
|
||||||
|
'authentication' => "login",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (!$error) {
|
||||||
|
try {
|
||||||
|
// To emulate the command connect, you can run
|
||||||
|
// openssl s_client -crlf -connect outlook.office365.com:993
|
||||||
|
// TAG1 AUTHENTICATE XOAUTH2 dXN...
|
||||||
|
// TO Get debug log, you can set protected $debug = true; in Protocol.php file
|
||||||
|
//
|
||||||
|
// A MS bug make this not working !
|
||||||
|
// See https://github.com/MicrosoftDocs/office-developer-exchange-docs/issues/100
|
||||||
|
// See github.com/MicrosoftDocs/office-developer-exchange-docs/issues/87
|
||||||
|
// See github.com/Webklex/php-imap/issues/81
|
||||||
|
$client->connect();
|
||||||
|
|
||||||
|
$f = $client->getFolders(false, $object->source_directory);
|
||||||
|
$nbemail = $f[0]->examine()["exists"];
|
||||||
|
$morehtml .= $nbemail;
|
||||||
|
} catch (ConnectionFailedException $e) {
|
||||||
|
$morehtml .= 'ConnectionFailedException '.$e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (function_exists('imap_open')) {
|
||||||
try {
|
try {
|
||||||
if ($sourcedir) {
|
if ($sourcedir) {
|
||||||
//$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir);
|
//$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir);
|
||||||
@ -521,7 +544,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
|
|||||||
|
|
||||||
//dol_syslog("end imap_open connection=".var_export($connection, true));
|
//dol_syslog("end imap_open connection=".var_export($connection, true));
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
print $e->getMessage();
|
$morehtml .= $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$connection) {
|
if (!$connection) {
|
||||||
@ -540,16 +563,16 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
|
|||||||
dol_syslog("Imap close");
|
dol_syslog("Imap close");
|
||||||
imap_close($connection);
|
imap_close($connection);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$morehtml .= 'IMAP functions not available on your PHP. ';
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$morehtml .= '<a class="flat" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=scan&token='.newToken().'">'.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").'</a>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver);
|
|
||||||
} else {
|
} else {
|
||||||
$morehtml .= 'IMAP functions not available on your PHP. ';
|
$morehtml .= '<a class="flat" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=scan&token='.newToken().'">'.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").'</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver);
|
||||||
|
|
||||||
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'<div class="refidno">'.$morehtml.'</div>', '', 0, '', '', 0, '');
|
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'<div class="refidno">'.$morehtml.'</div>', '', 0, '', '', 0, '');
|
||||||
|
|
||||||
print '<div class="fichecenter">';
|
print '<div class="fichecenter">';
|
||||||
|
|||||||
@ -273,25 +273,6 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
|
|||||||
$parameters = array();
|
$parameters = array();
|
||||||
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
|
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
|
||||||
$sql .= $hookmanager->resPrint;
|
$sql .= $hookmanager->resPrint;
|
||||||
|
|
||||||
/* If a group by is required
|
|
||||||
$sql.= " GROUP BY ";
|
|
||||||
foreach ($object->fields as $key => $val) {
|
|
||||||
$sql .= "t.".$db->escape($key).", ";
|
|
||||||
}
|
|
||||||
// Add fields from extrafields
|
|
||||||
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
|
|
||||||
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
|
|
||||||
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add where from hooks
|
|
||||||
$parameters=array();
|
|
||||||
$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
|
|
||||||
$sql .= $hookmanager->resPrint;
|
|
||||||
$sql = preg_replace('/,\s*$/', '', $sql);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Count total nb of records
|
// Count total nb of records
|
||||||
$nbtotalofrecords = '';
|
$nbtotalofrecords = '';
|
||||||
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
|
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
|
||||||
@ -333,6 +314,22 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $
|
|||||||
|
|
||||||
llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', '');
|
llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', '');
|
||||||
|
|
||||||
|
|
||||||
|
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
|
||||||
|
print load_fiche_titre($title, $linkback, 'title_setup');
|
||||||
|
|
||||||
|
|
||||||
|
$head = array();
|
||||||
|
$h = 0;
|
||||||
|
$head[$h][0] = DOL_URL_ROOT."/admin/emailcollector_list.php";
|
||||||
|
$head[$h][1] = $langs->trans("Setup");
|
||||||
|
$head[$h][2] = 'common';
|
||||||
|
$h++;
|
||||||
|
|
||||||
|
print dol_get_fiche_head($head, 'common', '', -1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$arrayofselected = is_array($toselect) ? $toselect : array();
|
$arrayofselected = is_array($toselect) ? $toselect : array();
|
||||||
|
|
||||||
$param = '';
|
$param = '';
|
||||||
@ -388,11 +385,9 @@ print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
|
|||||||
print '<input type="hidden" name="page" value="'.$page.'">';
|
print '<input type="hidden" name="page" value="'.$page.'">';
|
||||||
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
|
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
|
||||||
|
|
||||||
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
|
|
||||||
|
|
||||||
$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'emailcollector_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
|
$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'emailcollector_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
|
||||||
|
|
||||||
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'email', 0, $newcardbutton.' '.$linkback, '', $limit, 0, 0, 1);
|
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'email', 0, $newcardbutton, '', $limit, 0, 0, 1);
|
||||||
|
|
||||||
// Add code for pre mass action (confirmation or email presend form)
|
// Add code for pre mass action (confirmation or email presend form)
|
||||||
/*$topicmail="";
|
/*$topicmail="";
|
||||||
@ -699,7 +694,22 @@ print '<td>'.$langs->trans("Parameter").'</td>';
|
|||||||
print '<td></td>';
|
print '<td></td>';
|
||||||
print "</tr>\n";
|
print "</tr>\n";
|
||||||
|
|
||||||
// Hide e-mail headers from collected messages
|
// MAIN_IMAP_USE_PHPIMAP: Enable use of the PHP Imap library
|
||||||
|
print '<tr class="oddeven"><td>';
|
||||||
|
//print $form->textwithpicto($langs->trans("MAIN_IMAP_USE_PHPIMAP"), $langs->transnoentitiesnoconv("MAIN_IMAP_USE_PHPIMAPDesc"));
|
||||||
|
print $langs->trans("MAIN_IMAP_USE_PHPIMAP");
|
||||||
|
print '</td>';
|
||||||
|
print '<td class="left">';
|
||||||
|
if ($conf->use_javascript_ajax) {
|
||||||
|
print ajax_constantonoff('MAIN_IMAP_USE_PHPIMAP');
|
||||||
|
} else {
|
||||||
|
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
|
||||||
|
print $form->selectarray("MAIN_IMAP_USE_PHPIMAP", $arrval, $conf->global->MAIN_IMAP_USE_PHPIMAP);
|
||||||
|
}
|
||||||
|
print '</td>';
|
||||||
|
print '</tr>';
|
||||||
|
|
||||||
|
// MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER: Hide e-mail headers from collected messages
|
||||||
print '<tr class="oddeven"><td>'.$form->textwithpicto($langs->trans("EmailCollectorHideMailHeaders"), $langs->transnoentitiesnoconv("EmailCollectorHideMailHeadersHelp")).'</td>';
|
print '<tr class="oddeven"><td>'.$form->textwithpicto($langs->trans("EmailCollectorHideMailHeaders"), $langs->transnoentitiesnoconv("EmailCollectorHideMailHeadersHelp")).'</td>';
|
||||||
print '<td class="left">';
|
print '<td class="left">';
|
||||||
if ($conf->use_javascript_ajax) {
|
if ($conf->use_javascript_ajax) {
|
||||||
@ -738,6 +748,10 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n
|
|||||||
print $formfile->showdocuments('massfilesarea_emailcollector', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
|
print $formfile->showdocuments('massfilesarea_emailcollector', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dol_get_fiche_end();
|
||||||
|
|
||||||
|
|
||||||
// End of page
|
// End of page
|
||||||
llxFooter();
|
llxFooter();
|
||||||
$db->close();
|
$db->close();
|
||||||
|
|||||||
137
htdocs/admin/mails_ingoing.php
Normal file
137
htdocs/admin/mails_ingoing.php
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
/* Copyright (C) 2007-2020 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||||
|
* Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
|
||||||
|
* Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
|
||||||
|
* Copyright (C) 2016 Jonathan TISSEAU <jonathan.tisseau@86dev.fr>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file htdocs/admin/mails_ingoing.php
|
||||||
|
* \brief Page to setup emails entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Load Dolibarr environment
|
||||||
|
require '../main.inc.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||||
|
|
||||||
|
// Load translation files required by the page
|
||||||
|
$langs->loadLangs(array("companies", "products", "admin", "mails", "other", "errors"));
|
||||||
|
|
||||||
|
$action = GETPOST('action', 'aZ09');
|
||||||
|
$cancel = GETPOST('cancel', 'aZ09');
|
||||||
|
|
||||||
|
$trackid = GETPOST('trackid');
|
||||||
|
|
||||||
|
if (!$user->admin) {
|
||||||
|
accessforbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($action == 'update' && !$cancel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* View
|
||||||
|
*/
|
||||||
|
|
||||||
|
$form = new Form($db);
|
||||||
|
|
||||||
|
$linuxlike = 1;
|
||||||
|
if (preg_match('/^win/i', PHP_OS)) {
|
||||||
|
$linuxlike = 0;
|
||||||
|
}
|
||||||
|
if (preg_match('/^mac/i', PHP_OS)) {
|
||||||
|
$linuxlike = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//$wikihelp = 'EN:Setup_EMails|FR:Paramétrage_EMails|ES:Configuración_EMails';
|
||||||
|
$wikihelp = '';
|
||||||
|
llxHeader('', $langs->trans("Setup"), $wikihelp);
|
||||||
|
|
||||||
|
print load_fiche_titre($langs->trans("EMailsSetup"), '', 'title_setup');
|
||||||
|
|
||||||
|
$head = email_admin_prepare_head();
|
||||||
|
|
||||||
|
// List of sending methods
|
||||||
|
$listofmethods = array();
|
||||||
|
$listofmethods['mail'] = 'PHP mail function';
|
||||||
|
$listofmethods['smtps'] = 'SMTP/SMTPS socket library';
|
||||||
|
if (version_compare(phpversion(), '7.0', '>=')) {
|
||||||
|
$listofmethods['swiftmailer'] = 'Swift Mailer socket library';
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of oauth services
|
||||||
|
$oauthservices = array();
|
||||||
|
|
||||||
|
foreach ($conf->global as $key => $val) {
|
||||||
|
if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
|
||||||
|
$key = preg_replace('/^OAUTH_/', '', $key);
|
||||||
|
$key = preg_replace('/_ID$/', '', $key);
|
||||||
|
if (preg_match('/^.*-/', $key)) {
|
||||||
|
$name = preg_replace('/^.*-/', '', $key);
|
||||||
|
} else {
|
||||||
|
$name = $langs->trans("NoName");
|
||||||
|
}
|
||||||
|
$provider = preg_replace('/-.*$/', '', $key);
|
||||||
|
$provider = ucfirst(strtolower($provider));
|
||||||
|
|
||||||
|
$oauthservices[$key] = $name." (".$provider.")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print dol_get_fiche_head($head, 'common_ingoing', '', -1);
|
||||||
|
|
||||||
|
print '<br>';
|
||||||
|
print '<span class="opacitymedium">'.$langs->trans("EMailsInGoingDesc", $langs->transnoentitiesnoconv("EmailCollector"))."</span><br>\n";
|
||||||
|
print "<br><br>\n";
|
||||||
|
|
||||||
|
/*
|
||||||
|
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
|
||||||
|
print '<table class="noborder centpercent">';
|
||||||
|
print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
|
||||||
|
|
||||||
|
print '<br>';
|
||||||
|
|
||||||
|
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
|
||||||
|
print '<table class="noborder centpercent">';
|
||||||
|
|
||||||
|
// SMTPS oauth service
|
||||||
|
if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail'), array('smtps', 'swiftmailer')) && getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE') === "XOAUTH2") {
|
||||||
|
$text = $oauthservices[$conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE];
|
||||||
|
if (empty($text)) {
|
||||||
|
$text = $langs->trans("Undefined").img_warning();
|
||||||
|
}
|
||||||
|
print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").'</td><td>'.$text.'</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
print '</table>';
|
||||||
|
print '</div>';
|
||||||
|
*/
|
||||||
|
|
||||||
|
print dol_get_fiche_end();
|
||||||
|
|
||||||
|
|
||||||
|
// End of page
|
||||||
|
llxFooter();
|
||||||
|
$db->close();
|
||||||
@ -1041,7 +1041,7 @@ if ($mode == 'marketplace') {
|
|||||||
|
|
||||||
print '<div class="liste_titre liste_titre_bydiv centpercent"><div class="divsearchfield">';
|
print '<div class="liste_titre liste_titre_bydiv centpercent"><div class="divsearchfield">';
|
||||||
|
|
||||||
print '<form method="POST" class="centpercent" id="searchFormList" action="'.urlencode($dolistore->url).'">';
|
print '<form method="POST" class="centpercent" id="searchFormList" action="'.$dolistore->url.'">';
|
||||||
?>
|
?>
|
||||||
<input type="hidden" name="token" value="<?php echo newToken(); ?>">
|
<input type="hidden" name="token" value="<?php echo newToken(); ?>">
|
||||||
<input type="hidden" name="mode" value="marketplace">
|
<input type="hidden" name="mode" value="marketplace">
|
||||||
|
|||||||
@ -84,6 +84,11 @@ if ($action == 'update') {
|
|||||||
$error++;
|
$error++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (GETPOSTISSET($constvalue.'_TENANT')) {
|
||||||
|
if (!dolibarr_set_const($db, $constvalue.'_TENANT', GETPOST($constvalue.'_TENANT'), 'chaine', 0, '', $conf->entity)) {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (GETPOSTISSET($constvalue.'_SCOPE')) {
|
if (GETPOSTISSET($constvalue.'_SCOPE')) {
|
||||||
if (is_array(GETPOST($constvalue.'_SCOPE'))) {
|
if (is_array(GETPOST($constvalue.'_SCOPE'))) {
|
||||||
$scopestring = implode(',', GETPOST($constvalue.'_SCOPE'));
|
$scopestring = implode(',', GETPOST($constvalue.'_SCOPE'));
|
||||||
@ -128,6 +133,8 @@ if ($action == 'confirm_delete') {
|
|||||||
$callbacktodel .= '/core/modules/oauth/stripelive_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
$callbacktodel .= '/core/modules/oauth/stripelive_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
||||||
} elseif ($label == 'OAUTH_STRIPE_TEST') {
|
} elseif ($label == 'OAUTH_STRIPE_TEST') {
|
||||||
$callbacktodel .= '/core/modules/oauth/stripetest_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
$callbacktodel .= '/core/modules/oauth/stripetest_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
||||||
|
} elseif ($label == 'OAUTH_MICROSOFT') {
|
||||||
|
$callbacktodel .= '/core/modules/oauth/microsoft_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
||||||
} elseif ($label == 'OAUTH_OTHER') {
|
} elseif ($label == 'OAUTH_OTHER') {
|
||||||
$callbacktodel .= '/core/modules/oauth/generic_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
$callbacktodel .= '/core/modules/oauth/generic_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl);
|
||||||
}
|
}
|
||||||
@ -242,8 +249,10 @@ if (count($listinsetup) > 0) {
|
|||||||
$keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
|
$keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
|
||||||
$keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
|
$keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
|
||||||
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
||||||
|
$keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||||
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
||||||
} else {
|
} else {
|
||||||
|
$keybeforeprovider = $keyforsupportedoauth2array;
|
||||||
$keyforprovider = '';
|
$keyforprovider = '';
|
||||||
}
|
}
|
||||||
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||||
@ -337,6 +346,16 @@ if (count($listinsetup) > 0) {
|
|||||||
print '<td></td>';
|
print '<td></td>';
|
||||||
print '</tr>';
|
print '</tr>';
|
||||||
|
|
||||||
|
// Tenant
|
||||||
|
if ($keybeforeprovider == 'MICROSOFT') {
|
||||||
|
print '<tr class="oddeven value">';
|
||||||
|
print '<td><label for="'.$key[2].'">'.$langs->trans("OAUTH_TENANT").'</label></td>';
|
||||||
|
print '<td><input type="text" size="100" id="OAUTH_'.$keybeforeprovider.($keyforprovider ? '-'.$keyforprovider : '').'_TENANT" name="OAUTH_'.$keybeforeprovider.($keyforprovider ? '-'.$keyforprovider : '').'_TENANT" value="'.getDolGlobalString('OAUTH_'.$keybeforeprovider.($keyforprovider ? '-'.$keyforprovider : '').'_TENANT').'">';
|
||||||
|
print '</td>';
|
||||||
|
print '<td></td>';
|
||||||
|
print '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Move this into token generation ?
|
// TODO Move this into token generation ?
|
||||||
if ($supported) {
|
if ($supported) {
|
||||||
if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') {
|
if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') {
|
||||||
@ -386,7 +405,7 @@ if (count($listinsetup) > 0) {
|
|||||||
|
|
||||||
print '</div>';
|
print '</div>';
|
||||||
|
|
||||||
print $form->buttonsSaveCancel("Modify", '');
|
print $form->buttonsSaveCancel("Save", '');
|
||||||
|
|
||||||
print '</form>';
|
print '</form>';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -162,8 +162,10 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
$keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
|
$keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
|
||||||
$keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
|
$keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
|
||||||
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
||||||
|
$keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||||
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
||||||
} else {
|
} else {
|
||||||
|
$keybeforeprovider = $keyforsupportedoauth2array;
|
||||||
$keyforprovider = '';
|
$keyforprovider = '';
|
||||||
}
|
}
|
||||||
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||||
@ -179,13 +181,12 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
$state = $shortscope; // TODO USe a better state
|
$state = $shortscope; // TODO USe a better state
|
||||||
|
|
||||||
// Define $urltorenew, $urltodelete, $urltocheckperms
|
// Define $urltorenew, $urltodelete, $urltocheckperms
|
||||||
// TODO Use array $supportedoauth2array
|
|
||||||
if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
|
if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
|
||||||
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
|
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
|
||||||
// We pass this param list in to 'state' because we need it before and after the redirect.
|
// We pass this param list in to 'state' because we need it before and after the redirect.
|
||||||
|
|
||||||
// Note: github does not accept csrf key inside the state parameter (only known values)
|
// Note: github does not accept csrf key inside the state parameter (only known values)
|
||||||
$urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
$urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||||
$urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
$urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||||
$urltocheckperms = 'https://github.com/settings/applications/';
|
$urltocheckperms = 'https://github.com/settings/applications/';
|
||||||
} elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
|
} elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
|
||||||
@ -195,17 +196,9 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||||
$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||||
$urltocheckperms = 'https://security.google.com/settings/security/permissions';
|
$urltocheckperms = 'https://security.google.com/settings/security/permissions';
|
||||||
} elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') {
|
} elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
|
||||||
$urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
$urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||||
$urltodelete = '';
|
$urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||||
$urltocheckperms = '';
|
|
||||||
} elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') {
|
|
||||||
$urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
|
||||||
$urltodelete = '';
|
|
||||||
$urltocheckperms = '';
|
|
||||||
} elseif ($keyforsupportedoauth2array = 'OAUTH_OTHER_NAME') {
|
|
||||||
$urltorenew = $urlwithroot.'/core/modules/oauth/generic_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
|
||||||
$urltodelete = '';
|
|
||||||
$urltocheckperms = '';
|
$urltocheckperms = '';
|
||||||
} else {
|
} else {
|
||||||
$urltorenew = '';
|
$urltorenew = '';
|
||||||
@ -220,17 +213,22 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
$urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
|
$urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Show value of token
|
// Show value of token
|
||||||
$tokenobj = null;
|
$tokenobj = null;
|
||||||
// Token
|
// Token
|
||||||
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||||
// Dolibarr storage
|
// Dolibarr storage
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
try {
|
try {
|
||||||
|
// $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
|
||||||
|
print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||||
|
//print $storage->token.'<br>';
|
||||||
|
//print $tokenobj->getExtraParams()['id_token'].'<br>';
|
||||||
|
//print $tokenobj->getAccessToken().'<br>';
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// Return an error if token not found
|
// Return an error if token not found
|
||||||
|
//print $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set other properties
|
// Set other properties
|
||||||
@ -321,7 +319,11 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
// Links to delete/checks token
|
// Links to delete/checks token
|
||||||
if (is_object($tokenobj)) {
|
if (is_object($tokenobj)) {
|
||||||
//test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
|
//test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
|
||||||
print '<a class="button smallpaddingimp" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
|
if ($urltodelete) {
|
||||||
|
print '<a class="button smallpaddingimp" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
|
||||||
|
} else {
|
||||||
|
print '<span class="opacitymedium">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span><br>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Request remote token
|
// Request remote token
|
||||||
if ($urltorenew) {
|
if ($urltorenew) {
|
||||||
@ -343,7 +345,6 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
print '<td colspan="2">';
|
print '<td colspan="2">';
|
||||||
|
|
||||||
if (is_object($tokenobj)) {
|
if (is_object($tokenobj)) {
|
||||||
//var_dump($tokenobj);
|
|
||||||
$tokentoshow = $tokenobj->getAccessToken();
|
$tokentoshow = $tokenobj->getAccessToken();
|
||||||
print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
|
print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
|
||||||
//print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
|
//print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
|
||||||
|
|||||||
@ -43,10 +43,6 @@ $rowid = GETPOST('rowid', 'alpha');
|
|||||||
|
|
||||||
$id = 1;
|
$id = 1;
|
||||||
|
|
||||||
if (!$user->admin) {
|
|
||||||
accessforbidden();
|
|
||||||
}
|
|
||||||
|
|
||||||
$acts[0] = "activate";
|
$acts[0] = "activate";
|
||||||
$acts[1] = "disable";
|
$acts[1] = "disable";
|
||||||
$actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
|
$actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
|
||||||
@ -125,6 +121,10 @@ $tabfieldcheck[1] = array();
|
|||||||
$elementList = array();
|
$elementList = array();
|
||||||
$sourceList = array();
|
$sourceList = array();
|
||||||
|
|
||||||
|
if (!$user->admin) {
|
||||||
|
accessforbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Actions
|
* Actions
|
||||||
@ -581,8 +581,8 @@ if ($id) {
|
|||||||
fieldListWebsites($fieldlist, $obj, $tabname[$id], 'edit');
|
fieldListWebsites($fieldlist, $obj, $tabname[$id], 'edit');
|
||||||
}
|
}
|
||||||
|
|
||||||
print '<td colspan="3" class="right"><a name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"> </a><input type="submit" class="button button-edit" name="actionmodify" value="'.$langs->trans("Modify").'">';
|
print '<td colspan="4" class="right"><a name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"> </a><input type="submit" class="button button-edit small" name="actionmodify" value="'.$langs->trans("Modify").'">';
|
||||||
print ' <input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'"></td>';
|
print ' <input type="submit" class="button button-cancel small" name="actioncancel" value="'.$langs->trans("Cancel").'"></td>';
|
||||||
} else {
|
} else {
|
||||||
$tmpaction = 'view';
|
$tmpaction = 'view';
|
||||||
$parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]);
|
$parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]);
|
||||||
|
|||||||
@ -922,6 +922,10 @@ while ($currentdaytoshow < $lastdaytoshow) {
|
|||||||
if ($usergroup > 0) {
|
if ($usergroup > 0) {
|
||||||
$sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
|
$sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
|
||||||
}
|
}
|
||||||
|
if ($user->socid > 0) {
|
||||||
|
// External users should see only contacts of their company
|
||||||
|
$sql .= " AND u.fk_soc = ".((int) $user->socid);
|
||||||
|
}
|
||||||
|
|
||||||
//print $sql;
|
//print $sql;
|
||||||
$resql = $db->query($sql);
|
$resql = $db->query($sql);
|
||||||
|
|||||||
@ -61,25 +61,17 @@ if (isset($user->socid) && $user->socid > 0) {
|
|||||||
$socid = $user->socid;
|
$socid = $user->socid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
|
$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
|
||||||
|
$maxofloop = (empty($conf->global->MAIN_MAXLIST_OVERLOAD) ? 500 : $conf->global->MAIN_MAXLIST_OVERLOAD);
|
||||||
$now = dol_now();
|
$now = dol_now();
|
||||||
|
|
||||||
// Security check
|
//restrictedArea($user, 'societe', $socid, '&societe', '', 'fk_soc', 'rowid', 0);
|
||||||
$socid = GETPOST("socid", 'int');
|
|
||||||
if ($user->socid > 0) {
|
|
||||||
$action = '';
|
|
||||||
$id = $user->socid;
|
|
||||||
} else {
|
|
||||||
$id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//restrictedArea($user, 'societe', $id, '&societe', '', 'fk_soc', 'rowid', 0);
|
|
||||||
if (!$user->hasRight('propal', 'read') && !$user->hasRight('supplier_proposal', 'read') && !$user->hasRight('commande', 'read') && !$user->hasRight('fournisseur', 'commande', 'read')
|
if (!$user->hasRight('propal', 'read') && !$user->hasRight('supplier_proposal', 'read') && !$user->hasRight('commande', 'read') && !$user->hasRight('fournisseur', 'commande', 'read')
|
||||||
&& !$user->hasRight('supplier_order', 'read') && !$user->hasRight('fichinter', 'read')) {
|
&& !$user->hasRight('supplier_order', 'read') && !$user->hasRight('fichinter', 'read')) {
|
||||||
accessforbidden();
|
accessforbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
$maxofloop = (empty($conf->global->MAIN_MAXLIST_OVERLOAD) ? 500 : $conf->global->MAIN_MAXLIST_OVERLOAD);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
|
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
|
||||||
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
|
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
|
||||||
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
||||||
|
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -1843,25 +1844,25 @@ if ($action == 'create' && $usercancreate) {
|
|||||||
// Delivery delay
|
// Delivery delay
|
||||||
print '<tr class="fielddeliverydelay"><td>'.$langs->trans('AvailabilityPeriod').'</td><td>';
|
print '<tr class="fielddeliverydelay"><td>'.$langs->trans('AvailabilityPeriod').'</td><td>';
|
||||||
print img_picto('', 'clock', 'class="pictofixedwidth"');
|
print img_picto('', 'clock', 'class="pictofixedwidth"');
|
||||||
$form->selectAvailabilityDelay($availability_id, 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
|
$form->selectAvailabilityDelay((GETPOSTISSET('availability_id')?GETPOST('availability_id'):$availability_id), 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Terms of payment
|
// Terms of payment
|
||||||
print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
|
print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
|
||||||
print img_picto('', 'payment', 'class="pictofixedwidth"');
|
print img_picto('', 'payment', 'class="pictofixedwidth"');
|
||||||
print $form->getSelectConditionsPaiements($cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
|
print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id')?GETPOST('cond_reglement_id'):$cond_reglement_id), 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Payment mode
|
// Payment mode
|
||||||
print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
|
print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
|
||||||
print img_picto('', 'bank', 'class="pictofixedwidth"');
|
print img_picto('', 'bank', 'class="pictofixedwidth"');
|
||||||
print $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
|
print $form->select_types_paiements((GETPOSTISSET('mode_reglement_id')?GETPOST('mode_reglement_id'):$mode_reglement_id), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Bank Account
|
// Bank Account
|
||||||
if (!empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER) && isModEnabled("banque")) {
|
if (!empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER) && isModEnabled("banque")) {
|
||||||
print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
|
print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
|
||||||
print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
|
print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes((GETPOSTISSET('fk_account')?GETPOST('fk_account'):$fk_account), 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1869,7 +1870,7 @@ if ($action == 'create' && $usercancreate) {
|
|||||||
if (isModEnabled('expedition')) {
|
if (isModEnabled('expedition')) {
|
||||||
print '<tr><td>'.$langs->trans('SendingMethod').'</td><td>';
|
print '<tr><td>'.$langs->trans('SendingMethod').'</td><td>';
|
||||||
print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
|
print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
|
||||||
$form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
|
$form->selectShippingMethod((GETPOSTISSET('shipping_method_id')?GETPOST('shipping_method_id'):$shipping_method_id), 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1878,14 +1879,14 @@ if ($action == 'create' && $usercancreate) {
|
|||||||
require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
|
require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
|
||||||
$formproduct = new FormProduct($db);
|
$formproduct = new FormProduct($db);
|
||||||
print '<tr><td>'.$langs->trans('Warehouse').'</td><td>';
|
print '<tr><td>'.$langs->trans('Warehouse').'</td><td>';
|
||||||
print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($warehouse_id, 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
|
print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses((GETPOSTISSET('warehouse_id')?GETPOST('warehouse_id'):$warehouse_id), 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source / Channel - What trigger creation
|
// Source / Channel - What trigger creation
|
||||||
print '<tr><td>'.$langs->trans('Channel').'</td><td>';
|
print '<tr><td>'.$langs->trans('Channel').'</td><td>';
|
||||||
print img_picto('', 'question', 'class="pictofixedwidth"');
|
print img_picto('', 'question', 'class="pictofixedwidth"');
|
||||||
$form->selectInputReason($demand_reason_id, 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
|
$form->selectInputReason((GETPOSTISSET('demand_reason_id')?GETPOST('demand_reason_id'):$demand_reason_id), 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// TODO How record was recorded OrderMode (llx_c_input_method)
|
// TODO How record was recorded OrderMode (llx_c_input_method)
|
||||||
@ -1895,7 +1896,7 @@ if ($action == 'create' && $usercancreate) {
|
|||||||
$langs->load("projects");
|
$langs->load("projects");
|
||||||
print '<tr>';
|
print '<tr>';
|
||||||
print '<td>'.$langs->trans("Project").'</td><td>';
|
print '<td>'.$langs->trans("Project").'</td><td>';
|
||||||
print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
|
print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), (GETPOSTISSET('projectid')?GETPOST('projectid'):$projectid), 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
|
||||||
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
|
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
|
||||||
print '</td>';
|
print '</td>';
|
||||||
print '</tr>';
|
print '</tr>';
|
||||||
@ -1954,7 +1955,7 @@ if ($action == 'create' && $usercancreate) {
|
|||||||
print '<tr>';
|
print '<tr>';
|
||||||
print '<td>'.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).'</td>';
|
print '<td>'.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).'</td>';
|
||||||
print '<td class="maxwidthonsmartphone">';
|
print '<td class="maxwidthonsmartphone">';
|
||||||
print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency($currency_code, 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx');
|
print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency((GETPOSTISSET('multicurrency_code')?GETPOST('multicurrency_code'):$currency_code), 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -249,9 +249,9 @@ if ($modecompta == 'CREANCES-DETTES') {
|
|||||||
$sql .= " sum(f.total_ht) as amount, sum(f.total_ttc) as amount_ttc";
|
$sql .= " sum(f.total_ht) as amount, sum(f.total_ttc) as amount_ttc";
|
||||||
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s";
|
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s";
|
||||||
if ($selected_cat === -2) { // Without any category
|
if ($selected_cat === -2) { // Without any category
|
||||||
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc";
|
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc";
|
||||||
} elseif ($selected_cat) { // Into a specific category
|
} elseif ($selected_cat) { // Into a specific category
|
||||||
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_societe as cs";
|
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
|
||||||
}
|
}
|
||||||
$sql .= " WHERE f.fk_statut in (1,2)";
|
$sql .= " WHERE f.fk_statut in (1,2)";
|
||||||
$sql .= " AND f.type IN (0,2)";
|
$sql .= " AND f.type IN (0,2)";
|
||||||
@ -276,9 +276,9 @@ if ($modecompta == 'CREANCES-DETTES') {
|
|||||||
$sql .= ", ".MAIN_DB_PREFIX."paiementfourn as p";
|
$sql .= ", ".MAIN_DB_PREFIX."paiementfourn as p";
|
||||||
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
|
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
|
||||||
if ($selected_cat === -2) { // Without any category
|
if ($selected_cat === -2) { // Without any category
|
||||||
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc";
|
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc";
|
||||||
} elseif ($selected_cat) { // Into a specific category
|
} elseif ($selected_cat) { // Into a specific category
|
||||||
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_societe as cs";
|
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
|
||||||
}
|
}
|
||||||
$sql .= " WHERE p.rowid = pf.fk_paiementfourn";
|
$sql .= " WHERE p.rowid = pf.fk_paiementfourn";
|
||||||
$sql .= " AND pf.fk_facturefourn = f.rowid";
|
$sql .= " AND pf.fk_facturefourn = f.rowid";
|
||||||
|
|||||||
@ -302,7 +302,7 @@ $dolibarr_main_restrict_ip='';
|
|||||||
// This might be required if you access Dolibarr behind a proxy that make bad URL rewriting, to avoid false alarms.
|
// This might be required if you access Dolibarr behind a proxy that make bad URL rewriting, to avoid false alarms.
|
||||||
// In most cases, you should always keep this to 0.
|
// In most cases, you should always keep this to 0.
|
||||||
// Default value: 0
|
// Default value: 0
|
||||||
// Possible values: 0 or 1
|
// Possible values: 0 or 1 (no strict CSRF test, only test on referer) or 2 (no CSRF test at all)
|
||||||
// Examples:
|
// Examples:
|
||||||
// $dolibarr_nocsrfcheck='0';
|
// $dolibarr_nocsrfcheck='0';
|
||||||
//
|
//
|
||||||
|
|||||||
@ -908,7 +908,7 @@ class CMailFile
|
|||||||
|
|
||||||
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||||
|
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
try {
|
try {
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||||
$expire = false;
|
$expire = false;
|
||||||
@ -1030,7 +1030,7 @@ class CMailFile
|
|||||||
|
|
||||||
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||||
|
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||||
|
|||||||
@ -82,6 +82,8 @@ class CGenericDic
|
|||||||
$fieldlabel = 'label';
|
$fieldlabel = 'label';
|
||||||
if ($this->table_element == 'c_stcomm') {
|
if ($this->table_element == 'c_stcomm') {
|
||||||
$fieldlabel = 'libelle';
|
$fieldlabel = 'libelle';
|
||||||
|
} elseif ($this->table_element == 'c_type_fees') {
|
||||||
|
$fieldrowid = 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
$error = 0;
|
$error = 0;
|
||||||
@ -162,6 +164,8 @@ class CGenericDic
|
|||||||
if ($this->table_element == 'c_stcomm') {
|
if ($this->table_element == 'c_stcomm') {
|
||||||
$fieldrowid = 'id';
|
$fieldrowid = 'id';
|
||||||
$fieldlabel = 'libelle';
|
$fieldlabel = 'libelle';
|
||||||
|
} elseif ($this->table_element == 'c_type_fees') {
|
||||||
|
$fieldrowid = 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "SELECT";
|
$sql = "SELECT";
|
||||||
@ -233,6 +237,8 @@ class CGenericDic
|
|||||||
if ($this->table_element == 'c_stcomm') {
|
if ($this->table_element == 'c_stcomm') {
|
||||||
$fieldrowid = 'id';
|
$fieldrowid = 'id';
|
||||||
$fieldlabel = 'libelle';
|
$fieldlabel = 'libelle';
|
||||||
|
} elseif ($this->table_element == 'c_type_fees') {
|
||||||
|
$fieldrowid = 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "SELECT";
|
$sql = "SELECT";
|
||||||
@ -303,6 +309,8 @@ class CGenericDic
|
|||||||
if ($this->table_element == 'c_stcomm') {
|
if ($this->table_element == 'c_stcomm') {
|
||||||
$fieldrowid = 'id';
|
$fieldrowid = 'id';
|
||||||
$fieldlabel = 'libelle';
|
$fieldlabel = 'libelle';
|
||||||
|
} elseif ($this->table_element == 'c_type_fees') {
|
||||||
|
$fieldrowid = 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean parameters
|
// Clean parameters
|
||||||
|
|||||||
@ -849,7 +849,7 @@ abstract class CommonObject
|
|||||||
}
|
}
|
||||||
if ($this->element == 'contact') {
|
if ($this->element == 'contact') {
|
||||||
$contactid = $this->id;
|
$contactid = $this->id;
|
||||||
$thirdpartyid = empty($object->fk_soc) ? 0 : $object->fk_soc;
|
$thirdpartyid = empty($this->fk_soc) ? 0 : $this->fk_soc;
|
||||||
}
|
}
|
||||||
if ($this->element == 'user') {
|
if ($this->element == 'user') {
|
||||||
$contactid = $this->contact_id;
|
$contactid = $this->contact_id;
|
||||||
@ -6084,6 +6084,8 @@ abstract class CommonObject
|
|||||||
if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) {
|
if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) {
|
||||||
//var_dump($conf->disable_compute);
|
//var_dump($conf->disable_compute);
|
||||||
if (empty($conf->disable_compute)) {
|
if (empty($conf->disable_compute)) {
|
||||||
|
global $objectoffield; // We set a global variable to $objectoffield so
|
||||||
|
$objectoffield = $this; // we can use it inside computed formula
|
||||||
$this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, '');
|
$this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,12 +99,12 @@ function first_execution() {
|
|||||||
function check_events() {
|
function check_events() {
|
||||||
if (Notification.permission === "granted")
|
if (Notification.permission === "granted")
|
||||||
{
|
{
|
||||||
var newToken = 'notrequired';
|
var currentToken = 'notrequired';
|
||||||
const allMeta = document.getElementsByTagName("meta");
|
const allMeta = document.getElementsByTagName("meta");
|
||||||
for (let i = 0; i < allMeta.length; i++) {
|
for (let i = 0; i < allMeta.length; i++) {
|
||||||
if (allMeta[i].getAttribute("name") == 'anti-csrf-token') {
|
if (allMeta[i].getAttribute("name") == 'anti-csrf-currenttoken') {
|
||||||
newToken = allMeta[i].getAttribute('content');
|
currentToken = allMeta[i].getAttribute('content');
|
||||||
console.log("newToken in page = "+newToken);
|
console.log("currentToken in page = "+currentToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time_js_next_test += time_auto_update;
|
time_js_next_test += time_auto_update;
|
||||||
@ -113,7 +113,7 @@ function check_events() {
|
|||||||
$.ajax("<?php print DOL_URL_ROOT.'/core/ajax/check_notifications.php'; ?>", {
|
$.ajax("<?php print DOL_URL_ROOT.'/core/ajax/check_notifications.php'; ?>", {
|
||||||
type: "post", // Usually post or get
|
type: "post", // Usually post or get
|
||||||
async: true,
|
async: true,
|
||||||
data: { time_js_next_test: time_js_next_test, forcechecknow: 1, token: newToken },
|
data: { time_js_next_test: time_js_next_test, forcechecknow: 1, token: currentToken },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (result) {
|
success: function (result) {
|
||||||
//console.log(result);
|
//console.log(result);
|
||||||
@ -181,7 +181,7 @@ function check_events() {
|
|||||||
$.ajax("<?php print DOL_URL_ROOT.'/core/ajax/check_notifications.php?action=stopreminder&listofreminderids='; ?>"+listofreminderids, {
|
$.ajax("<?php print DOL_URL_ROOT.'/core/ajax/check_notifications.php?action=stopreminder&listofreminderids='; ?>"+listofreminderids, {
|
||||||
type: "POST", // Usually post or get
|
type: "POST", // Usually post or get
|
||||||
async: true,
|
async: true,
|
||||||
data: { time_js_next_test: time_js_next_test, token: newToken }
|
data: { time_js_next_test: time_js_next_test, token: currentToken }
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log("No reminder to do found, next search at "+time_js_next_test);
|
console.log("No reminder to do found, next search at "+time_js_next_test);
|
||||||
|
|||||||
@ -2054,6 +2054,11 @@ function email_admin_prepare_head()
|
|||||||
$head[$h][2] = 'templates';
|
$head[$h][2] = 'templates';
|
||||||
$h++;
|
$h++;
|
||||||
|
|
||||||
|
$head[$h][0] = DOL_URL_ROOT."/admin/mails_ingoing.php";
|
||||||
|
$head[$h][1] = $langs->trans("InGoingEmailSetup", $langs->transnoentitiesnoconv("EMailing"));
|
||||||
|
$head[$h][2] = 'common_ingoing';
|
||||||
|
$h++;
|
||||||
|
|
||||||
complete_head_from_modules($conf, $langs, null, $head, $h, 'email_admin', 'remove');
|
complete_head_from_modules($conf, $langs, null, $head, $h, 'email_admin', 'remove');
|
||||||
|
|
||||||
return $head;
|
return $head;
|
||||||
|
|||||||
@ -1117,7 +1117,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl
|
|||||||
$extrafieldsobjectkey = $contactstatic->table_element;
|
$extrafieldsobjectkey = $contactstatic->table_element;
|
||||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
|
||||||
|
|
||||||
$sql = "SELECT t.rowid, t.entity, t.lastname, t.firstname, t.fk_pays as country_id, t.civility, t.poste, t.phone as phone_pro, t.phone_mobile, t.phone_perso, t.fax, t.email, t.socialnetworks, t.statut, t.photo,";
|
$sql = "SELECT t.rowid, t.entity, t.lastname, t.firstname, t.fk_pays as country_id, t.civility, t.poste, t.phone as phone_pro, t.phone_mobile, t.phone_perso, t.fax, t.email, t.socialnetworks, t.statut, t.photo, t.fk_soc,";
|
||||||
$sql .= " t.civility as civility_id, t.address, t.zip, t.town";
|
$sql .= " t.civility as civility_id, t.address, t.zip, t.town";
|
||||||
$sql .= ", t.note_private";
|
$sql .= ", t.note_private";
|
||||||
$sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t";
|
$sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t";
|
||||||
@ -1272,6 +1272,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl
|
|||||||
$contactstatic->email = $obj->email;
|
$contactstatic->email = $obj->email;
|
||||||
$contactstatic->socialnetworks = $obj->socialnetworks;
|
$contactstatic->socialnetworks = $obj->socialnetworks;
|
||||||
$contactstatic->photo = $obj->photo;
|
$contactstatic->photo = $obj->photo;
|
||||||
|
$contactstatic->fk_soc = $obj->fk_soc;
|
||||||
$contactstatic->entity = $obj->entity;
|
$contactstatic->entity = $obj->entity;
|
||||||
|
|
||||||
$country_code = getCountry($obj->country_id, 2);
|
$country_code = getCountry($obj->country_id, 2);
|
||||||
|
|||||||
@ -4102,7 +4102,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
|
|||||||
'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'proposal', 'puce',
|
'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'proposal', 'puce',
|
||||||
'stock', 'resize', 'service', 'stats', 'trip',
|
'stock', 'resize', 'service', 'stats', 'trip',
|
||||||
'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench',
|
'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench',
|
||||||
'github', 'google', 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp',
|
'github', 'google', 'jabber', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp',
|
||||||
'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies',
|
'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies',
|
||||||
'generic', 'home', 'hrm', 'members', 'products', 'invoicing',
|
'generic', 'home', 'hrm', 'members', 'products', 'invoicing',
|
||||||
'partnership', 'payment', 'payment_vat', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region',
|
'partnership', 'payment', 'payment_vat', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region',
|
||||||
@ -4123,7 +4123,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
|
|||||||
if (in_array($pictowithouttext, array('card', 'bell', 'clock', 'establishment', 'generic', 'minus-square', 'object_generic', 'pdf', 'plus-square', 'timespent', 'note', 'off', 'on', 'object_bookmark', 'bookmark', 'vcard'))) {
|
if (in_array($pictowithouttext, array('card', 'bell', 'clock', 'establishment', 'generic', 'minus-square', 'object_generic', 'pdf', 'plus-square', 'timespent', 'note', 'off', 'on', 'object_bookmark', 'bookmark', 'vcard'))) {
|
||||||
$fa = 'far';
|
$fa = 'far';
|
||||||
}
|
}
|
||||||
if (in_array($pictowithouttext, array('black-tie', 'github', 'google', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) {
|
if (in_array($pictowithouttext, array('black-tie', 'github', 'google', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) {
|
||||||
$fa = 'fab';
|
$fa = 'fab';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8917,10 +8917,12 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
|
|||||||
// Only global variables can be changed by eval function and returned to caller
|
// Only global variables can be changed by eval function and returned to caller
|
||||||
global $db, $langs, $user, $conf, $website, $websitepage;
|
global $db, $langs, $user, $conf, $website, $websitepage;
|
||||||
global $action, $mainmenu, $leftmenu;
|
global $action, $mainmenu, $leftmenu;
|
||||||
|
global $mysoc;
|
||||||
|
global $objectoffield;
|
||||||
|
|
||||||
|
// Old variables used
|
||||||
global $rights;
|
global $rights;
|
||||||
global $object;
|
global $object;
|
||||||
global $mysoc;
|
|
||||||
|
|
||||||
global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object
|
global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object
|
||||||
global $soc; // For backward compatibility
|
global $soc; // For backward compatibility
|
||||||
|
|
||||||
|
|||||||
@ -281,8 +281,8 @@ function getNumberInvoicesPieChart($mode)
|
|||||||
{
|
{
|
||||||
global $conf, $db, $langs, $user;
|
global $conf, $db, $langs, $user;
|
||||||
|
|
||||||
if (($mode == 'customers' && isModEnabled('facture') && !empty($user->rights->facture->lire))
|
if (($mode == 'customers' && isModEnabled('facture') && $user->hasRight('facture', 'lire'))
|
||||||
|| ($mode == 'suppliers' && (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && !empty($user->rights->facture->lire))
|
|| ($mode == 'suppliers' && (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && $user->hasRight('fournisseur', 'facture', 'lire'))
|
||||||
) {
|
) {
|
||||||
include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php';
|
include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php';
|
||||||
|
|
||||||
|
|||||||
@ -25,15 +25,17 @@
|
|||||||
|
|
||||||
// Supported OAUTH (a provider is supported when a file xxx_oauthcallback.php is available into htdocs/core/modules/oauth)
|
// Supported OAUTH (a provider is supported when a file xxx_oauthcallback.php is available into htdocs/core/modules/oauth)
|
||||||
$supportedoauth2array = array(
|
$supportedoauth2array = array(
|
||||||
'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google', 'urlforcredentials'=>'https://console.developers.google.com/', 'availablescopes'=> 'userinfo_email,userinfo_profile,openid,email,profile,cloud_print,admin_directory_user,gmail_full'),
|
'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google', 'urlforcredentials'=>'https://console.developers.google.com/', 'availablescopes'=> 'userinfo_email,userinfo_profile,openid,email,profile,cloud_print,admin_directory_user,gmail_full', 'returnurl'=>'/core/modules/oauth/google_oauthcallback.php'),
|
||||||
);
|
);
|
||||||
if (isModEnabled('stripe')) {
|
if (isModEnabled('stripe')) {
|
||||||
$supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest', 'urlforcredentials'=>'', 'availablescopes'=>'read_write');
|
$supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest', 'urlforcredentials'=>'', 'availablescopes'=>'read_write', 'returnurl'=>'/core/modules/oauth/stripetest_oauthcallback.php');
|
||||||
$supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'availablescopes'=>'read_write');
|
$supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'availablescopes'=>'read_write', 'returnurl'=>'/core/modules/oauth/stripelive_oauthcallback.php');
|
||||||
}
|
}
|
||||||
$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'availablescopes'=>'user,public_repo');
|
$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'availablescopes'=>'user,public_repo', 'returnurl'=>'/core/modules/oauth/github_oauthcallback.php');
|
||||||
|
$supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,User.Read,https://outlook.office365.com/IMAP.AccessAsUser.All,https://outlook.office365.com/SMTP.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php');
|
||||||
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
|
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
|
||||||
$supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard');
|
$supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard', 'returnurl'=>'/core/modules/oauth/generic_oauthcallback.php');
|
||||||
|
// See https://learn.microsoft.com/fr-fr/azure/active-directory/develop/quickstart-register-app#register-an-application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -119,6 +119,7 @@ function dolGetRandomBytes($length)
|
|||||||
function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR")
|
function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR")
|
||||||
{
|
{
|
||||||
global $dolibarr_main_instance_unique_id;
|
global $dolibarr_main_instance_unique_id;
|
||||||
|
global $dolibarr_disable_dolcrypt_for_debug;
|
||||||
|
|
||||||
if ($chain === '' || is_null($chain)) {
|
if ($chain === '' || is_null($chain)) {
|
||||||
return '';
|
return '';
|
||||||
@ -136,7 +137,7 @@ function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR")
|
|||||||
|
|
||||||
$newchain = $chain;
|
$newchain = $chain;
|
||||||
|
|
||||||
if (function_exists('openssl_encrypt')) {
|
if (function_exists('openssl_encrypt') && empty($dolibarr_disable_dolcrypt_for_debug)) {
|
||||||
$ivlen = 16;
|
$ivlen = 16;
|
||||||
if (function_exists('openssl_cipher_iv_length')) {
|
if (function_exists('openssl_cipher_iv_length')) {
|
||||||
$ivlen = openssl_cipher_iv_length($ciphering);
|
$ivlen = openssl_cipher_iv_length($ciphering);
|
||||||
|
|||||||
@ -336,15 +336,19 @@ class doc_generic_invoice_odt extends ModelePDFFactures
|
|||||||
$object->fetchObjectLinked('', '', '', '');
|
$object->fetchObjectLinked('', '', '', '');
|
||||||
//print_r($object->linkedObjects['propal']); exit;
|
//print_r($object->linkedObjects['propal']); exit;
|
||||||
|
|
||||||
$propal_object = $object->linkedObjects['propal'][0];
|
if (isset($object->linkedObjects['propal'][0])) {
|
||||||
|
$propal_object = $object->linkedObjects['propal'][0];
|
||||||
|
} else {
|
||||||
|
$propal_object = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Make substitution
|
// Make substitution
|
||||||
$substitutionarray = array(
|
$substitutionarray = array(
|
||||||
'__FROM_NAME__' => $this->emetteur->name,
|
'__FROM_NAME__' => $this->emetteur->name,
|
||||||
'__FROM_EMAIL__' => $this->emetteur->email,
|
'__FROM_EMAIL__' => $this->emetteur->email,
|
||||||
'__TOTAL_TTC__' => $object->total_ttc,
|
'__TOTAL_TTC__' => $object->total_ttc,
|
||||||
'__TOTAL_HT__' => $object->total_ht,
|
'__TOTAL_HT__' => $object->total_ht,
|
||||||
'__TOTAL_VAT__' => $object->total_tva
|
'__TOTAL_VAT__' => $object->total_tva
|
||||||
);
|
);
|
||||||
complete_substitutions_array($substitutionarray, $langs, $object);
|
complete_substitutions_array($substitutionarray, $langs, $object);
|
||||||
// Call the ODTSubstitution hook
|
// Call the ODTSubstitution hook
|
||||||
@ -435,8 +439,8 @@ class doc_generic_invoice_odt extends ModelePDFFactures
|
|||||||
} else {
|
} else {
|
||||||
$odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
|
$odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
|
||||||
}
|
}
|
||||||
} else // Text
|
} else {
|
||||||
{
|
// Text
|
||||||
$odfHandler->setVars($key, $value, true, 'UTF-8');
|
$odfHandler->setVars($key, $value, true, 'UTF-8');
|
||||||
}
|
}
|
||||||
} catch (OdfException $e) {
|
} catch (OdfException $e) {
|
||||||
|
|||||||
@ -51,7 +51,7 @@ class modOauth extends DolibarrModules
|
|||||||
// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
|
// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
|
||||||
$this->name = preg_replace('/^mod/i', '', get_class($this));
|
$this->name = preg_replace('/^mod/i', '', get_class($this));
|
||||||
// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
|
// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
|
||||||
$this->description = "Enable OAuth authentication";
|
$this->description = "Enable OAuth2 authentication";
|
||||||
// Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version
|
// Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version
|
||||||
$this->version = 'dolibarr';
|
$this->version = 'dolibarr';
|
||||||
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
||||||
|
|||||||
@ -66,7 +66,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient();
|
|||||||
$serviceFactory->setHttpClient($httpClient);
|
$serviceFactory->setHttpClient($httpClient);
|
||||||
|
|
||||||
// Dolibarr storage
|
// Dolibarr storage
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
$keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
||||||
@ -77,9 +77,11 @@ $credentials = new Credentials(
|
|||||||
$currentUri->getAbsoluteUri()
|
$currentUri->getAbsoluteUri()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$state = GETPOST('state');
|
||||||
|
|
||||||
$requestedpermissionsarray = array();
|
$requestedpermissionsarray = array();
|
||||||
if (GETPOST('state')) {
|
if ($state) {
|
||||||
$requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back
|
$requestedpermissionsarray = explode(',', $state); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back
|
||||||
}
|
}
|
||||||
if ($action != 'delete' && empty($requestedpermissionsarray)) {
|
if ($action != 'delete' && empty($requestedpermissionsarray)) {
|
||||||
print 'Error, parameter state is not defined';
|
print 'Error, parameter state is not defined';
|
||||||
@ -88,7 +90,8 @@ if ($action != 'delete' && empty($requestedpermissionsarray)) {
|
|||||||
//var_dump($requestedpermissionsarray);exit;
|
//var_dump($requestedpermissionsarray);exit;
|
||||||
|
|
||||||
// Instantiate the Api service using the credentials, http client and storage mechanism for the token
|
// Instantiate the Api service using the credentials, http client and storage mechanism for the token
|
||||||
$apiService = $serviceFactory->createService($genericstring, $credentials, $storage, $requestedpermissionsarray);
|
// ucfirst(strtolower($genericstring)) must be the name of a class into OAuth/OAuth2/Services/Xxxx
|
||||||
|
$apiService = $serviceFactory->createService(ucfirst(strtolower($genericstring)), $credentials, $storage, $requestedpermissionsarray);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : ''));
|
var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : ''));
|
||||||
@ -128,35 +131,25 @@ if ($action == 'delete') {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GETPOST('code')) { // We are coming from oauth provider page
|
if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provider page
|
||||||
// We should have
|
// We should have
|
||||||
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
||||||
|
|
||||||
dol_syslog("We are coming from the oauth provider page");
|
dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)." error=".GETPOST('error'));
|
||||||
//llxHeader('',$langs->trans("OAuthSetup"));
|
|
||||||
|
|
||||||
//$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
|
|
||||||
//print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
|
|
||||||
|
|
||||||
//print dol_get_fiche_head();
|
|
||||||
// retrieve the CSRF state parameter
|
|
||||||
$state = GETPOSTISSET('state') ? GETPOST('state') : null;
|
|
||||||
//print '<table>';
|
|
||||||
|
|
||||||
// This was a callback request from service, get the token
|
// This was a callback request from service, get the token
|
||||||
try {
|
try {
|
||||||
//var_dump($_GET['code']);
|
|
||||||
//var_dump($state);
|
//var_dump($state);
|
||||||
//var_dump($apiService); // OAuth\OAuth2\Service\GitHub
|
//var_dump($apiService); // OAuth\OAuth2\Service\Xxx
|
||||||
|
|
||||||
//$token = $apiService->requestAccessToken(GETPOST('code'), $state);
|
if (GETPOST('error')) {
|
||||||
$token = $apiService->requestAccessToken(GETPOST('code'));
|
setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors');
|
||||||
// Github is a service that does not need state to be stored.
|
} else {
|
||||||
// Into constructor of GitHub, the call
|
//$token = $apiService->requestAccessToken(GETPOST('code'), $state);
|
||||||
// parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri)
|
$token = $apiService->requestAccessToken(GETPOST('code'));
|
||||||
// has not the ending parameter to true like the Google class constructor.
|
|
||||||
|
|
||||||
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
||||||
|
}
|
||||||
|
|
||||||
$backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
|
$backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
|
||||||
unset($_SESSION["backtourlsavedbeforeoauthjump"]);
|
unset($_SESSION["backtourlsavedbeforeoauthjump"]);
|
||||||
@ -166,15 +159,17 @@ if (GETPOST('code')) { // We are coming from oauth provider page
|
|||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
print $e->getMessage();
|
print $e->getMessage();
|
||||||
}
|
}
|
||||||
} else { // If entry on page with no parameter, we arrive here
|
} else {
|
||||||
|
// If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect
|
||||||
|
// to the OAuth provider login page.
|
||||||
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
|
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
|
||||||
$_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
|
$_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
|
||||||
$_SESSION['oauthstateanticsrf'] = $state;
|
$_SESSION['oauthstateanticsrf'] = $state;
|
||||||
|
|
||||||
// This may create record into oauth_state before the header redirect.
|
// This may create record into oauth_state before the header redirect.
|
||||||
// Creation of record with state in this tables depend on the Provider used (see its constructor).
|
// Creation of record with state in this tables depend on the Provider used (see its constructor).
|
||||||
if (GETPOST('state')) {
|
if ($state) {
|
||||||
$url = $apiService->getAuthorizationUri(array('state' => GETPOST('state')));
|
$url = $apiService->getAuthorizationUri(array('state' => $state));
|
||||||
} else {
|
} else {
|
||||||
$url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
|
$url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,7 +65,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient();
|
|||||||
$serviceFactory->setHttpClient($httpClient);
|
$serviceFactory->setHttpClient($httpClient);
|
||||||
|
|
||||||
// Dolibarr storage
|
// Dolibarr storage
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$keyforparamid = 'OAUTH_GITHUB'.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
$keyforparamid = 'OAUTH_GITHUB'.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
||||||
@ -115,30 +115,21 @@ if ($action == 'delete') {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_GET['code'])) { // We are coming from oauth provider page
|
if (GETPOST('code')) { // We are coming from oauth provider page
|
||||||
// We should have
|
// We should have
|
||||||
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
||||||
|
|
||||||
dol_syslog("We are coming from the oauth provider page");
|
dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5));
|
||||||
//llxHeader('',$langs->trans("OAuthSetup"));
|
|
||||||
|
|
||||||
//$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
|
|
||||||
//print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
|
|
||||||
|
|
||||||
//print dol_get_fiche_head();
|
|
||||||
// retrieve the CSRF state parameter
|
|
||||||
$state = isset($_GET['state']) ? $_GET['state'] : null;
|
|
||||||
//print '<table>';
|
|
||||||
|
|
||||||
// This was a callback request from service, get the token
|
// This was a callback request from service, get the token
|
||||||
try {
|
try {
|
||||||
//var_dump($_GET['code']);
|
|
||||||
//var_dump($state);
|
//var_dump($state);
|
||||||
//var_dump($apiService); // OAuth\OAuth2\Service\GitHub
|
//var_dump($apiService); // OAuth\OAuth2\Service\GitHub
|
||||||
|
|
||||||
//$token = $apiService->requestAccessToken($_GET['code'], $state);
|
//$token = $apiService->requestAccessToken(GETPOST('code'), $state);
|
||||||
$token = $apiService->requestAccessToken($_GET['code']);
|
$token = $apiService->requestAccessToken(GETPOST('code'));
|
||||||
// Github is a service that does not need state to be stored.
|
// Github is a service that does not need state to be stored as second paramater of requestAccessToken
|
||||||
|
|
||||||
// Into constructor of GitHub, the call
|
// Into constructor of GitHub, the call
|
||||||
// parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri)
|
// parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri)
|
||||||
// has not the ending parameter to true like the Google class constructor.
|
// has not the ending parameter to true like the Google class constructor.
|
||||||
|
|||||||
@ -137,7 +137,7 @@ if ($action == 'delete') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GETPOST('code')) { // We are coming from oauth provider page.
|
if (GETPOST('code')) { // We are coming from oauth provider page.
|
||||||
dol_syslog("We are coming from the oauth provider page keyforprovider=".$keyforprovider);
|
dol_syslog("We are coming from the oauth provider page keyforprovider=".$keyforprovider." code=".dol_trunc(GETPOST('code'), 5));
|
||||||
|
|
||||||
// We must validate that the $state is the same than the one into $_SESSION['oauthstateanticsrf'], return error if not.
|
// We must validate that the $state is the same than the one into $_SESSION['oauthstateanticsrf'], return error if not.
|
||||||
if (isset($_SESSION['oauthstateanticsrf']) && $state != $_SESSION['oauthstateanticsrf']) {
|
if (isset($_SESSION['oauthstateanticsrf']) && $state != $_SESSION['oauthstateanticsrf']) {
|
||||||
@ -146,7 +146,6 @@ if (GETPOST('code')) { // We are coming from oauth provider page.
|
|||||||
} else {
|
} else {
|
||||||
// This was a callback request from service, get the token
|
// This was a callback request from service, get the token
|
||||||
try {
|
try {
|
||||||
//var_dump($_GET['code']);
|
|
||||||
//var_dump($state);
|
//var_dump($state);
|
||||||
//var_dump($apiService); // OAuth\OAuth2\Service\Google
|
//var_dump($apiService); // OAuth\OAuth2\Service\Google
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ if (GETPOST('code')) { // We are coming from oauth provider page.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we enter this page without 'code' parameter, we arrive here. this is the case when we want to get the redirect
|
// If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect
|
||||||
// to the OAuth provider login page.
|
// to the OAuth provider login page.
|
||||||
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
|
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
|
||||||
$_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
|
$_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
|
||||||
@ -218,6 +217,8 @@ if (GETPOST('code')) { // We are coming from oauth provider page.
|
|||||||
//$url .= 'hd=xxx';
|
//$url .= 'hd=xxx';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//var_dump($url);exit;
|
||||||
|
|
||||||
// we go on oauth provider authorization page
|
// we go on oauth provider authorization page
|
||||||
header('Location: '.$url);
|
header('Location: '.$url);
|
||||||
exit();
|
exit();
|
||||||
|
|||||||
214
htdocs/core/modules/oauth/microsoft_oauthcallback.php
Normal file
214
htdocs/core/modules/oauth/microsoft_oauthcallback.php
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
<?php
|
||||||
|
/* Copyright (C) 2022 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||||
|
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file htdocs/core/modules/oauth/microsoft_oauthcallback.php
|
||||||
|
* \ingroup oauth
|
||||||
|
* \brief Page to get oauth callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Load Dolibarr environment
|
||||||
|
require '../../../main.inc.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||||
|
use OAuth\Common\Storage\DoliStorage;
|
||||||
|
use OAuth\Common\Consumer\Credentials;
|
||||||
|
use OAuth\OAuth2\Service\GitHub;
|
||||||
|
|
||||||
|
// Define $urlwithroot
|
||||||
|
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
|
||||||
|
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
|
||||||
|
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
|
||||||
|
|
||||||
|
|
||||||
|
$action = GETPOST('action', 'aZ09');
|
||||||
|
$backtourl = GETPOST('backtourl', 'alpha');
|
||||||
|
$keyforprovider = GETPOST('keyforprovider', 'aZ09');
|
||||||
|
if (empty($keyforprovider) && !empty($_SESSION["oauthkeyforproviderbeforeoauthjump"]) && (GETPOST('code') || $action == 'delete')) {
|
||||||
|
$keyforprovider = $_SESSION["oauthkeyforproviderbeforeoauthjump"];
|
||||||
|
}
|
||||||
|
$genericstring = 'MICROSOFT';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of the URI class with the current URI, stripping the query string
|
||||||
|
*/
|
||||||
|
$uriFactory = new \OAuth\Common\Http\Uri\UriFactory();
|
||||||
|
//$currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
|
||||||
|
//$currentUri->setQuery('');
|
||||||
|
$currentUri = $uriFactory->createFromAbsolute($urlwithroot.'/core/modules/oauth/microsoft_oauthcallback.php');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the credential for the service
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @var $serviceFactory \OAuth\ServiceFactory An OAuth service factory. */
|
||||||
|
$serviceFactory = new \OAuth\ServiceFactory();
|
||||||
|
$httpClient = new \OAuth\Common\Http\Client\CurlClient();
|
||||||
|
// TODO Set options for proxy and timeout
|
||||||
|
// $params=array('CURLXXX'=>value, ...)
|
||||||
|
//$httpClient->setCurlParameters($params);
|
||||||
|
$serviceFactory->setHttpClient($httpClient);
|
||||||
|
|
||||||
|
// Dolibarr storage
|
||||||
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
|
// Setup the credentials for the requests
|
||||||
|
$keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
||||||
|
$keyforparamsecret = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_SECRET';
|
||||||
|
$keyforparamtenant = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_TENANT';
|
||||||
|
$credentials = new Credentials(
|
||||||
|
getDolGlobalString($keyforparamid),
|
||||||
|
getDolGlobalString($keyforparamsecret),
|
||||||
|
$currentUri->getAbsoluteUri()
|
||||||
|
);
|
||||||
|
|
||||||
|
$state = GETPOST('state');
|
||||||
|
|
||||||
|
$requestedpermissionsarray = array();
|
||||||
|
if ($state) {
|
||||||
|
$requestedpermissionsarray = explode(',', $state); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back
|
||||||
|
}
|
||||||
|
if ($action != 'delete' && empty($requestedpermissionsarray)) {
|
||||||
|
print 'Error, parameter state is not defined';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
//var_dump($requestedpermissionsarray);exit;
|
||||||
|
|
||||||
|
// Instantiate the Api service using the credentials, http client and storage mechanism for the token
|
||||||
|
// ucfirst(strtolower($genericstring)) must be the name of a class into OAuth/OAuth2/Services/Xxxx
|
||||||
|
// $requestedpermissionsarray contains list of scopes.
|
||||||
|
// Conversion into URL is done by Reflection on constant with name SCOPE_scope_in_uppercase
|
||||||
|
try {
|
||||||
|
$apiService = $serviceFactory->createService(ucfirst(strtolower($genericstring)), $credentials, $storage, $requestedpermissionsarray);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
print $e->getMessage();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : ''));
|
||||||
|
var_dump($credentials);
|
||||||
|
var_dump($storage);
|
||||||
|
var_dump($requestedpermissionsarray);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (empty($apiService)) {
|
||||||
|
print 'Error, failed to create serviceFactory';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// access type needed to have oauth provider refreshing token
|
||||||
|
//$apiService->setAccessType('offline');
|
||||||
|
|
||||||
|
$langs->load("oauth");
|
||||||
|
|
||||||
|
if (!getDolGlobalString($keyforparamid)) {
|
||||||
|
accessforbidden('Setup of service is not complete. Customer ID is missing');
|
||||||
|
}
|
||||||
|
if (!getDolGlobalString($keyforparamsecret)) {
|
||||||
|
accessforbidden('Setup of service is not complete. Secret key is missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($action == 'delete') {
|
||||||
|
$storage->clearToken($genericstring);
|
||||||
|
|
||||||
|
setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs');
|
||||||
|
|
||||||
|
header('Location: '.$backtourl);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//dol_syslog("GET=".join(',', $_GET));
|
||||||
|
|
||||||
|
|
||||||
|
if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provider page
|
||||||
|
// We should have
|
||||||
|
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
||||||
|
|
||||||
|
dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)." error=".GETPOST('error'));
|
||||||
|
|
||||||
|
// This was a callback request from service, get the token
|
||||||
|
try {
|
||||||
|
//var_dump($state);
|
||||||
|
//var_dump($apiService); // OAuth\OAuth2\Service\Microsoft
|
||||||
|
|
||||||
|
if (GETPOST('error')) {
|
||||||
|
setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors');
|
||||||
|
} else {
|
||||||
|
//print GETPOST('code');exit;
|
||||||
|
|
||||||
|
//$token = $apiService->requestAccessToken(GETPOST('code'), $state);
|
||||||
|
$token = $apiService->requestAccessToken(GETPOST('code'));
|
||||||
|
// Microsoft is a service that does not need state to be stored as second paramater of requestAccessToken
|
||||||
|
|
||||||
|
//print $token->getAccessToken().'<br><br>';
|
||||||
|
//print $token->getExtraParams()['id_token'].'<br>';
|
||||||
|
//print $token->getRefreshToken().'<br>';exit;
|
||||||
|
|
||||||
|
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
||||||
|
}
|
||||||
|
|
||||||
|
$backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
|
||||||
|
unset($_SESSION["backtourlsavedbeforeoauthjump"]);
|
||||||
|
|
||||||
|
header('Location: '.$backtourl);
|
||||||
|
exit();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
print $e->getMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect
|
||||||
|
// to the OAuth provider login page.
|
||||||
|
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
|
||||||
|
$_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
|
||||||
|
$_SESSION['oauthstateanticsrf'] = $state;
|
||||||
|
|
||||||
|
//if (!preg_match('/^forlogin/', $state)) {
|
||||||
|
// $apiService->setApprouvalPrompt('auto');
|
||||||
|
//}
|
||||||
|
|
||||||
|
// This may create record into oauth_state before the header redirect.
|
||||||
|
// Creation of record with state in this tables depend on the Provider used (see its constructor).
|
||||||
|
if ($state) {
|
||||||
|
$url = $apiService->getAuthorizationUri(array('state' => $state));
|
||||||
|
} else {
|
||||||
|
$url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show url to get authorization
|
||||||
|
//var_dump((string) $url);exit;
|
||||||
|
dol_syslog("Redirect to url=".$url);
|
||||||
|
|
||||||
|
// we go on oauth provider authorization page
|
||||||
|
header('Location: '.$url);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* View
|
||||||
|
*/
|
||||||
|
|
||||||
|
// No view at all, just actions
|
||||||
|
|
||||||
|
$db->close();
|
||||||
@ -65,7 +65,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient();
|
|||||||
$serviceFactory->setHttpClient($httpClient);
|
$serviceFactory->setHttpClient($httpClient);
|
||||||
|
|
||||||
// Dolibarr storage
|
// Dolibarr storage
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$keyforparamid = 'OAUTH_STRIPE_LIVE'.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
$keyforparamid = 'OAUTH_STRIPE_LIVE'.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
||||||
@ -121,33 +121,20 @@ if ($action == 'delete') {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_GET['code'])) { // We are coming from oauth provider page
|
if (GETPOST('code')) { // We are coming from oauth provider page
|
||||||
// We should have
|
// We should have
|
||||||
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
||||||
|
|
||||||
dol_syslog("We are coming from the oauth provider page");
|
dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5));
|
||||||
//llxHeader('',$langs->trans("OAuthSetup"));
|
|
||||||
|
|
||||||
//$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
|
|
||||||
//print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
|
|
||||||
|
|
||||||
//print dol_get_fiche_head();
|
|
||||||
// retrieve the CSRF state parameter
|
|
||||||
$state = isset($_GET['state']) ? $_GET['state'] : null;
|
|
||||||
//print '<table>';
|
|
||||||
|
|
||||||
// This was a callback request from service, get the token
|
// This was a callback request from service, get the token
|
||||||
try {
|
try {
|
||||||
//var_dump($_GET['code']);
|
|
||||||
//var_dump($state);
|
//var_dump($state);
|
||||||
//var_dump($apiService); // OAuth\OAuth2\Service\GitHub
|
//var_dump($apiService); // OAuth\OAuth2\Service\Stripe
|
||||||
|
|
||||||
//$token = $apiService->requestAccessToken($_GET['code'], $state);
|
//$token = $apiService->requestAccessToken(GETPOST('code'), $state);
|
||||||
$token = $apiService->requestAccessToken($_GET['code']);
|
$token = $apiService->requestAccessToken(GETPOST('code'));
|
||||||
// Github is a service that does not need state to be stored.
|
// Stripe is a service that does not need state to be stored as second paramater of requestAccessToken
|
||||||
// Into constructor of GitHub, the call
|
|
||||||
// parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri)
|
|
||||||
// has not the ending parameter to true like the Google class constructor.
|
|
||||||
|
|
||||||
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
||||||
|
|
||||||
|
|||||||
@ -65,7 +65,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient();
|
|||||||
$serviceFactory->setHttpClient($httpClient);
|
$serviceFactory->setHttpClient($httpClient);
|
||||||
|
|
||||||
// Dolibarr storage
|
// Dolibarr storage
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$keyforparamid = 'OAUTH_STRIPE_TEST'.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
$keyforparamid = 'OAUTH_STRIPE_TEST'.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
|
||||||
@ -121,33 +121,20 @@ if ($action == 'delete') {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_GET['code'])) { // We are coming from oauth provider page
|
if (GETPOST('code')) { // We are coming from oauth provider page
|
||||||
// We should have
|
// We should have
|
||||||
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
|
||||||
|
|
||||||
dol_syslog("We are coming from the oauth provider page");
|
dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5));
|
||||||
//llxHeader('',$langs->trans("OAuthSetup"));
|
|
||||||
|
|
||||||
//$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
|
|
||||||
//print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
|
|
||||||
|
|
||||||
//print dol_get_fiche_head();
|
|
||||||
// retrieve the CSRF state parameter
|
|
||||||
$state = isset($_GET['state']) ? $_GET['state'] : null;
|
|
||||||
//print '<table>';
|
|
||||||
|
|
||||||
// This was a callback request from service, get the token
|
// This was a callback request from service, get the token
|
||||||
try {
|
try {
|
||||||
//var_dump($_GET['code']);
|
|
||||||
//var_dump($state);
|
//var_dump($state);
|
||||||
//var_dump($apiService); // OAuth\OAuth2\Service\GitHub
|
//var_dump($apiService); // OAuth\OAuth2\Service\Stripe
|
||||||
|
|
||||||
//$token = $apiService->requestAccessToken($_GET['code'], $state);
|
//$token = $apiService->requestAccessToken(GETPOST('code'), $state);
|
||||||
$token = $apiService->requestAccessToken($_GET['code']);
|
$token = $apiService->requestAccessToken(GETPOST('code'));
|
||||||
// Github is a service that does not need state to be stored.
|
// Stripe is a service that does not need state to be stored as second paramater of requestAccessToken
|
||||||
// Into constructor of GitHub, the call
|
|
||||||
// parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri)
|
|
||||||
// has not the ending parameter to true like the Google class constructor.
|
|
||||||
|
|
||||||
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
|
||||||
|
|
||||||
|
|||||||
@ -116,10 +116,12 @@ class printing_printgcp extends PrintingDriver
|
|||||||
'type'=>'info',
|
'type'=>'info',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
$keyforprovider = ''; // @FIXME
|
||||||
|
|
||||||
$this->google_id = getDolGlobalString('OAUTH_GOOGLE_ID');
|
$this->google_id = getDolGlobalString('OAUTH_GOOGLE_ID');
|
||||||
$this->google_secret = getDolGlobalString('OAUTH_GOOGLE_SECRET');
|
$this->google_secret = getDolGlobalString('OAUTH_GOOGLE_SECRET');
|
||||||
// Token storage
|
// Token storage
|
||||||
$storage = new DoliStorage($this->db, $this->conf);
|
$storage = new DoliStorage($this->db, $this->conf, $keyforprovider);
|
||||||
//$storage->clearToken($this->OAUTH_SERVICENAME_GOOGLE);
|
//$storage->clearToken($this->OAUTH_SERVICENAME_GOOGLE);
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$credentials = new Credentials(
|
$credentials = new Credentials(
|
||||||
@ -254,8 +256,11 @@ class printing_printgcp extends PrintingDriver
|
|||||||
public function getlistAvailablePrinters()
|
public function getlistAvailablePrinters()
|
||||||
{
|
{
|
||||||
$ret = array();
|
$ret = array();
|
||||||
|
|
||||||
|
$keyforprovider = ''; // @FIXME
|
||||||
|
|
||||||
// Token storage
|
// Token storage
|
||||||
$storage = new DoliStorage($this->db, $this->conf);
|
$storage = new DoliStorage($this->db, $this->conf, $keyforprovider);
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$credentials = new Credentials(
|
$credentials = new Credentials(
|
||||||
$this->google_id,
|
$this->google_id,
|
||||||
@ -392,8 +397,11 @@ class printing_printgcp extends PrintingDriver
|
|||||||
'content' => base64_encode($contents), // encode file content as base64
|
'content' => base64_encode($contents), // encode file content as base64
|
||||||
'contentType' => $contenttype,
|
'contentType' => $contenttype,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$keyforprovider = ''; // @FIXME
|
||||||
|
|
||||||
// Dolibarr Token storage
|
// Dolibarr Token storage
|
||||||
$storage = new DoliStorage($this->db, $this->conf);
|
$storage = new DoliStorage($this->db, $this->conf, $keyforprovider);
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$credentials = new Credentials(
|
$credentials = new Credentials(
|
||||||
$this->google_id,
|
$this->google_id,
|
||||||
@ -441,8 +449,11 @@ class printing_printgcp extends PrintingDriver
|
|||||||
|
|
||||||
$error = 0;
|
$error = 0;
|
||||||
$html = '';
|
$html = '';
|
||||||
|
|
||||||
|
$keyforprovider = ''; // @FIXME
|
||||||
|
|
||||||
// Token storage
|
// Token storage
|
||||||
$storage = new DoliStorage($this->db, $this->conf);
|
$storage = new DoliStorage($this->db, $this->conf, $keyforprovider);
|
||||||
// Setup the credentials for the requests
|
// Setup the credentials for the requests
|
||||||
$credentials = new Credentials(
|
$credentials = new Credentials(
|
||||||
$this->google_id,
|
$this->google_id,
|
||||||
|
|||||||
@ -1082,10 +1082,13 @@ class EmailCollector extends CommonObject
|
|||||||
//$debugtext = "Host: ".$this->host."<br>Port: ".$this->port."<br>Login: ".$this->login."<br>Password: ".$this->password."<br>access type: ".$this->acces_type."<br>oauth service: ".$this->oauth_service."<br>Max email per collect: ".$this->maxemailpercollect;
|
//$debugtext = "Host: ".$this->host."<br>Port: ".$this->port."<br>Login: ".$this->login."<br>Password: ".$this->password."<br>access type: ".$this->acces_type."<br>oauth service: ".$this->oauth_service."<br>Max email per collect: ".$this->maxemailpercollect;
|
||||||
//dol_syslog($debugtext);
|
//dol_syslog($debugtext);
|
||||||
|
|
||||||
$storage = new DoliStorage($db, $conf);
|
$token = '';
|
||||||
|
|
||||||
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||||
|
|
||||||
$expire = true;
|
$expire = true;
|
||||||
// Is token expired or will token expire in the next 30 seconds
|
// Is token expired or will token expire in the next 30 seconds
|
||||||
// if (is_object($tokenobj)) {
|
// if (is_object($tokenobj)) {
|
||||||
@ -1122,7 +1125,6 @@ class EmailCollector extends CommonObject
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$cm = new ClientManager();
|
$cm = new ClientManager();
|
||||||
$client = $cm->make([
|
$client = $cm->make([
|
||||||
'host' => $this->host,
|
'host' => $this->host,
|
||||||
|
|||||||
@ -206,7 +206,7 @@ include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
|
|||||||
// when we post forms (we allow GET and HEAD to accept direct link from a particular page).
|
// when we post forms (we allow GET and HEAD to accept direct link from a particular page).
|
||||||
// Note about $_SERVER[HTTP_HOST/SERVER_NAME]: http://shiflett.org/blog/2006/mar/server-name-versus-http-host
|
// Note about $_SERVER[HTTP_HOST/SERVER_NAME]: http://shiflett.org/blog/2006/mar/server-name-versus-http-host
|
||||||
// See also CSRF protections done into main.inc.php
|
// See also CSRF protections done into main.inc.php
|
||||||
if (!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck)) {
|
if (!defined('NOCSRFCHECK') && isset($dolibarr_nocsrfcheck) && $dolibarr_nocsrfcheck == 1) { // If $dolibarr_nocsrfcheck is 0, there is a strict CSRF test with token in main
|
||||||
if (!empty($_SERVER['REQUEST_METHOD']) && !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) && !empty($_SERVER['HTTP_HOST'])) {
|
if (!empty($_SERVER['REQUEST_METHOD']) && !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) && !empty($_SERVER['HTTP_HOST'])) {
|
||||||
$csrfattack = false;
|
$csrfattack = false;
|
||||||
if (empty($_SERVER['HTTP_REFERER'])) {
|
if (empty($_SERVER['HTTP_REFERER'])) {
|
||||||
|
|||||||
@ -57,6 +57,7 @@ class StreamClient extends AbstractClient
|
|||||||
}
|
}
|
||||||
$extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody);
|
$extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody);
|
||||||
|
|
||||||
|
//var_dump($requestBody); var_dump($extraHeaders);var_dump($method);exit;
|
||||||
$context = $this->generateStreamContext($requestBody, $extraHeaders, $method);
|
$context = $this->generateStreamContext($requestBody, $extraHeaders, $method);
|
||||||
|
|
||||||
$level = error_reporting(0);
|
$level = error_reporting(0);
|
||||||
|
|||||||
@ -57,6 +57,8 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
private $key;
|
private $key;
|
||||||
//private $stateKey;
|
//private $stateKey;
|
||||||
private $keyforprovider;
|
private $keyforprovider;
|
||||||
|
public $token;
|
||||||
|
private $tenant;
|
||||||
|
|
||||||
public $state;
|
public $state;
|
||||||
public $date_creation;
|
public $date_creation;
|
||||||
@ -73,6 +75,7 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
$this->conf = $conf;
|
$this->conf = $conf;
|
||||||
$this->keyforprovider = $keyforprovider;
|
$this->keyforprovider = $keyforprovider;
|
||||||
|
$this->token = '';
|
||||||
$this->tokens = array();
|
$this->tokens = array();
|
||||||
$this->states = array();
|
$this->states = array();
|
||||||
//$this->key = $key;
|
//$this->key = $key;
|
||||||
@ -96,7 +99,7 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function storeAccessToken($service, TokenInterface $token)
|
public function storeAccessToken($service, TokenInterface $tokenobj)
|
||||||
{
|
{
|
||||||
global $conf;
|
global $conf;
|
||||||
|
|
||||||
@ -104,16 +107,25 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
//var_dump($token);
|
//var_dump($token);
|
||||||
dol_syslog("storeAccessToken service=".$service);
|
dol_syslog("storeAccessToken service=".$service);
|
||||||
|
|
||||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
|
$servicepluskeyforprovider = $service;
|
||||||
$serializedToken = dolEncrypt(serialize($token));
|
if (!empty($this->keyforprovider)) {
|
||||||
|
// We clean the keyforprovider after the - to be sure it is not present
|
||||||
|
$servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider);
|
||||||
|
// Now we add the keyforprovider
|
||||||
|
$servicepluskeyforprovider .= '-'.$this->keyforprovider;
|
||||||
|
}
|
||||||
|
|
||||||
$this->tokens[$service] = $token;
|
include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
|
||||||
|
$serializedToken = serialize($tokenobj);
|
||||||
|
|
||||||
if (!is_array($this->tokens)) {
|
if (!is_array($this->tokens)) {
|
||||||
$this->tokens = array();
|
$this->tokens = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->tokens[$service] = $tokenobj;
|
||||||
|
|
||||||
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token";
|
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token";
|
||||||
$sql .= " WHERE service = '".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."'";
|
$sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'";
|
||||||
$sql .= " AND entity IN (".getEntity('oauth_token').")";
|
$sql .= " AND entity IN (".getEntity('oauth_token').")";
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
if (! $resql) {
|
if (! $resql) {
|
||||||
@ -123,16 +135,22 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
if ($obj) {
|
if ($obj) {
|
||||||
// update
|
// update
|
||||||
$sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token";
|
$sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token";
|
||||||
$sql.= " SET token = '".$this->db->escape($serializedToken)."'";
|
$sql.= " SET token = '".$this->db->escape(dolEncrypt($serializedToken))."'";
|
||||||
$sql.= " WHERE rowid = ".((int) $obj['rowid']);
|
$sql.= " WHERE rowid = ".((int) $obj['rowid']);
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
|
if (!$resql) {
|
||||||
|
dol_print_error($this->db);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// save
|
// save
|
||||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity, datec)";
|
$sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity, datec)";
|
||||||
$sql .= " VALUES ('".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."', '".$this->db->escape($serializedToken)."', ".((int) $conf->entity).", ";
|
$sql .= " VALUES ('".$this->db->escape($servicepluskeyforprovider)."', '".$this->db->escape(dolEncrypt($serializedToken))."', ".((int) $conf->entity).", ";
|
||||||
$sql .= " '".$this->db->idate(dol_now())."'";
|
$sql .= " '".$this->db->idate(dol_now())."'";
|
||||||
$sql .= ")";
|
$sql .= ")";
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
|
if (!$resql) {
|
||||||
|
dol_print_error($this->db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//print $sql;
|
//print $sql;
|
||||||
|
|
||||||
@ -141,15 +159,26 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* Load token and other data from a $service
|
||||||
|
* Note: Token load are cumulated into array ->tokens when other properties are erased by last loaded token.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function hasAccessToken($service)
|
public function hasAccessToken($service)
|
||||||
{
|
{
|
||||||
// get from db
|
// get from db
|
||||||
dol_syslog("hasAccessToken service=".$service);
|
dol_syslog("hasAccessToken service=".$service);
|
||||||
|
|
||||||
|
$servicepluskeyforprovider = $service;
|
||||||
|
if (!empty($this->keyforprovider)) {
|
||||||
|
// We clean the keyforprovider after the - to be sure it is not present
|
||||||
|
$servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider);
|
||||||
|
// Now we add the keyforprovider
|
||||||
|
$servicepluskeyforprovider .= '-'.$this->keyforprovider;
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT token, datec, tms, state FROM ".MAIN_DB_PREFIX."oauth_token";
|
$sql = "SELECT token, datec, tms, state FROM ".MAIN_DB_PREFIX."oauth_token";
|
||||||
$sql .= " WHERE service = '".$this->db->escape($service.(empty($this->keyforprovider) ? '' : '-'.$this->keyforprovider))."'";
|
$sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'";
|
||||||
$sql .= " AND entity IN (".getEntity('oauth_token').")";
|
$sql .= " AND entity IN (".getEntity('oauth_token').")";
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
if (! $resql) {
|
if (! $resql) {
|
||||||
@ -158,18 +187,20 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
$result = $this->db->fetch_array($resql);
|
$result = $this->db->fetch_array($resql);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
|
include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
|
||||||
$token = unserialize(dolDecrypt($result['token']));
|
$tokenobj = unserialize(dolDecrypt($result['token']));
|
||||||
|
$this->token = dolDecrypt($result['token']);
|
||||||
$this->date_creation = $this->db->jdate($result['datec']);
|
$this->date_creation = $this->db->jdate($result['datec']);
|
||||||
$this->date_modification = $this->db->jdate($result['tms']);
|
$this->date_modification = $this->db->jdate($result['tms']);
|
||||||
$this->state = $result['state'];
|
$this->state = $result['state'];
|
||||||
} else {
|
} else {
|
||||||
$token = '';
|
$tokenobj = '';
|
||||||
|
$this->token = '';
|
||||||
$this->date_creation = null;
|
$this->date_creation = null;
|
||||||
$this->date_modification = null;
|
$this->date_modification = null;
|
||||||
$this->state = '';
|
$this->state = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->tokens[$service] = $token;
|
$this->tokens[$service] = $tokenobj;
|
||||||
|
|
||||||
return is_array($this->tokens)
|
return is_array($this->tokens)
|
||||||
&& isset($this->tokens[$service])
|
&& isset($this->tokens[$service])
|
||||||
@ -325,4 +356,18 @@ class DoliStorage implements TokenStorageInterface
|
|||||||
// allow chaining
|
// allow chaining
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the token
|
||||||
|
*
|
||||||
|
* @return string String for the tenant used to create the token
|
||||||
|
*/
|
||||||
|
public function getTenant()
|
||||||
|
{
|
||||||
|
// Set/Reset tenant now so it will be defined for.
|
||||||
|
// TODO We must store it into the table llx_oauth_token
|
||||||
|
$this->tenant = getDolGlobalString('OAUTH_MICROSOFT'.($this->keyforprovider ? '-'.$this->keyforprovider : '').'_TENANT');
|
||||||
|
|
||||||
|
return $this->tenant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,8 +56,8 @@ abstract class AbstractService extends BaseAbstractService implements ServiceInt
|
|||||||
$this->stateParameterInAuthUrl = $stateParameterInAutUrl;
|
$this->stateParameterInAuthUrl = $stateParameterInAutUrl;
|
||||||
|
|
||||||
foreach ($scopes as $scope) {
|
foreach ($scopes as $scope) {
|
||||||
if (!$this->isValidScope($scope)) {
|
if (!$this->isValidScope($scope)) {
|
||||||
throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this));
|
throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +223,8 @@ abstract class AbstractService extends BaseAbstractService implements ServiceInt
|
|||||||
$parameters,
|
$parameters,
|
||||||
$this->getExtraOAuthHeaders()
|
$this->getExtraOAuthHeaders()
|
||||||
);
|
);
|
||||||
|
//print $responseBody;exit; // We must have a result "{"token_type":"Bearer","scope...
|
||||||
|
|
||||||
$token = $this->parseAccessTokenResponse($responseBody);
|
$token = $this->parseAccessTokenResponse($responseBody);
|
||||||
$this->storage->storeAccessToken($this->service(), $token);
|
$this->storage->storeAccessToken($this->service(), $token);
|
||||||
|
|
||||||
|
|||||||
@ -12,30 +12,40 @@ use OAuth\Common\Http\Uri\UriInterface;
|
|||||||
|
|
||||||
class Microsoft extends AbstractService
|
class Microsoft extends AbstractService
|
||||||
{
|
{
|
||||||
const SCOPE_BASIC = 'wl.basic';
|
const SCOPE_BASIC = 'basic';
|
||||||
const SCOPE_OFFLINE = 'wl.offline_access';
|
const SCOPE_OFFLINE_ACCESS = 'offline_access';
|
||||||
const SCOPE_SIGNIN = 'wl.signin';
|
const SCOPE_SIGNIN = 'signin';
|
||||||
const SCOPE_BIRTHDAY = 'wl.birthday';
|
const SCOPE_BIRTHDAY = 'birthday';
|
||||||
const SCOPE_CALENDARS = 'wl.calendars';
|
const SCOPE_CALENDARS = 'calendars';
|
||||||
const SCOPE_CALENDARS_UPDATE = 'wl.calendars_update';
|
const SCOPE_CALENDARS_UPDATE = 'calendars_update';
|
||||||
const SCOPE_CONTACTS_BIRTHDAY = 'wl.contacts_birthday';
|
const SCOPE_CONTACTS_BIRTHDAY = 'contacts_birthday';
|
||||||
const SCOPE_CONTACTS_CREATE = 'wl.contacts_create';
|
const SCOPE_CONTACTS_CREATE = 'contacts_create';
|
||||||
const SCOPE_CONTACTS_CALENDARS = 'wl.contacts_calendars';
|
const SCOPE_CONTACTS_CALENDARS = 'contacts_calendars';
|
||||||
const SCOPE_CONTACTS_PHOTOS = 'wl.contacts_photos';
|
const SCOPE_CONTACTS_PHOTOS = 'contacts_photos';
|
||||||
const SCOPE_CONTACTS_SKYDRIVE = 'wl.contacts_skydrive';
|
const SCOPE_CONTACTS_SKYDRIVE = 'contacts_skydrive';
|
||||||
const SCOPE_EMAILS = 'wl.emails';
|
const SCOPE_EMAIL = 'email';
|
||||||
const SCOPE_EVENTS_CREATE = 'wl.events_create';
|
const SCOPE_EVENTS_CREATE = 'events_create';
|
||||||
const SCOPE_MESSENGER = 'wl.messenger';
|
const SCOPE_MESSENGER = 'messenger';
|
||||||
const SCOPE_PHONE_NUMBERS = 'wl.phone_numbers';
|
const SCOPE_OPENID = 'openid';
|
||||||
const SCOPE_PHOTOS = 'wl.photos';
|
const SCOPE_PHONE_NUMBERS = 'phone_numbers';
|
||||||
const SCOPE_POSTAL_ADDRESSES = 'wl.postal_addresses';
|
const SCOPE_PHOTOS = 'photos';
|
||||||
const SCOPE_SHARE = 'wl.share';
|
const SCOPE_POSTAL_ADDRESSES = 'postal_addresses';
|
||||||
const SCOPE_SKYDRIVE = 'wl.skydrive';
|
const SCOPE_PROFILE = 'profile';
|
||||||
const SCOPE_SKYDRIVE_UPDATE = 'wl.skydrive_update';
|
const SCOPE_SHARE = 'share';
|
||||||
const SCOPE_WORK_PROFILE = 'wl.work_profile';
|
const SCOPE_SKYDRIVE = 'skydrive';
|
||||||
const SCOPE_APPLICATIONS = 'wl.applications';
|
const SCOPE_SKYDRIVE_UPDATE = 'skydrive_update';
|
||||||
const SCOPE_APPLICATIONS_CREATE = 'wl.applications_create';
|
const SCOPE_WORK_PROFILE = 'work_profile';
|
||||||
const SCOPE_IMAP = 'wl.imap';
|
const SCOPE_APPLICATIONS = 'applications';
|
||||||
|
const SCOPE_APPLICATIONS_CREATE = 'applications_create';
|
||||||
|
const SCOPE_IMAP = 'imap';
|
||||||
|
const SOCPE_IMAP_ACCESSASUSERALL = 'https://outlook.office365.com/IMAP.AccessAsUser.All';
|
||||||
|
const SOCPE_SMTPSEND = 'https://outlook.office365.com/SMTP.Send';
|
||||||
|
const SOCPE_USERREAD = 'User.Read';
|
||||||
|
const SOCPE_MAILREAD = 'Mail.Read';
|
||||||
|
const SOCPE_MAILSEND = 'Mail.Send';
|
||||||
|
|
||||||
|
protected $storage;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MS uses some magical not officialy supported scope to get even moar info like full emailaddresses.
|
* MS uses some magical not officialy supported scope to get even moar info like full emailaddresses.
|
||||||
@ -48,7 +58,8 @@ class Microsoft extends AbstractService
|
|||||||
*
|
*
|
||||||
* Considering this scope is not officially supported: use with care
|
* Considering this scope is not officially supported: use with care
|
||||||
*/
|
*/
|
||||||
const SCOPE_CONTACTS_EMAILS = 'wl.contacts_emails';
|
const SCOPE_CONTACTS_EMAILS = 'contacts_emails';
|
||||||
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
CredentialsInterface $credentials,
|
CredentialsInterface $credentials,
|
||||||
@ -59,6 +70,8 @@ class Microsoft extends AbstractService
|
|||||||
) {
|
) {
|
||||||
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
|
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
|
||||||
|
|
||||||
|
$this->storage = $storage;
|
||||||
|
|
||||||
if (null === $baseApiUri) {
|
if (null === $baseApiUri) {
|
||||||
$this->baseApiUri = new Uri('https://apis.live.net/v5.0/');
|
$this->baseApiUri = new Uri('https://apis.live.net/v5.0/');
|
||||||
}
|
}
|
||||||
@ -69,7 +82,11 @@ class Microsoft extends AbstractService
|
|||||||
*/
|
*/
|
||||||
public function getAuthorizationEndpoint()
|
public function getAuthorizationEndpoint()
|
||||||
{
|
{
|
||||||
return new Uri('https://login.live.com/oauth20_authorize.srf');
|
$tenant = $this->storage->getTenant();
|
||||||
|
|
||||||
|
//return new Uri('https://login.live.com/oauth20_authorize.srf');
|
||||||
|
//return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize');
|
||||||
|
return new Uri('https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/authorize');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +94,11 @@ class Microsoft extends AbstractService
|
|||||||
*/
|
*/
|
||||||
public function getAccessTokenEndpoint()
|
public function getAccessTokenEndpoint()
|
||||||
{
|
{
|
||||||
return new Uri('https://login.live.com/oauth20_token.srf');
|
$tenant = $this->storage->getTenant();
|
||||||
|
|
||||||
|
//return new Uri('https://login.live.com/oauth20_token.srf');
|
||||||
|
//return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/token');
|
||||||
|
return new Uri('https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,6 +121,7 @@ class Microsoft extends AbstractService
|
|||||||
} elseif (isset($data['error'])) {
|
} elseif (isset($data['error'])) {
|
||||||
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
|
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
|
||||||
}
|
}
|
||||||
|
//print $data['access_token'];exit;
|
||||||
|
|
||||||
$token = new StdOAuth2Token();
|
$token = new StdOAuth2Token();
|
||||||
$token->setAccessToken($data['access_token']);
|
$token->setAccessToken($data['access_token']);
|
||||||
|
|||||||
@ -353,6 +353,7 @@ class Client {
|
|||||||
} catch (Exceptions\RuntimeException $e) {
|
} catch (Exceptions\RuntimeException $e) {
|
||||||
throw new ConnectionFailedException("connection setup failed - run exception", 0, $e);
|
throw new ConnectionFailedException("connection setup failed - run exception", 0, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->authenticate();
|
$this->authenticate();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@ -190,7 +190,7 @@ abstract class Protocol implements ProtocolInterface {
|
|||||||
STREAM_CLIENT_CONNECT,
|
STREAM_CLIENT_CONNECT,
|
||||||
stream_context_create($this->defaultSocketOptions($transport))
|
stream_context_create($this->defaultSocketOptions($transport))
|
||||||
);
|
);
|
||||||
stream_set_timeout($stream, $timeout);
|
//stream_set_timeout($stream, $timeout); // Hang id $strem empty and already done line 199
|
||||||
|
|
||||||
if (!$stream) {
|
if (!$stream) {
|
||||||
throw new ConnectionFailedException($errstr, $errno);
|
throw new ConnectionFailedException($errstr, $errno);
|
||||||
|
|||||||
@ -451,7 +451,7 @@ ExtrafieldCheckBox=Checkboxes
|
|||||||
ExtrafieldCheckBoxFromList=Checkboxes from table
|
ExtrafieldCheckBoxFromList=Checkboxes from table
|
||||||
ExtrafieldLink=Link to an object
|
ExtrafieldLink=Link to an object
|
||||||
ComputedFormula=Computed field
|
ComputedFormula=Computed field
|
||||||
ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: <strong>$db, $conf, $langs, $mysoc, $user, $object</strong>.<br><strong>WARNING</strong>: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.<br>Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.<br><br>Example of formula:<br>$object->id < 10 ? round($object->id / 2, 2): ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)<br><br>Example to reload object<br>(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($obj->id ? $obj->id: ($obj->rowid ? $obj->rowid: $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1'<br><br>Other example of formula to force load of object and its parent object:<br>(($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref: 'Parent project not found'
|
ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: <strong>$db, $conf, $langs, $mysoc, $user, $objectoffield</strong>.<br><strong>WARNING</strong>: If you need properties of an object not loaded, just fetch yourself the object into your formula like in the second example.<br>Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.<br><br>Example of formula:<br>$objectoffield->id < 10 ? round($objectoffield->id / 2, 2): ($objectoffield->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)<br><br>Example to reload object<br>(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($objectoffield->id) > 0 ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1')<br><br>Other example of formula to force load of object and its parent object:<br>(($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($objectoffield->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref: 'Parent project not found'
|
||||||
Computedpersistent=Store computed field
|
Computedpersistent=Store computed field
|
||||||
ComputedpersistentDesc=Computed extra fields will be stored in the database, however, the value will only be recalculated when the object of this field is changed. If the computed field depends on other objects or global data this value might be wrong!!
|
ComputedpersistentDesc=Computed extra fields will be stored in the database, however, the value will only be recalculated when the object of this field is changed. If the computed field depends on other objects or global data this value might be wrong!!
|
||||||
ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).<br>Set 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value)
|
ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).<br>Set 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value)
|
||||||
@ -700,6 +700,8 @@ Module62000Name=Incoterms
|
|||||||
Module62000Desc=Add features to manage Incoterms
|
Module62000Desc=Add features to manage Incoterms
|
||||||
Module63000Name=Resources
|
Module63000Name=Resources
|
||||||
Module63000Desc=Manage resources (printers, cars, rooms, ...) for allocating to events
|
Module63000Desc=Manage resources (printers, cars, rooms, ...) for allocating to events
|
||||||
|
Module66000Name=Enable OAuth2 authentication
|
||||||
|
Module66000Desc=Provide a tool to generate and manage OAuth2 tokens. The token can then be used by some other modules.
|
||||||
Module94160Name=Receptions
|
Module94160Name=Receptions
|
||||||
Permission11=Read customer invoices
|
Permission11=Read customer invoices
|
||||||
Permission12=Create/modify customer invoices
|
Permission12=Create/modify customer invoices
|
||||||
@ -2348,3 +2350,5 @@ AllowExternalDownload=Allow external download (without login, using a shared lin
|
|||||||
DeadlineDayVATSubmission=Deadline day for vat submission on the next month
|
DeadlineDayVATSubmission=Deadline day for vat submission on the next month
|
||||||
MaxNumberOfAttachementOnForms=Max number of joinded files in a form
|
MaxNumberOfAttachementOnForms=Max number of joinded files in a form
|
||||||
IfDefinedUseAValueBeetween=If defined, use a value between %s and %s
|
IfDefinedUseAValueBeetween=If defined, use a value between %s and %s
|
||||||
|
EMailsInGoingDesc=Incoming emails are managed by the module %s. You must enable and configure it if you need to support ingoing emails.
|
||||||
|
MAIN_IMAP_USE_PHPIMAP=Use the PHP-IMAP library for IMAP instead of native PHP IMAP. This also allows the use of an OAuth2 connection for IMAP (module OAuth must also be activated).
|
||||||
|
|||||||
@ -31,8 +31,9 @@ OAUTH_GITHUB_SECRET=OAuth GitHub Secret
|
|||||||
OAUTH_URL_FOR_CREDENTIAL=Go to <a class="notasortlink" href="%s" target="_blank" rel="noopener noreferrer external">this page<span class="fas fa-external-link-alt paddingleft"></span></a> to create or get your OAuth ID and Secret
|
OAUTH_URL_FOR_CREDENTIAL=Go to <a class="notasortlink" href="%s" target="_blank" rel="noopener noreferrer external">this page<span class="fas fa-external-link-alt paddingleft"></span></a> to create or get your OAuth ID and Secret
|
||||||
OAUTH_STRIPE_TEST_NAME=OAuth Stripe Test
|
OAUTH_STRIPE_TEST_NAME=OAuth Stripe Test
|
||||||
OAUTH_STRIPE_LIVE_NAME=OAuth Stripe Live
|
OAUTH_STRIPE_LIVE_NAME=OAuth Stripe Live
|
||||||
OAUTH_ID=OAuth ID
|
OAUTH_ID=OAuth Client ID
|
||||||
OAUTH_SECRET=OAuth secret
|
OAUTH_SECRET=OAuth secret
|
||||||
|
OAUTH_TENANT=OAuth tenant
|
||||||
OAuthProviderAdded=OAuth provider added
|
OAuthProviderAdded=OAuth provider added
|
||||||
AOAuthEntryForThisProviderAndLabelAlreadyHasAKey=An OAuth entry for this provider and label already exists
|
AOAuthEntryForThisProviderAndLabelAlreadyHasAKey=An OAuth entry for this provider and label already exists
|
||||||
URLOfServiceForAuthorization=URL provided by OAuth service for authentication
|
URLOfServiceForAuthorization=URL provided by OAuth service for authentication
|
||||||
|
|||||||
@ -501,7 +501,7 @@ if ((!empty($conf->global->MAIN_VERSION_LAST_UPGRADE) && ($conf->global->MAIN_VE
|
|||||||
|
|
||||||
// Creation of a token against CSRF vulnerabilities
|
// Creation of a token against CSRF vulnerabilities
|
||||||
if (!defined('NOTOKENRENEWAL') && !defined('NOSESSION')) {
|
if (!defined('NOTOKENRENEWAL') && !defined('NOSESSION')) {
|
||||||
// No token renewal on .css.php, .js.php and .json.php
|
// No token renewal on .css.php, .js.php and .json.php (even if the NOTOKENRENEWAL was not provided)
|
||||||
if (!preg_match('/\.(css|js|json)\.php$/', $_SERVER["PHP_SELF"])) {
|
if (!preg_match('/\.(css|js|json)\.php$/', $_SERVER["PHP_SELF"])) {
|
||||||
// Rolling token at each call ($_SESSION['token'] contains token of previous page)
|
// Rolling token at each call ($_SESSION['token'] contains token of previous page)
|
||||||
if (isset($_SESSION['newtoken'])) {
|
if (isset($_SESSION['newtoken'])) {
|
||||||
@ -1561,7 +1561,8 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr
|
|||||||
print '<meta name="robots" content="'.($disablenoindex ? 'index' : 'noindex').($disablenofollow ? ',follow' : ',nofollow').'">'."\n"; // Do not index
|
print '<meta name="robots" content="'.($disablenoindex ? 'index' : 'noindex').($disablenofollow ? ',follow' : ',nofollow').'">'."\n"; // Do not index
|
||||||
print '<meta name="viewport" content="width=device-width, initial-scale=1.0">'."\n"; // Scale for mobile device
|
print '<meta name="viewport" content="width=device-width, initial-scale=1.0">'."\n"; // Scale for mobile device
|
||||||
print '<meta name="author" content="Dolibarr Development Team">'."\n";
|
print '<meta name="author" content="Dolibarr Development Team">'."\n";
|
||||||
print '<meta name="anti-csrf-token" content="'.newToken().'">'."\n";
|
print '<meta name="anti-csrf-newtoken" content="'.newToken().'">'."\n";
|
||||||
|
print '<meta name="anti-csrf-currenttoken" content="'.currentToken().'">'."\n";
|
||||||
if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) {
|
if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) {
|
||||||
print '<meta name="MAIN_FEATURES_LEVEL" content="'.getDolGlobalInt('MAIN_FEATURES_LEVEL').'">'."\n";
|
print '<meta name="MAIN_FEATURES_LEVEL" content="'.getDolGlobalInt('MAIN_FEATURES_LEVEL').'">'."\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -201,13 +201,15 @@ if ($mode == 'setup' && $user->admin) {
|
|||||||
$i++;
|
$i++;
|
||||||
|
|
||||||
if ($key['varname'] == 'PRINTGCP_TOKEN_ACCESS') {
|
if ($key['varname'] == 'PRINTGCP_TOKEN_ACCESS') {
|
||||||
|
$keyforprovider = ''; // @BUG This must be set
|
||||||
|
|
||||||
// Token
|
// Token
|
||||||
print '<tr class="oddeven">';
|
print '<tr class="oddeven">';
|
||||||
print '<td>'.$langs->trans("Token").'</td>';
|
print '<td>'.$langs->trans("Token").'</td>';
|
||||||
print '<td colspan="2">';
|
print '<td colspan="2">';
|
||||||
$tokenobj = null;
|
$tokenobj = null;
|
||||||
// Dolibarr storage
|
// Dolibarr storage
|
||||||
$storage = new DoliStorage($db, $conf);
|
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||||
try {
|
try {
|
||||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME_GOOGLE);
|
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME_GOOGLE);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|||||||
@ -1846,7 +1846,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
if ($object->isService()) {
|
if ($object->isService()) {
|
||||||
$type = $langs->trans('Service');
|
$type = $langs->trans('Service');
|
||||||
}
|
}
|
||||||
//print load_fiche_titre($langs->trans('Modify').' '.$type.' : '.(is_object($object->oldcopy)?$object->oldcopy->ref:$object->ref), "");
|
// print load_fiche_titre($langs->trans('Modify').' '.$type.' : '.(is_object($object->oldcopy)?$object->oldcopy->ref:$object->ref), "");
|
||||||
|
|
||||||
// Main official, simple, and not duplicated code
|
// Main official, simple, and not duplicated code
|
||||||
print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="formprod">'."\n";
|
print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="formprod">'."\n";
|
||||||
@ -1865,19 +1865,18 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
|
|
||||||
// Ref
|
// Ref
|
||||||
if (empty($conf->global->MAIN_PRODUCT_REF_NOT_EDITABLE)) {
|
if (empty($conf->global->MAIN_PRODUCT_REF_NOT_EDITABLE)) {
|
||||||
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag($object->ref).'"></td></tr>';
|
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag(GETPOSTISSET('ref') ? GETPOST('ref') : $object->ref).'"></td></tr>';
|
||||||
} else {
|
} else {
|
||||||
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag($object->ref).'" readonly="true"></td></tr>';
|
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag($object->ref).'" readonly="true"></td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="3"><input name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.dol_escape_htmltag($object->label).'"></td></tr>';
|
print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="3"><input name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.dol_escape_htmltag(GETPOSTISSET('label') ? GETPOST('label') : $object->label).'"></td></tr>';
|
||||||
|
|
||||||
// Status To sell
|
// Status To sell
|
||||||
print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Sell").')</td><td colspan="3">';
|
print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Sell").')</td><td colspan="3">';
|
||||||
print '<select class="flat" name="statut">';
|
print '<select class="flat" name="statut">';
|
||||||
if ($object->status) {
|
if ((GETPOSTISSET('statut') && GETPOST('statut')) || (!GETPOSTISSET('statut') && $object->status)) {
|
||||||
print '<option value="1" selected>'.$langs->trans("OnSell").'</option>';
|
print '<option value="1" selected>'.$langs->trans("OnSell").'</option>';
|
||||||
print '<option value="0">'.$langs->trans("NotOnSell").'</option>';
|
print '<option value="0">'.$langs->trans("NotOnSell").'</option>';
|
||||||
} else {
|
} else {
|
||||||
@ -1890,7 +1889,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
// Status To Buy
|
// Status To Buy
|
||||||
print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Buy").')</td><td colspan="3">';
|
print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Buy").')</td><td colspan="3">';
|
||||||
print '<select class="flat" name="statut_buy">';
|
print '<select class="flat" name="statut_buy">';
|
||||||
if ($object->status_buy) {
|
if ((GETPOSTISSET('statut_buy') && GETPOST('statut_buy')) || (!GETPOSTISSET('statut_buy') && $object->status_buy)) {
|
||||||
print '<option value="1" selected>'.$langs->trans("ProductStatusOnBuy").'</option>';
|
print '<option value="1" selected>'.$langs->trans("ProductStatusOnBuy").'</option>';
|
||||||
print '<option value="0">'.$langs->trans("ProductStatusNotOnBuy").'</option>';
|
print '<option value="0">'.$langs->trans("ProductStatusNotOnBuy").'</option>';
|
||||||
} else {
|
} else {
|
||||||
@ -1905,7 +1904,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
|
if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
|
||||||
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td>';
|
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td>';
|
||||||
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
|
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
|
||||||
print $form->selectarray('status_batch', $statutarray, $object->status_batch);
|
print $form->selectarray('status_batch', $statutarray, (GETPOSTISSET('status_batch') ? GETPOST('status_batch') : $object->status_batch));
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
if (!empty($object->status_batch) || !empty($conf->use_javascript_ajax)) {
|
if (!empty($object->status_batch) || !empty($conf->use_javascript_ajax)) {
|
||||||
$langs->load("admin");
|
$langs->load("admin");
|
||||||
@ -2024,7 +2023,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
// Default warehouse
|
// Default warehouse
|
||||||
print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
|
print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
|
||||||
print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"');
|
print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"');
|
||||||
print $formproduct->selectWarehouses($object->fk_default_warehouse, 'fk_default_warehouse', 'warehouseopen', 1);
|
print $formproduct->selectWarehouses((GETPOSTISSET('fk_default_warehouse') ? GETPOST('fk_default_warehouse') : $object->fk_default_warehouse), 'fk_default_warehouse', 'warehouseopen', 1);
|
||||||
print ' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF'].'?action=create&type='.GETPOST('type', 'int')).'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddWarehouse").'"></span></a>';
|
print ' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF'].'?action=create&type='.GETPOST('type', 'int')).'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddWarehouse").'"></span></a>';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
/*
|
/*
|
||||||
@ -2072,7 +2071,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
if (empty($conf->global->PRODUCT_DISABLE_NATURE)) {
|
if (empty($conf->global->PRODUCT_DISABLE_NATURE)) {
|
||||||
// Nature
|
// Nature
|
||||||
print '<tr><td>'.$form->textwithpicto($langs->trans("NatureOfProductShort"), $langs->trans("NatureOfProductDesc")).'</td><td>';
|
print '<tr><td>'.$form->textwithpicto($langs->trans("NatureOfProductShort"), $langs->trans("NatureOfProductDesc")).'</td><td>';
|
||||||
print $formproduct->selectProductNature('finished', $object->finished);
|
print $formproduct->selectProductNature('finished', (GETPOSTISSET('finished') ? GETPOST('finished') : $object->finished));
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2080,7 +2079,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
if (!$object->isService() && isModEnabled('bom')) {
|
if (!$object->isService() && isModEnabled('bom')) {
|
||||||
print '<tr><td>'.$form->textwithpicto($langs->trans("DefaultBOM"), $langs->trans("DefaultBOMDesc", $langs->transnoentitiesnoconv("Finished"))).'</td><td>';
|
print '<tr><td>'.$form->textwithpicto($langs->trans("DefaultBOM"), $langs->trans("DefaultBOMDesc", $langs->transnoentitiesnoconv("Finished"))).'</td><td>';
|
||||||
$bomkey = "Bom:bom/class/bom.class.php:0:t.status=1 AND t.fk_product=".((int) $object->id);
|
$bomkey = "Bom:bom/class/bom.class.php:0:t.status=1 AND t.fk_product=".((int) $object->id);
|
||||||
print $form->selectForForms($bomkey, 'fk_default_bom', $object->fk_default_bom, 1);
|
print $form->selectForForms($bomkey, 'fk_default_bom', (GETPOSTISSET('fk_default_bom') ? GETPOST('fk_default_bom') : $object->fk_default_bom), 1);
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2135,7 +2134,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
|
|
||||||
// Custom code
|
// Custom code
|
||||||
if (!$object->isService() && empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO)) {
|
if (!$object->isService() && empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO)) {
|
||||||
print '<tr><td class="wordbreak">'.$langs->trans("CustomCode").'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.$object->customcode.'"></td></tr>';
|
print '<tr><td class="wordbreak">'.$langs->trans("CustomCode").'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.(GETPOSTISSET('customcode') ? GETPOST('customcode') : $object->customcode).'"></td></tr>';
|
||||||
// Origin country
|
// Origin country
|
||||||
print '<tr><td>'.$langs->trans("CountryOrigin").'</td>';
|
print '<tr><td>'.$langs->trans("CountryOrigin").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
@ -2188,6 +2187,11 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
$arrayselected[] = $cat->id;
|
$arrayselected[] = $cat->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (GETPOSTISSET('categories', 'array')) {
|
||||||
|
foreach (GETPOST('categories', 'array') as $cat) {
|
||||||
|
$arrayselected[] = $cat;
|
||||||
|
}
|
||||||
|
}
|
||||||
print img_picto('', 'category').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
|
print img_picto('', 'category').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
|
||||||
print "</td></tr>";
|
print "</td></tr>";
|
||||||
}
|
}
|
||||||
@ -2213,76 +2217,76 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
|||||||
// Accountancy_code_sell
|
// Accountancy_code_sell
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellCode").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $formaccounting->select_account($object->accountancy_code_sell, 'accountancy_code_sell', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_sell') ? GETPOST('accountancy_code_sell') : $object->accountancy_code_sell), 'accountancy_code_sell', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Accountancy_code_sell_intra
|
// Accountancy_code_sell_intra
|
||||||
if ($mysoc->isInEEC()) {
|
if ($mysoc->isInEEC()) {
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellIntraCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellIntraCode").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $formaccounting->select_account($object->accountancy_code_sell_intra, 'accountancy_code_sell_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_sell_intra') ? GETPOST('accountancy_code_sell_intra') : $object->accountancy_code_sell_intra), 'accountancy_code_sell_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accountancy_code_sell_export
|
// Accountancy_code_sell_export
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellExportCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellExportCode").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $formaccounting->select_account($object->accountancy_code_sell_export, 'accountancy_code_sell_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_sell_export') ? GETPOST('accountancy_code_sell_export') : $object->accountancy_code_sell_export), 'accountancy_code_sell_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Accountancy_code_buy
|
// Accountancy_code_buy
|
||||||
print '<tr><td>'.$langs->trans("ProductAccountancyBuyCode").'</td>';
|
print '<tr><td>'.$langs->trans("ProductAccountancyBuyCode").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $formaccounting->select_account($object->accountancy_code_buy, 'accountancy_code_buy', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_buy') ? GETPOST('accountancy_code_buy') : $object->accountancy_code_buy), 'accountancy_code_buy', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Accountancy_code_buy_intra
|
// Accountancy_code_buy_intra
|
||||||
if ($mysoc->isInEEC()) {
|
if ($mysoc->isInEEC()) {
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyIntraCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyIntraCode").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $formaccounting->select_account($object->accountancy_code_buy_intra, 'accountancy_code_buy_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_buy_intra') ? GETPOST('accountancy_code_buy_intra') : $object->accountancy_code_buy_intra), 'accountancy_code_buy_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accountancy_code_buy_export
|
// Accountancy_code_buy_export
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyExportCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyExportCode").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $formaccounting->select_account($object->accountancy_code_buy_export, 'accountancy_code_buy_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_buy_export') ? GETPOST('accountancy_code_buy_export') : $object->accountancy_code_buy_export), 'accountancy_code_buy_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
} else {
|
} else {
|
||||||
// For external software
|
// For external software
|
||||||
// Accountancy_code_sell
|
// Accountancy_code_sell
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellCode").'</td>';
|
||||||
print '<td><input name="accountancy_code_sell" class="maxwidth200" value="'.$object->accountancy_code_sell.'">';
|
print '<td><input name="accountancy_code_sell" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_sell') ? GETPOST('accountancy_code_sell') : $object->accountancy_code_sell).'">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Accountancy_code_sell_intra
|
// Accountancy_code_sell_intra
|
||||||
if ($mysoc->isInEEC()) {
|
if ($mysoc->isInEEC()) {
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellIntraCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellIntraCode").'</td>';
|
||||||
print '<td><input name="accountancy_code_sell_intra" class="maxwidth200" value="'.$object->accountancy_code_sell_intra.'">';
|
print '<td><input name="accountancy_code_sell_intra" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_sell_intra') ? GETPOST('accountancy_code_sell_intra') : $object->accountancy_code_sell_intra).'">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accountancy_code_sell_export
|
// Accountancy_code_sell_export
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellExportCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellExportCode").'</td>';
|
||||||
print '<td><input name="accountancy_code_sell_export" class="maxwidth200" value="'.$object->accountancy_code_sell_export.'">';
|
print '<td><input name="accountancy_code_sell_export" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_sell_export') ? GETPOST('accountancy_code_sell_export') : $object->accountancy_code_sell_export).'">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Accountancy_code_buy
|
// Accountancy_code_buy
|
||||||
print '<tr><td>'.$langs->trans("ProductAccountancyBuyCode").'</td>';
|
print '<tr><td>'.$langs->trans("ProductAccountancyBuyCode").'</td>';
|
||||||
print '<td><input name="accountancy_code_buy" class="maxwidth200" value="'.$object->accountancy_code_buy.'">';
|
print '<td><input name="accountancy_code_buy" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_buy') ? GETPOST('accountancy_code_buy') : $object->accountancy_code_buy).'">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Accountancy_code_buy_intra
|
// Accountancy_code_buy_intra
|
||||||
if ($mysoc->isInEEC()) {
|
if ($mysoc->isInEEC()) {
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyIntraCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyIntraCode").'</td>';
|
||||||
print '<td><input name="accountancy_code_buy_intra" class="maxwidth200" value="'.$object->accountancy_code_buy_intra.'">';
|
print '<td><input name="accountancy_code_buy_intra" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_buy_intra') ? GETPOST('accountancy_code_buy_intra') : $object->accountancy_code_buy_intra).'">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accountancy_code_buy_export
|
// Accountancy_code_buy_export
|
||||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyExportCode").'</td>';
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyExportCode").'</td>';
|
||||||
print '<td><input name="accountancy_code_buy_export" class="maxwidth200" value="'.$object->accountancy_code_buy_export.'">';
|
print '<td><input name="accountancy_code_buy_export" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_buy_export') ? GETPOST('accountancy_code_buy_export') : $object->accountancy_code_buy_export).'">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2807,7 +2807,7 @@ if (!GETPOST('hide_websitemenu')) {
|
|||||||
$atleastonepage = (is_array($array) && count($array) > 0);
|
$atleastonepage = (is_array($array) && count($array) > 0);
|
||||||
|
|
||||||
$websitepage = new WebSitePage($db);
|
$websitepage = new WebSitePage($db);
|
||||||
if ($pageid > 0 && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')) {
|
if ($pageid > 0) {
|
||||||
$websitepage->fetch($pageid);
|
$websitepage->fetch($pageid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user