mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2026-02-08 00:52:01 +01:00
Merge branch 'develop' into dolibarr_partnership
This commit is contained in:
15
.gitattributes
vendored
15
.gitattributes
vendored
@@ -11,12 +11,14 @@
|
||||
*.htm text eol=lf
|
||||
*.html text eol=lf
|
||||
*.js text eol=lf
|
||||
*.json text eol=lf
|
||||
*.css text eol=lf
|
||||
*.lang text eol=lf
|
||||
*.txt text eol=lf
|
||||
*.md text eol=lf
|
||||
*.pp text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.yaml text eol=lf
|
||||
*.conf text eol=lf
|
||||
|
||||
@@ -24,15 +26,16 @@
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.bmp binary
|
||||
*.ico binary
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.odt binary
|
||||
*.odf binary
|
||||
*.frm binary
|
||||
*.ico binary
|
||||
*.jpeg binary
|
||||
*.jpg binary
|
||||
*.MYD binary
|
||||
*.MYI binary
|
||||
*.odf binary
|
||||
*.odt binary
|
||||
*.png binary
|
||||
|
||||
|
||||
# Export ignores to generate clean production tarballs
|
||||
/build export-ignore
|
||||
|
||||
@@ -23,7 +23,7 @@ PEAR Mail_MIME 1.8.9 BSD Yes
|
||||
ParseDown 1.6 MIT License Yes Markdown parser
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"ckeditor/ckeditor" : "4.12.1",
|
||||
"mike42/escpos-php" : "2.2",
|
||||
"mobiledetect/mobiledetectlib" : "2.8.34",
|
||||
"phpoffice/phpexcel" : "1.8.2",
|
||||
"restler/framework" : "3.0.0-RC6",
|
||||
"tecnickcom/tcpdf" : "6.3.2",
|
||||
"nnnick/chartjs" : "^2.9",
|
||||
|
||||
57
composer.lock
generated
57
composer.lock
generated
@@ -328,6 +328,63 @@
|
||||
},
|
||||
"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",
|
||||
"version": "3.0.0-RC6",
|
||||
|
||||
@@ -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 =
|
||||
@@ -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 =
|
||||
28
dev/setup/fail2ban/jail.local
Normal file
28
dev/setup/fail2ban/jail.local
Normal 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
|
||||
|
||||
@@ -200,7 +200,7 @@ class BookKeeping extends CommonObject
|
||||
|
||||
$error = 0;
|
||||
|
||||
// Clean parameters
|
||||
// Clean parameters</center>
|
||||
if (isset($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 .= " AND fk_doc = ".$this->fk_doc;
|
||||
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 numero_compte = '".$this->db->escape($this->numero_compte)."'";
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
* Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org>
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -33,6 +34,7 @@
|
||||
require '../../main.inc.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.'/adherents/class/adherent_type.class.php';
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array("admin", "members"));
|
||||
@@ -101,11 +103,12 @@ if ($action == 'set_default') {
|
||||
}
|
||||
} elseif ($action == 'updateall') {
|
||||
$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);
|
||||
$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);
|
||||
$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
|
||||
if ($conf->facture->enabled) {
|
||||
$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 "</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
|
||||
print '<tr class="oddeven"><td>'.$langs->trans("MoreActionsOnSubscription").'</td>';
|
||||
$arraychoices = array('0'=>$langs->trans("None"));
|
||||
|
||||
@@ -177,7 +177,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
|
||||
print $langs->trans("ForceMemberType");
|
||||
print '</td><td class="right">';
|
||||
$listofval = array();
|
||||
$listofval += $adht->liste_array();
|
||||
$listofval += $adht->liste_array(1);
|
||||
$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 "</td></tr>\n";
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Copyright (C) 2018-2019 Thibault FOUCART <support@ptibogxiv.net>
|
||||
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
|
||||
* 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
|
||||
* 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_banque Name of bank of cheque
|
||||
* @param int $datesubend Date end subscription
|
||||
* @param int $fk_type Member type id
|
||||
* @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;
|
||||
|
||||
@@ -1523,6 +1524,7 @@ class Adherent extends CommonObject
|
||||
$subscription->amount = $amount;
|
||||
$subscription->note = $label; // deprecated
|
||||
$subscription->note_public = $label;
|
||||
$subscription->fk_type = $fk_type;
|
||||
|
||||
$rowid = $subscription->create($user);
|
||||
if ($rowid > 0) {
|
||||
|
||||
@@ -60,6 +60,7 @@ $arrayofparameters = array(
|
||||
'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_ATTENDES'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
|
||||
'EVENTORGANIZATION_SECUREKEY'=>array('type'=>'securekey', 'enabled'=>1),
|
||||
);
|
||||
|
||||
$error = 0;
|
||||
@@ -74,6 +75,7 @@ if ((float) DOL_VERSION >= 6) {
|
||||
include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
|
||||
}
|
||||
|
||||
|
||||
if ($action == 'updateMask') {
|
||||
$maskconstorder = GETPOST('maskconstorder', '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
|
||||
echo '<span class="opacitymedium">'.$langs->trans("EventOrganizationSetupPage").'</span><br><br>';
|
||||
|
||||
|
||||
if ($action == 'edit') {
|
||||
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
||||
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>';
|
||||
|
||||
foreach ($arrayofparameters as $constname => $val) {
|
||||
if ($val['enabled']==1) {
|
||||
$setupnotempty++;
|
||||
print '<tr class="oddeven"><td>';
|
||||
$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 '</td><td>';
|
||||
if ($val['enabled']==1) {
|
||||
$setupnotempty++;
|
||||
print '<tr class="oddeven"><td>';
|
||||
$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 '</td><td>';
|
||||
|
||||
if ($val['type'] == 'textarea') {
|
||||
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';
|
||||
$formcompany = new FormCompany($db);
|
||||
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 ' '.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 {
|
||||
print '<input name="'.$constname.'" class="flat '.(empty($val['css']) ? 'minwidth200' : $val['css']).'" value="'.$conf->global->{$constname}.'">';
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
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 (version_compare($newversion['content'], $versiontrans) > 0) {
|
||||
print " <span class='butAction' title='".$langs->trans('LastStableVersion')."'>".$newversion['content']."</span>";
|
||||
|
||||
@@ -78,10 +78,10 @@ print '<br>';
|
||||
$file_list = array('missing' => array(), 'updated' => array());
|
||||
|
||||
// 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);
|
||||
$xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile;
|
||||
$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.'/install/'.$xmlshortfile;
|
||||
// Remote file to compare to
|
||||
$xmlremote = GETPOST('xmlremote');
|
||||
$xmlremote = GETPOST('xmlremote', 'alphanohtml');
|
||||
if (empty($xmlremote) && !empty($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)) {
|
||||
$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
|
||||
$enableremotecheck = true;
|
||||
@@ -147,12 +151,12 @@ if (GETPOST('target') == 'local') {
|
||||
}
|
||||
$xml = simplexml_load_file($xmlfile);
|
||||
} else {
|
||||
print $langs->trans('XmlNotFound').': '.$xmlfile;
|
||||
print '<div class="warning">'.$langs->trans('XmlNotFound').': '.$xmlfile.'</span>';
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
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...)
|
||||
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') {
|
||||
|
||||
@@ -58,7 +58,11 @@ class Login
|
||||
{
|
||||
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
|
||||
if (empty($dolibarr_main_authentication)) {
|
||||
@@ -87,7 +91,7 @@ class Login
|
||||
}
|
||||
|
||||
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)) {
|
||||
throw new RestException(403, 'Access denied');
|
||||
}
|
||||
|
||||
@@ -1647,8 +1647,8 @@ class Setup extends DolibarrApi
|
||||
$file_list = array('missing' => array(), 'updated' => array());
|
||||
|
||||
// Local file to compare to
|
||||
$xmlshortfile = GETPOST('xmlshortfile') ?GETPOST('xmlshortfile') : '/install/filelist-'.DOL_VERSION.'.xml';
|
||||
$xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile;
|
||||
$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.'/install/'.$xmlshortfile;
|
||||
// Remote file to compare to
|
||||
$xmlremote = ($target == 'default' ? '' : $target);
|
||||
if (empty($xmlremote) && !empty($conf->global->MAIN_FILECHECK_URL)) {
|
||||
@@ -1661,6 +1661,10 @@ class Setup extends DolibarrApi
|
||||
if (empty($xmlremote)) {
|
||||
$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 (dol_is_file($xmlfile)) {
|
||||
@@ -1669,7 +1673,7 @@ class Setup extends DolibarrApi
|
||||
throw new RestException(500, $langs->trans('XmlNotFound').': '.$xmlfile);
|
||||
}
|
||||
} 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...)
|
||||
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') {
|
||||
|
||||
@@ -99,6 +99,10 @@ class Boms extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->bom->read) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
$tmpobject = new BOM($this->db);
|
||||
|
||||
|
||||
@@ -579,20 +579,25 @@ class ActionComm extends CommonObject
|
||||
// Now insert assigned users
|
||||
if (!$error) {
|
||||
//dol_syslog(var_export($this->userassigned, true));
|
||||
$already_inserted = array();
|
||||
foreach ($this->userassigned as $key => $val) {
|
||||
if (!is_array($val)) { // For backward compatibility when val=id
|
||||
$val = array('id'=>$val);
|
||||
}
|
||||
|
||||
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 .= " 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);
|
||||
if (!$resql) {
|
||||
$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();
|
||||
} else {
|
||||
$already_inserted[$val['id']] = true;
|
||||
}
|
||||
//var_dump($sql);exit;
|
||||
}
|
||||
@@ -601,15 +606,20 @@ class ActionComm extends CommonObject
|
||||
|
||||
if (!$error) {
|
||||
if (!empty($this->socpeopleassigned)) {
|
||||
$already_inserted = array();
|
||||
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 .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)";
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
if (!$resql) {
|
||||
$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();
|
||||
} 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'";
|
||||
$resql = $this->db->query($sql);
|
||||
|
||||
$already_inserted = array();
|
||||
foreach ($this->userassigned as $key => $val) {
|
||||
if (!is_array($val)) { // For backward compatibility when val=id
|
||||
$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 .= " 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) {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror();
|
||||
} else {
|
||||
$already_inserted[$val['id']] = true;
|
||||
}
|
||||
//var_dump($sql);exit;
|
||||
}
|
||||
@@ -1164,7 +1179,10 @@ class ActionComm extends CommonObject
|
||||
$resql = $this->db->query($sql);
|
||||
|
||||
if (!empty($this->socpeopleassigned)) {
|
||||
$already_inserted = array();
|
||||
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 .= " VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)";
|
||||
|
||||
@@ -1172,6 +1190,8 @@ class ActionComm extends CommonObject
|
||||
if (!$resql) {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror();
|
||||
} else {
|
||||
$already_inserted[$val['id']] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,10 @@ class Proposals extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->propal->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -158,6 +158,10 @@ class Orders extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->commande->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -165,6 +165,10 @@ class Invoices extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->facture->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -235,17 +235,26 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->tax->char
|
||||
$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->date_ech = dol_time_plus_duree($object->date_ech, 1, 'm');
|
||||
} 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'));
|
||||
$newdateech = dol_mktime(0, 0, 0, GETPOST('clone_date_echmonth', 'int'), GETPOST('clone_date_echday', 'int'), GETPOST('clone_date_echyear', 'int'));
|
||||
if ($newdateperiod) {
|
||||
$object->periode = $newdateperiod;
|
||||
if (empty($newdateech)) {
|
||||
$object->date_ech = $object->periode;
|
||||
}
|
||||
}
|
||||
if ($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
|
||||
if ($action === 'clone') {
|
||||
$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);
|
||||
} else {
|
||||
$formquestion[] = array('type' => 'date', 'name' => 'clone_date_ech', 'label' => $langs->trans("Date"), 'value' => -1);
|
||||
|
||||
@@ -197,7 +197,7 @@ class ChargeSociales extends CommonObject
|
||||
{
|
||||
$newamount = price2num($this->amount, 'MT');
|
||||
|
||||
// Validation parametres
|
||||
// Validation of parameters
|
||||
if (!$newamount > 0 || empty($this->date_ech) || empty($this->periode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,10 @@ class Contracts extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->contrat->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -77,6 +77,7 @@ class box_external_rss extends ModeleBoxes
|
||||
$this->max = $max;
|
||||
|
||||
// On recupere numero de param de la boite
|
||||
$reg = array();
|
||||
preg_match('/^([0-9]+) /', $this->paramdef, $reg);
|
||||
$site = $reg[1];
|
||||
|
||||
|
||||
@@ -405,7 +405,7 @@ class SimpleOpenID
|
||||
$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);
|
||||
if (count($servers) == 0) {
|
||||
@@ -525,7 +525,7 @@ class SimpleOpenID
|
||||
dol_syslog(get_class($this).'::sendDiscoveryRequestToGetXRDS get XRDS');
|
||||
|
||||
$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:
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">
|
||||
|
||||
@@ -392,7 +392,6 @@ class SMTPs
|
||||
} else {
|
||||
if (function_exists('stream_socket_client') && !empty($this->_options)) {
|
||||
$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(
|
||||
preg_replace('@tls://@i', '', $this->getHost()).// Host to 'hit', IP or domain
|
||||
':'.$this->getPort(), // which Port number to use
|
||||
|
||||
@@ -190,6 +190,7 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation =
|
||||
|
||||
$info = curl_getinfo($ch); // Reading of request must be done after sending request
|
||||
$http_code = $info['http_code'];
|
||||
|
||||
if ($followlocation && ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307)) {
|
||||
$newUrl = $info['redirect_url'];
|
||||
$maxRedirection--;
|
||||
|
||||
@@ -30,6 +30,23 @@ $maxheightmini = 72; // 16/9eme
|
||||
$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
|
||||
@@ -40,12 +57,7 @@ $quality = 80;
|
||||
*/
|
||||
function image_format_supported($file, $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
|
||||
}
|
||||
$regeximgext = getListOfPossibleImageExt();
|
||||
|
||||
// Case filename is not a format image
|
||||
$reg = array();
|
||||
|
||||
@@ -534,7 +534,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
|
||||
|
||||
/**
|
||||
* 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 array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...)
|
||||
|
||||
@@ -1023,7 +1023,7 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify
|
||||
|
||||
if (empty($alreadygrabbed[$urltograbbis])) {
|
||||
if ($grabimages) {
|
||||
$tmpgeturl = getURLContent($urltograbbis);
|
||||
$tmpgeturl = getURLContent($urltograbbis, 'GET', '', 1, array(), array('http', 'https'), 0);
|
||||
if ($tmpgeturl['curl_error_no']) {
|
||||
$error++;
|
||||
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 ($grabimages) {
|
||||
$tmpgeturl = getURLContent($urltograbbis);
|
||||
$tmpgeturl = getURLContent($urltograbbis, 'GET', '', 1, array(), array('http', 'https'), 0);
|
||||
if ($tmpgeturl['curl_error_no']) {
|
||||
$error++;
|
||||
setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors');
|
||||
|
||||
@@ -193,7 +193,7 @@ class ExportExcel2007 extends ModeleExports
|
||||
|
||||
$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 PHPEXCELNEW_PATH.'Spreadsheet.php';
|
||||
|
||||
|
||||
@@ -1025,7 +1025,11 @@ class pdf_crabe extends ModelePDFFactures
|
||||
if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
|
||||
$pdf->SetFont('', 'B', $default_font_size - 2);
|
||||
$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;
|
||||
}
|
||||
|
||||
@@ -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->version = '1.0'; // Driver version
|
||||
// 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/Psr/autoloader.php';
|
||||
require_once PHPEXCELNEW_PATH . 'Spreadsheet.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
|
||||
require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
|
||||
$this->workbook = new Spreadsheet();
|
||||
|
||||
//if ($this->id == 'excel2007new')
|
||||
|
||||
@@ -100,6 +100,7 @@ class modExternalRss extends DolibarrModules
|
||||
$result = $this->db->query($sql);
|
||||
if ($result) {
|
||||
while ($obj = $this->db->fetch_object($result)) {
|
||||
$reg = array();
|
||||
if (preg_match('/EXTERNAL_RSS_TITLE_([0-9]+)/i', $obj->name, $reg)) {
|
||||
// Definie la boite si on a trouvee une ancienne configuration
|
||||
//$this->boxes[$reg[1]][0] = "(ExternalRSSInformations)";
|
||||
|
||||
@@ -182,6 +182,9 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
|
||||
if ($object->element == 'mo') {
|
||||
$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));
|
||||
if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$tmpkeyextra]))
|
||||
|
||||
@@ -103,6 +103,10 @@ class Donations extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->don->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// 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) {
|
||||
throw new RestException(401, "Insuffisant rights");
|
||||
}
|
||||
|
||||
// Check mandatory fields
|
||||
$result = $this->_validate($request_data);
|
||||
|
||||
@@ -247,6 +252,7 @@ class Donations extends DolibarrApi
|
||||
if (!DolibarrApiAccess::$user->rights->don->supprimer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$result = $this->don->fetch($id);
|
||||
if (!$result) {
|
||||
throw new RestException(404, 'Donation not found');
|
||||
@@ -295,6 +301,7 @@ class Donations extends DolibarrApi
|
||||
if (!DolibarrApiAccess::$user->rights->don->creer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$result = $this->don->fetch($id);
|
||||
if (!$result) {
|
||||
throw new RestException(404, 'Donation not found');
|
||||
|
||||
@@ -103,6 +103,10 @@ class Shipments extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->expedition->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -99,6 +99,10 @@ class ExpenseReports extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->expensereport->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// 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) {
|
||||
throw new RestException(401, "Insuffisant rights");
|
||||
}
|
||||
|
||||
// Check mandatory fields
|
||||
$result = $this->_validate($request_data);
|
||||
|
||||
@@ -427,6 +432,7 @@ class ExpenseReports extends DolibarrApi
|
||||
if (!DolibarrApiAccess::$user->rights->expensereport->supprimer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$result = $this->expensereport->fetch($id);
|
||||
if (!$result) {
|
||||
throw new RestException(404, 'Expense Report not found');
|
||||
@@ -469,6 +475,7 @@ class ExpenseReports extends DolibarrApi
|
||||
if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$result = $this->expensereport->fetch($id);
|
||||
if( ! $result ) {
|
||||
throw new RestException(404, 'expensereport not found');
|
||||
|
||||
@@ -110,6 +110,10 @@ class Interventions extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->ficheinter->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -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.'/'));
|
||||
}
|
||||
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')) {
|
||||
define('ODTPHP_PATH', (!isset($dolibarr_lib_ODTPHP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/odtphp/' : (empty($dolibarr_lib_ODTPHP_PATH) ? '' : $dolibarr_lib_ODTPHP_PATH.'/'));
|
||||
|
||||
@@ -102,6 +102,10 @@ class SupplierInvoices extends DolibarrApi
|
||||
{
|
||||
global $db;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -101,6 +101,10 @@ class SupplierOrders extends DolibarrApi
|
||||
{
|
||||
global $db, $conf;
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->fournisseur->commande->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
|
||||
|
||||
@@ -634,9 +634,10 @@ class ProductFournisseur extends Product
|
||||
* @param string $sortorder Sort order
|
||||
* @param int $limit Limit
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
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 .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")";
|
||||
$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);
|
||||
if (empty($sortfield)) {
|
||||
$sql .= " ORDER BY s.nom, pfp.quantity, pfp.price";
|
||||
|
||||
1
htdocs/fourn/js/index.html
Normal file
1
htdocs/fourn/js/index.html
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -492,12 +492,16 @@ if ($step == 2 && $datatoimport) {
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="max_file_size" value="'.$conf->maxfilesize.'">';
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<span class="opacitymedium">';
|
||||
$s = $langs->trans("ChooseFormatOfFileToImport", '{s1}');
|
||||
$s = str_replace('{s1}', img_picto('', 'next'), $s);
|
||||
print $s;
|
||||
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 '<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>';
|
||||
$text = $objmodelimport->getDriverDescForKey($key);
|
||||
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
|
||||
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>';
|
||||
@@ -587,7 +593,7 @@ if ($step == 3 && $datatoimport) {
|
||||
print '</table>';
|
||||
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="fichecenter">';
|
||||
@@ -598,8 +604,8 @@ if ($step == 3 && $datatoimport) {
|
||||
print '<td>';
|
||||
$text = $objmodelimport->getDriverDescForKey($format);
|
||||
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 '</table>';
|
||||
@@ -890,7 +896,7 @@ if ($step == 4 && $datatoimport) {
|
||||
print '</table>';
|
||||
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="fichecenter">';
|
||||
@@ -1374,7 +1380,7 @@ if ($step == 5 && $datatoimport) {
|
||||
print '</table>';
|
||||
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="fichecenter">';
|
||||
@@ -1468,7 +1474,7 @@ if ($step == 5 && $datatoimport) {
|
||||
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="fichecenter">';
|
||||
@@ -1812,7 +1818,7 @@ if ($step == 6 && $datatoimport) {
|
||||
print '</table>';
|
||||
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="fichecenter">';
|
||||
@@ -1875,8 +1881,7 @@ if ($step == 6 && $datatoimport) {
|
||||
print '<b>'.$langs->trans("InformationOnTargetTables").'</b>';
|
||||
print '<div class="underbanner clearboth"></div>';
|
||||
print '<div class="fichecenter">';
|
||||
print '<table width="100%" class="border">';
|
||||
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnTargetTables").'</b></td></tr>';
|
||||
print '<table class="border centpercent">';
|
||||
|
||||
// Tables imported
|
||||
print '<tr><td width="25%">';
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ class Calculation
|
||||
/**
|
||||
* 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;
|
||||
|
||||
@@ -1945,6 +1945,11 @@ class Calculation
|
||||
'functionCall' => [MathTrig::class, 'SUMXMY2'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'SWITCH' => [
|
||||
'category' => Category::CATEGORY_LOGICAL,
|
||||
'functionCall' => [Logical::class, 'statementSwitch'],
|
||||
'argumentCount' => '3+',
|
||||
],
|
||||
'SYD' => [
|
||||
'category' => Category::CATEGORY_FINANCIAL,
|
||||
'functionCall' => [Financial::class, 'SYD'],
|
||||
@@ -2207,8 +2212,8 @@ class Calculation
|
||||
private static function loadLocales()
|
||||
{
|
||||
$localeFileDirectory = __DIR__ . '/locale/';
|
||||
foreach (glob($localeFileDirectory . '/*', GLOB_ONLYDIR) as $filename) {
|
||||
$filename = substr($filename, strlen($localeFileDirectory) + 1);
|
||||
foreach (glob($localeFileDirectory . '*', GLOB_ONLYDIR) as $filename) {
|
||||
$filename = substr($filename, strlen($localeFileDirectory));
|
||||
if ($filename != 'en') {
|
||||
self::$validLocaleLanguages[] = $filename;
|
||||
}
|
||||
@@ -2413,7 +2418,6 @@ class Calculation
|
||||
if (strpos($locale, '_') !== false) {
|
||||
list($language) = explode('_', $locale);
|
||||
}
|
||||
|
||||
if (count(self::$validLocaleLanguages) == 1) {
|
||||
self::loadLocales();
|
||||
}
|
||||
@@ -2704,7 +2708,7 @@ class Calculation
|
||||
* @param Cell $pCell Cell to calculate
|
||||
* @param bool $resetLog Flag indicating whether the debug log should be reset or not
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -2808,7 +2812,7 @@ class Calculation
|
||||
* @param string $cellID Address of the cell to calculate
|
||||
* @param Cell $pCell Cell to calculate
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -2892,6 +2896,15 @@ class Calculation
|
||||
{
|
||||
$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
|
||||
// We simply return the cell value if not
|
||||
$formula = trim($formula);
|
||||
@@ -273,6 +273,60 @@ class Logical
|
||||
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.
|
||||
*
|
||||
@@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class LookupRef
|
||||
@@ -473,8 +474,9 @@ class LookupRef
|
||||
$lookupValue = Functions::flattenSingleValue($lookupValue);
|
||||
$matchType = ($matchType === null) ? 1 : (int) Functions::flattenSingleValue($matchType);
|
||||
|
||||
$initialLookupValue = $lookupValue;
|
||||
// MATCH is not case sensitive
|
||||
$lookupValue = strtolower($lookupValue);
|
||||
$lookupValue = StringHelper::strToLower($lookupValue);
|
||||
|
||||
// Lookup_value type has to be number, text, or logical values
|
||||
if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) {
|
||||
@@ -502,7 +504,7 @@ class LookupRef
|
||||
}
|
||||
// Convert strings to lowercase for case-insensitive testing
|
||||
if (is_string($lookupArrayValue)) {
|
||||
$lookupArray[$i] = strtolower($lookupArrayValue);
|
||||
$lookupArray[$i] = StringHelper::strToLower($lookupArrayValue);
|
||||
}
|
||||
if (($lookupArrayValue === null) && (($matchType == 1) || ($matchType == -1))) {
|
||||
$lookupArray = array_slice($lookupArray, 0, $i - 1);
|
||||
@@ -522,9 +524,13 @@ class LookupRef
|
||||
|
||||
if ($matchType == 0 || $matchType == 1) {
|
||||
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
|
||||
return ++$i;
|
||||
return $i + 1;
|
||||
} elseif (($matchType == 1) && ($lookupArrayValue <= $lookupValue)) {
|
||||
$i = array_search($i, $keySet);
|
||||
|
||||
@@ -661,7 +667,9 @@ class LookupRef
|
||||
{
|
||||
reset($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;
|
||||
}
|
||||
|
||||
@@ -707,11 +715,14 @@ class LookupRef
|
||||
uasort($lookup_array, ['self', 'vlookupSort']);
|
||||
}
|
||||
|
||||
$lookupLower = StringHelper::strToLower($lookup_value);
|
||||
$rowNumber = $rowValue = false;
|
||||
foreach ($lookup_array as $rowKey => $rowData) {
|
||||
$firstLower = StringHelper::strToLower($rowData[$firstColumn]);
|
||||
|
||||
// break if we have passed possible keys
|
||||
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;
|
||||
}
|
||||
// remember the last key, but only if datatypes match
|
||||
@@ -719,17 +730,15 @@ class LookupRef
|
||||
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]))) {
|
||||
if ($not_exact_match) {
|
||||
$rowNumber = $rowKey;
|
||||
$rowValue = $rowData[$firstColumn];
|
||||
|
||||
continue;
|
||||
} elseif ((strtolower($rowData[$firstColumn]) == strtolower($lookup_value))
|
||||
} elseif (($firstLower == $lookupLower)
|
||||
// Spreadsheets software returns first exact match,
|
||||
// we have sorted and we might have broken key orders
|
||||
// we want the first one (by its initial index)
|
||||
&& (($rowNumber == false) || ($rowKey < $rowNumber))
|
||||
) {
|
||||
$rowNumber = $rowKey;
|
||||
$rowValue = $rowData[$firstColumn];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -782,8 +791,11 @@ class LookupRef
|
||||
// break if we have passed possible keys
|
||||
$bothNumeric = 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) ||
|
||||
($bothNotNumeric && strtolower($rowData) > strtolower($lookup_value))) {
|
||||
($bothNotNumeric && $rowDataLower > $lookupLower)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -793,7 +805,7 @@ class LookupRef
|
||||
$rowNumber = $rowKey;
|
||||
|
||||
continue;
|
||||
} elseif (strtolower($rowData) === strtolower($lookup_value)
|
||||
} elseif ($rowDataLower === $lookupLower
|
||||
&& ($rowNumber === null || $rowKey < $rowNumber)
|
||||
) {
|
||||
$rowNumber = $rowKey;
|
||||
@@ -1224,11 +1224,12 @@ class MathTrig
|
||||
}
|
||||
|
||||
$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)) {
|
||||
// Is it a value within our criteria and only numeric can be added to the result
|
||||
$returnValue += $sumArgs[$key];
|
||||
$returnValue += $sumValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ SUMSQ
|
||||
SUMX2MY2
|
||||
SUMX2PY2
|
||||
SUMXMY2
|
||||
SWITCH
|
||||
SYD
|
||||
T
|
||||
TAN
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user