From ce283b6546f34640cfc10777d9ccb45a1a3b6d84 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Apr 2023 22:21:14 +0200 Subject: [PATCH 01/15] Doc --- htdocs/core/login/README.txt | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/htdocs/core/login/README.txt b/htdocs/core/login/README.txt index 8128dfacd57..0231ef807fa 100644 --- a/htdocs/core/login/README.txt +++ b/htdocs/core/login/README.txt @@ -3,24 +3,27 @@ README (english) Decription of htdocs/core/login directory --------------------------------------------- -This directory contains files that handle way to validate passwords. +This directory contains files that handle the way to validate passwords. -If you want to add a new password checker function, just add a file in -this directory that follow example of already existing files. +If you want to add a new password checker function, just add a file in this directory that follow an example of an already existing files. This file must be called for example : -functions_mypasschecker.php + functions_mypasschecker.php -Edit function name to call it: -check_user_mypasschecker +Edit the function name to call it: + check_user_mypasschecker -Change code of this function to return true if couple -$usertotest / $passwordtotest is ok for you. +Change code of this function to return true if couple $usertotest / $passwordtotest is ok for you. Then, you must edit you conf.php file to change the value of -$dolibarr_main_authentication + $dolibarr_main_authentication parameter to set it to : -mypasschecker + mypasschecker Once this is done, when you log in to Dolibarr, the function check_user_mypasschecker in this file is called. If the function return true and login exists, login is accepted. + + + +See page https://wiki.dolibarr.org/index.php?title=Authentication,_SSO_and_SSL for more information. + From 998b2b263ee83860f0c2d9889198f3790c19bcf7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Apr 2023 23:42:05 +0200 Subject: [PATCH 02/15] Fix public virtual card --- htdocs/public/users/view.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/htdocs/public/users/view.php b/htdocs/public/users/view.php index 53bc597aaa9..4da6d3baad9 100644 --- a/htdocs/public/users/view.php +++ b/htdocs/public/users/view.php @@ -269,12 +269,7 @@ if ($showbarcode) { } -// Me -// Show photo -if ($urllogo) { - print ''; -} - +// Me section $usersection = ''; @@ -325,6 +320,11 @@ if (!empty($object->socialnetworks) && is_array($object->socialnetworks) && coun } if ($usersection) { + // Show photo + if ($urllogo) { + print ''; + } + print ''."\n"; // Output payment summary form @@ -340,6 +340,11 @@ if ($usersection) { print ''."\n"; print '
'."\n"; +} else { + // Show photo + if ($urllogo) { + print '
'; + } } From 863a9eb440ab7744945b42dd02c74c95e6956b01 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 20 Apr 2023 12:20:50 +0200 Subject: [PATCH 03/15] Fix: we should not mention external modules --- htdocs/core/modules/modPaypal.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modPaypal.class.php b/htdocs/core/modules/modPaypal.class.php index 02caa6c3388..82da86230a3 100644 --- a/htdocs/core/modules/modPaypal.class.php +++ b/htdocs/core/modules/modPaypal.class.php @@ -72,7 +72,7 @@ class modPaypal extends DolibarrModules // Dependencies $this->hidden = false; // A condition to hide module $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled - $this->requiredby = array('modPaypalPlus'); // List of module ids to disable if this one is disabled + $this->requiredby = array(); // List of module ids to disable if this one is disabled $this->conflictwith = array(); // List of module class names as string this module is in conflict with $this->phpmin = array(7, 0); // Minimum version of PHP required by module $this->need_dolibarr_version = array(3, 0); // Minimum version of Dolibarr required by module From 6dea0425cf8a98dd7946611558bd68312f70ddbd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 20 Apr 2023 12:21:55 +0200 Subject: [PATCH 04/15] No ambigous test --- htdocs/public/payment/paymentok.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 81fac152717..6cfc2e4e81b 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -121,7 +121,7 @@ if (preg_match('/PM=([^\.]+)/', $FULLTAG, $reg)) { $paymentmethod = $reg[1]; } if (empty($paymentmethod)) { - dol_print_error(null, 'The back url does not contains a parameter fulltag that should help us to find the payment method used'); + dol_print_error(null, 'The callback url does not contains a parameter fulltag that should help us to find the payment method used'); exit; } @@ -250,7 +250,7 @@ print '


'; if (isModEnabled('paypal')) { - if ($paymentmethod == 'paypal') { // We call this page only if payment is ok on payment system + if ($paymentmethod === 'paypal') { // We call this page only if payment is ok on payment system if ($PAYPALTOKEN) { // Get on url call $onlinetoken = $PAYPALTOKEN; @@ -330,14 +330,14 @@ if (isModEnabled('paypal')) { } if (isModEnabled('paybox')) { - if ($paymentmethod == 'paybox') { + if ($paymentmethod === 'paybox') { // TODO Add a check to validate that payment is ok. $ispaymentok = true; // We call this page only if payment is ok on payment system } } if (isModEnabled('stripe')) { - if ($paymentmethod == 'stripe') { + if ($paymentmethod === 'stripe') { // TODO Add a check to validate that payment is ok. We can request Stripe with payment_intent and payment_intent_client_secret $ispaymentok = true; // We call this page only if payment is ok on payment system } From a39ceee42684fba6b315578847cdc4d3de5910a4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 20 Apr 2023 13:01:24 +0200 Subject: [PATCH 05/15] Log --- htdocs/public/payment/paymentok.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 6cfc2e4e81b..bd12e9be48c 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -121,6 +121,7 @@ if (preg_match('/PM=([^\.]+)/', $FULLTAG, $reg)) { $paymentmethod = $reg[1]; } if (empty($paymentmethod)) { + dol_syslog("***** paymentok.php was called with a non valid parameter FULLTAG=".$FULLTAG, LOG_DEBUG, 0, '_payment'); dol_print_error(null, 'The callback url does not contains a parameter fulltag that should help us to find the payment method used'); exit; } From 692eee1e2571436eef1aca5f673cb3de3af65ca0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 20 Apr 2023 13:14:50 +0200 Subject: [PATCH 06/15] FIX bad message oncallback of online payment --- htdocs/public/payment/paymentok.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index bd12e9be48c..84110d58353 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -351,11 +351,14 @@ $parameters = [ ]; $reshook = $hookmanager->executeHooks('isPaymentOK', $parameters, $object, $action); if ($reshook >= 0) { - $ispaymentok = $hookmanager->resArray['ispaymentok']; + if (isset($hookmanager->resArray['ispaymentok'])) { + dol_syslog('ispaymentok overwrite by hook return with value='.$hookmanager->resArray['ispaymentok'], LOG_DEBUG, 0, '_payment'); + $ispaymentok = $hookmanager->resArray['ispaymentok']; + } } -// If data not provided from back url, search them into the session env +// If data not provided into callback url, search them into the session env if (empty($ipaddress)) { $ipaddress = $_SESSION['ipaddress']; } @@ -815,13 +818,13 @@ if ($ispaymentok) { $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; $paymentTypeId = 0; - if ($paymentmethod == 'paybox') { + if ($paymentmethod === 'paybox') { $paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS; } - if ($paymentmethod == 'paypal') { + if ($paymentmethod === 'paypal') { $paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS; } - if ($paymentmethod == 'stripe') { + if ($paymentmethod === 'stripe') { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { From c6aa069705537da1cc6b6df5ea8f176f72516cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Apr 2023 18:32:09 +0200 Subject: [PATCH 07/15] Fix :heart_eyes: in dolibarr when using utf8mb4 --- htdocs/core/db/mysqli.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index aaeaaf4c910..ff38a549938 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -112,7 +112,7 @@ class DoliDBMysqli extends DoliDB $this->ok = true; // If client is old latin, we force utf8 - $clientmustbe = empty($conf->db->dolibarr_main_db_character_set) ? 'utf8' : $conf->db->dolibarr_main_db_character_set; + $clientmustbe = empty($conf->db->character_set) ? 'utf8' : $conf->db->db_character_set; if (preg_match('/latin1/', $clientmustbe)) { $clientmustbe = 'utf8'; } From 9ae24a03697762eda3a45564b4883d718335f2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Apr 2023 18:46:40 +0200 Subject: [PATCH 08/15] fix bad edit :flushed: --- htdocs/core/db/mysqli.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index ff38a549938..837ec5d385c 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -112,7 +112,7 @@ class DoliDBMysqli extends DoliDB $this->ok = true; // If client is old latin, we force utf8 - $clientmustbe = empty($conf->db->character_set) ? 'utf8' : $conf->db->db_character_set; + $clientmustbe = empty($conf->db->character_set) ? 'utf8' : $conf->db->character_set; if (preg_match('/latin1/', $clientmustbe)) { $clientmustbe = 'utf8'; } From 163bd91ebe4dc1d0afa4c00daf5beea1ecfeb00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Apr 2023 18:53:04 +0200 Subject: [PATCH 09/15] Update mysqli.class.php --- htdocs/core/db/mysqli.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 837ec5d385c..68906fbf481 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -142,7 +142,7 @@ class DoliDBMysqli extends DoliDB if ($this->connected) { // If client is old latin, we force utf8 - $clientmustbe = empty($conf->db->dolibarr_main_db_character_set) ? 'utf8' : $conf->db->dolibarr_main_db_character_set; + $clientmustbe = empty($conf->db->character_set) ? 'utf8' : $conf->db->character_set; if (preg_match('/latin1/', $clientmustbe)) { $clientmustbe = 'utf8'; } From dbfc6d0715e8f07a11b24b2b010e4a9e05251d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Apr 2023 22:12:56 +0200 Subject: [PATCH 10/15] add hooks in ecm card --- htdocs/ecm/index.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 6f4b9577c92..7e4e76080f8 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -89,6 +89,8 @@ $permissiontocreatedir = $user->hasRight('ecm', 'setup'); $permissiontodelete = $user->hasRight('ecm', 'upload'); $permissiontodeletedir = $user->hasRight('ecm', 'setup'); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('ecmindexcard', 'globalcard')); /* * Actions From 78ae00d34279a408d41650e8d00ed2399601626a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 20 Apr 2023 22:14:02 +0200 Subject: [PATCH 11/15] add init hook --- htdocs/ecm/index_medias.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/ecm/index_medias.php b/htdocs/ecm/index_medias.php index 39118774430..a9e887a7e43 100644 --- a/htdocs/ecm/index_medias.php +++ b/htdocs/ecm/index_medias.php @@ -102,6 +102,8 @@ $websitekey = ''; $permissiontoadd = $permissiontouploadfile; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('ecmmediascard', 'globalcard')); /* * Actions From 9859720dc3a21fcd02c9705406943f6f3adf46c1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 21 Apr 2023 13:27:50 +0200 Subject: [PATCH 12/15] Clean module dependency system --- htdocs/admin/modulehelp.php | 26 ++++++++-- htdocs/blockedlog/admin/blockedlog_list.php | 5 +- htdocs/core/class/menubase.class.php | 2 +- htdocs/core/lib/admin.lib.php | 52 ++++++++++++------- htdocs/core/modules/modBom.class.php | 7 +-- htdocs/core/modules/modBookCal.class.php | 2 +- .../modules/modEventOrganization.class.php | 2 +- .../modules/modKnowledgeManagement.class.php | 2 +- htdocs/core/modules/modMrp.class.php | 2 +- htdocs/core/modules/modPartnership.class.php | 2 +- htdocs/core/modules/modRecruitment.class.php | 2 +- .../core/modules/modStockTransfer.class.php | 2 +- htdocs/core/modules/modTakePos.class.php | 3 +- htdocs/core/modules/modWebhook.class.php | 2 +- htdocs/core/modules/modWorkstation.class.php | 2 +- htdocs/core/modules/modZapier.class.php | 2 +- .../core/modules/modMyModule.class.php | 8 +-- 17 files changed, 80 insertions(+), 43 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 09172e985e9..ecbe14e76f4 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -369,14 +369,32 @@ if ($mode == 'desc') { if ($mode == 'feature') { $text .= '
'.$langs->trans("DependsOn").': '; - if (count($objMod->depends)) { - $text .= join(',', $objMod->depends); + if (is_array($objMod->depends) && count($objMod->depends)) { + $i = 0; + foreach($objMod->depends as $modulestringorarray) { + if (is_array($modulestringorarray)) { + $text .= ($i ? ', ' : '').join(', ', $modulestringorarray); + } else { + $text .= ($i ? ', ' : '').$modulestringorarray; + } + $i++; + } } else { $text .= ''.$langs->trans("None").''; } + $text .= '
'; + $text .= '
'.$langs->trans("RequiredBy").': '; - if (count($objMod->requiredby)) { - $text .= join(',', $objMod->requiredby); + if (is_array($objMod->requiredby) && count($objMod->requiredby)) { + $i = 0; + foreach($objMod->requiredby as $modulestringorarray) { + if (is_array($modulestringorarray)) { + $text .= ($i ? ', ' : '').join(', ', $modulestringorarray); + } else { + $text .= ($i ? ', ' : '').$modulestringorarray; + } + $i++; + } } else { $text .= ''.$langs->trans("None").''; } diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index bf5a07f98b5..8d03c029cd6 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -550,7 +550,10 @@ if (is_array($blocks)) { print ''; // Link to source object - print ''.$object_link.''; + print ''; + print ''; // $object_link can be a ''; // Amount print ''.price($block->amounts).''; diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php index 2965db0f7c5..f289e2c8cf9 100644 --- a/htdocs/core/class/menubase.class.php +++ b/htdocs/core/class/menubase.class.php @@ -313,7 +313,7 @@ class Menubase } } else { dol_syslog(get_class($this)."::create menu entry already exists", LOG_WARNING); - $this->error = 'Error Menu entry already exists'; + $this->error = 'Error Menu entry ('.$this->menu_handler.','.$this->position.','.$this->url.') already exists'; return 0; } } else { diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 0064fad3bc7..572b4219bd4 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1166,33 +1166,45 @@ function activateModule($value, $withdeps = 1, $noconfverification = 0) if ($withdeps) { if (isset($objMod->depends) && is_array($objMod->depends) && !empty($objMod->depends)) { // Activation of modules this module depends on - // this->depends may be array('modModule1', 'mmodModule2') or array('always1'=>"modModule1", 'FR'=>'modModule2') - foreach ($objMod->depends as $key => $modulestring) { + // this->depends may be array('modModule1', 'mmodModule2') or array('always'=>array('modModule1'), 'FR'=>array('modModule2")) + foreach ($objMod->depends as $key => $modulestringorarray) { //var_dump((! is_numeric($key)) && ! preg_match('/^always/', $key) && $mysoc->country_code && ! preg_match('/^'.$mysoc->country_code.'/', $key));exit; if ((!is_numeric($key)) && !preg_match('/^always/', $key) && $mysoc->country_code && !preg_match('/^'.$mysoc->country_code.'/', $key)) { dol_syslog("We are not concerned by dependency with key=".$key." because our country is ".$mysoc->country_code); continue; } - $activate = false; - foreach ($modulesdir as $dir) { - if (file_exists($dir.$modulestring.".class.php")) { - $resarray = activateModule($modulestring); - if (empty($resarray['errors'])) { - $activate = true; - } else { - foreach ($resarray['errors'] as $errorMessage) { - dol_syslog($errorMessage, LOG_ERR); - } - } - break; - } + + if (!is_array($modulestringorarray)) { + $modulestringorarray = array($modulestringorarray); } - if ($activate) { - $ret['nbmodules'] += $resarray['nbmodules']; - $ret['nbperms'] += $resarray['nbperms']; - } else { - $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $modulestring); + foreach($modulestringorarray as $modulestring) { + $activate = false; + $activateerr = ''; + foreach ($modulesdir as $dir) { + if (file_exists($dir.$modulestring.".class.php")) { + $resarray = activateModule($modulestring); + if (empty($resarray['errors'])) { + $activate = true; + } else { + $activateerr = join(', ', $resarray['errors']); + foreach ($resarray['errors'] as $errorMessage) { + dol_syslog($errorMessage, LOG_ERR); + } + } + break; + } + } + + if ($activate) { + $ret['nbmodules'] += $resarray['nbmodules']; + $ret['nbperms'] += $resarray['nbperms']; + } else { + if ($activateerr) { + $ret['errors'][] = $activateerr; + } + $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $modulestring); + } } } } diff --git a/htdocs/core/modules/modBom.class.php b/htdocs/core/modules/modBom.class.php index 12fc50b5ff3..d8c95c3c26b 100644 --- a/htdocs/core/modules/modBom.class.php +++ b/htdocs/core/modules/modBom.class.php @@ -105,9 +105,10 @@ class modBom extends DolibarrModules // Dependencies $this->hidden = false; // A condition to hide module - $this->depends = array('modProduct'); // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) - $this->requiredby = array('modMrp'); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) - $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) + $this->depends = array('modProduct'); + $this->requiredby = array('modMrp'); + $this->conflictwith = array(); $this->langfiles = array("mrp"); //$this->phpmin = array(7, 0)); // Minimum version of PHP required by module $this->need_dolibarr_version = array(9, 0); // Minimum version of Dolibarr required by module diff --git a/htdocs/core/modules/modBookCal.class.php b/htdocs/core/modules/modBookCal.class.php index 6e3d6768206..935293fedc4 100644 --- a/htdocs/core/modules/modBookCal.class.php +++ b/htdocs/core/modules/modBookCal.class.php @@ -129,7 +129,7 @@ class modBookCal extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array(); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index 1bec1c5c67e..0ecd1ba805f 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -114,7 +114,7 @@ class modEventOrganization extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array('modProjet','modCategorie'); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modKnowledgeManagement.class.php b/htdocs/core/modules/modKnowledgeManagement.class.php index c372f611c60..6bfee4935e9 100644 --- a/htdocs/core/modules/modKnowledgeManagement.class.php +++ b/htdocs/core/modules/modKnowledgeManagement.class.php @@ -131,7 +131,7 @@ class modKnowledgeManagement extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array(); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modMrp.class.php b/htdocs/core/modules/modMrp.class.php index 593a5611de0..f315a4594c4 100644 --- a/htdocs/core/modules/modMrp.class.php +++ b/htdocs/core/modules/modMrp.class.php @@ -117,7 +117,7 @@ class modMrp extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array('modBom'); $this->requiredby = array('modWorkstation'); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modPartnership.class.php b/htdocs/core/modules/modPartnership.class.php index 44ef6b527db..b8aafc853fb 100644 --- a/htdocs/core/modules/modPartnership.class.php +++ b/htdocs/core/modules/modPartnership.class.php @@ -138,7 +138,7 @@ class modPartnership extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array(); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index 8b2db1a115a..499b6419982 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -117,7 +117,7 @@ class modRecruitment extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array(); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modStockTransfer.class.php b/htdocs/core/modules/modStockTransfer.class.php index 34de040fdb8..b0b616e3b36 100644 --- a/htdocs/core/modules/modStockTransfer.class.php +++ b/htdocs/core/modules/modStockTransfer.class.php @@ -119,7 +119,7 @@ class modStockTransfer extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array('modStock', 'modProduct'); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modTakePos.class.php b/htdocs/core/modules/modTakePos.class.php index ce6395fdb73..697501a62a7 100644 --- a/htdocs/core/modules/modTakePos.class.php +++ b/htdocs/core/modules/modTakePos.class.php @@ -98,7 +98,8 @@ class modTakePos extends DolibarrModules // Dependencies $this->hidden = false; // A condition to hide module - $this->depends = array('always1'=>"modBanque", 'always2'=>"modFacture", 'always3'=>"modProduct", 'always4'=>'modCategorie', 'FR1'=>'modBlockedLog'); // List of module class names as string that must be enabled if this module is enabled + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) + $this->depends = array('always'=>array("modBanque", "modFacture", "modProduct", "modCategorie"), 'FR'=>array('modBlockedLog')); $this->requiredby = array(); // List of module ids to disable if this one is disabled $this->conflictwith = array(); // List of module class names as string this module is in conflict with $this->langfiles = array("cashdesk"); diff --git a/htdocs/core/modules/modWebhook.class.php b/htdocs/core/modules/modWebhook.class.php index e9f3e7f5baa..57761bb6fe2 100644 --- a/htdocs/core/modules/modWebhook.class.php +++ b/htdocs/core/modules/modWebhook.class.php @@ -130,7 +130,7 @@ class modWebhook extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array(); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php index 6bba7b1807a..be697917563 100644 --- a/htdocs/core/modules/modWorkstation.class.php +++ b/htdocs/core/modules/modWorkstation.class.php @@ -119,7 +119,7 @@ class modWorkstation extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array('modMrp'); $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) diff --git a/htdocs/core/modules/modZapier.class.php b/htdocs/core/modules/modZapier.class.php index b14419e0982..f3d187cf3bb 100644 --- a/htdocs/core/modules/modZapier.class.php +++ b/htdocs/core/modules/modZapier.class.php @@ -117,7 +117,7 @@ class modZapier extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names as string that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR'...)) $this->depends = array('modApi'); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) $this->requiredby = array(); diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 2788c78fc37..8133013bbb0 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -135,10 +135,12 @@ class modMyModule extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR')...) $this->depends = array(); - $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) - $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) + // List of module class names to disable if this one is disabled. Example: array('modModuleToDisable1', ...) + $this->requiredby = array(); + // List of module class names this module is in conflict with. Example: array('modModuleToDisable1', ...) + $this->conflictwith = array(); // The language file dedicated to your module $this->langfiles = array("mymodule@mymodule"); From aa459721b7cc8ecd036aa03e15c737386b086798 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 21 Apr 2023 13:36:35 +0200 Subject: [PATCH 13/15] Invert PROJECT_HIDE_PROJECT_LIST_ON_PROJECT_AREA into PROJECT_SHOW_OPEN_PROJECTS_LIST_ON_PROJECT_AREA --- htdocs/projet/index.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php index d78e3c47f0a..aa40ba4bc5a 100644 --- a/htdocs/projet/index.php +++ b/htdocs/projet/index.php @@ -412,10 +412,9 @@ if ($resql) { dol_print_error($db); } -if (empty($conf->global->PROJECT_HIDE_PROJECT_LIST_ON_PROJECT_AREA)) { - // This list can be very long, so we allow to hide it to prefer to use the list page. - // Add constant PROJECT_HIDE_PROJECT_LIST_ON_PROJECT_AREA to hide this list - +if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') || getDolGlobalInt('PROJECT_SHOW_OPEN_PROJECTS_LIST_ON_PROJECT_AREA')) { + // This list is surely very long and useless when we are using opportunities, so we hide it for this use case, but we allow to show it if + // we really want it and to allow interface backward compatibility. print '
'; print_projecttasks_array($db, $form, $socid, $projectsListId, 0, 1, $listofoppstatus, array()); From ec83fe478f6597a0df6665550fceefbfdbbcdcd0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 21 Apr 2023 14:17:24 +0200 Subject: [PATCH 14/15] NEW product images on popup are cached --- htdocs/core/class/commonobject.class.php | 20 +++++++++----------- htdocs/product/class/product.class.php | 9 ++++----- htdocs/viewimage.php | 4 ++-- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 1c3481fb1f6..de8f758d8e4 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8767,9 +8767,10 @@ abstract class CommonObject * @param int $nolink Do not add a href link to view enlarged imaged into a new tab * @param int|string $overwritetitle Do not add title tag on image * @param int $usesharelink Use the public shared link of image (if not available, the 'nophoto' image will be shown instead) + * @param string $cache A string if we want to use a cached version of image * @return string Html code to show photo. Number of photos shown is saved in this->nbphoto */ - public function show_photos($modulepart, $sdir, $size = 0, $nbmax = 0, $nbbyrow = 5, $showfilename = 0, $showaction = 0, $maxHeight = 120, $maxWidth = 160, $nolink = 0, $overwritetitle = 0, $usesharelink = 0) + public function show_photos($modulepart, $sdir, $size = 0, $nbmax = 0, $nbbyrow = 5, $showfilename = 0, $showaction = 0, $maxHeight = 120, $maxWidth = 160, $nolink = 0, $overwritetitle = 0, $usesharelink = 0, $cache = '') { // phpcs:enable global $conf, $user, $langs; @@ -8854,13 +8855,11 @@ abstract class CommonObject if ($nbphoto % $nbbyrow == 1) { $return .= ''; } - $return .= ''; + $return .= ''."\n"; } elseif ($nbbyrow < 0) { - $return .= '
'."\n"; } } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 243d31e2c1d..c2de9c24770 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5032,10 +5032,9 @@ class Product extends CommonObject } if (!empty($this->entity)) { - $tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80); + $tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80, 0, 0, 0, 0, 1); if ($this->nbphoto > 0) { - $datas['photo'] = '
' . $tmpphoto . '
'; - //$label .= '
'; + $datas['photo'] = '
'."\n" . $tmpphoto . '
'; } } @@ -5172,9 +5171,9 @@ class Product extends CommonObject if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowProduct"); - $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1, 1).'"'; } - $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"'); + $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1, 1).'"' : ' title="tocomplete"'); $linkclose .= $dataparams.' class="nowraponall '.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ' class="nowraponall'.($morecss ? ' '.$morecss : '').'"'; diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 51df71c85ef..8cd37f2e96f 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -153,8 +153,8 @@ if ($modulepart == 'fckeditor') { */ if (GETPOST("cache", 'alpha')) { - // Important: Following code is to avoid page request by browser and PHP CPU at - // each Dolibarr page access. + // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. + // Add param cache=abcdef if (empty($dolibarr_nocache)) { header('Cache-Control: max-age=3600, public, must-revalidate'); header('Pragma: cache'); // This is to avoid having Pragma: no-cache From 3999f87fd2b9254e7dbc63d2f42a4a351a2b2a36 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 21 Apr 2023 14:26:39 +0200 Subject: [PATCH 15/15] Debug v18 --- htdocs/adherents/list.php | 2 +- htdocs/projet/class/task.class.php | 6 +----- htdocs/projet/list.php | 10 +++++----- htdocs/projet/tasks/list.php | 14 +++++++------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 0c4a5aaccf1..37261676e98 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -720,7 +720,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields if ($massactionbutton) { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index cf356d070b7..65de5cf22c3 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -2380,12 +2380,8 @@ class Task extends CommonObjectLine if (property_exists($this, 'budget_amount')) { //$return .= '
'.$langs->trans("Budget").' : '.price($this->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; } - if (property_exists($this, 'fk_statut')) { - $return .= '
'.$this->fk_statut.''; - //$return .= ' '.$this->progress.'%'; - } if (property_exists($this, 'duration_effective')) { - $return .= '
'.getTaskProgressView($this, false, true).'
'; + $return .= '

'.getTaskProgressView($this, false, true).'
'; } $return .= ''; $return .= ''; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 17f4d66168b..c5cdda8b576 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -425,7 +425,7 @@ if (count($listofprojectcontacttypeexternal) == 0) { $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields -$distinct = 'DISTINCT'; // We add distinct until we have added a protection to be sure a contact of a project and task is only once. +$distinct = 'DISTINCT'; // We add distinct until filter on contact of project or task is implemented with AND EXISTS $sql = "SELECT ".$distinct." p.rowid as id, p.ref, p.title, p.fk_statut as status, p.fk_opp_status, p.public, p.fk_user_creat,"; $sql .= " p.datec as date_creation, p.dateo as date_start, p.datee as date_end, p.opp_amount, p.opp_percent, (p.opp_amount*p.opp_percent/100) as opp_weighted_amount, p.tms as date_update, p.budget_amount,"; $sql .= " p.usage_opportunity, p.usage_task, p.usage_bill_time, p.usage_organize_event,"; @@ -1028,7 +1028,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); @@ -1253,7 +1253,7 @@ $totalarray['nbfield'] = 0; // -------------------------------------------------------------------- print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } if (!empty($arrayfields['p.ref']['checked'])) { @@ -1376,7 +1376,7 @@ if (!empty($arrayfields['p.fk_statut']['checked'])) { } // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } print ''."\n"; @@ -1409,7 +1409,7 @@ while ($i < $imaxinloop) { $object->opp_percent = $obj->opp_percent; $object->opp_status = $obj->fk_opp_status; $object->opp_status_code = $obj->opp_status_code; - $object->opp_amount = !empty($obj->opp_ammount) ? $obj->opp_ammount : ""; + $object->opp_amount = !empty($obj->opp_amount) ? $obj->opp_amount : ""; $object->opp_weighted_amount = $obj->opp_weighted_amount; $object->budget_amount = $obj->budget_amount; $object->usage_opportunity = $obj->usage_opportunity; diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index adf86b7ac49..829b8687b55 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -162,8 +162,8 @@ $arrayfields = array( 't.datee'=>array('label'=>"Deadline", 'checked'=>1, 'position'=>101), 'p.ref'=>array('label'=>"ProjectRef", 'checked'=>1), 'p.title'=>array('label'=>"ProjectLabel", 'checked'=>0), - 's.nom'=>array('label'=>"ThirdParty", 'checked'=>0), - 's.name_alias'=>array('label'=>"AliasNameShort", 'checked'=>1), + 's.nom'=>array('label'=>"ThirdParty", 'checked'=>0, 'csslist'=>'tdoverflowmax125'), + 's.name_alias'=>array('label'=>"AliasNameShort", 'checked'=>1, 'csslist'=>'tdoverflowmax125'), 'p.fk_statut'=>array('label'=>"ProjectStatus", 'checked'=>1), 't.planned_workload'=>array('label'=>"PlannedWorkload", 'checked'=>1, 'position'=>102), 't.duration_effective'=>array('label'=>"TimeSpent", 'checked'=>1, 'position'=>103), @@ -1166,7 +1166,7 @@ while ($i < $imaxinloop) { } } - $object->fk_statut = $projectstatic->getLibStatut(1); + $arraydata = array(); $arraydata['projectlink'] = $projectstatic->getNomUrl(1); print $object->getKanbanView('', $arraydata); if ($i == ($imaxinloop - 1)) { @@ -1278,8 +1278,8 @@ while ($i < $imaxinloop) { } // Project title if (!empty($arrayfields['p.title']['checked'])) { - print ''; - print dol_trunc($obj->projecttitle, 80); + print ''; + print dol_escape_htmltag($obj->projecttitle); print ''; if (!$i) { $totalarray['nbfield']++; @@ -1287,7 +1287,7 @@ while ($i < $imaxinloop) { } // Third party if (!empty($arrayfields['s.nom']['checked'])) { - print ''; + print ''; if ($obj->socid) { print $socstatic->getNomUrl(1, '', 0, 0, -1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1); } else { @@ -1300,7 +1300,7 @@ while ($i < $imaxinloop) { } // Alias if (!empty($arrayfields['s.name_alias']['checked'])) { - print ''; + print ''; if ($obj->socid) { print $socstatic->name_alias; } else {