diff --git a/ChangeLog b/ChangeLog
index 951c4297f0c..646c1314b1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@ English Dolibarr ChangeLog
For users:
----------
+NEW: Several security issues after a second private bug bounty campaign.
For developers:
@@ -19,12 +20,60 @@ WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* The ICS value for direct debit or credit transfer is now store on each bank account instead of into the global setup.
* API /setup/shipment_methods has been replaced with API /setup/shipping_methods
-* Field "tva" renamed into "total_tva" in llx_propal, llx_supplier_proposal, llx_commande, llx_commande_fournisseur for better field name consistency
-* Field "total" renamed into "total_ttc" in llx_propal, llx_supplier_proposal for better field name consistency
+* Field "tva" renamed into "total_tva" for table llx_propal, llx_supplier_proposal, llx_commande, llx_commande_fournisseur for better field name consistency
+* Field "total" renamed into "total_ttc" for table lx_propal, llx_supplier_proposal for better field name consistency
* If your database is PostgreSql, you must use version 9.1.0 or more (Dolibarr need the SQL function CONCAT)
* If your database is MySql or MariaDB, you need at least version 5.1
+
+***** ChangeLog for 13.0.2 compared to 13.0.1 *****
+
+FIX: 11.0 - $this->socid injected in query without checking for empty value
+FIX: #16096 #16085 Any call of ajax pages must provide the token
+FIX: #16296
+FIX: #16325
+FIX: #16341 : Fetch the Product ExtraFields in Shippment lines
+FIX: #16366
+FIX: #16393 Do not sanitize
+FIX: #16420 #16423 #16488 #16477
+FIX: #16431
+FIX: #16465
+FIX: #16480
+FIX: #16485
+FIX: #16487
+FIX: #16503
+FIX: #16530
+FIX: #16533
+FIX: #16629
+FIX: #16671 Can not generate zip file of documents in backup tool
+FIX: Add "Now" link on social charges creation card
+FIX: avoid undefined url and missing token
+FIX: Bad project filter in ticket list
+FIX: Buttons to disable bindings not working
+FIX: class not found when creating recuring invoice from invoice+discount
+FIX: File attachment on lots
+FIX: handling $heightforinfotot when he's superior to a page height on Supplier Invoice
+FIX: hourglass and hide button to pay
+FIX: massaction validate invoice do not regenerate pdf
+FIX: missing mp4 video mime
+FIX: picto on shipment to reset qty to 0. Some quantities were not reset.
+FIX: Protection to avoid #16504
+FIX: rounding amount on card updating
+FIX: Rounding amount on social charges card updating
+FIX: select list dependencies now work for ModuleBuilder sellist field
+FIX: Status in popup of member in widget
+FIX: status on tooltip on widgets
+FIX: Timezone management for datetime on list of events
+FIX: Timezone management for datetime with modulebuilder and extrafields
+FIX: Total_ht not show in contract link element
+FIX: use post instead get
+FIX: use var "saved_url" instead global var "$url"
+FIX: Various payment - Missing fields for check transmitter & bank name
+FIX: warning if setup of chart of account is not yet done.
+FIX: wrong extension
+
+
***** ChangeLog for 13.0.1 compared to 13.0.0 *****
FIX: 10.0 before crediting a withdrawal receipt, check whether it has been credited already.
diff --git a/SECURITY.md b/SECURITY.md
index f63f9c3f277..7d65b7e98e4 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -12,7 +12,7 @@ This file contains some policies about the security reports on Dolibarr ERP CRM
## Reporting a Vulnerability
-To report a vulnerability, please use GitHub security advisory at https://github.com/Dolibarr/dolibarr/security/advisories/new (or alternatively send an email to security@dolibarr.org)
+To report a vulnerability, please use GitHub security advisory at https://github.com/Dolibarr/dolibarr/security/advisories/new (if you have permissions) or alternatively send an email to security@dolibarr.org (for everybody)
## Hunting vulnerabilities on Dolibarr
@@ -55,7 +55,7 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us
* $dolibarr_nocsrfcheck must be kept to the value 0 into conf.php (this is the default value)
* $dolibarr_main_force_https must be set to something else than 0.
* The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 1 into backoffice menu Home - Setup - Other (this protection should be set to 1 soon by default)
-* The module DebugBar and ModuleBuilder must NOT be enabled (by default, this module is not enabled. This is a developer tool)
+* The module DebugBar and ModuleBuilder must NOT be enabled (by default, these modules are not enabled. They are developer tools)
* ONLY security reports on modules provided by default and with the "stable" status are valid (troubles into "experimental", "developement" or external modules are not valid vulnerabilities).
* The root of web server must link to htdocs and the documents directory must be outside of the web server root (this is the default when using the default installer but may differs with external installer).
* The web server setup must be done so only the documents directory is in write mode. The root directory called htdocs must be readonly.
@@ -65,12 +65,12 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us
Scope is the web application (back office) and the APIs.
-## Qualifying vulnerabilities for Bug bounty programs
+## Qualifying vulnerabilities for reporting
* Remote code execution (RCE)
* Local files access and manipulation (LFI, RFI, XXE, SSRF, XSPA)
* Code injections (HTML, JS, SQL, PHP, ...)
-* Cross-Site Scripting (XSS)
+* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose or into module "Web site" when permission to edit website content is allowed).
* Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users)
* Open redirect
* Broken authentication & session management
@@ -82,7 +82,7 @@ Scope is the web application (back office) and the APIs.
* Stack traces or path disclosure (for non admin users only)
-## Non-qualifying vulnerabilities for Bug bounty programs, but qualified for reporting
+## Non-qualifying vulnerabilities for reporting
* "Self" XSS
* SSL/TLS best practices
diff --git a/build/debian/control b/build/debian/control
index eed54669555..059325eecb9 100755
--- a/build/debian/control
+++ b/build/debian/control
@@ -33,7 +33,7 @@ Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm |
Recommends: apache2 | lighttpd | httpd,
mariadb-server | virtual-mysql-server,
# Required PHP extensions for debian 9 but we can't add them into a Depends, it does not exists on debian 7 and 8
- php-xml, php-mbstring
+ php-xml, php-mbstring, php-intl
Suggests: www-browser, php5-geoip
Description: Web based software to manage a company or foundation
Dolibarr ERP & CRM is an easy to use open source/free software package for
diff --git a/build/doxygen/doxygen_header.html b/build/doxygen/doxygen_header.html
index 235797bb6c9..f60f4829d76 100644
--- a/build/doxygen/doxygen_header.html
+++ b/build/doxygen/doxygen_header.html
@@ -2,7 +2,7 @@
-$title
+Dolibarr source code documentation
&2;
# Determine if a file list is passed
if [ "$#" -eq 1 ]
@@ -20,36 +24,50 @@ then
fi
SFILES=${SFILES:-$STAGED_FILES_CMD}
-echo "Checking PHP Lint..."
+echo "Checking PHP Lint with php -l ..."
+
for FILE in $SFILES
do
php -l -d display_errors=0 $PROJECT/$FILE
- if [ $? != 0 ]
+
+ result1=$?
+
+ if [ "x$result1" != "x0" ]
then
- echo "Fix the error before commit."
+ echo "Fix the error before commit." 1>&2;
exit 1
fi
FILES="$FILES $PROJECT/$FILE"
done
+
if [ "$FILES" != "" ]
then
echo "Running PHPCS Code Sniffer..."
+
#~/vendor/bin/phpcs --version
#phpcs --standard=PSR2 --encoding=utf-8 -n -p $FILES
# Check Dolibarr standard
- ~/vendor/bin/phpcs -s -p -d memory_limit=-1 --parallel=2 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
+ ${DIRPHPCS}phpcs -s -p -d memory_limit=-1 --parallel=2 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
# Check your own standard
- #~/vendor/bin/phpcs -s -p -d memory_limit=-1 --parallel=2 --extensions=php --colors --tab-width=4 --standard=htdocs/custom/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
+ #${DIRPHPCS}phpcs -s -p -d memory_limit=-1 --parallel=2 --extensions=php --colors --tab-width=4 --standard=htdocs/custom/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
+
+ result2=$?
- if [ $? != 0 ]
+ if [ "x$result2" != "x0" ]
then
- # fix standard errors
- ~/vendor/bin/phpcbf -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
- #~/vendor/bin/phpcbf -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=htdocs/custom/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
- echo "Fix the error before commit."
- exit 1
+ # Fix standard errors
+ if [ "x$AUTOFIX" != "x0" ]
+ then
+ ${DIRPHPCS}phpcbf -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
+ #${DIRPHPCS}phpcbf -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=htdocs/custom/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES
+ echo "Found some errors in syntax rules. An automatic fix has been applied. Check it before commit." 1>&2;
+ exit 1
+ else
+ echo "Found some errors in syntax rules. Fix the error(s) before commit." 1>&2;
+ exit 1
+ fi
fi
fi
-exit $?
+exit 0
diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php
index faf55427786..cf2bd2065a2 100644
--- a/htdocs/accountancy/admin/account.php
+++ b/htdocs/accountancy/admin/account.php
@@ -529,11 +529,11 @@ if ($resql) {
if (!empty($arrayfields['aa.reconcilable']['checked'])) {
print '
';
if (empty($object->validated)) {
- print 'id . '&action=enable">';
+ print 'id . '&action=enable&token='.newToken().'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '';
} else {
- print 'id . '&action=disable">';
+ print 'id . '&action=disable&token='.newToken().'">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '';
}
diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
index 8ca4175f87f..40a8284adc4 100644
--- a/htdocs/accountancy/bookkeeping/list.php
+++ b/htdocs/accountancy/bookkeeping/list.php
@@ -3,7 +3,7 @@
* Copyright (C) 2013-2016 Florian Henry
* Copyright (C) 2013-2020 Alexandre Spangaro
* Copyright (C) 2016-2017 Laurent Destailleur
- * Copyright (C) 2018 Frédéric France
+ * Copyright (C) 2018-2021 Frédéric France
*
* 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
@@ -171,6 +171,16 @@ if (empty($listofformat[$formatexportset])) {
$error = 0;
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Actions
@@ -471,7 +481,7 @@ if (count($filter) > 0) {
}
}
$sql .= ' WHERE t.entity IN ('.getEntity('accountancy').')';
-if ($conf->global->ACCOUNTING_REEXPORT == 0) {
+if (empty($conf->global->ACCOUNTING_REEXPORT)) {
$sql .= " AND t.date_export IS NULL";
}
if (count($sqlwhere) > 0) {
@@ -487,7 +497,7 @@ if (!empty($sortfield)) {
// Must be after definition of $sql
if ($action == 'export_fileconfirm' && $user->rights->accounting->mouvements->export) {
// TODO Replace the fetchAll + ->export later that consume too much memory on large export with the query($sql) and loop on each line to export them.
- $result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', $conf->global->ACCOUNTING_REEXPORT);
+ $result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', (empty($conf->global->ACCOUNTING_REEXPORT) ? 0 : 1));
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php
index 99b644d1e0a..24bcc4706c1 100644
--- a/htdocs/accountancy/bookkeeping/listbyaccount.php
+++ b/htdocs/accountancy/bookkeeping/listbyaccount.php
@@ -163,6 +163,16 @@ if ($search_date_end && empty($search_date_endyear)) {
$search_date_endday = $tmparray['mday'];
}
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Action
diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php
index 72b6574bea5..129e695de3c 100644
--- a/htdocs/accountancy/bookkeeping/listbysubaccount.php
+++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php
@@ -163,10 +163,21 @@ if ($search_date_end && empty($search_date_endyear)) {
$search_date_endday = $tmparray['mday'];
}
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Action
*/
+
if (GETPOST('cancel', 'alpha')) {
$action = 'list'; $massaction = '';
}
diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
index a2192d5ea60..0064e8c4715 100644
--- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
+++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
@@ -94,6 +94,16 @@ if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Action
@@ -128,7 +138,7 @@ $form = new Form($db);
$formaccounting = new FormAccounting($db);
$title = $object->name." - ".$langs->trans('TabLetteringCustomer');
-$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
+$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner';
llxHeader('', $title, $help_url);
$head = societe_prepare_head($object);
diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
index f8167846aff..a73f711e15a 100644
--- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
+++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
@@ -94,10 +94,21 @@ if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Action
*/
+
if ($action == 'lettering') {
$result = $lettering->updateLettering($toselect);
@@ -127,7 +138,7 @@ $form = new Form($db);
$formaccounting = new FormAccounting($db);
$title = $object->name." - ".$langs->trans('TabLetteringSupplier');
-$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
+$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner';
llxHeader('', $title, $help_url);
$head = societe_prepare_head($object);
diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php
index 95d88c80c87..1bdc0f438bf 100644
--- a/htdocs/accountancy/class/accountancycategory.class.php
+++ b/htdocs/accountancy/class/accountancycategory.class.php
@@ -261,7 +261,7 @@ class AccountancyCategory // extends CommonObject
$sql .= " t.active";
$sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as t";
if ($id) {
- $sql .= " WHERE t.rowid = ".$id;
+ $sql .= " WHERE t.rowid = ".((int) $id);
} else {
$sql .= " WHERE t.entity IN (".getEntity('c_accounting_category').")"; // Dont't use entity if you use rowid
if ($code) {
@@ -354,7 +354,7 @@ class AccountancyCategory // extends CommonObject
$sql .= " position=".(isset($this->position) ? $this->position : "null").",";
$sql .= " fk_country=".(isset($this->fk_country) ? $this->fk_country : "null").",";
$sql .= " active=".(isset($this->active) ? $this->active : "null")."";
- $sql .= " WHERE rowid=".$this->id;
+ $sql .= " WHERE rowid=".((int) $this->id);
$this->db->begin();
@@ -392,7 +392,7 @@ class AccountancyCategory // extends CommonObject
$error = 0;
$sql = "DELETE FROM ".MAIN_DB_PREFIX."c_accounting_category";
- $sql .= " WHERE rowid=".$this->id;
+ $sql .= " WHERE rowid=".((int) $this->id);
$this->db->begin();
@@ -743,7 +743,7 @@ class AccountancyCategory // extends CommonObject
}
$listofaccount .= "'".$cptcursor."'";
}
- $sql .= " AND t.numero_compte IN (".$listofaccount.")";
+ $sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount).")";
} else {
$sql .= " AND t.numero_compte = '".$this->db->escape($cpt)."'";
}
diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php
index d5fad9b8f60..a7d89c45294 100644
--- a/htdocs/accountancy/class/accountingaccount.class.php
+++ b/htdocs/accountancy/class/accountingaccount.class.php
@@ -414,7 +414,7 @@ class AccountingAccount extends CommonObject
if (!$error) {
$sql = "DELETE FROM ".MAIN_DB_PREFIX."accounting_account";
- $sql .= " WHERE rowid=".$this->id;
+ $sql .= " WHERE rowid=".((int) $this->id);
dol_syslog(get_class($this)."::delete sql=".$sql);
$resql = $this->db->query($sql);
@@ -553,7 +553,7 @@ class AccountingAccount extends CommonObject
{
$sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms';
$sql .= ' FROM '.MAIN_DB_PREFIX.'accounting_account as a';
- $sql .= ' WHERE a.rowid = '.$id;
+ $sql .= ' WHERE a.rowid = '.((int) $id);
dol_syslog(get_class($this).'::info sql='.$sql);
$result = $this->db->query($sql);
diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
index 27a84270e95..7286e954d0e 100644
--- a/htdocs/accountancy/class/bookkeeping.class.php
+++ b/htdocs/accountancy/class/bookkeeping.class.php
@@ -729,7 +729,7 @@ class BookKeeping extends CommonObject
if (null !== $ref) {
$sql .= " AND t.ref = '".$this->db->escape($ref)."'";
} else {
- $sql .= ' AND t.rowid = '.$id;
+ $sql .= ' AND t.rowid = '.((int) $id);
}
$resql = $this->db->query($sql);
@@ -1262,7 +1262,7 @@ class BookKeeping extends CommonObject
$sql .= ' code_journal = '.(isset($this->code_journal) ? "'".$this->db->escape($this->code_journal)."'" : "null").',';
$sql .= ' journal_label = '.(isset($this->journal_label) ? "'".$this->db->escape($this->journal_label)."'" : "null").',';
$sql .= ' piece_num = '.(isset($this->piece_num) ? $this->piece_num : "null");
- $sql .= ' WHERE rowid='.$this->id;
+ $sql .= ' WHERE rowid='.((int) $this->id);
$this->db->begin();
@@ -1359,7 +1359,7 @@ class BookKeeping extends CommonObject
if (!$error) {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.$mode;
- $sql .= ' WHERE rowid='.$this->id;
+ $sql .= ' WHERE rowid='.((int) $this->id);
$resql = $this->db->query($sql);
if (!$resql) {
diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
index ad6f186d68f..b2abf01948e 100644
--- a/htdocs/accountancy/class/lettering.class.php
+++ b/htdocs/accountancy/class/lettering.class.php
@@ -126,7 +126,7 @@ class Lettering extends BookKeeping
if (count($ids_fact)) {
$sql = 'SELECT bk.rowid, facf.ref, facf.ref_supplier ';
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn facf ";
- $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_bookkeeping as bk ON( bk.fk_doc = facf.rowid AND facf.rowid IN (".implode(',', $ids_fact)."))";
+ $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_bookkeeping as bk ON( bk.fk_doc = facf.rowid AND facf.rowid IN (".$this->db->sanitize(implode(',', $ids_fact))."))";
$sql .= " WHERE bk.code_journal IN (SELECT code FROM ".MAIN_DB_PREFIX."accounting_journal WHERE nature=3 AND entity=".$conf->entity.") ";
$sql .= " AND facf.entity = ".$conf->entity;
$sql .= " AND ( ";
@@ -185,7 +185,7 @@ class Lettering extends BookKeeping
if (count($ids_fact)) {
$sql = 'SELECT bk.rowid, fac.ref, fac.ref_supplier ';
$sql .= " FROM ".MAIN_DB_PREFIX."facture fac ";
- $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_bookkeeping as bk ON( bk.fk_doc = fac.rowid AND fac.rowid IN (".implode(',', $ids_fact)."))";
+ $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_bookkeeping as bk ON( bk.fk_doc = fac.rowid AND fac.rowid IN (".$this->db->sanitize(implode(',', $ids_fact))."))";
$sql .= " WHERE code_journal IN (SELECT code FROM ".MAIN_DB_PREFIX."accounting_journal WHERE nature=2 AND entity=".$conf->entity.") ";
$sql .= " AND fac.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
$sql .= " AND ( ";
@@ -255,7 +255,7 @@ class Lettering extends BookKeeping
}
$sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE ";
- $sql .= " rowid IN (".implode(',', $ids).") AND date_validated IS NULL";
+ $sql .= " rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL";
$result = $this->db->query($sql);
if ($result) {
$obj = $this->db->fetch_object($result);
@@ -276,7 +276,7 @@ class Lettering extends BookKeeping
$sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET";
$sql .= " lettering_code='".$this->db->escape($lettre)."'";
$sql .= " , date_lettering = '".$this->db->idate($now)."'"; // todo correct date it's false
- $sql .= " WHERE rowid IN (".implode(',', $ids).") AND date_validated IS NULL ";
+ $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL ";
$this->db->begin();
dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
diff --git a/htdocs/accountancy/closure/index.php b/htdocs/accountancy/closure/index.php
index 94e59de1812..3ba552cdfa4 100644
--- a/htdocs/accountancy/closure/index.php
+++ b/htdocs/accountancy/closure/index.php
@@ -35,17 +35,6 @@ $socid = GETPOST('socid', 'int');
$action = GETPOST('action', 'aZ09');
-// Security check
-if (empty($conf->accounting->enabled)) {
- accessforbidden();
-}
-if ($user->socid > 0) {
- accessforbidden();
-}
-if (!$user->rights->accounting->fiscalyear->write) {
- accessforbidden();
-}
-
$object = new BookKeeping($db);
$month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
@@ -67,10 +56,23 @@ $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start);
$search_date_end = dol_get_last_day($year_end, $month_end);
$year_current = $year_start;
+// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (!$user->rights->accounting->fiscalyear->write) {
+ accessforbidden();
+}
+
+
/*
* Actions
*/
-if ($action == 'validate_movements_confirm' && $user->rights->accounting->fiscalyear->write) {
+
+if ($action == 'validate_movements_confirm' && !empty($user->rights->accounting->fiscalyear->write)) {
$result = $object->fetchAll();
if ($result < 0) {
diff --git a/htdocs/accountancy/customer/card.php b/htdocs/accountancy/customer/card.php
index 9807922c43f..98e9151877e 100644
--- a/htdocs/accountancy/customer/card.php
+++ b/htdocs/accountancy/customer/card.php
@@ -38,9 +38,16 @@ $codeventil = GETPOST('codeventil', 'int');
$id = GETPOST('id', 'int');
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
@@ -55,7 +62,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) {
$sql = " UPDATE ".MAIN_DB_PREFIX."facturedet";
$sql .= " SET fk_code_ventilation = ".$codeventil;
- $sql .= " WHERE rowid = ".$id;
+ $sql .= " WHERE rowid = ".((int) $id);
$resql = $db->query($sql);
if (!$resql) {
@@ -99,7 +106,7 @@ if (!empty($id)) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON l.fk_code_ventilation = aa.rowid";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = l.fk_facture";
- $sql .= " WHERE f.fk_statut > 0 AND l.rowid = ".$id;
+ $sql .= " WHERE f.fk_statut > 0 AND l.rowid = ".((int) $id);
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
dol_syslog("/accounting/customer/card.php sql=".$sql, LOG_DEBUG);
diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php
index 983e7957583..6b025e6f3c1 100644
--- a/htdocs/accountancy/customer/lines.php
+++ b/htdocs/accountancy/customer/lines.php
@@ -80,13 +80,17 @@ if (!$sortorder) {
}
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
-if (!$user->rights->accounting->bind->write) {
+if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
+
$formaccounting = new FormAccounting($db);
@@ -112,7 +116,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_tvaintra = '';
}
-if (is_array($changeaccount) && count($changeaccount) > 0) {
+if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->accounting->bind->write) {
$error = 0;
if (!(GETPOST('account_parent', 'int') >= 0)) {
@@ -125,7 +129,7 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
$sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet as l";
$sql1 .= " SET l.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0');
- $sql1 .= ' WHERE l.rowid IN ('.implode(',', $changeaccount).')';
+ $sql1 .= ' WHERE l.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')';
dol_syslog('accountancy/customer/lines.php::changeaccount sql= '.$sql1);
$resql1 = $db->query($sql1);
@@ -242,11 +246,11 @@ if (strlen(trim($search_country))) {
if ($search_country == 'special_allnotme') {
$sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
} elseif ($search_country == 'special_eec') {
- $sql .= " AND co.code IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC, 1).")";
} elseif ($search_country == 'special_eecnotme') {
- $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC_without_me, 1).")";
} elseif ($search_country == 'special_noteec') {
- $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code NOT IN (".$db->sanitize($country_code_in_EEC, 1).")";
} else {
$sql .= natural_search("co.code", $search_country);
}
diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php
index 8d5c2788425..2e28ae4b566 100644
--- a/htdocs/accountancy/customer/list.php
+++ b/htdocs/accountancy/customer/list.php
@@ -88,10 +88,13 @@ if (!$sortorder) {
}
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
-if (!$user->rights->accounting->bind->write) {
+if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
@@ -148,7 +151,7 @@ if (empty($reshook)) {
}
-if ($massaction == 'ventil') {
+if ($massaction == 'ventil' && $user->rights->accounting->bind->write) {
$msg = '';
//print '
' . $langs->trans("Processing") . '...
';
@@ -280,11 +283,11 @@ if (strlen(trim($search_country))) {
if ($search_country == 'special_allnotme') {
$sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
} elseif ($search_country == 'special_eec') {
- $sql .= " AND co.code IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC, 1).")";
} elseif ($search_country == 'special_eecnotme') {
- $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC_without_me, 1).")";
} elseif ($search_country == 'special_noteec') {
- $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code NOT IN (".$db->sanitize($country_code_in_EEC, 1).")";
} else {
$sql .= natural_search("co.code", $search_country);
}
diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php
index d68326ad68e..200a493cfed 100644
--- a/htdocs/accountancy/expensereport/card.php
+++ b/htdocs/accountancy/expensereport/card.php
@@ -42,9 +42,15 @@ $codeventil = GETPOST('codeventil', 'int');
$id = GETPOST('id', 'int');
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
/*
@@ -59,7 +65,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) {
$sql = " UPDATE ".MAIN_DB_PREFIX."expensereport_det";
$sql .= " SET fk_code_ventilation = ".$codeventil;
- $sql .= " WHERE rowid = ".$id;
+ $sql .= " WHERE rowid = ".((int) $id);
$resql = $db->query($sql);
if (!$resql) {
@@ -101,7 +107,7 @@ if (!empty($id)) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as f ON f.id = erd.fk_c_type_fees";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON erd.fk_code_ventilation = aa.rowid";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."expensereport as er ON er.rowid = erd.fk_expensereport";
- $sql .= " WHERE er.fk_statut > 0 AND erd.rowid = ".$id;
+ $sql .= " WHERE er.fk_statut > 0 AND erd.rowid = ".((int) $id);
$sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy
dol_syslog("/accounting/expensereport/card.php sql=".$sql, LOG_DEBUG);
diff --git a/htdocs/accountancy/expensereport/index.php b/htdocs/accountancy/expensereport/index.php
index ffa0bfcc07d..38f7f596932 100644
--- a/htdocs/accountancy/expensereport/index.php
+++ b/htdocs/accountancy/expensereport/index.php
@@ -32,17 +32,6 @@ require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
// Load translation files required by the page
$langs->loadLangs(array("compta", "bills", "other", "main", "accountancy"));
-// Security check
-if (empty($conf->accounting->enabled)) {
- accessforbidden();
-}
-if ($user->socid > 0) {
- accessforbidden();
-}
-if (!$user->rights->accounting->bind->write) {
- accessforbidden();
-}
-
$month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
if (GETPOST("year", 'int')) {
$year_start = GETPOST("year", 'int');
@@ -65,13 +54,23 @@ $year_current = $year_start;
// Validate History
$action = GETPOST('action', 'aZ09');
+// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
/*
* Actions
*/
-if ($action == 'clean' || $action == 'validatehistory') {
+if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accounting->bind->write) {
// Clean database
$db->begin();
$sql1 = "UPDATE ".MAIN_DB_PREFIX."expensereport_det as erd";
diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php
index 3c4760b3730..df50eaaff87 100644
--- a/htdocs/accountancy/expensereport/lines.php
+++ b/htdocs/accountancy/expensereport/lines.php
@@ -74,13 +74,17 @@ if (!$sortorder) {
}
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
-if (!$user->rights->accounting->bind->write) {
+if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
+
$formaccounting = new FormAccounting($db);
@@ -102,7 +106,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_year = '';
}
-if (is_array($changeaccount) && count($changeaccount) > 0) {
+if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->accounting->bind->write) {
$error = 0;
if (!(GETPOST('account_parent', 'int') >= 0)) {
@@ -115,7 +119,7 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
$sql1 = "UPDATE ".MAIN_DB_PREFIX."expensereport_det as erd";
$sql1 .= " SET erd.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0');
- $sql1 .= ' WHERE erd.rowid IN ('.implode(',', $changeaccount).')';
+ $sql1 .= ' WHERE erd.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')';
dol_syslog('accountancy/expensereport/lines.php::changeaccount sql= '.$sql1);
$resql1 = $db->query($sql1);
diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php
index 05476756531..84cd64bb44f 100644
--- a/htdocs/accountancy/expensereport/list.php
+++ b/htdocs/accountancy/expensereport/list.php
@@ -83,19 +83,22 @@ if (!$sortorder) {
}
}
-// Security check
-if ($user->socid > 0) {
- accessforbidden();
-}
-if (!$user->rights->accounting->bind->write) {
- accessforbidden();
-}
-
$formaccounting = new FormAccounting($db);
$accounting = new AccountingAccount($db);
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
+// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Action
@@ -130,7 +133,7 @@ $permissiontodelete = $user->rights->expensereport->delete;
$uploaddir = $conf->expensereport->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
-if ($massaction == 'ventil') {
+if ($massaction == 'ventil' && $user->rights->accounting->bind->write) {
$msg = '';
//print '
' . $langs->trans("Processing") . '...
';
if (!empty($mesCasesCochees)) {
diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
index 5b2f807fcd7..94dc6aa05c9 100644
--- a/htdocs/accountancy/index.php
+++ b/htdocs/accountancy/index.php
@@ -1,7 +1,7 @@
* Copyright (C) 2016-2019 Alexandre Spangaro
- * Copyright (C) 2019 Frédéric France
+ * Copyright (C) 2019-2021 Frédéric France
*
* 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
@@ -31,13 +31,20 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
// Load translation files required by the page
$langs->loadLangs(array("compta", "bills", "other", "accountancy", "loans", "banks", "admin", "dict"));
+// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array of hooks
+$hookmanager->initHooks(array('accountancyindex'));
+
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
-// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array of hooks
-$hookmanager->initHooks(array('accountancyindex'));
/*
@@ -220,7 +227,7 @@ if ($conf->accounting->enabled) {
/*
* Show boxes
*/
- $boxlist .= '
';
+ $boxlist = '
';
$boxlist .= '
';
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index b79b8433c03..9093721bff6 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -7,7 +7,7 @@
* Copyright (C) 2013-2019 Alexandre Spangaro
* Copyright (C) 2013-2014 Florian Henry
* Copyright (C) 2013-2014 Olivier Geffroy
- * Copyright (C) 2017-2020 Frédéric France
+ * Copyright (C) 2017-2021 Frédéric France
* Copyright (C) 2018 Ferran Marcet
* Copyright (C) 2018 Eric Seigne
* Copyright (C) 2021 Gauthier VERDOL
@@ -83,7 +83,13 @@ $now = dol_now();
$action = GETPOST('action', 'aZ09');
// Security check
-if ($user->socid > 0 && empty($id_journal)) {
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
@@ -954,13 +960,18 @@ if (empty($action) || $action == 'view') {
$nom = $langs->trans("FinanceJournal").' | '.$accountingjournalstatic->getNomUrl(0, 1, 1, '', 1);
$builddate = dol_now();
//$description = $langs->trans("DescFinanceJournal") . ' ';
- $description .= $langs->trans("DescJournalOnlyBindedVisible").' ';
+ $description = $langs->trans("DescJournalOnlyBindedVisible").' ';
- $listofchoices = array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
+ $listofchoices = array(
+ 'notyet'=>$langs->trans("NotYetInGeneralLedger"),
+ 'already'=>$langs->trans("AlreadyInGeneralLedger")
+ );
$period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0);
$period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
$varlink = 'id_journal='.$id_journal;
+ $periodlink = '';
+ $exportlink = '';
journalHead($nom, '', $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
index 9010261dbe0..2f7569ab152 100644
--- a/htdocs/accountancy/journal/expensereportsjournal.php
+++ b/htdocs/accountancy/journal/expensereportsjournal.php
@@ -58,13 +58,21 @@ if ($in_bookkeeping == '') {
$now = dol_now();
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Actions
*/
+
$accountingaccount = new AccountingAccount($db);
// Get informations of journal
diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
index 46363fb3a09..f6fa5c4b76a 100644
--- a/htdocs/accountancy/journal/purchasesjournal.php
+++ b/htdocs/accountancy/journal/purchasesjournal.php
@@ -57,17 +57,25 @@ if ($in_bookkeeping == '') {
$now = dol_now();
+$hookmanager->initHooks(array('purchasesjournal'));
+$parameters = array();
+
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
-$hookmanager->initHooks(array('purchasesjournal'));
-$parameters = array();
/*
* Actions
*/
+
$reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
$accountingaccount = new AccountingAccount($db);
diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
index 16209e1a241..bdf525d2827 100644
--- a/htdocs/accountancy/journal/sellsjournal.php
+++ b/htdocs/accountancy/journal/sellsjournal.php
@@ -8,7 +8,7 @@
* Copyright (C) 2013-2016 Florian Henry
* Copyright (C) 2013-2016 Olivier Geffroy
* Copyright (C) 2014 Raphaël Doursenaud
- * Copyright (C) 2018 Frédéric France
+ * Copyright (C) 2018-2021 Frédéric France
*
* 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
@@ -59,13 +59,20 @@ if ($in_bookkeeping == '') {
$now = dol_now();
+$hookmanager->initHooks(array('sellsjournal'));
+$parameters = array();
+
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
-$hookmanager->initHooks(array('sellsjournal'));
-$parameters = array();
/*
* Actions
@@ -656,7 +663,7 @@ if (empty($action) || $action == 'view') {
$periodlink = '';
$exportlink = '';
$builddate = dol_now();
- $description .= $langs->trans("DescJournalOnlyBindedVisible").' ';
+ $description = $langs->trans("DescJournalOnlyBindedVisible").' ';
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$description .= $langs->trans("DepositsAreNotIncluded");
} else {
diff --git a/htdocs/accountancy/supplier/card.php b/htdocs/accountancy/supplier/card.php
index 25a3fc04ca4..eee2059c660 100644
--- a/htdocs/accountancy/supplier/card.php
+++ b/htdocs/accountancy/supplier/card.php
@@ -42,9 +42,15 @@ $codeventil = GETPOST('codeventil', 'int');
$id = GETPOST('id', 'int');
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
/*
@@ -59,7 +65,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) {
$sql = " UPDATE ".MAIN_DB_PREFIX."facture_fourn_det";
$sql .= " SET fk_code_ventilation = ".$codeventil;
- $sql .= " WHERE rowid = ".$id;
+ $sql .= " WHERE rowid = ".((int) $id);
$resql = $db->query($sql);
if (!$resql) {
@@ -101,7 +107,7 @@ if (!empty($id)) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON l.fk_code_ventilation = aa.rowid";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON f.rowid = l.fk_facture_fourn ";
- $sql .= " WHERE f.fk_statut > 0 AND l.rowid = ".$id;
+ $sql .= " WHERE f.fk_statut > 0 AND l.rowid = ".((int) $id);
$sql .= " AND f.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
dol_syslog("/accounting/supplier/card.php sql=".$sql, LOG_DEBUG);
diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php
index 937173fc1e6..7ef09acf91a 100644
--- a/htdocs/accountancy/supplier/index.php
+++ b/htdocs/accountancy/supplier/index.php
@@ -69,12 +69,23 @@ $action = GETPOST('action', 'aZ09');
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
+// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Actions
*/
-if ($action == 'clean' || $action == 'validatehistory') {
+if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accounting->bind->write) {
// Clean database
$db->begin();
$sql1 = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det as fd";
diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php
index 6bdc714ec4c..a87280744ec 100644
--- a/htdocs/accountancy/supplier/lines.php
+++ b/htdocs/accountancy/supplier/lines.php
@@ -80,16 +80,19 @@ if (!$sortorder) {
}
}
+$formaccounting = new FormAccounting($db);
+
// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
if ($user->socid > 0) {
accessforbidden();
}
-if (!$user->rights->accounting->bind->write) {
+if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
-$formaccounting = new FormAccounting($db);
-
/*
* Actions
@@ -127,7 +130,7 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
$sql1 = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det as l";
$sql1 .= " SET l.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0');
- $sql1 .= ' WHERE l.rowid IN ('.implode(',', $changeaccount).')';
+ $sql1 .= ' WHERE l.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')';
dol_syslog('accountancy/supplier/lines.php::changeaccount sql= '.$sql1);
$resql1 = $db->query($sql1);
@@ -235,11 +238,11 @@ if (strlen(trim($search_country))) {
if ($search_country == 'special_allnotme') {
$sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
} elseif ($search_country == 'special_eec') {
- $sql .= " AND co.code IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC, 1).")";
} elseif ($search_country == 'special_eecnotme') {
- $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC_without_me, 1).")";
} elseif ($search_country == 'special_noteec') {
- $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code NOT IN (".$db->sanitize($country_code_in_EEC, 1).")";
} else {
$sql .= natural_search("co.code", $search_country);
}
diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php
index d49effd791d..aa3f8b4a403 100644
--- a/htdocs/accountancy/supplier/list.php
+++ b/htdocs/accountancy/supplier/list.php
@@ -88,14 +88,6 @@ if (!$sortorder) {
}
}
-// Security check
-if ($user->socid > 0) {
- accessforbidden();
-}
-if (!$user->rights->accounting->bind->write) {
- accessforbidden();
-}
-
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('accountancysupplierlist'));
@@ -107,6 +99,17 @@ $aarowid_p = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUN
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
+// Security check
+if (empty($conf->accounting->enabled)) {
+ accessforbidden();
+}
+if ($user->socid > 0) {
+ accessforbidden();
+}
+if (empty($user->rights->accounting->mouvements->lire)) {
+ accessforbidden();
+}
+
/*
* Actions
@@ -285,11 +288,11 @@ if (strlen(trim($search_country))) {
if ($search_country == 'special_allnotme') {
$sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
} elseif ($search_country == 'special_eec') {
- $sql .= " AND co.code IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC, 1).")";
} elseif ($search_country == 'special_eecnotme') {
- $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
+ $sql .= " AND co.code IN (".$db->sanitize($country_code_in_EEC_without_me, 1).")";
} elseif ($search_country == 'special_noteec') {
- $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
+ $sql .= " AND co.code NOT IN (".$db->sanitize($country_code_in_EEC, 1).")";
} else {
$sql .= natural_search("co.code", $search_country);
}
diff --git a/htdocs/adherents/admin/adherent.php b/htdocs/adherents/admin/member.php
similarity index 98%
rename from htdocs/adherents/admin/adherent.php
rename to htdocs/adherents/admin/member.php
index adcf7d49311..3d40f8d758b 100644
--- a/htdocs/adherents/admin/adherent.php
+++ b/htdocs/adherents/admin/member.php
@@ -8,7 +8,7 @@
* Copyright (C) 2011-2012 Juanjo Menent
* Copyright (C) 2012 J. Fernando Lagrange
* Copyright (C) 2015 Jean-François Ferry
- * Copyright (C) 2020 Frédéric France
+ * Copyright (C) 2020-2021 Frédéric France
*
* 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
@@ -178,7 +178,7 @@ if ($action == 'unset') {
$form = new Form($db);
-$help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros';
+$help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros|DE:Modul_Mitglieder';
llxHeader('', $langs->trans("MembersSetup"), $help_url);
@@ -254,7 +254,8 @@ if ($conf->facture->enabled) {
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
print '
';
if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && $conf->global->LDAP_MEMBER_ACTIVE != 'ldap2dolibarr') {
diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php
index c37e9e325cf..b06a7538aae 100644
--- a/htdocs/adherents/list.php
+++ b/htdocs/adherents/list.php
@@ -41,9 +41,6 @@ $confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'memberslist'; // To manage different context of search
-// Security check
-$result = restrictedArea($user, 'adherent');
-
$search = GETPOST("search", 'alpha');
$search_ref = GETPOST("search_ref", 'alpha');
$search_lastname = GETPOST("search_lastname", 'alpha');
@@ -79,7 +76,7 @@ if ($statut != '') {
$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
-if ($search_status < -1) {
+if ($search_status < -2) {
$search_status = '';
}
@@ -162,6 +159,9 @@ $arrayfields = array(
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
+// Security check
+$result = restrictedArea($user, 'adherent');
+
/*
* Actions
@@ -302,13 +302,13 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on (s.rowid = d.fk_soc)";
$sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
$sql .= " WHERE d.fk_adherent_type = t.rowid ";
if ($catid > 0) {
- $sql .= " AND cm.fk_categorie = ".$db->escape($catid);
+ $sql .= " AND cm.fk_categorie = ".((int) $catid);
}
if ($catid == -2) {
$sql .= " AND cm.fk_categorie IS NULL";
}
if ($search_categ > 0) {
- $sql .= " AND cm.fk_categorie = ".$db->escape($search_categ);
+ $sql .= " AND cm.fk_categorie = ".((int) $search_categ);
}
if ($search_categ == -2) {
$sql .= " AND cm.fk_categorie IS NULL";
@@ -379,7 +379,7 @@ if ($search_phone_mobile) {
$sql .= natural_search("d.phone_mobile", $search_phone_mobile);
}
if ($search_country) {
- $sql .= " AND d.country IN (".$search_country.')';
+ $sql .= " AND d.country IN (".$db->sanitize($search_country).')';
}
// Add where from extra fields
@@ -452,6 +452,9 @@ if (GETPOSTISSET("search_status")) {
if ($search_status == '0') {
$titre = $langs->trans("MembersListResiliated");
}
+ if ($search_status == '-2') {
+ $titre = $langs->trans("MembersListExcluded");
+ }
} elseif ($action == 'search') {
$titre = $langs->trans("MembersListQualified");
}
@@ -750,9 +753,10 @@ if (!empty($arrayfields['d.statut']['checked'])) {
$liststatus = array(
'-1'=>$langs->trans("Draft"),
'1'=>$langs->trans("Validated"),
- '0'=>$langs->trans("Resiliated")
+ '0'=>$langs->trans("Resiliated"),
+ '-2'=>$langs->trans("Excluded")
);
- print $form->selectarray('search_status', $liststatus, $search_status, -2);
+ print $form->selectarray('search_status', $liststatus, $search_status, -3);
print '';
}
// Action column
diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php
index 437a8c0c577..26fec04a5e6 100644
--- a/htdocs/adherents/note.php
+++ b/htdocs/adherents/note.php
@@ -57,9 +57,12 @@ include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include,
/*
* View
*/
+
$title = $langs->trans("Member")." - ".$langs->trans("Note");
-$helpurl = "EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros";
-llxHeader("", $title, $helpurl);
+
+$help_url = "EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros|DE:Modul_Mitglieder";
+
+llxHeader("", $title, $help_url);
$form = new Form($db);
diff --git a/htdocs/adherents/stats/byproperties.php b/htdocs/adherents/stats/byproperties.php
index 9f8691a69a6..1238fd0fe15 100644
--- a/htdocs/adherents/stats/byproperties.php
+++ b/htdocs/adherents/stats/byproperties.php
@@ -59,7 +59,7 @@ $title = $langs->trans("MembersStatisticsByProperties");
print load_fiche_titre($title, '', $memberstatic->picto);
-dol_mkdir($dir);
+//dol_mkdir($dir);
$data = array();
@@ -134,7 +134,7 @@ if ($resql) {
}
-$head = member_stats_prepare_head($adh);
+$head = member_stats_prepare_head($memberstatic);
print dol_get_fiche_head($head, 'statsbyproperties', '', -1, '');
@@ -169,7 +169,7 @@ if (!$foundmor) {
foreach ($data as $val) {
$nb = $val['nb'];
- $nbsubscriptions = $val['nbsubscriptions'];
+ $nbsubscriptions = isset($val['nbsubscriptions']) ? $val['nbsubscriptions'] : 0;
$nbactive = $val['nbactive'];
print '
';
diff --git a/htdocs/adherents/stats/geo.php b/htdocs/adherents/stats/geo.php
index 6107669c967..2d1450b8ae5 100644
--- a/htdocs/adherents/stats/geo.php
+++ b/htdocs/adherents/stats/geo.php
@@ -78,7 +78,7 @@ llxHeader('', $title, '', '', 0, 0, $arrayjs);
print load_fiche_titre($title, '', $memberstatic->picto);
-dol_mkdir($dir);
+//dol_mkdir($dir);
if ($mode) {
// Define sql
@@ -87,7 +87,7 @@ if ($mode) {
$tab = 'statscountry';
$data = array();
- $sql .= "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, c.code, c.label";
+ $sql = "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, c.code, c.label";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c on d.country = c.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."subscription as s ON s.fk_adherent = d.rowid";
@@ -103,7 +103,7 @@ if ($mode) {
$tab = 'statsstate';
$data = array();
- $sql .= "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, co.code, co.label, c.nom as label2"; //
+ $sql = "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, co.code, co.label, c.nom as label2"; //
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c on d.state_id = c.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as r on c.fk_region = r.code_region";
@@ -120,7 +120,7 @@ if ($mode) {
$tab = 'statsregion'; //onglet
$data = array(); //tableau de donnée
- $sql .= "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, co.code, co.label, r.nom as label2";
+ $sql = "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, co.code, co.label, r.nom as label2";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c on d.state_id = c.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as r on c.fk_region = r.code_region";
@@ -137,7 +137,7 @@ if ($mode) {
$tab = 'statstown';
$data = array();
- $sql .= "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, c.code, c.label, d.town as label2";
+ $sql = "SELECT COUNT(DISTINCT d.rowid) as nb, COUNT(s.rowid) as nbsubscriptions, MAX(d.datevalid) as lastdate, MAX(s.dateadh) as lastsubscriptiondate, c.code, c.label, d.town as label2";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c on d.country = c.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."subscription as s ON s.fk_adherent = d.rowid";
@@ -207,7 +207,7 @@ if ($mode) {
}
-$head = member_stats_prepare_head($adh);
+$head = member_stats_prepare_head($memberstatic);
print dol_get_fiche_head($head, $tab, '', -1, '');
@@ -299,7 +299,7 @@ if ($mode) {
print '
';
print '
';
print '
'.$label.'
';
- if ($label2) {
+ if (isset($label2)) {
print '
'."\n";
diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php
index ecc30c74ac9..e6211f0b56f 100644
--- a/htdocs/admin/barcode.php
+++ b/htdocs/admin/barcode.php
@@ -121,7 +121,7 @@ if ($action == 'setcoder') {
$form = new Form($db);
$formbarcode = new FormBarCode($db);
-$help_url = 'EN:Module_Barcode|FR:Module_Codes_Barre|ES:Módulo Código de barra';
+$help_url = 'EN:Module_Barcode|FR:Module_Codes_Barre|ES:Módulo Código de barra|DE:Modul_Barcode';
llxHeader('', $langs->trans("BarcodeSetup"), $help_url);
$linkback = ''.$langs->trans("BackToModuleList").'';
diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php
index b28c81a25b1..5b89eefc4f7 100644
--- a/htdocs/admin/boxes.php
+++ b/htdocs/admin/boxes.php
@@ -49,8 +49,8 @@ $boxes = array();
*/
if ($action == 'addconst') {
- dolibarr_set_const($db, "MAIN_BOXES_MAXLINES", $_POST["MAIN_BOXES_MAXLINES"], '', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_ACTIVATE_FILECACHE", $_POST["MAIN_ACTIVATE_FILECACHE"], 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_BOXES_MAXLINES", GETPOST("MAIN_BOXES_MAXLINES", 'int'), '', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_ACTIVATE_FILECACHE", GETPOST("MAIN_ACTIVATE_FILECACHE", 'alpha'), 'chaine', 0, '', $conf->entity);
}
if ($action == 'add') {
diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php
index 6fb4430d88e..89363a9027b 100644
--- a/htdocs/admin/commande.php
+++ b/htdocs/admin/commande.php
@@ -9,6 +9,7 @@
* Copyright (C) 2011-2013 Juanjo Menent
* Copyright (C) 2011-2016 Philippe Grand
* Copyright (C) 2013 Florian Henry
+ * Copyright (C) 2021 Frédéric France
*
* 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
@@ -642,7 +643,7 @@ print '';
// Shippable Icon in List
/* Kept as hidden feature for the moment, result seems bugged.
-Whet is definition of "shippable" according to all different STOCK_CALCULATE_... options ?
+Where is definition of "shippable" according to all different STOCK_CALCULATE_... options ?
print '
';
+*/
/*
// Seems to be not so used. So kept hidden for the moment to avoid dangerous options inflation.
// Ask for payment bank during order
-if ($conf->banque->enabled)
-{
+if ($conf->banque->enabled) {
print '
\n";
}
// Web user group real (detected by 'id' external command)
-$arrayout = array(); $varout = 0;
-exec('id', $arrayout, $varout);
-if (empty($varout)) { // Test command is ok. Work only on Linux OS.
- print '
\n";
+if (function_exists('exec')) {
+ $arrayout = array(); $varout = 0;
+ exec('id', $arrayout, $varout);
+ if (empty($varout)) { // Test command is ok. Work only on Linux OS.
+ print '
";
}
-/* ************************************************************************** */
-/* */
-/* Creation d'un champ optionnel */
-/* */
-/* ************************************************************************** */
-
+// Creation of an optional field
if ($action == 'create') {
print " ";
print load_fiche_titre($langs->trans('NewAttribute'));
@@ -97,11 +92,7 @@ if ($action == 'create') {
include DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
}
-/* ************************************************************************** */
-/* */
-/* Edition d'un champ optionnel */
-/* */
-/* ************************************************************************** */
+// Edition of an optional field
if ($action == 'edit' && !empty($attrname)) {
print " ";
print load_fiche_titre($langs->trans("FieldEdition", $attrname));
diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php
index 7d97b4f7dbe..98ce554c363 100644
--- a/htdocs/admin/ticket_public.php
+++ b/htdocs/admin/ticket_public.php
@@ -59,6 +59,38 @@ if ($action == 'setTICKET_ENABLE_PUBLIC_INTERFACE') {
if ($action == 'setvar') {
include_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
+ if (GETPOSTISSET('TICKET_ENABLE_PUBLIC_INTERFACE')) { // only for no js case
+ $param_enable_public_interface = GETPOST('TICKET_ENABLE_PUBLIC_INTERFACE', 'alpha');
+ $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', $param_enable_public_interface, 'chaine', 0, '', $conf->entity);
+ if (!($res > 0)) {
+ $error++;
+ }
+ }
+
+ if (GETPOSTISSET('TICKET_EMAIL_MUST_EXISTS')) { // only for no js case
+ $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha');
+ $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity);
+ if (!($res > 0)) {
+ $error++;
+ }
+ }
+
+ if (GETPOSTISSET('TICKET_DISABLE_CUSTOMER_MAILS')) { // only for no js case
+ $param_disable_email = GETPOST('TICKET_DISABLE_CUSTOMER_MAILS', 'alpha');
+ $res = dolibarr_set_const($db, 'TICKET_DISABLE_CUSTOMER_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity);
+ if (!($res > 0)) {
+ $error++;
+ }
+ }
+
+ if (GETPOSTISSET('TICKET_SHOW_COMPANY_LOGO')) { // only for no js case
+ $param_show_module_logo = GETPOST('TICKET_SHOW_COMPANY_LOGO', 'alpha');
+ $res = dolibarr_set_const($db, 'TICKET_SHOW_COMPANY_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity);
+ if (!($res > 0)) {
+ $error++;
+ }
+ }
+
$topic_interface = GETPOST('TICKET_PUBLIC_INTERFACE_TOPIC', 'nohtml');
if (!empty($topic_interface)) {
$res = dolibarr_set_const($db, 'TICKET_PUBLIC_INTERFACE_TOPIC', $topic_interface, 'chaine', 0, '', $conf->entity);
@@ -114,32 +146,6 @@ if ($action == 'setvar') {
if (!($res > 0)) {
$error++;
}
-}
-
-if ($action == 'setvarother') {
- $param_enable_public_interface = GETPOST('TICKET_ENABLE_PUBLIC_INTERFACE', 'alpha');
- $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', $param_enable_public_interface, 'chaine', 0, '', $conf->entity);
- if (!($res > 0)) {
- $error++;
- }
-
- $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha');
- $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity);
- if (!($res > 0)) {
- $error++;
- }
-
- $param_disable_email = GETPOST('TICKET_DISABLE_CUSTOMER_MAILS', 'alpha');
- $res = dolibarr_set_const($db, 'TICKET_DISABLE_CUSTOMER_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity);
- if (!($res > 0)) {
- $error++;
- }
-
- $param_show_module_logo = GETPOST('TICKET_SHOW_COMPANY_LOGO', 'alpha');
- $res = dolibarr_set_const($db, 'TICKET_SHOW_COMPANY_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity);
- if (!($res > 0)) {
- $error++;
- }
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
$param_notification_also_main_addressemail = GETPOST('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', 'alpha');
@@ -197,18 +203,16 @@ print '';
- print '';
- print '';
- }
+ print '';
- }
-
- // Admin var of module
- print load_fiche_titre($langs->trans("TicketParamMail"));
-
- print '
';
- print '
';
-
- print '
";
+ // Code to adjust value date with plus and less picto using an Ajax call instead of a full reload of page
+ $urlajax = DOL_URL_ROOT.'/core/ajax/bankconciliate.php?token='.currentToken();
+ print '
+
+ ';
+
print "
";
print "\n";
diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php
index 1d0613ead0a..c94f8810cd8 100644
--- a/htdocs/compta/bank/transfer.php
+++ b/htdocs/compta/bank/transfer.php
@@ -5,7 +5,7 @@
* Copyright (C) 2012 Juanjo Menent
* Copyright (C) 2015 Jean-François Ferry
* Copyright (C) 2015 Marcos García
- * Copyright (C) 2018 Frédéric France
+ * Copyright (C) 2018-2021 Frédéric France
*
* 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,7 +33,10 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
// Load translation files required by the page
$langs->loadLangs(array("banks", "categories", "multicurrency"));
-
+$socid = 0;
+if ($user->socid > 0) {
+ $socid = $user->socid;
+}
if (!$user->rights->banque->transfer) {
accessforbidden();
}
@@ -230,6 +233,7 @@ $account_from = '';
$account_to = '';
$label = '';
$amount = '';
+$amountto = '';
if ($error) {
$account_from = GETPOST('account_from', 'int');
diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php
index b1dac2858b0..6ccd953a68b 100644
--- a/htdocs/compta/bank/treso.php
+++ b/htdocs/compta/bank/treso.php
@@ -37,22 +37,23 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$langs->loadLangs(array('banks', 'categories', 'bills', 'companies'));
// Security check
-if (isset($_GET["account"]) || isset($_GET["ref"])) {
- $id = isset($_GET["account"]) ? $_GET["account"] : (isset($_GET["ref"]) ? $_GET["ref"] : '');
+if (GETPOSTISSET("account") || GETPOSTISSET("ref")) {
+ $id = GETPOSTISSET("account") ? GETPOST("account") : (GETPOSTISSET("ref") ? GETPOST("ref") : '');
}
-$fieldid = isset($_GET["ref"]) ? 'ref' : 'rowid';
+$fieldid = GETPOSTISSET("ref") ? 'ref' : 'rowid';
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid);
-$vline = isset($_GET["vline"]) ? $_GET["vline"] : $_POST["vline"];
-$page = isset($_GET["page"]) ? $_GET["page"] : 0;
+$vline = GETPOST('vline');
+$page = GETPOSTISSET("page") ? GETPOST("page") : 0;
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('banktreso', 'globalcard'));
+
/*
* View
*/
@@ -68,7 +69,7 @@ $socialcontribstatic = new ChargeSociales($db);
$form = new Form($db);
-if ($_REQUEST["account"] || $_REQUEST["ref"]) {
+if (GETPOST("account") || GETPOST("ref")) {
if ($vline) {
$viewline = $vline;
} else {
@@ -76,11 +77,11 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) {
}
$object = new Account($db);
- if ($_GET["account"]) {
- $result = $object->fetch($_GET["account"]);
+ if (GETPOST("account", 'int')) {
+ $result = $object->fetch(GETPOST("account", 'int'));
}
- if ($_GET["ref"]) {
- $result = $object->fetch(0, $_GET["ref"]);
+ if (GETPOST("ref")) {
+ $result = $object->fetch(0, GETPOST("ref"));
$_GET["account"] = $object->id;
}
@@ -91,6 +92,8 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) {
$linkback = ''.$langs->trans("BackToList").'';
+ $morehtmlref = '';
+
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1);
print dol_get_fiche_end();
diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php
index d19ccbed908..2b4a68bec90 100644
--- a/htdocs/compta/bank/various_payment/card.php
+++ b/htdocs/compta/bank/various_payment/card.php
@@ -665,7 +665,7 @@ if ($id) {
/*
- * Action buttons
+ * Action bar
*/
print '
'."\n";
diff --git a/htdocs/compta/bank/various_payment/list.php b/htdocs/compta/bank/various_payment/list.php
index 39cbb91fde1..dcc1f4aef97 100644
--- a/htdocs/compta/bank/various_payment/list.php
+++ b/htdocs/compta/bank/various_payment/list.php
@@ -264,10 +264,6 @@ if ($search_accountancy_subledger > 0) {
if ($typeid > 0) {
$sql .= " AND v.fk_typepayment=".$typeid;
}
-if ($filtre) {
- $filtre = str_replace(":", "=", $filtre);
- $sql .= " AND ".$filtre;
-}
if ($search_all) {
$sql .= natural_search(array_keys($fieldstosearchall), $search_all);
}
@@ -675,7 +671,7 @@ if ($result) {
if ($arrayfields['debit']['checked']) {
print '
';
if ($obj->sens == 0) {
- print price($obj->amount);
+ print ''.price($obj->amount).'';
$totalarray['val']['total_deb'] += $obj->amount;
}
if (!$i) {
@@ -691,7 +687,7 @@ if ($result) {
if ($arrayfields['credit']['checked']) {
print '
';
if ($obj->sens == 1) {
- print price($obj->amount);
+ print ''.price($obj->amount).'';
$totalarray['val']['total_cred'] += $obj->amount;
}
if (!$i) {
diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php
index da018dd1f06..ccaa0158af2 100644
--- a/htdocs/compta/cashcontrol/cashcontrol_card.php
+++ b/htdocs/compta/cashcontrol/cashcontrol_card.php
@@ -67,11 +67,6 @@ if ($contextpage == 'takepos') {
$_GET['optioncss'] = 'print';
}
-// Security check
-if (!$user->rights->cashdesk->run && !$user->rights->takepos->run) {
- accessforbidden();
-}
-
$arrayofpaymentmode = array('cash'=>'Cash', 'cheque'=>'Cheque', 'card'=>'CreditCard');
$arrayofposavailable = array();
@@ -95,6 +90,15 @@ $hookmanager->initHooks(array('cashcontrolcard', 'globalcard'));
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
+// Security check
+if ($user->socid > 0) { // Protection if external user
+ //$socid = $user->socid;
+ accessforbidden();
+}
+if (!$user->rights->cashdesk->run && !$user->rights->takepos->run) {
+ accessforbidden();
+}
+
/*
* Actions
diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php
index 6c4141e4b6a..79ac1e1b708 100644
--- a/htdocs/compta/cashcontrol/cashcontrol_list.php
+++ b/htdocs/compta/cashcontrol/cashcontrol_list.php
@@ -31,14 +31,17 @@
//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on).
//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
-//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
+//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
+//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value
//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler
//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
+//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
+//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
+//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php';
@@ -66,7 +69,7 @@ $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
+if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
$page = 0;
} // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
@@ -83,32 +86,30 @@ $hookmanager->initHooks(array('cashcontrol')); // Note that conf->hooks_modules
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
+//$extrafields->fetch_name_optionals_label($object->table_element_line);
$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
// Default sort order (if not yet defined by previous GETPOST)
if (!$sortfield) {
+ reset($object->fields); // Reset is required to avoid key() to return null.
$sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
}
if (!$sortorder) {
$sortorder = "ASC";
}
-// Security check
-$socid = 0;
-if ($user->socid > 0) { // Protection if external user
- //$socid = $user->socid;
- accessforbidden();
-}
-//$result = restrictedArea($user, 'monmodule', $id, '');
-
// Initialize array of search criterias
-$search_all = GETPOST("search_all", 'alpha');
+$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml');
$search = array();
foreach ($object->fields as $key => $val) {
- if (GETPOST('search_'.$key, 'alpha')) {
+ if (GETPOST('search_'.$key, 'alpha') !== '') {
$search[$key] = GETPOST('search_'.$key, 'alpha');
}
+ if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
+ $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
+ $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
+ }
}
// List of fields to search into when doing a "search in all"
@@ -133,6 +134,14 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
+// Security check
+if ($user->socid > 0) { // Protection if external user
+ //$socid = $user->socid;
+ accessforbidden();
+}
+if (!$user->rights->cashdesk->run && !$user->rights->takepos->run) {
+ accessforbidden();
+}
/*
@@ -161,6 +170,10 @@ if (empty($reshook)) {
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
foreach ($object->fields as $key => $val) {
$search[$key] = '';
+ if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
+ $search[$key.'_dtstart'] = '';
+ $search[$key.'_dtend'] = '';
+ }
}
$toselect = '';
$search_array_options = array();
@@ -198,9 +211,7 @@ $title = $langs->trans('CashControl');
// Build and execute select
// --------------------------------------------------------------------
$sql = 'SELECT ';
-foreach ($object->fields as $key => $val) {
- $sql .= 't.'.$key.', ';
-}
+$sql .= $object->getFieldList('t');
// Add fields from extrafields
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
@@ -210,24 +221,48 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-$sql = preg_replace('/, $/', '', $sql);
+$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
+$sql = preg_replace('/,\s*$/', '', $sql);
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
}
+// Add table from hooks
+$parameters = array();
+$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
+$sql .= $hookmanager->resPrint;
if ($object->ismultientitymanaged == 1) {
$sql .= " WHERE t.entity IN (".getEntity($object->element).")";
} else {
$sql .= " WHERE 1 = 1";
}
foreach ($search as $key => $val) {
- if ($key == 'status' && $search[$key] == -1) {
- continue;
- }
- $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
- if ($search[$key] != '') {
- $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search));
+ if (array_key_exists($key, $object->fields)) {
+ if ($key == 'status' && $search[$key] == -1) {
+ continue;
+ }
+ $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
+ if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0)) {
+ if ($search[$key] == '-1' || $search[$key] === '0') {
+ $search[$key] = '';
+ }
+ $mode_search = 2;
+ }
+ if ($search[$key] != '') {
+ $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search));
+ }
+ } else {
+ if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
+ $columnName=preg_replace('/(_dtstart|_dtend)$/', '', $key);
+ if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
+ if (preg_match('/_dtstart$/', $key)) {
+ $sql .= " AND t." . $columnName . " >= '" . $db->idate($search[$key]) . "'";
+ }
+ if (preg_match('/_dtend$/', $key)) {
+ $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'";
+ }
+ }
+ }
}
}
if ($search_all) {
@@ -241,20 +276,20 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec
$sql .= $hookmanager->resPrint;
/* If a group by is required
- $sql.= " GROUP BY "
- foreach($object->fields as $key => $val)
- {
- $sql.='t.'.$key.', ';
- }
- // Add fields from extrafields
- if (! empty($extrafields->attributes[$object->table_element]['label'])) {
- foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
- // Add where from hooks
- $parameters=array();
- $reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook
- $sql.=$hookmanager->resPrint;
- $sql=preg_replace('/, $/','', $sql);
- */
+$sql.= " GROUP BY ";
+foreach($object->fields as $key => $val) {
+ $sql.='t.'.$key.', ';
+}
+// Add fields from extrafields
+if (! empty($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
+}
+// Add where from hooks
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters, $object); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
+$sql=preg_replace('/,\s*$/','', $sql);
+*/
$sql .= $db->order($sortfield, $sortorder);
@@ -269,10 +304,12 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
}
}
// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
-if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
+if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) {
$num = $nbtotalofrecords;
} else {
- $sql .= $db->plimit($limit + 1, $offset);
+ if ($limit) {
+ $sql .= $db->plimit($limit + 1, $offset);
+ }
$resql = $db->query($sql);
if (!$resql) {
@@ -284,10 +321,10 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
}
// Direct jump if only one record found
-if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) {
+if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
$obj = $db->fetch_object($resql);
$id = $obj->rowid;
- header("Location: ".dol_buildpath('/compta/cashcontrol/cashcontrol_card.php', 1).'?id='.$id);
+ header("Location: ".DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_card.php?id='.$id);
exit;
}
@@ -295,7 +332,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $
// Output page
// --------------------------------------------------------------------
-llxHeader('', $title, $help_url);
+llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'classforhorizontalscrolloftabs');
// Example : Adding jquery code
print '';
+
+if ($projectid > 0) {
+ // To verify role of users
+ //$userAccess = $object->restrictedProjectArea($user,'read');
+ $userWrite = $project->restrictedProjectArea($user, 'write');
+ //$userDelete = $object->restrictedProjectArea($user,'delete');
+ //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
+
+ $head = project_prepare_head($project);
+ print dol_get_fiche_head($head, 'eventorganisation', $langs->trans("Project"), -1, ($project->public ? 'projectpub' : 'project'));
+
+ // Project card
+ $linkback = ''.$langs->trans("BackToList").'';
+
+ $morehtmlref = '