Merge branch 'develop' into dolibarr_partnership

This commit is contained in:
NextGestion 2021-04-09 12:01:44 +01:00 committed by GitHub
commit d6e4cb7d0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
349 changed files with 3592 additions and 1541 deletions

15
.gitattributes vendored
View File

@ -11,12 +11,14 @@
*.htm text eol=lf *.htm text eol=lf
*.html text eol=lf *.html text eol=lf
*.js text eol=lf *.js text eol=lf
*.json text eol=lf
*.css text eol=lf *.css text eol=lf
*.lang text eol=lf *.lang text eol=lf
*.txt text eol=lf *.txt text eol=lf
*.md text eol=lf *.md text eol=lf
*.pp text eol=lf *.pp text eol=lf
*.sh text eol=lf *.sh text eol=lf
*.yml text eol=lf
*.yaml text eol=lf *.yaml text eol=lf
*.conf text eol=lf *.conf text eol=lf
@ -24,15 +26,16 @@
# Denote all files that are truly binary and should not be modified. # Denote all files that are truly binary and should not be modified.
*.bmp binary *.bmp binary
*.ico binary
*.png binary
*.jpg binary
*.jpeg binary
*.odt binary
*.odf binary
*.frm binary *.frm binary
*.ico binary
*.jpeg binary
*.jpg binary
*.MYD binary *.MYD binary
*.MYI binary *.MYI binary
*.odf binary
*.odt binary
*.png binary
# Export ignores to generate clean production tarballs # Export ignores to generate clean production tarballs
/build export-ignore /build export-ignore

View File

@ -23,7 +23,7 @@ PEAR Mail_MIME 1.8.9 BSD Yes
ParseDown 1.6 MIT License Yes Markdown parser ParseDown 1.6 MIT License Yes Markdown parser
PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files
PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers
PHPSpreadSheet ? LGPL-2.1+ Yes Read/Write XLS files, read ODS files PHPSpreadSheet 1.8.2 LGPL-2.1+ Yes Read/Write XLS files, read ODS files
php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service
PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests

View File

@ -29,6 +29,7 @@
"ckeditor/ckeditor" : "4.12.1", "ckeditor/ckeditor" : "4.12.1",
"mike42/escpos-php" : "2.2", "mike42/escpos-php" : "2.2",
"mobiledetect/mobiledetectlib" : "2.8.34", "mobiledetect/mobiledetectlib" : "2.8.34",
"phpoffice/phpexcel" : "1.8.2",
"restler/framework" : "3.0.0-RC6", "restler/framework" : "3.0.0-RC6",
"tecnickcom/tcpdf" : "6.3.2", "tecnickcom/tcpdf" : "6.3.2",
"nnnick/chartjs" : "^2.9", "nnnick/chartjs" : "^2.9",

57
composer.lock generated
View File

@ -328,6 +328,63 @@
}, },
"time": "2020-03-23T09:12:05+00:00" "time": "2020-03-23T09:12:05+00:00"
}, },
{
"name": "phpoffice/phpexcel",
"version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PHPExcel.git",
"reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/1441011fb7ecdd8cc689878f54f8b58a6805f870",
"reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"php": "^5.2|^7.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "2.*"
},
"type": "library",
"autoload": {
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "http://blog.maartenballiauw.be"
},
{
"name": "Erik Tilt"
},
{
"name": "Franck Lefevre",
"homepage": "http://rootslabs.net"
},
{
"name": "Mark Baker",
"homepage": "http://markbakeruk.net"
}
],
"description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PHPExcel",
"keywords": [
"OpenXML",
"excel",
"xlsx"
],
"abandoned": "phpoffice/phpspreadsheet",
"time": "2018-11-22T23:07:24+00:00"
},
{ {
"name": "restler/framework", "name": "restler/framework",
"version": "3.0.0-RC6", "version": "3.0.0-RC6",

View File

@ -0,0 +1,20 @@
# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.
[Definition]
# To test, you can inject this example into log
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 functions_dolibarr::check_user_password_abcd Authentication KO" >> /mypath/documents/dolibarr.log
#
# then
# fail2ban-client status web-dol-bruteforce
#
# To test rule file on a existing log file
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-rulesbruteforce.conf
failregex = ^ [A-Z\s]+ <HOST>\s+functions_dolibarr::check_user_password_.* Authentication KO
ignoreregex =

View File

@ -0,0 +1,20 @@
# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.
[Definition]
# To test, you can inject this example into log
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 --- Access to GET /passwordforgotten.php - action=buildnewpassword, massaction=" >> /mypath/documents/dolibarr.log
#
# then
# fail2ban-client status web-dol-passforgotten
#
# To test rule file on a existing log file
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-rulespassforgotten.conf
failregex = ^ [A-Z\s]+ <HOST>\s+--- Access to .*/passwordforgotten.php - action=buildnewpassword
ignoreregex =

View File

@ -0,0 +1,28 @@
#
# Examle of rule you can add to fail2ban to restrict bruteforce attacks.
#
[web-dol-passforgotten]
; rule against call of passwordforgottenpage
enabled = true
port = http,https
filter = web-dolibarr-rulespassforgotten
logpath = >> /mypath/documents/documents/dolibarr.log
action = %(action_mw)s
bantime = 4320000 ; 50 days
findtime = 86400 ; 1 day
maxretry = 10
[web-dol-bruteforce]
; rule against bruteforce hacking (login + api)
enabled = true
port = http,https
filter = web-dolibarr-rulesbruteforce
logpath = >> /mypath/documents/documents/dolibarr.log
action = %(action_mw)s
bantime = 86400 ; 1 day
findtime = 3600 ; 1 hour
maxretry = 10

View File

@ -200,7 +200,7 @@ class BookKeeping extends CommonObject
$error = 0; $error = 0;
// Clean parameters // Clean parameters</center>
if (isset($this->doc_type)) { if (isset($this->doc_type)) {
$this->doc_type = trim($this->doc_type); $this->doc_type = trim($this->doc_type);
} }
@ -296,7 +296,7 @@ class BookKeeping extends CommonObject
$sql .= " WHERE doc_type = '".$this->db->escape($this->doc_type)."'"; $sql .= " WHERE doc_type = '".$this->db->escape($this->doc_type)."'";
$sql .= " AND fk_doc = ".$this->fk_doc; $sql .= " AND fk_doc = ".$this->fk_doc;
if (!empty($conf->global->ACCOUNTANCY_ENABLE_FKDOCDET)) { if (!empty($conf->global->ACCOUNTANCY_ENABLE_FKDOCDET)) {
// DO NOT USE THIS IN PRPDUCTION. This will generate a lot of trouble into reports and will corrupt database (by generating duplicate entries. // DO NOT USE THIS IN PRPDUCTION. This will generate a lot of trouble into reports and will corrupt database (by generating duplicate entries.
$sql .= " AND fk_docdet = " . $this->fk_docdet; // This field can be 0 if record is for several lines $sql .= " AND fk_docdet = " . $this->fk_docdet; // This field can be 0 if record is for several lines
} }
$sql .= " AND numero_compte = '".$this->db->escape($this->numero_compte)."'"; $sql .= " AND numero_compte = '".$this->db->escape($this->numero_compte)."'";

View File

@ -8,7 +8,8 @@
* Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org> * Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr> * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2020-2021 Frédéric France <frederic.france@netlogic.fr> * Copyright (C) 2020-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2021 Waël Almoman <info@almoman.com>
* *
* 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
@ -33,6 +34,7 @@
require '../../main.inc.php'; require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
// Load translation files required by the page // Load translation files required by the page
$langs->loadLangs(array("admin", "members")); $langs->loadLangs(array("admin", "members"));
@ -101,11 +103,12 @@ if ($action == 'set_default') {
} }
} elseif ($action == 'updateall') { } elseif ($action == 'updateall') {
$db->begin(); $db->begin();
$res1 = $res2 = $res3 = $res4 = $res5 = $res6 = 0; $res1 = $res2 = $res3 = $res4 = $res5 = $res6 = $res7 = 0;
$res1 = dolibarr_set_const($db, 'ADHERENT_LOGIN_NOT_REQUIRED', GETPOST('ADHERENT_LOGIN_NOT_REQUIRED', 'alpha') ? 0 : 1, 'chaine', 0, '', $conf->entity); $res1 = dolibarr_set_const($db, 'ADHERENT_LOGIN_NOT_REQUIRED', GETPOST('ADHERENT_LOGIN_NOT_REQUIRED', 'alpha') ? 0 : 1, 'chaine', 0, '', $conf->entity);
$res2 = dolibarr_set_const($db, 'ADHERENT_MAIL_REQUIRED', GETPOST('ADHERENT_MAIL_REQUIRED', 'alpha'), 'chaine', 0, '', $conf->entity); $res2 = dolibarr_set_const($db, 'ADHERENT_MAIL_REQUIRED', GETPOST('ADHERENT_MAIL_REQUIRED', 'alpha'), 'chaine', 0, '', $conf->entity);
$res3 = dolibarr_set_const($db, 'ADHERENT_DEFAULT_SENDINFOBYMAIL', GETPOST('ADHERENT_DEFAULT_SENDINFOBYMAIL', 'alpha'), 'chaine', 0, '', $conf->entity); $res3 = dolibarr_set_const($db, 'ADHERENT_DEFAULT_SENDINFOBYMAIL', GETPOST('ADHERENT_DEFAULT_SENDINFOBYMAIL', 'alpha'), 'chaine', 0, '', $conf->entity);
$res4 = dolibarr_set_const($db, 'ADHERENT_BANK_USE', GETPOST('ADHERENT_BANK_USE', 'alpha'), 'chaine', 0, '', $conf->entity); $res4 = dolibarr_set_const($db, 'ADHERENT_BANK_USE', GETPOST('ADHERENT_BANK_USE', 'alpha'), 'chaine', 0, '', $conf->entity);
$res7 = dolibarr_set_const($db, "MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE", json_encode(GETPOST('MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE')), 'array', 0, '', $conf->entity);
// Use vat for invoice creation // Use vat for invoice creation
if ($conf->facture->enabled) { if ($conf->facture->enabled) {
$res4 = dolibarr_set_const($db, 'ADHERENT_VAT_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_VAT_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity); $res4 = dolibarr_set_const($db, 'ADHERENT_VAT_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_VAT_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity);
@ -217,6 +220,18 @@ print '<tr class="oddeven"><td>'.$langs->trans("MemberSendInformationByMailByDef
print $form->selectyesno('ADHERENT_DEFAULT_SENDINFOBYMAIL', (!empty($conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL) ? $conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL : 0), 1); print $form->selectyesno('ADHERENT_DEFAULT_SENDINFOBYMAIL', (!empty($conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL) ? $conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL : 0), 1);
print "</td></tr>\n"; print "</td></tr>\n";
// Amount by member type
$adht = new AdherentType($db);
$amountbytype = empty($conf->global->MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE) ? -1 : json_decode($conf->global->MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE, true);
print '<tr class="oddeven"><td>'.$langs->trans("DefineAmountMemberType").'</td><td>';
foreach ($adht->liste_array(1) as $typeid => $type) {
print $type .' : ';
print '<input type="text" id="MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE['.$typeid.']" name="MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE['.$typeid.']" " size="5" value="'.(!empty($amountbytype[$typeid]) ? $amountbytype[$typeid] : '').'">';
print '<br>';
}
print "</td></tr>\n";
// Insert subscription into bank account // Insert subscription into bank account
print '<tr class="oddeven"><td>'.$langs->trans("MoreActionsOnSubscription").'</td>'; print '<tr class="oddeven"><td>'.$langs->trans("MoreActionsOnSubscription").'</td>';
$arraychoices = array('0'=>$langs->trans("None")); $arraychoices = array('0'=>$langs->trans("None"));

View File

@ -177,7 +177,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print $langs->trans("ForceMemberType"); print $langs->trans("ForceMemberType");
print '</td><td class="right">'; print '</td><td class="right">';
$listofval = array(); $listofval = array();
$listofval += $adht->liste_array(); $listofval += $adht->liste_array(1);
$forcetype = empty($conf->global->MEMBER_NEWFORM_FORCETYPE) ? -1 : $conf->global->MEMBER_NEWFORM_FORCETYPE; $forcetype = empty($conf->global->MEMBER_NEWFORM_FORCETYPE) ? -1 : $conf->global->MEMBER_NEWFORM_FORCETYPE;
print $form->selectarray("MEMBER_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval) > 1 ? 1 : 0); print $form->selectarray("MEMBER_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval) > 1 ? 1 : 0);
print "</td></tr>\n"; print "</td></tr>\n";

View File

@ -13,7 +13,7 @@
* Copyright (C) 2018-2019 Thibault FOUCART <support@ptibogxiv.net> * Copyright (C) 2018-2019 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com> * Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2020 Josep Lluís Amador <joseplluis@lliuretic.cat> * Copyright (C) 2020 Josep Lluís Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2021 Waël Almoman <info@almoman.com> * Copyright (C) 2021 Waël Almoman <info@almoman.com>
* *
* 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
@ -1490,9 +1490,10 @@ class Adherent extends CommonObject
* @param string $emetteur_nom Name of cheque writer * @param string $emetteur_nom Name of cheque writer
* @param string $emetteur_banque Name of bank of cheque * @param string $emetteur_banque Name of bank of cheque
* @param int $datesubend Date end subscription * @param int $datesubend Date end subscription
* @param int $fk_type Member type id
* @return int rowid of record added, <0 if KO * @return int rowid of record added, <0 if KO
*/ */
public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0) public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
{ {
global $conf, $langs, $user; global $conf, $langs, $user;
@ -1523,6 +1524,7 @@ class Adherent extends CommonObject
$subscription->amount = $amount; $subscription->amount = $amount;
$subscription->note = $label; // deprecated $subscription->note = $label; // deprecated
$subscription->note_public = $label; $subscription->note_public = $label;
$subscription->fk_type = $fk_type;
$rowid = $subscription->create($user); $rowid = $subscription->create($user);
if ($rowid > 0) { if ($rowid > 0) {

View File

@ -60,6 +60,7 @@ $arrayofparameters = array(
'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), 'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), 'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), 'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
'EVENTORGANIZATION_SECUREKEY'=>array('type'=>'securekey', 'enabled'=>1),
); );
$error = 0; $error = 0;
@ -74,6 +75,7 @@ if ((float) DOL_VERSION >= 6) {
include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
} }
if ($action == 'updateMask') { if ($action == 'updateMask') {
$maskconstorder = GETPOST('maskconstorder', 'alpha'); $maskconstorder = GETPOST('maskconstorder', 'alpha');
$maskorder = GETPOST('maskorder', 'alpha'); $maskorder = GETPOST('maskorder', 'alpha');
@ -196,7 +198,6 @@ print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, 'even
// Setup page goes here // Setup page goes here
echo '<span class="opacitymedium">'.$langs->trans("EventOrganizationSetupPage").'</span><br><br>'; echo '<span class="opacitymedium">'.$langs->trans("EventOrganizationSetupPage").'</span><br><br>';
if ($action == 'edit') { if ($action == 'edit') {
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">'; print '<input type="hidden" name="token" value="'.newToken().'">';
@ -206,12 +207,12 @@ if ($action == 'edit') {
print '<tr class="liste_titre"><td class="titlefieldcreate">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>'; print '<tr class="liste_titre"><td class="titlefieldcreate">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
foreach ($arrayofparameters as $constname => $val) { foreach ($arrayofparameters as $constname => $val) {
if ($val['enabled']==1) { if ($val['enabled']==1) {
$setupnotempty++; $setupnotempty++;
print '<tr class="oddeven"><td>'; print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : '');
print '<span id="helplink'.$constname.'" class="spanforparamtooltip">'.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).'</span>'; print '<span id="helplink'.$constname.'" class="spanforparamtooltip">'.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).'</span>';
print '</td><td>'; print '</td><td>';
if ($val['type'] == 'textarea') { if ($val['type'] == 'textarea') {
print '<textarea class="flat" name="'.$constname.'" id="'.$constname.'" cols="50" rows="5" wrap="soft">' . "\n"; print '<textarea class="flat" name="'.$constname.'" id="'.$constname.'" cols="50" rows="5" wrap="soft">' . "\n";
@ -255,6 +256,26 @@ if ($action == 'edit') {
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
$formcompany = new FormCompany($db); $formcompany = new FormCompany($db);
print $formcompany->selectProspectCustomerType($conf->global->{$constname}, $constname); print $formcompany->selectProspectCustomerType($conf->global->{$constname}, $constname);
} elseif ($val['type'] == 'securekey') {
print '<input required="required" type="text" class="flat" id="'.$constname.'" name="'.$constname.'" value="'.(GETPOST($constname, 'alpha') ?GETPOST($constname, 'alpha') : $conf->global->{$constname}).'" size="40">';
if (!empty($conf->use_javascript_ajax)) {
print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"');
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token'.$constname.'").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#'.$constname.'").val(token);
});
});
});';
print '</script>';
}
} else { } else {
print '<input name="'.$constname.'" class="flat '.(empty($val['css']) ? 'minwidth200' : $val['css']).'" value="'.$conf->global->{$constname}.'">'; print '<input name="'.$constname.'" class="flat '.(empty($val['css']) ? 'minwidth200' : $val['css']).'" value="'.$conf->global->{$constname}.'">';
} }

View File

@ -897,7 +897,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
if (!empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)) { // This is a bad practice to activate a synch external access during building of a page. 1 external module can hang the application. if (!empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)) { // This is a bad practice to activate a synch external access during building of a page. 1 external module can hang the application.
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
if (!empty($objMod->url_last_version)) { if (!empty($objMod->url_last_version)) {
$newversion = getURLContent($objMod->url_last_version); $newversion = getURLContent($objMod->url_last_version, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
if (isset($newversion['content'])) { if (isset($newversion['content'])) {
if (version_compare($newversion['content'], $versiontrans) > 0) { if (version_compare($newversion['content'], $versiontrans) > 0) {
print "&nbsp;<span class='butAction' title='".$langs->trans('LastStableVersion')."'>".$newversion['content']."</span>"; print "&nbsp;<span class='butAction' title='".$langs->trans('LastStableVersion')."'>".$newversion['content']."</span>";

View File

@ -78,10 +78,10 @@ print '<br>';
$file_list = array('missing' => array(), 'updated' => array()); $file_list = array('missing' => array(), 'updated' => array());
// Local file to compare to // Local file to compare to
$xmlshortfile = GETPOST('xmlshortfile', 'alpha') ?GETPOST('xmlshortfile', 'alpha') : '/install/filelist-'.DOL_VERSION.(empty($conf->global->MAIN_FILECHECK_LOCAL_SUFFIX) ? '' : $conf->global->MAIN_FILECHECK_LOCAL_SUFFIX).'.xml'.(empty($conf->global->MAIN_FILECHECK_LOCAL_EXT) ? '' : $conf->global->MAIN_FILECHECK_LOCAL_EXT); $xmlshortfile = dol_sanitizeFileName(GETPOST('xmlshortfile', 'alpha') ? GETPOST('xmlshortfile', 'alpha') : 'filelist-'.DOL_VERSION.(empty($conf->global->MAIN_FILECHECK_LOCAL_SUFFIX) ? '' : $conf->global->MAIN_FILECHECK_LOCAL_SUFFIX).'.xml'.(empty($conf->global->MAIN_FILECHECK_LOCAL_EXT) ? '' : $conf->global->MAIN_FILECHECK_LOCAL_EXT));
$xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile; $xmlfile = DOL_DOCUMENT_ROOT.'/install/'.$xmlshortfile;
// Remote file to compare to // Remote file to compare to
$xmlremote = GETPOST('xmlremote'); $xmlremote = GETPOST('xmlremote', 'alphanohtml');
if (empty($xmlremote) && !empty($conf->global->MAIN_FILECHECK_URL)) { if (empty($xmlremote) && !empty($conf->global->MAIN_FILECHECK_URL)) {
$xmlremote = $conf->global->MAIN_FILECHECK_URL; $xmlremote = $conf->global->MAIN_FILECHECK_URL;
} }
@ -92,7 +92,11 @@ if (empty($xmlremote) && !empty($conf->global->$param)) {
if (empty($xmlremote)) { if (empty($xmlremote)) {
$xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml'; $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
} }
if ($xmlremote && !preg_match('/^https?:\/\//', $xmlremote)) {
$langs->load("errors");
setEventMessages($langs->trans("ErrorURLMustStartWithHttp", $xmlremote), '', 'errors');
$error++;
}
// Test if remote test is ok // Test if remote test is ok
$enableremotecheck = true; $enableremotecheck = true;
@ -147,12 +151,12 @@ if (GETPOST('target') == 'local') {
} }
$xml = simplexml_load_file($xmlfile); $xml = simplexml_load_file($xmlfile);
} else { } else {
print $langs->trans('XmlNotFound').': '.$xmlfile; print '<div class="warning">'.$langs->trans('XmlNotFound').': '.$xmlfile.'</span>';
$error++; $error++;
} }
} }
if (GETPOST('target') == 'remote') { if (GETPOST('target') == 'remote') {
$xmlarray = getURLContent($xmlremote); $xmlarray = getURLContent($xmlremote, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
// Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...) // Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') { if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') {

View File

@ -58,7 +58,11 @@ class Login
{ {
global $conf, $dolibarr_main_authentication, $dolibarr_auto_user; global $conf, $dolibarr_main_authentication, $dolibarr_auto_user;
// TODO Remove the API login. The token must be generated from backoffice only. // Is the login API disabled ? The token must be generated from backoffice only.
if (! empty($conf->global->API_DISABLE_LOGIN_API)) {
dol_syslog("Warning: A try to use the login API has been done while the login API is disabled. You must generate or get the token from the backoffice.", LOG_WARNING);
throw new RestException(403, "Error, the login API has been disabled for security purpose. You must generate or get the token from the backoffice.");
}
// Authentication mode // Authentication mode
if (empty($dolibarr_main_authentication)) { if (empty($dolibarr_main_authentication)) {
@ -87,7 +91,7 @@ class Login
} }
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
$login = checkLoginPassEntity($login, $password, $entity, $authmode, 'api'); $login = checkLoginPassEntity($login, $password, $entity, $authmode, 'api'); // Check credentials.
if (empty($login)) { if (empty($login)) {
throw new RestException(403, 'Access denied'); throw new RestException(403, 'Access denied');
} }

View File

@ -1647,8 +1647,8 @@ class Setup extends DolibarrApi
$file_list = array('missing' => array(), 'updated' => array()); $file_list = array('missing' => array(), 'updated' => array());
// Local file to compare to // Local file to compare to
$xmlshortfile = GETPOST('xmlshortfile') ?GETPOST('xmlshortfile') : '/install/filelist-'.DOL_VERSION.'.xml'; $xmlshortfile = dol_sanitizeFileName(GETPOST('xmlshortfile', 'alpha') ? GETPOST('xmlshortfile', 'alpha') : 'filelist-'.DOL_VERSION.(empty($conf->global->MAIN_FILECHECK_LOCAL_SUFFIX) ? '' : $conf->global->MAIN_FILECHECK_LOCAL_SUFFIX).'.xml'.(empty($conf->global->MAIN_FILECHECK_LOCAL_EXT) ? '' : $conf->global->MAIN_FILECHECK_LOCAL_EXT));
$xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile; $xmlfile = DOL_DOCUMENT_ROOT.'/install/'.$xmlshortfile;
// Remote file to compare to // Remote file to compare to
$xmlremote = ($target == 'default' ? '' : $target); $xmlremote = ($target == 'default' ? '' : $target);
if (empty($xmlremote) && !empty($conf->global->MAIN_FILECHECK_URL)) { if (empty($xmlremote) && !empty($conf->global->MAIN_FILECHECK_URL)) {
@ -1661,6 +1661,10 @@ class Setup extends DolibarrApi
if (empty($xmlremote)) { if (empty($xmlremote)) {
$xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml'; $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
} }
if ($xmlremote && !preg_match('/^https?:\/\//', $xmlremote)) {
$langs->load("errors");
throw new RestException(500, $langs->trans("ErrorURLMustStartWithHttp", $xmlremote));
}
if ($target == 'local') { if ($target == 'local') {
if (dol_is_file($xmlfile)) { if (dol_is_file($xmlfile)) {
@ -1669,7 +1673,7 @@ class Setup extends DolibarrApi
throw new RestException(500, $langs->trans('XmlNotFound').': '.$xmlfile); throw new RestException(500, $langs->trans('XmlNotFound').': '.$xmlfile);
} }
} else { } else {
$xmlarray = getURLContent($xmlremote); $xmlarray = getURLContent($xmlremote, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
// Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...) // Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') { if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') {

View File

@ -99,6 +99,10 @@ class Boms extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->bom->read) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
$tmpobject = new BOM($this->db); $tmpobject = new BOM($this->db);

View File

@ -579,20 +579,25 @@ class ActionComm extends CommonObject
// Now insert assigned users // Now insert assigned users
if (!$error) { if (!$error) {
//dol_syslog(var_export($this->userassigned, true)); //dol_syslog(var_export($this->userassigned, true));
$already_inserted = array();
foreach ($this->userassigned as $key => $val) { foreach ($this->userassigned as $key => $val) {
if (!is_array($val)) { // For backward compatibility when val=id if (!is_array($val)) { // For backward compatibility when val=id
$val = array('id'=>$val); $val = array('id'=>$val);
} }
if ($val['id'] > 0) { if ($val['id'] > 0) {
if (!empty($already_inserted[$val['id']])) continue;
$sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
$sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")"; $sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")";
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
dol_syslog('Error to process userassigned: '.$this->db->lasterror(), LOG_ERR); dol_syslog('Error to process userassigned: ' . $this->db->lasterror(), LOG_ERR);
$this->errors[] = $this->db->lasterror(); $this->errors[] = $this->db->lasterror();
} else {
$already_inserted[$val['id']] = true;
} }
//var_dump($sql);exit; //var_dump($sql);exit;
} }
@ -601,15 +606,20 @@ class ActionComm extends CommonObject
if (!$error) { if (!$error) {
if (!empty($this->socpeopleassigned)) { if (!empty($this->socpeopleassigned)) {
$already_inserted = array();
foreach ($this->socpeopleassigned as $id => $val) { foreach ($this->socpeopleassigned as $id => $val) {
if (!empty($already_inserted[$val['id']])) continue;
$sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
$sql .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)"; $sql .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)";
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
dol_syslog('Error to process socpeopleassigned: '.$this->db->lasterror(), LOG_ERR); dol_syslog('Error to process socpeopleassigned: ' . $this->db->lasterror(), LOG_ERR);
$this->errors[] = $this->db->lasterror(); $this->errors[] = $this->db->lasterror();
} else {
$already_inserted[$val['id']] = true;
} }
} }
} }
@ -1143,10 +1153,13 @@ class ActionComm extends CommonObject
$sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".$this->id." AND element_type = 'user'"; $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".$this->id." AND element_type = 'user'";
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
$already_inserted = array();
foreach ($this->userassigned as $key => $val) { foreach ($this->userassigned as $key => $val) {
if (!is_array($val)) { // For backward compatibility when val=id if (!is_array($val)) { // For backward compatibility when val=id
$val = array('id'=>$val); $val = array('id'=>$val);
} }
if (!empty($already_inserted[$val['id']])) continue;
$sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
$sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")"; $sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")";
@ -1154,6 +1167,8 @@ class ActionComm extends CommonObject
if (!$resql) { if (!$resql) {
$error++; $error++;
$this->errors[] = $this->db->lasterror(); $this->errors[] = $this->db->lasterror();
} else {
$already_inserted[$val['id']] = true;
} }
//var_dump($sql);exit; //var_dump($sql);exit;
} }
@ -1164,7 +1179,10 @@ class ActionComm extends CommonObject
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!empty($this->socpeopleassigned)) { if (!empty($this->socpeopleassigned)) {
$already_inserted = array();
foreach (array_keys($this->socpeopleassigned) as $id) { foreach (array_keys($this->socpeopleassigned) as $id) {
if (!empty($already_inserted[$val['id']])) continue;
$sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
$sql .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)"; $sql .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)";
@ -1172,6 +1190,8 @@ class ActionComm extends CommonObject
if (!$resql) { if (!$resql) {
$error++; $error++;
$this->errors[] = $this->db->lasterror(); $this->errors[] = $this->db->lasterror();
} else {
$already_inserted[$val['id']] = true;
} }
} }
} }

View File

@ -155,6 +155,10 @@ class Proposals extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->propal->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -158,6 +158,10 @@ class Orders extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->commande->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -165,6 +165,10 @@ class Invoices extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->facture->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -235,17 +235,26 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->tax->char
$object->label = $langs->trans("CopyOf").' '.$object->label; $object->label = $langs->trans("CopyOf").' '.$object->label;
} }
if (GETPOST('clone_for_next_month', 'int')) { if (GETPOST('clone_for_next_month', 'int')) { // This can be true only if TAX_ADD_CLONE_FOR_NEXT_MONTH_CHECKBOX has been set
$object->periode = dol_time_plus_duree($object->periode, 1, 'm'); $object->periode = dol_time_plus_duree($object->periode, 1, 'm');
$object->date_ech = dol_time_plus_duree($object->date_ech, 1, 'm'); $object->date_ech = dol_time_plus_duree($object->date_ech, 1, 'm');
} else { } else {
// Note dateech is often a little bit higher than dateperiod
$newdateperiod = dol_mktime(0, 0, 0, GETPOST('clone_periodmonth', 'int'), GETPOST('clone_periodday', 'int'), GETPOST('clone_periodyear', 'int')); $newdateperiod = dol_mktime(0, 0, 0, GETPOST('clone_periodmonth', 'int'), GETPOST('clone_periodday', 'int'), GETPOST('clone_periodyear', 'int'));
$newdateech = dol_mktime(0, 0, 0, GETPOST('clone_date_echmonth', 'int'), GETPOST('clone_date_echday', 'int'), GETPOST('clone_date_echyear', 'int')); $newdateech = dol_mktime(0, 0, 0, GETPOST('clone_date_echmonth', 'int'), GETPOST('clone_date_echday', 'int'), GETPOST('clone_date_echyear', 'int'));
if ($newdateperiod) { if ($newdateperiod) {
$object->periode = $newdateperiod; $object->periode = $newdateperiod;
if (empty($newdateech)) {
$object->date_ech = $object->periode;
}
} }
if ($newdateech) { if ($newdateech) {
$object->date_ech = $newdateech; $object->date_ech = $newdateech;
if (empty($newdateperiod)) {
// TODO We can here get dol_get_last_day of previous month:
// $object->periode = dol_get_last_day(year of $object->date_ech - 1m, month or $object->date_ech -1m)
$object->periode = $object->date_ech;
}
} }
} }
@ -410,9 +419,9 @@ if ($id > 0) {
// Clone confirmation // Clone confirmation
if ($action === 'clone') { if ($action === 'clone') {
$formquestion = array( $formquestion = array(
array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf").' '.$object->label), array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf").' '.$object->label, 'tdclass'=>'fieldrequired'),
); );
if (!empty($conf->global->TAX_ADD_CLON_FOR_NEXT_MONTH_CHECKBOX)) { if (!empty($conf->global->TAX_ADD_CLONE_FOR_NEXT_MONTH_CHECKBOX)) {
$formquestion[] = array('type' => 'checkbox', 'name' => 'clone_for_next_month', 'label' => $langs->trans("CloneTaxForNextMonth"), 'value' => 1); $formquestion[] = array('type' => 'checkbox', 'name' => 'clone_for_next_month', 'label' => $langs->trans("CloneTaxForNextMonth"), 'value' => 1);
} else { } else {
$formquestion[] = array('type' => 'date', 'name' => 'clone_date_ech', 'label' => $langs->trans("Date"), 'value' => -1); $formquestion[] = array('type' => 'date', 'name' => 'clone_date_ech', 'label' => $langs->trans("Date"), 'value' => -1);

View File

@ -197,7 +197,7 @@ class ChargeSociales extends CommonObject
{ {
$newamount = price2num($this->amount, 'MT'); $newamount = price2num($this->amount, 'MT');
// Validation parametres // Validation of parameters
if (!$newamount > 0 || empty($this->date_ech) || empty($this->periode)) { if (!$newamount > 0 || empty($this->date_ech) || empty($this->periode)) {
return false; return false;
} }

View File

@ -106,6 +106,10 @@ class Contracts extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->contrat->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -77,6 +77,7 @@ class box_external_rss extends ModeleBoxes
$this->max = $max; $this->max = $max;
// On recupere numero de param de la boite // On recupere numero de param de la boite
$reg = array();
preg_match('/^([0-9]+) /', $this->paramdef, $reg); preg_match('/^([0-9]+) /', $this->paramdef, $reg);
$site = $reg[1]; $site = $reg[1];

View File

@ -405,7 +405,7 @@ class SimpleOpenID
$url = $conf->global->MAIN_AUTHENTICATION_OPENID_URL; $url = $conf->global->MAIN_AUTHENTICATION_OPENID_URL;
} }
$response = getURLContent($url); $response = getURLContent($url, 'GET', '', 1, array(), array('http', 'https'));
list($servers, $delegates) = $this->HTML2OpenIDServer($response); list($servers, $delegates) = $this->HTML2OpenIDServer($response);
if (count($servers) == 0) { if (count($servers) == 0) {
@ -525,7 +525,7 @@ class SimpleOpenID
dol_syslog(get_class($this).'::sendDiscoveryRequestToGetXRDS get XRDS'); dol_syslog(get_class($this).'::sendDiscoveryRequestToGetXRDS get XRDS');
$addheaders = array('Accept: application/xrds+xml'); $addheaders = array('Accept: application/xrds+xml');
$response = getURLContent($url, 'GET', '', 1, $addheaders); $response = getURLContent($url, 'GET', '', 1, $addheaders, array('http', 'https'), 0);
/* response should like this: /* response should like this:
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)"> <xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">

View File

@ -392,7 +392,6 @@ class SMTPs
} else { } else {
if (function_exists('stream_socket_client') && !empty($this->_options)) { if (function_exists('stream_socket_client') && !empty($this->_options)) {
$socket_context = stream_context_create($this->_options); // An array of options for stream_context_create() $socket_context = stream_context_create($this->_options); // An array of options for stream_context_create()
set_error_handler([$this, 'errorHandler']);
$this->socket = @stream_socket_client( $this->socket = @stream_socket_client(
preg_replace('@tls://@i', '', $this->getHost()).// Host to 'hit', IP or domain preg_replace('@tls://@i', '', $this->getHost()).// Host to 'hit', IP or domain
':'.$this->getPort(), // which Port number to use ':'.$this->getPort(), // which Port number to use

View File

@ -190,6 +190,7 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation =
$info = curl_getinfo($ch); // Reading of request must be done after sending request $info = curl_getinfo($ch); // Reading of request must be done after sending request
$http_code = $info['http_code']; $http_code = $info['http_code'];
if ($followlocation && ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307)) { if ($followlocation && ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307)) {
$newUrl = $info['redirect_url']; $newUrl = $info['redirect_url'];
$maxRedirection--; $maxRedirection--;

View File

@ -30,6 +30,23 @@ $maxheightmini = 72; // 16/9eme
$quality = 80; $quality = 80;
/**
* Return if a filename is file name of a supported image format
*
* @param int $acceptsvg 0=Default (depends on setup), 1=Always accept SVG as image files
* @return string Return list fo image format
*/
function getListOfPossibleImageExt($acceptsvg = 0)
{
global $conf;
$regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php
if ($acceptsvg || !empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)) {
$regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript
}
return $regeximgext;
}
/** /**
* Return if a filename is file name of a supported image format * Return if a filename is file name of a supported image format
@ -40,12 +57,7 @@ $quality = 80;
*/ */
function image_format_supported($file, $acceptsvg = 0) function image_format_supported($file, $acceptsvg = 0)
{ {
global $conf; $regeximgext = getListOfPossibleImageExt();
$regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php
if ($acceptsvg || !empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)) {
$regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript
}
// Case filename is not a format image // Case filename is not a format image
$reg = array(); $reg = array();

View File

@ -534,7 +534,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
/** /**
* Check access by user to object. * Check access by user to object.
* This function is also called by restrictedArea * This function is also called by restrictedArea that check before if module is enabled and permissions of user compared to $action.
* *
* @param User $user User to check * @param User $user User to check
* @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...) * @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...)

View File

@ -1023,7 +1023,7 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify
if (empty($alreadygrabbed[$urltograbbis])) { if (empty($alreadygrabbed[$urltograbbis])) {
if ($grabimages) { if ($grabimages) {
$tmpgeturl = getURLContent($urltograbbis); $tmpgeturl = getURLContent($urltograbbis, 'GET', '', 1, array(), array('http', 'https'), 0);
if ($tmpgeturl['curl_error_no']) { if ($tmpgeturl['curl_error_no']) {
$error++; $error++;
setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors'); setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors');
@ -1094,7 +1094,7 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify
if (empty($alreadygrabbed[$urltograbbis])) { if (empty($alreadygrabbed[$urltograbbis])) {
if ($grabimages) { if ($grabimages) {
$tmpgeturl = getURLContent($urltograbbis); $tmpgeturl = getURLContent($urltograbbis, 'GET', '', 1, array(), array('http', 'https'), 0);
if ($tmpgeturl['curl_error_no']) { if ($tmpgeturl['curl_error_no']) {
$error++; $error++;
setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors'); setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors');

View File

@ -193,7 +193,7 @@ class ExportExcel2007 extends ModeleExports
$outputlangs->load("exports"); $outputlangs->load("exports");
require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/autoloader.php'; require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php'; require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
require_once PHPEXCELNEW_PATH.'Spreadsheet.php'; require_once PHPEXCELNEW_PATH.'Spreadsheet.php';

View File

@ -1025,7 +1025,11 @@ class pdf_crabe extends ModelePDFFactures
if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) { if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
$pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetFont('', 'B', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche, $posy); $pdf->SetXY($this->marge_gauche, $posy);
$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); if ($mysoc->forme_juridique_code == 92) {
$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0);
} else {
$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
}
$posy = $pdf->GetY() + 4; $posy = $pdf->GetY() + 4;
} }

View File

@ -112,9 +112,9 @@ class ImportXlsx extends ModeleImports
$this->picto = 'mime/xls'; // Picto (This is not used by the example file code as Mime type, too bad ...) $this->picto = 'mime/xls'; // Picto (This is not used by the example file code as Mime type, too bad ...)
$this->version = '1.0'; // Driver version $this->version = '1.0'; // Driver version
// If driver use an external library, put its name here // If driver use an external library, put its name here
require_once DOL_DOCUMENT_ROOT . '/includes/phpoffice/autoloader.php'; require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
require_once DOL_DOCUMENT_ROOT . '/includes/Psr/autoloader.php'; require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
require_once PHPEXCELNEW_PATH . 'Spreadsheet.php'; require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
$this->workbook = new Spreadsheet(); $this->workbook = new Spreadsheet();
//if ($this->id == 'excel2007new') //if ($this->id == 'excel2007new')

View File

@ -100,6 +100,7 @@ class modExternalRss extends DolibarrModules
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
while ($obj = $this->db->fetch_object($result)) { while ($obj = $this->db->fetch_object($result)) {
$reg = array();
if (preg_match('/EXTERNAL_RSS_TITLE_([0-9]+)/i', $obj->name, $reg)) { if (preg_match('/EXTERNAL_RSS_TITLE_([0-9]+)/i', $obj->name, $reg)) {
// Definie la boite si on a trouvee une ancienne configuration // Definie la boite si on a trouvee une ancienne configuration
//$this->boxes[$reg[1]][0] = "(ExternalRSSInformations)"; //$this->boxes[$reg[1]][0] = "(ExternalRSSInformations)";

View File

@ -182,6 +182,9 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
if ($object->element == 'mo') { if ($object->element == 'mo') {
$permok = $user->rights->mrp->write; $permok = $user->rights->mrp->write;
} }
if ($object->element == 'contact') {
$permok = $user->rights->societe->contact->creer;
}
$isdraft = ((isset($object->statut) && $object->statut == 0) || (isset($object->status) && $object->status == 0)); $isdraft = ((isset($object->statut) && $object->statut == 0) || (isset($object->status) && $object->status == 0));
if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$tmpkeyextra])) if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$tmpkeyextra]))

View File

@ -103,6 +103,10 @@ class Donations extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->don->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
@ -179,6 +183,7 @@ class Donations extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->don->creer) { if (!DolibarrApiAccess::$user->rights->don->creer) {
throw new RestException(401, "Insuffisant rights"); throw new RestException(401, "Insuffisant rights");
} }
// Check mandatory fields // Check mandatory fields
$result = $this->_validate($request_data); $result = $this->_validate($request_data);
@ -247,6 +252,7 @@ class Donations extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->don->supprimer) { if (!DolibarrApiAccess::$user->rights->don->supprimer) {
throw new RestException(401); throw new RestException(401);
} }
$result = $this->don->fetch($id); $result = $this->don->fetch($id);
if (!$result) { if (!$result) {
throw new RestException(404, 'Donation not found'); throw new RestException(404, 'Donation not found');
@ -295,6 +301,7 @@ class Donations extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->don->creer) { if (!DolibarrApiAccess::$user->rights->don->creer) {
throw new RestException(401); throw new RestException(401);
} }
$result = $this->don->fetch($id); $result = $this->don->fetch($id);
if (!$result) { if (!$result) {
throw new RestException(404, 'Donation not found'); throw new RestException(404, 'Donation not found');

View File

@ -103,6 +103,10 @@ class Shipments extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->expedition->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -99,6 +99,10 @@ class ExpenseReports extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->expensereport->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $societe param is ignored and replaced by user's socid // case of external user, $societe param is ignored and replaced by user's socid
@ -164,6 +168,7 @@ class ExpenseReports extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->expensereport->creer) { if (!DolibarrApiAccess::$user->rights->expensereport->creer) {
throw new RestException(401, "Insuffisant rights"); throw new RestException(401, "Insuffisant rights");
} }
// Check mandatory fields // Check mandatory fields
$result = $this->_validate($request_data); $result = $this->_validate($request_data);
@ -427,6 +432,7 @@ class ExpenseReports extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->expensereport->supprimer) { if (!DolibarrApiAccess::$user->rights->expensereport->supprimer) {
throw new RestException(401); throw new RestException(401);
} }
$result = $this->expensereport->fetch($id); $result = $this->expensereport->fetch($id);
if (!$result) { if (!$result) {
throw new RestException(404, 'Expense Report not found'); throw new RestException(404, 'Expense Report not found');
@ -469,6 +475,7 @@ class ExpenseReports extends DolibarrApi
if(! DolibarrApiAccess::$user->rights->expensereport->creer) { if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
throw new RestException(401); throw new RestException(401);
} }
$result = $this->expensereport->fetch($id); $result = $this->expensereport->fetch($id);
if( ! $result ) { if( ! $result ) {
throw new RestException(404, 'expensereport not found'); throw new RestException(404, 'expensereport not found');

View File

@ -110,6 +110,10 @@ class Interventions extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->ficheinter->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -298,7 +298,7 @@ if (!defined('NUSOAP_PATH')) {
define('NUSOAP_PATH', (!isset($dolibarr_lib_NUSOAP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/nusoap/lib/' : (empty($dolibarr_lib_NUSOAP_PATH) ? '' : $dolibarr_lib_NUSOAP_PATH.'/')); define('NUSOAP_PATH', (!isset($dolibarr_lib_NUSOAP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/nusoap/lib/' : (empty($dolibarr_lib_NUSOAP_PATH) ? '' : $dolibarr_lib_NUSOAP_PATH.'/'));
} }
if (!defined('PHPEXCELNEW_PATH')) { if (!defined('PHPEXCELNEW_PATH')) {
define('PHPEXCELNEW_PATH', (!isset($dolibarr_lib_PHPEXCELNEW_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/phpoffice/PhpSpreadsheet/' : (empty($dolibarr_lib_PHPEXCELNEW_PATH) ? '' : $dolibarr_lib_PHPEXCELNEW_PATH.'/')); define('PHPEXCELNEW_PATH', (!isset($dolibarr_lib_PHPEXCELNEW_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/PhpSpreadsheet/' : (empty($dolibarr_lib_PHPEXCELNEW_PATH) ? '' : $dolibarr_lib_PHPEXCELNEW_PATH.'/'));
} }
if (!defined('ODTPHP_PATH')) { if (!defined('ODTPHP_PATH')) {
define('ODTPHP_PATH', (!isset($dolibarr_lib_ODTPHP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/odtphp/' : (empty($dolibarr_lib_ODTPHP_PATH) ? '' : $dolibarr_lib_ODTPHP_PATH.'/')); define('ODTPHP_PATH', (!isset($dolibarr_lib_ODTPHP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/odtphp/' : (empty($dolibarr_lib_ODTPHP_PATH) ? '' : $dolibarr_lib_ODTPHP_PATH.'/'));

View File

@ -102,6 +102,10 @@ class SupplierInvoices extends DolibarrApi
{ {
global $db; global $db;
if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -101,6 +101,10 @@ class SupplierOrders extends DolibarrApi
{ {
global $db, $conf; global $db, $conf;
if (!DolibarrApiAccess::$user->rights->fournisseur->commande->lire) {
throw new RestException(401);
}
$obj_ret = array(); $obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid // case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -634,9 +634,10 @@ class ProductFournisseur extends Product
* @param string $sortorder Sort order * @param string $sortorder Sort order
* @param int $limit Limit * @param int $limit Limit
* @param int $offset Offset * @param int $offset Offset
* @param int $socid Filter on a third party id
* @return array Array of Products with new properties to define supplier price * @return array Array of Products with new properties to define supplier price
*/ */
public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0) public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0, $socid = 0)
{ {
// phpcs:enable // phpcs:enable
global $conf; global $conf;
@ -652,7 +653,8 @@ class ProductFournisseur extends Product
$sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."societe as s"; $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")"; $sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")";
$sql .= " AND pfp.fk_soc = s.rowid AND pfp.fk_product = p.rowid"; $sql .= " AND pfp.fk_soc = s.rowid AND pfp.fk_product = p.rowid";
$sql .= " AND s.status=1"; // only enabled company selected $sql .= ($socid > 0 ? ' AND pfp.fk_soc = '.((int) $socid) : '');
$sql .= " AND s.status = 1"; // only enabled company selected
$sql .= " AND pfp.fk_product = ".((int) $prodid); $sql .= " AND pfp.fk_product = ".((int) $prodid);
if (empty($sortfield)) { if (empty($sortfield)) {
$sql .= " ORDER BY s.nom, pfp.quantity, pfp.price"; $sql .= " ORDER BY s.nom, pfp.quantity, pfp.price";

View File

@ -0,0 +1 @@

View File

@ -492,12 +492,16 @@ if ($step == 2 && $datatoimport) {
print '<input type="hidden" name="token" value="'.newToken().'">'; print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="max_file_size" value="'.$conf->maxfilesize.'">'; print '<input type="hidden" name="max_file_size" value="'.$conf->maxfilesize.'">';
print '<br>';
print '<span class="opacitymedium">'; print '<span class="opacitymedium">';
$s = $langs->trans("ChooseFormatOfFileToImport", '{s1}'); $s = $langs->trans("ChooseFormatOfFileToImport", '{s1}');
$s = str_replace('{s1}', img_picto('', 'next'), $s); $s = str_replace('{s1}', img_picto('', 'next'), $s);
print $s; print $s;
print '</span><br><br>'; print '</span><br><br>';
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 '<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" width="100%" cellspacing="0" cellpadding="4">'; print '<table class="noborder" width="100%" cellspacing="0" cellpadding="4">';
@ -513,7 +517,9 @@ if ($step == 2 && $datatoimport) {
print '<td width="16">'.img_picto_common($key, $objmodelimport->getPictoForKey($key)).'</td>'; print '<td width="16">'.img_picto_common($key, $objmodelimport->getPictoForKey($key)).'</td>';
$text = $objmodelimport->getDriverDescForKey($key); $text = $objmodelimport->getDriverDescForKey($key);
print '<td>'.$form->textwithpicto($objmodelimport->getDriverLabelForKey($key), $text).'</td>'; print '<td>'.$form->textwithpicto($objmodelimport->getDriverLabelForKey($key), $text).'</td>';
print '<td style="text-align:center"><a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a></td>'; print '<td style="text-align:center">';
print img_picto('', 'download', 'class="paddingright opacitymedium"').'<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>';
print '</td>';
// Action button // Action button
print '<td style="text-align:right">'; print '<td style="text-align:right">';
print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=3&format='.$key.$param.'">'.img_picto($langs->trans("SelectFormat"), 'next', 'class="fa-15x"').'</a>'; print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=3&format='.$key.$param.'">'.img_picto($langs->trans("SelectFormat"), 'next', 'class="fa-15x"').'</a>';
@ -587,7 +593,7 @@ if ($step == 3 && $datatoimport) {
print '</table>'; print '</table>';
print '</div>'; print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">'; print '<div class="fichecenter">';
@ -598,8 +604,8 @@ if ($step == 3 && $datatoimport) {
print '<td>'; print '<td>';
$text = $objmodelimport->getDriverDescForKey($format); $text = $objmodelimport->getDriverDescForKey($format);
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text); print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
print '</td><td style="text-align:right" class="nowrap"><a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>'; print '</td><td style="text-align:right" class="nowrap">';
print img_picto('', 'download', 'class="paddingright opacitymedium"').'<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>';
print '</td></tr>'; print '</td></tr>';
print '</table>'; print '</table>';
@ -890,7 +896,7 @@ if ($step == 4 && $datatoimport) {
print '</table>'; print '</table>';
print '</div>'; print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">'; print '<div class="fichecenter">';
@ -1374,7 +1380,7 @@ if ($step == 5 && $datatoimport) {
print '</table>'; print '</table>';
print '</div>'; print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">'; print '<div class="fichecenter">';
@ -1468,7 +1474,7 @@ if ($step == 5 && $datatoimport) {
print '</div>'; print '</div>';
print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', ''); print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', 'file-import');
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">'; print '<div class="fichecenter">';
@ -1812,7 +1818,7 @@ if ($step == 6 && $datatoimport) {
print '</table>'; print '</table>';
print '</div>'; print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">'; print '<div class="fichecenter">';
@ -1875,8 +1881,7 @@ if ($step == 6 && $datatoimport) {
print '<b>'.$langs->trans("InformationOnTargetTables").'</b>'; print '<b>'.$langs->trans("InformationOnTargetTables").'</b>';
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">'; print '<div class="fichecenter">';
print '<table width="100%" class="border">'; print '<table class="border centpercent">';
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnTargetTables").'</b></td></tr>';
// Tables imported // Tables imported
print '<tr><td width="25%">'; print '<tr><td width="25%">';

View File

@ -1,31 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Reader;
interface IReader
{
/**
* IReader constructor.
*/
public function __construct();
/**
* Can the current IReader read the file?
*
* @param string $pFilename
*
* @return bool
*/
public function canRead($pFilename);
/**
* Loads PhpSpreadsheet from file.
*
* @param string $pFilename
*
* @throws Exception
*
* @return \PhpOffice\PhpSpreadsheet\Spreadsheet
*/
public function load($pFilename);
}

View File

@ -1,24 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Writer;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
interface IWriter
{
/**
* IWriter constructor.
*
* @param Spreadsheet $spreadsheet
*/
public function __construct(Spreadsheet $spreadsheet);
/**
* Save PhpSpreadsheet to file.
*
* @param string $pFilename Name of the file to save
*
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public function save($pFilename);
}

View File

@ -117,7 +117,7 @@ class Calculation
/** /**
* An array of the nested cell references accessed by the calculation engine, used for the debug log. * An array of the nested cell references accessed by the calculation engine, used for the debug log.
* *
* @var array of string * @var CyclicReferenceStack
*/ */
private $cyclicReferenceStack; private $cyclicReferenceStack;
@ -1945,6 +1945,11 @@ class Calculation
'functionCall' => [MathTrig::class, 'SUMXMY2'], 'functionCall' => [MathTrig::class, 'SUMXMY2'],
'argumentCount' => '2', 'argumentCount' => '2',
], ],
'SWITCH' => [
'category' => Category::CATEGORY_LOGICAL,
'functionCall' => [Logical::class, 'statementSwitch'],
'argumentCount' => '3+',
],
'SYD' => [ 'SYD' => [
'category' => Category::CATEGORY_FINANCIAL, 'category' => Category::CATEGORY_FINANCIAL,
'functionCall' => [Financial::class, 'SYD'], 'functionCall' => [Financial::class, 'SYD'],
@ -2207,8 +2212,8 @@ class Calculation
private static function loadLocales() private static function loadLocales()
{ {
$localeFileDirectory = __DIR__ . '/locale/'; $localeFileDirectory = __DIR__ . '/locale/';
foreach (glob($localeFileDirectory . '/*', GLOB_ONLYDIR) as $filename) { foreach (glob($localeFileDirectory . '*', GLOB_ONLYDIR) as $filename) {
$filename = substr($filename, strlen($localeFileDirectory) + 1); $filename = substr($filename, strlen($localeFileDirectory));
if ($filename != 'en') { if ($filename != 'en') {
self::$validLocaleLanguages[] = $filename; self::$validLocaleLanguages[] = $filename;
} }
@ -2413,7 +2418,6 @@ class Calculation
if (strpos($locale, '_') !== false) { if (strpos($locale, '_') !== false) {
list($language) = explode('_', $locale); list($language) = explode('_', $locale);
} }
if (count(self::$validLocaleLanguages) == 1) { if (count(self::$validLocaleLanguages) == 1) {
self::loadLocales(); self::loadLocales();
} }
@ -2704,7 +2708,7 @@ class Calculation
* @param Cell $pCell Cell to calculate * @param Cell $pCell Cell to calculate
* @param bool $resetLog Flag indicating whether the debug log should be reset or not * @param bool $resetLog Flag indicating whether the debug log should be reset or not
* *
* @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception
* *
* @return mixed * @return mixed
*/ */
@ -2808,7 +2812,7 @@ class Calculation
* @param string $cellID Address of the cell to calculate * @param string $cellID Address of the cell to calculate
* @param Cell $pCell Cell to calculate * @param Cell $pCell Cell to calculate
* *
* @throws Exception * @throws \PhpOffice\PhpSpreadsheet\Exception
* *
* @return mixed * @return mixed
*/ */
@ -2892,6 +2896,15 @@ class Calculation
{ {
$cellValue = null; $cellValue = null;
// Quote-Prefixed cell values cannot be formulae, but are treated as strings
if ($pCell !== null && $pCell->getStyle()->getQuotePrefix() === true) {
return self::wrapResult((string) $formula);
}
if (preg_match('/^=\s*cmd\s*\|/miu', $formula) !== 0) {
return self::wrapResult($formula);
}
// Basic validation that this is indeed a formula // Basic validation that this is indeed a formula
// We simply return the cell value if not // We simply return the cell value if not
$formula = trim($formula); $formula = trim($formula);

View File

@ -273,6 +273,60 @@ class Logical
return ($condition) ? $returnIfTrue : $returnIfFalse; return ($condition) ? $returnIfTrue : $returnIfFalse;
} }
/**
* STATEMENT_SWITCH.
*
* Returns corresponding with first match (any data type such as a string, numeric, date, etc).
*
* Excel Function:
* =SWITCH (expression, value1, result1, value2, result2, ... value_n, result_n [, default])
*
* Expression
* The expression to compare to a list of values.
* value1, value2, ... value_n
* A list of values that are compared to expression. The SWITCH function is looking for the first value that matches the expression.
* result1, result2, ... result_n
* A list of results. The SWITCH function returns the corresponding result when a value matches expression.
* default
* Optional. It is the default to return if expression does not match any of the values (value1, value2, ... value_n).
*
* @category Logical Functions
*
* @param mixed $arguments Statement arguments
*
* @return mixed The value of matched expression
*/
public static function statementSwitch(...$arguments)
{
$result = Functions::VALUE();
if (count($arguments) > 0) {
$targetValue = Functions::flattenSingleValue($arguments[0]);
$argc = count($arguments) - 1;
$switchCount = floor($argc / 2);
$switchSatisfied = false;
$hasDefaultClause = $argc % 2 !== 0;
$defaultClause = $argc % 2 === 0 ? null : $arguments[count($arguments) - 1];
if ($switchCount) {
for ($index = 0; $index < $switchCount; ++$index) {
if ($targetValue == $arguments[$index * 2 + 1]) {
$result = $arguments[$index * 2 + 2];
$switchSatisfied = true;
break;
}
}
}
if (!$switchSatisfied) {
$result = $hasDefaultClause ? $defaultClause : Functions::NA();
}
}
return $result;
}
/** /**
* IFERROR. * IFERROR.
* *

View File

@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class LookupRef class LookupRef
@ -473,8 +474,9 @@ class LookupRef
$lookupValue = Functions::flattenSingleValue($lookupValue); $lookupValue = Functions::flattenSingleValue($lookupValue);
$matchType = ($matchType === null) ? 1 : (int) Functions::flattenSingleValue($matchType); $matchType = ($matchType === null) ? 1 : (int) Functions::flattenSingleValue($matchType);
$initialLookupValue = $lookupValue;
// MATCH is not case sensitive // MATCH is not case sensitive
$lookupValue = strtolower($lookupValue); $lookupValue = StringHelper::strToLower($lookupValue);
// Lookup_value type has to be number, text, or logical values // Lookup_value type has to be number, text, or logical values
if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) { if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) {
@ -502,7 +504,7 @@ class LookupRef
} }
// Convert strings to lowercase for case-insensitive testing // Convert strings to lowercase for case-insensitive testing
if (is_string($lookupArrayValue)) { if (is_string($lookupArrayValue)) {
$lookupArray[$i] = strtolower($lookupArrayValue); $lookupArray[$i] = StringHelper::strToLower($lookupArrayValue);
} }
if (($lookupArrayValue === null) && (($matchType == 1) || ($matchType == -1))) { if (($lookupArrayValue === null) && (($matchType == 1) || ($matchType == -1))) {
$lookupArray = array_slice($lookupArray, 0, $i - 1); $lookupArray = array_slice($lookupArray, 0, $i - 1);
@ -522,9 +524,13 @@ class LookupRef
if ($matchType == 0 || $matchType == 1) { if ($matchType == 0 || $matchType == 1) {
foreach ($lookupArray as $i => $lookupArrayValue) { foreach ($lookupArray as $i => $lookupArrayValue) {
if (($matchType == 0) && ($lookupArrayValue == $lookupValue)) { $onlyNumeric = is_numeric($lookupArrayValue) && is_numeric($lookupValue);
$onlyNumericExactMatch = $onlyNumeric && $lookupArrayValue == $lookupValue;
$nonOnlyNumericExactMatch = !$onlyNumeric && $lookupArrayValue === $lookupValue;
$exactMatch = $onlyNumericExactMatch || $nonOnlyNumericExactMatch;
if (($matchType == 0) && $exactMatch) {
// exact match // exact match
return ++$i; return $i + 1;
} elseif (($matchType == 1) && ($lookupArrayValue <= $lookupValue)) { } elseif (($matchType == 1) && ($lookupArrayValue <= $lookupValue)) {
$i = array_search($i, $keySet); $i = array_search($i, $keySet);
@ -661,7 +667,9 @@ class LookupRef
{ {
reset($a); reset($a);
$firstColumn = key($a); $firstColumn = key($a);
if (($aLower = strtolower($a[$firstColumn])) == ($bLower = strtolower($b[$firstColumn]))) { $aLower = StringHelper::strToLower($a[$firstColumn]);
$bLower = StringHelper::strToLower($b[$firstColumn]);
if ($aLower == $bLower) {
return 0; return 0;
} }
@ -707,11 +715,14 @@ class LookupRef
uasort($lookup_array, ['self', 'vlookupSort']); uasort($lookup_array, ['self', 'vlookupSort']);
} }
$lookupLower = StringHelper::strToLower($lookup_value);
$rowNumber = $rowValue = false; $rowNumber = $rowValue = false;
foreach ($lookup_array as $rowKey => $rowData) { foreach ($lookup_array as $rowKey => $rowData) {
$firstLower = StringHelper::strToLower($rowData[$firstColumn]);
// break if we have passed possible keys // break if we have passed possible keys
if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) ||
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && ($firstLower > $lookupLower))) {
break; break;
} }
// remember the last key, but only if datatypes match // remember the last key, but only if datatypes match
@ -719,17 +730,15 @@ class LookupRef
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]))) { (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]))) {
if ($not_exact_match) { if ($not_exact_match) {
$rowNumber = $rowKey; $rowNumber = $rowKey;
$rowValue = $rowData[$firstColumn];
continue; continue;
} elseif ((strtolower($rowData[$firstColumn]) == strtolower($lookup_value)) } elseif (($firstLower == $lookupLower)
// Spreadsheets software returns first exact match, // Spreadsheets software returns first exact match,
// we have sorted and we might have broken key orders // we have sorted and we might have broken key orders
// we want the first one (by its initial index) // we want the first one (by its initial index)
&& (($rowNumber == false) || ($rowKey < $rowNumber)) && (($rowNumber == false) || ($rowKey < $rowNumber))
) { ) {
$rowNumber = $rowKey; $rowNumber = $rowKey;
$rowValue = $rowData[$firstColumn];
} }
} }
} }
@ -782,8 +791,11 @@ class LookupRef
// break if we have passed possible keys // break if we have passed possible keys
$bothNumeric = is_numeric($lookup_value) && is_numeric($rowData); $bothNumeric = is_numeric($lookup_value) && is_numeric($rowData);
$bothNotNumeric = !is_numeric($lookup_value) && !is_numeric($rowData); $bothNotNumeric = !is_numeric($lookup_value) && !is_numeric($rowData);
$lookupLower = StringHelper::strToLower($lookup_value);
$rowDataLower = StringHelper::strToLower($rowData);
if (($bothNumeric && $rowData > $lookup_value) || if (($bothNumeric && $rowData > $lookup_value) ||
($bothNotNumeric && strtolower($rowData) > strtolower($lookup_value))) { ($bothNotNumeric && $rowDataLower > $lookupLower)) {
break; break;
} }
@ -793,7 +805,7 @@ class LookupRef
$rowNumber = $rowKey; $rowNumber = $rowKey;
continue; continue;
} elseif (strtolower($rowData) === strtolower($lookup_value) } elseif ($rowDataLower === $lookupLower
&& ($rowNumber === null || $rowKey < $rowNumber) && ($rowNumber === null || $rowKey < $rowNumber)
) { ) {
$rowNumber = $rowKey; $rowNumber = $rowKey;

View File

@ -1224,11 +1224,12 @@ class MathTrig
} }
$testCondition = '=' . $arg . $condition; $testCondition = '=' . $arg . $condition;
$sumValue = array_key_exists($key, $sumArgs) ? $sumArgs[$key] : 0;
if (is_numeric($sumArgs[$key]) && if (is_numeric($sumValue) &&
Calculation::getInstance()->_calculateFormulaValue($testCondition)) { Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
// Is it a value within our criteria and only numeric can be added to the result // Is it a value within our criteria and only numeric can be added to the result
$returnValue += $sumArgs[$key]; $returnValue += $sumValue;
} }
} }

View File

@ -337,6 +337,7 @@ SUMSQ
SUMX2MY2 SUMX2MY2
SUMX2PY2 SUMX2PY2
SUMXMY2 SUMXMY2
SWITCH
SYD SYD
T T
TAN TAN

Some files were not shown because too many files have changed in this diff Show More