2
0
forked from Wavyzz/dolibarr

Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur
2024-02-25 23:49:57 +01:00
17 changed files with 370 additions and 130 deletions

View File

@@ -83,6 +83,7 @@ return [
// Alternately, you can pass in the full path to a PHP file // Alternately, you can pass in the full path to a PHP file
// with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php') // with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php')
'plugins' => [ 'plugins' => [
__DIR__.'/plugins/NoVarDumpPlugin.php',
// checks if a function, closure or method unconditionally returns. // checks if a function, closure or method unconditionally returns.
// can also be written as 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php' // can also be written as 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php'
//'DeprecateAliasPlugin', //'DeprecateAliasPlugin',
@@ -149,9 +150,13 @@ return [
'PhanPluginShortArray', 'PhanPluginShortArray',
'PhanPluginNumericalComparison', 'PhanPluginNumericalComparison',
'PhanPluginUnknownObjectMethodCall', 'PhanPluginUnknownObjectMethodCall',
'PhanPluginCanUseParamType',
'PhanPluginNonBoolInLogicalArith', 'PhanPluginNonBoolInLogicalArith',
'PhanPluginCanUseReturnType', // Fixers From PHPDocToRealTypesPlugin:
'PhanPluginCanUseParamType', // Fixer - Report/Add types in the function definition (function abc(string $var) (adds string)
'PhanPluginCanUseReturnType', // Fixer - Report/Add return types in the function definition (function abc(string $var) (adds string)
'PhanPluginCanUseNullableParamType', // Fixer - Report/Add nullable parameter types in the function definition
'PhanPluginCanUseNullableReturnType', // Fixer - Report/Add nullable return types in the function definition
// 'PhanPluginNotFullyQualifiedFunctionCall', // 'PhanPluginNotFullyQualifiedFunctionCall',
'PhanPluginConstantVariableScalar', 'PhanPluginConstantVariableScalar',
// 'PhanPluginNoCommentOnPublicProperty', // 'PhanPluginNoCommentOnPublicProperty',
@@ -166,7 +171,6 @@ return [
'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownArrayMethodReturnType',
'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternal',
'PhanPluginDuplicateAdjacentStatement', 'PhanPluginDuplicateAdjacentStatement',
'PhanPluginCanUseNullableParamType',
'PhanTypeInvalidLeftOperandOfNumericOp', 'PhanTypeInvalidLeftOperandOfNumericOp',
'PhanTypeMismatchProperty', 'PhanTypeMismatchProperty',
// 'PhanPluginNoCommentOnPublicMethod', // 'PhanPluginNoCommentOnPublicMethod',
@@ -190,7 +194,6 @@ return [
'PhanTypeInvalidLeftOperandOfAdd', 'PhanTypeInvalidLeftOperandOfAdd',
// 'PhanPluginNoCommentOnPrivateProperty', // 'PhanPluginNoCommentOnPrivateProperty',
// 'PhanPluginNoCommentOnFunction', // 'PhanPluginNoCommentOnFunction',
'PhanPluginCanUseNullableReturnType',
'PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionParamType',
// 'PhanPluginDescriptionlessCommentOnPublicProperty', // 'PhanPluginDescriptionlessCommentOnPublicProperty',
'PhanPluginUnknownFunctionParamType', 'PhanPluginUnknownFunctionParamType',

View File

@@ -83,6 +83,7 @@ return [
// Alternately, you can pass in the full path to a PHP file // Alternately, you can pass in the full path to a PHP file
// with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php') // with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php')
'plugins' => [ 'plugins' => [
__DIR__.'/plugins/NoVarDumpPlugin.php',
'DeprecateAliasPlugin', 'DeprecateAliasPlugin',
//'EmptyMethodAndFunctionPlugin', //'EmptyMethodAndFunctionPlugin',
'InvalidVariableIssetPlugin', 'InvalidVariableIssetPlugin',
@@ -102,7 +103,7 @@ return [
'NonBoolBranchPlugin', // Requires test on bool, nont on ints 'NonBoolBranchPlugin', // Requires test on bool, nont on ints
'NonBoolInLogicalArithPlugin', 'NonBoolInLogicalArithPlugin',
'NumericalComparisonPlugin', 'NumericalComparisonPlugin',
'PHPDocToRealTypesPlugin', // 'PHPDocToRealTypesPlugin', // Report/Add types to function definitions
'PHPDocInWrongCommentPlugin', // Missing /** (/* was used) 'PHPDocInWrongCommentPlugin', // Missing /** (/* was used)
//'ShortArrayPlugin', // Checks that [] is used //'ShortArrayPlugin', // Checks that [] is used
//'StrictLiteralComparisonPlugin', //'StrictLiteralComparisonPlugin',
@@ -138,10 +139,11 @@ return [
'PhanPluginCanUsePHP71Void', // Dolibarr is maintaining 7.0 compatibility 'PhanPluginCanUsePHP71Void', // Dolibarr is maintaining 7.0 compatibility
'PhanPluginShortArray', // Dolibarr uses array() 'PhanPluginShortArray', // Dolibarr uses array()
'PhanPluginShortArrayList', // Dolibarr uses array() 'PhanPluginShortArrayList', // Dolibarr uses array()
// The following may require that --quick is not used // Fixers From PHPDocToRealTypesPlugin:
'PhanPluginCanUseParamType', // Does not seem useful: is reporting types already in PHPDoc? 'PhanPluginCanUseParamType', // Fixer - Report/Add types in the function definition (function abc(string $var) (adds string)
'PhanPluginCanUseReturnType', // Does not seem useful: is reporting types already in PHPDoc? 'PhanPluginCanUseReturnType', // Fixer - Report/Add return types in the function definition (function abc(string $var) (adds string)
'PhanPluginCanUseNullableParamType', // Does not seem useful: is reporting types already in PHPDoc? 'PhanPluginCanUseNullableParamType', // Fixer - Report/Add nullable parameter types in the function definition
'PhanPluginCanUseNullableReturnType', // Fixer - Report/Add nullable return types in the function definition
'PhanPluginNonBoolBranch', // Not essential - 31240+ occurrences 'PhanPluginNonBoolBranch', // Not essential - 31240+ occurrences
'PhanPluginNumericalComparison', // Not essential - 19870+ occurrences 'PhanPluginNumericalComparison', // Not essential - 19870+ occurrences
'PhanTypeMismatchArgument', // Not essential - 12300+ occurrences 'PhanTypeMismatchArgument', // Not essential - 12300+ occurrences

View File

@@ -0,0 +1,81 @@
<?php
/* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*/
declare(strict_types=1);
use ast\Node;
use Phan\PluginV3;
use Phan\PluginV3\PluginAwarePostAnalysisVisitor;
use Phan\PluginV3\PostAnalyzeNodeCapability;
/**
* NoVarDumpPlugin hooks into one event:
*
* - getPostAnalyzeNodeVisitorClassName
* This method returns a visitor that is called on every AST node from every
* file being analyzed
*
* A plugin file must
*
* - Contain a class that inherits from \Phan\PluginV3
*
* - End by returning an instance of that class.
*
* It is assumed without being checked that plugins aren't
* mangling state within the passed code base or context.
*
* Note: When adding new plugins,
* add them to the corresponding section of README.md
*/
class NoVarDumpPlugin extends PluginV3 implements PostAnalyzeNodeCapability
{
/**
* @return string - name of PluginAwarePostAnalysisVisitor subclass
*/
public static function getPostAnalyzeNodeVisitorClassName(): string
{
return NoVarDumpVisitor::class;
}
}
/**
* When __invoke on this class is called with a node, a method
* will be dispatched based on the `kind` of the given node.
*
* Visitors such as this are useful for defining lots of different
* checks on a node based on its kind.
*/
class NoVarDumpVisitor extends PluginAwarePostAnalysisVisitor
{
// A plugin's visitors should not override visit() unless they need to.
/**
* @param Node $node A node to analyze
*
* @return void
*
* @override
*/
public function visitCall(Node $node): void
{
$name = $node->children['expr']->children['name'] ?? null;
if (!is_string($name)) {
return;
}
if (strcasecmp($name, 'var_dump') !== 0) {
return;
}
$this->emitPluginIssue(
$this->code_base,
$this->context,
'NoVarDumpPlugin',
'var_dump() should be commented in submitted code',
[]
);
}
}
// Every plugin needs to return an instance of itself at the
// end of the file in which it's defined.
return new NoVarDumpPlugin();

View File

@@ -106,13 +106,14 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha'))
$db->begin(); $db->begin();
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", GETPOST("nom", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", GETPOST("name", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_ADDRESS", GETPOST("MAIN_INFO_SOCIETE_ADDRESS", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_ADDRESS", GETPOST("MAIN_INFO_SOCIETE_ADDRESS", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_TOWN", GETPOST("MAIN_INFO_SOCIETE_TOWN", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_TOWN", GETPOST("MAIN_INFO_SOCIETE_TOWN", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_ZIP", GETPOST("MAIN_INFO_SOCIETE_ZIP", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_ZIP", GETPOST("MAIN_INFO_SOCIETE_ZIP", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_REGION", GETPOST("region_code", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_REGION", GETPOST("region_code", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MONNAIE", GETPOST("currency", 'aZ09'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_MONNAIE", GETPOST("currency", 'aZ09'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_TEL", GETPOST("tel", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_TEL", GETPOST("phone", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_MOBILE", GETPOST("phone_mobile", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_FAX", GETPOST("fax", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_FAX", GETPOST("fax", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_MAIL", GETPOST("mail", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_MAIL", GETPOST("mail", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_WEB", GETPOST("web", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_WEB", GETPOST("web", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
@@ -440,18 +441,18 @@ print '<tr class="liste_titre"><th class="titlefieldcreate wordbreak">'.$langs->
// Name // Name
print '<tr class="oddeven"><td class="fieldrequired wordbreak"><label for="name">'.$langs->trans("CompanyName").'</label></td><td>'; print '<tr class="oddeven"><td class="fieldrequired wordbreak"><label for="name">'.$langs->trans("CompanyName").'</label></td><td>';
print '<input name="nom" id="name" class="minwidth200" value="'.dol_escape_htmltag((GETPOSTISSET('nom') ? GETPOST('nom', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? $conf->global->MAIN_INFO_SOCIETE_NOM : ''))).'"'.(!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? ' autofocus="autofocus"' : '').'></td></tr>'."\n"; print '<input name="name" id="name" class="minwidth200" value="'.dol_escape_htmltag((GETPOSTISSET('name') ? GETPOST('name', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_NOM')))).'"'.(!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? ' autofocus="autofocus"' : '').'></td></tr>'."\n";
// Address // Address
print '<tr class="oddeven"><td><label for="MAIN_INFO_SOCIETE_ADDRESS">'.$langs->trans("CompanyAddress").'</label></td><td>'; print '<tr class="oddeven"><td><label for="MAIN_INFO_SOCIETE_ADDRESS">'.$langs->trans("CompanyAddress").'</label></td><td>';
print '<textarea name="MAIN_INFO_SOCIETE_ADDRESS" id="MAIN_INFO_SOCIETE_ADDRESS" class="quatrevingtpercent" rows="'.ROWS_3.'">'.(GETPOSTISSET('MAIN_INFO_SOCIETE_ADDRESS') ? GETPOST('MAIN_INFO_SOCIETE_ADDRESS', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS') ? $conf->global->MAIN_INFO_SOCIETE_ADDRESS : '')).'</textarea></td></tr>'."\n"; print '<textarea name="MAIN_INFO_SOCIETE_ADDRESS" id="MAIN_INFO_SOCIETE_ADDRESS" class="quatrevingtpercent" rows="'.ROWS_3.'">'.(GETPOSTISSET('MAIN_INFO_SOCIETE_ADDRESS') ? GETPOST('MAIN_INFO_SOCIETE_ADDRESS', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS'))).'</textarea></td></tr>'."\n";
// Zip // Zip
print '<tr class="oddeven" id="trzipbeforecountry"><td><label for="MAIN_INFO_SOCIETE_ZIP">'.$langs->trans("CompanyZip").'</label></td><td>'; print '<tr class="oddeven" id="trzipbeforecountry"><td><label for="MAIN_INFO_SOCIETE_ZIP">'.$langs->trans("CompanyZip").'</label></td><td>';
print '<input class="width100" name="MAIN_INFO_SOCIETE_ZIP" id="MAIN_INFO_SOCIETE_ZIP" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_INFO_SOCIETE_ZIP') ? GETPOST('MAIN_INFO_SOCIETE_ZIP', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_ZIP') ? $conf->global->MAIN_INFO_SOCIETE_ZIP : ''))).'"></td></tr>'."\n"; print '<input class="width100" name="MAIN_INFO_SOCIETE_ZIP" id="MAIN_INFO_SOCIETE_ZIP" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_INFO_SOCIETE_ZIP') ? GETPOST('MAIN_INFO_SOCIETE_ZIP', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_ZIP')))).'"></td></tr>'."\n";
print '<tr class="oddeven" id="trtownbeforecountry"><td><label for="MAIN_INFO_SOCIETE_TOWN">'.$langs->trans("CompanyTown").'</label></td><td>'; print '<tr class="oddeven" id="trtownbeforecountry"><td><label for="MAIN_INFO_SOCIETE_TOWN">'.$langs->trans("CompanyTown").'</label></td><td>';
print '<input name="MAIN_INFO_SOCIETE_TOWN" class="minwidth200" id="MAIN_INFO_SOCIETE_TOWN" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_INFO_SOCIETE_TOWN') ? GETPOST('MAIN_INFO_SOCIETE_TOWN', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_TOWN') ? $conf->global->MAIN_INFO_SOCIETE_TOWN : ''))).'"></td></tr>'."\n"; print '<input name="MAIN_INFO_SOCIETE_TOWN" class="minwidth200" id="MAIN_INFO_SOCIETE_TOWN" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_INFO_SOCIETE_TOWN') ? GETPOST('MAIN_INFO_SOCIETE_TOWN', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_TOWN')))).'"></td></tr>'."\n";
// Country // Country
print '<tr class="oddeven"><td class="fieldrequired"><label for="selectcountry_id">'.$langs->trans("Country").'</label></td><td>'; print '<tr class="oddeven"><td class="fieldrequired"><label for="selectcountry_id">'.$langs->trans("Country").'</label></td><td>';
@@ -481,13 +482,19 @@ print '</td></tr>'."\n";
// Phone // Phone
print '<tr class="oddeven"><td><label for="phone">'.$langs->trans("Phone").'</label></td><td>'; print '<tr class="oddeven"><td><label for="phone">'.$langs->trans("Phone").'</label></td><td>';
print img_picto('', 'object_phoning', '', false, 0, 0, '', 'pictofixedwidth'); print img_picto('', 'object_phoning', '', false, 0, 0, '', 'pictofixedwidth');
print '<input class="maxwidth150 widthcentpercentminusx" name="phone" id="phone" value="'.dol_escape_htmltag((GETPOSTISSET('phone') ? GETPOST('phone', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_TEL') ? $conf->global->MAIN_INFO_SOCIETE_TEL : ''))).'"></td></tr>'; print '<input class="maxwidth150 widthcentpercentminusx" name="phone" id="phone" value="'.dol_escape_htmltag((GETPOSTISSET('phone') ? GETPOST('phone', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_TEL')))).'"></td></tr>';
print '</td></tr>'."\n";
// Phone mobile
print '<tr class="oddeven"><td><label for="phone">'.$langs->trans("PhoneMobile").'</label></td><td>';
print img_picto('', 'object_phoning_mobile', '', false, 0, 0, '', 'pictofixedwidth');
print '<input class="maxwidth150 widthcentpercentminusx" name="phone_mobile" id="phone_mobile" value="'.dol_escape_htmltag((GETPOSTISSET('phone_mobile') ? GETPOST('phone_mobile', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_MOBILE')))).'"></td></tr>';
print '</td></tr>'."\n"; print '</td></tr>'."\n";
// Fax // Fax
print '<tr class="oddeven"><td><label for="fax">'.$langs->trans("Fax").'</label></td><td>'; print '<tr class="oddeven"><td><label for="fax">'.$langs->trans("Fax").'</label></td><td>';
print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'pictofixedwidth'); print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'pictofixedwidth');
print '<input class="maxwidth150" name="fax" id="fax" value="'.dol_escape_htmltag((GETPOSTISSET('fax') ? GETPOST('fax', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_FAX') ? $conf->global->MAIN_INFO_SOCIETE_FAX : ''))).'"></td></tr>'; print '<input class="maxwidth150" name="fax" id="fax" value="'.dol_escape_htmltag((GETPOSTISSET('fax') ? GETPOST('fax', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_FAX')))).'"></td></tr>';
print '</td></tr>'."\n"; print '</td></tr>'."\n";
// Email // Email

View File

@@ -10,7 +10,7 @@
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr> * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com> * Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
* Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr> * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr> * Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@@ -1707,7 +1707,7 @@ class Categorie extends CommonObject
* @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
* @return string Chaine avec URL * @return string Chaine avec URL
*/ */
public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = '') public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = 0)
{ {
global $conf, $langs, $hookmanager; global $conf, $langs, $hookmanager;

View File

@@ -2727,7 +2727,7 @@ while ($i < $imaxinloop) {
// Billed // Billed
if (!empty($arrayfields['c.facture']['checked'])) { if (!empty($arrayfields['c.facture']['checked'])) {
print '<td class="center">'.yn($obj->billed).'</td>'; print '<td class="center">'.yn($obj->billed, 4).'</td>';
if (!$i) { if (!$i) {
$totalarray['nbfield']++; $totalarray['nbfield']++;
} }

View File

@@ -2660,14 +2660,14 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
} }
} }
// Fix modulepart for backward compatibility // Fix modulepart for backward compatibility
if ($modulepart == 'users') { if ($modulepart == 'facture') {
$modulepart = 'invoice';
} elseif ($modulepart == 'users') {
$modulepart = 'user'; $modulepart = 'user';
} } elseif ($modulepart == 'tva') {
if ($modulepart == 'tva') {
$modulepart = 'tax-vat'; $modulepart = 'tax-vat';
} } elseif ($modulepart == 'expedition' && strpos($original_file, 'receipt/') === 0) {
// Fix modulepart delivery // Fix modulepart delivery
if ($modulepart == 'expedition' && strpos($original_file, 'receipt/') === 0) {
$modulepart = 'delivery'; $modulepart = 'delivery';
} }

View File

@@ -7236,6 +7236,9 @@ function yn($yesno, $case = 1, $color = 0)
if ($case == 3) { if ($case == 3) {
$result = '<input type="checkbox" value="1" checked disabled> '.$result; $result = '<input type="checkbox" value="1" checked disabled> '.$result;
} }
if ($case == 4) {
$result = img_picto('check', 'check');
}
$classname = 'ok'; $classname = 'ok';
} elseif ($yesno == 0 || strtolower($yesno) == 'no' || strtolower($yesno) == 'false') { } elseif ($yesno == 0 || strtolower($yesno) == 'no' || strtolower($yesno) == 'false') {
@@ -7249,6 +7252,9 @@ function yn($yesno, $case = 1, $color = 0)
if ($case == 3) { if ($case == 3) {
$result = '<input type="checkbox" value="0" disabled> '.$result; $result = '<input type="checkbox" value="0" disabled> '.$result;
} }
if ($case == 4) {
$result = img_picto('uncheck', 'uncheck');
}
if ($color == 2) { if ($color == 2) {
$classname = 'ok'; $classname = 'ok';

View File

@@ -1912,7 +1912,7 @@ function getListOfModels($db, $type, $maxfilenamelength = 0)
} }
if (is_dir($tmpdir)) { if (is_dir($tmpdir)) {
// all type of template is allowed // all type of template is allowed
$tmpfiles = dol_dir_list($tmpdir, 'files', 0, '', '', 'name', SORT_ASC, 0); $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '', null, 'name', SORT_ASC, 0);
if (count($tmpfiles)) { if (count($tmpfiles)) {
$listoffiles = array_merge($listoffiles, $tmpfiles); $listoffiles = array_merge($listoffiles, $tmpfiles);
} }

View File

@@ -6,7 +6,7 @@
* Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com> * Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2023 Frédéric France <frederic.france@netlogic.fr> * Copyright (C) 2023-2024 Frédéric France <frederic.france@free.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -602,7 +602,7 @@ class Delivery extends CommonObject
* @param array $array_options extrafields array * @param array $array_options extrafields array
* @return int Return integer <0 if KO, >0 if OK * @return int Return integer <0 if KO, >0 if OK
*/ */
public function update_line($id, $array_options = 0) public function update_line($id, $array_options = [])
{ {
// phpcs:enable // phpcs:enable
global $conf; global $conf;

View File

@@ -250,55 +250,55 @@ class FactureFournisseur extends CommonInvoice
public $fk_fac_rec_source; public $fk_fac_rec_source;
public $fields = array( public $fields = array(
'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15), 'ref' => array('type' => 'varchar(255)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 15),
'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefSupplier', 'enabled'=>1, 'visible'=>-1, 'position'=>20), 'ref_supplier' => array('type' => 'varchar(255)', 'label' => 'RefSupplier', 'enabled' => 1, 'visible' => -1, 'position' => 20),
'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>25, 'index'=>1), 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => 1, 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 25, 'index' => 1),
'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>30), 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 30),
'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), 'type' => array('type' => 'smallint(6)', 'label' => 'Type', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 35),
'subtype' =>array('type'=>'smallint(6)', 'label'=>'InvoiceSubtype', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>36), 'subtype' => array('type' => 'smallint(6)', 'label' => 'InvoiceSubtype', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 36),
'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'notnull'=>1, 'position'=>40), 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 40),
'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>45), 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 45),
'datef' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>50), 'datef' => array('type' => 'date', 'label' => 'Date', 'enabled' => 1, 'visible' => -1, 'position' => 50),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>55), 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 55),
'libelle' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'position'=>60), 'libelle' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'visible' => -1, 'position' => 60),
'paye' =>array('type'=>'smallint(6)', 'label'=>'Paye', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>65), 'paye' => array('type' => 'smallint(6)', 'label' => 'Paye', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 65),
'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), 'amount' => array('type' => 'double(24,8)', 'label' => 'Amount', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 70),
'remise' =>array('type'=>'double(24,8)', 'label'=>'Discount', 'enabled'=>1, 'visible'=>-1, 'position'=>75), 'remise' => array('type' => 'double(24,8)', 'label' => 'Discount', 'enabled' => 1, 'visible' => -1, 'position' => 75),
'close_code' =>array('type'=>'varchar(16)', 'label'=>'CloseCode', 'enabled'=>1, 'visible'=>-1, 'position'=>80), 'close_code' => array('type' => 'varchar(16)', 'label' => 'CloseCode', 'enabled' => 1, 'visible' => -1, 'position' => 80),
'close_note' =>array('type'=>'varchar(128)', 'label'=>'CloseNote', 'enabled'=>1, 'visible'=>-1, 'position'=>85), 'close_note' => array('type' => 'varchar(128)', 'label' => 'CloseNote', 'enabled' => 1, 'visible' => -1, 'position' => 85),
'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>90), 'tva' => array('type' => 'double(24,8)', 'label' => 'Tva', 'enabled' => 1, 'visible' => -1, 'position' => 90),
'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>95), 'localtax1' => array('type' => 'double(24,8)', 'label' => 'Localtax1', 'enabled' => 1, 'visible' => -1, 'position' => 95),
'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>100), 'localtax2' => array('type' => 'double(24,8)', 'label' => 'Localtax2', 'enabled' => 1, 'visible' => -1, 'position' => 100),
'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>105), 'total_ht' => array('type' => 'double(24,8)', 'label' => 'TotalHT', 'enabled' => 1, 'visible' => -1, 'position' => 105),
'total_tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>110), 'total_tva' => array('type' => 'double(24,8)', 'label' => 'TotalVAT', 'enabled' => 1, 'visible' => -1, 'position' => 110),
'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>115), 'total_ttc' => array('type' => 'double(24,8)', 'label' => 'TotalTTC', 'enabled' => 1, 'visible' => -1, 'position' => 115),
'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>125), 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -1, 'position' => 125),
'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>130), 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 130),
'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>135), 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 135),
'fk_facture_source' =>array('type'=>'integer', 'label'=>'Fk facture source', 'enabled'=>1, 'visible'=>-1, 'position'=>140), 'fk_facture_source' => array('type' => 'integer', 'label' => 'Fk facture source', 'enabled' => 1, 'visible' => -1, 'position' => 140),
'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>145), 'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label' => 'Project', 'enabled' => "isModEnabled('project')", 'visible' => -1, 'position' => 145),
'fk_account' =>array('type'=>'integer', 'label'=>'Account', 'enabled'=>'isModEnabled("banque")', 'visible'=>-1, 'position'=>150), 'fk_account' => array('type' => 'integer', 'label' => 'Account', 'enabled' => 'isModEnabled("banque")', 'visible' => -1, 'position' => 150),
'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>155), 'fk_cond_reglement' => array('type' => 'integer', 'label' => 'PaymentTerm', 'enabled' => 1, 'visible' => -1, 'position' => 155),
'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>160), 'fk_mode_reglement' => array('type' => 'integer', 'label' => 'PaymentMode', 'enabled' => 1, 'visible' => -1, 'position' => 160),
'date_lim_reglement' =>array('type'=>'date', 'label'=>'DateLimReglement', 'enabled'=>1, 'visible'=>-1, 'position'=>165), 'date_lim_reglement' => array('type' => 'date', 'label' => 'DateLimReglement', 'enabled' => 1, 'visible' => -1, 'position' => 165),
'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>170), 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 170),
'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>175), 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 175),
'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPdf', 'enabled'=>1, 'visible'=>0, 'position'=>180), 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'ModelPdf', 'enabled' => 1, 'visible' => 0, 'position' => 180),
'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>190), 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 190),
'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>-1, 'position'=>195), 'fk_incoterms' => array('type' => 'integer', 'label' => 'IncotermCode', 'enabled' => 1, 'visible' => -1, 'position' => 195),
'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>-1, 'position'=>200), 'location_incoterms' => array('type' => 'varchar(255)', 'label' => 'IncotermLocation', 'enabled' => 1, 'visible' => -1, 'position' => 200),
'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyId', 'enabled'=>1, 'visible'=>-1, 'position'=>205), 'fk_multicurrency' => array('type' => 'integer', 'label' => 'MulticurrencyId', 'enabled' => 1, 'visible' => -1, 'position' => 205),
'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>210), 'multicurrency_code' => array('type' => 'varchar(255)', 'label' => 'MulticurrencyCode', 'enabled' => 1, 'visible' => -1, 'position' => 210),
'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>1, 'visible'=>-1, 'position'=>215), 'multicurrency_tx' => array('type' => 'double(24,8)', 'label' => 'MulticurrencyRate', 'enabled' => 1, 'visible' => -1, 'position' => 215),
'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>220), 'multicurrency_total_ht' => array('type' => 'double(24,8)', 'label' => 'MulticurrencyTotalHT', 'enabled' => 1, 'visible' => -1, 'position' => 220),
'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>225), 'multicurrency_total_tva' => array('type' => 'double(24,8)', 'label' => 'MulticurrencyTotalVAT', 'enabled' => 1, 'visible' => -1, 'position' => 225),
'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>230), 'multicurrency_total_ttc' => array('type' => 'double(24,8)', 'label' => 'MulticurrencyTotalTTC', 'enabled' => 1, 'visible' => -1, 'position' => 230),
'date_pointoftax' =>array('type'=>'date', 'label'=>'Date pointoftax', 'enabled'=>1, 'visible'=>-1, 'position'=>235), 'date_pointoftax' => array('type' => 'date', 'label' => 'Date pointoftax', 'enabled' => 1, 'visible' => -1, 'position' => 235),
'date_valid' =>array('type'=>'date', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>240), 'date_valid' => array('type' => 'date', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 240),
'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>245), 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'Last main doc', 'enabled' => 1, 'visible' => -1, 'position' => 245),
'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), 'fk_statut' => array('type' => 'smallint(6)', 'label' => 'Status', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 500),
'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 900),
); );
@@ -1350,7 +1350,7 @@ class FactureFournisseur extends CommonInvoice
$facligne->rang = 1; $facligne->rang = 1;
$linecount = count($this->lines); $linecount = count($this->lines);
for ($ii = 1; $ii <= $linecount; $ii++) { for ($ii = 1; $ii <= $linecount; $ii++) {
$this->updateRangOfLine($this->lines[$ii - 1]->id, $ii+1); $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1);
} }
} }
@@ -2658,7 +2658,7 @@ class FactureFournisseur extends CommonInvoice
} }
if ($qualified) { if ($qualified) {
$paymentornot = ($obj->fk_paiementfourn ? 1 : 0); $paymentornot = ($obj->fk_paiementfourn ? 1 : 0);
$return[$obj->rowid] = array('ref'=>$obj->ref, 'status'=>$obj->fk_statut, 'type'=>$obj->type, 'paye'=>$obj->paye, 'paymentornot'=>$paymentornot); $return[$obj->rowid] = array('ref' => $obj->ref, 'status' => $obj->fk_statut, 'type' => $obj->type, 'paye' => $obj->paye, 'paymentornot' => $paymentornot);
} }
} }
@@ -2922,7 +2922,7 @@ class FactureFournisseur extends CommonInvoice
} }
global $action; global $action;
$hookmanager->initHooks(array($this->element . 'dao')); $hookmanager->initHooks(array($this->element . 'dao'));
$parameters = array('id'=>$this->id, 'getnomurl' => &$result); $parameters = array('id' => $this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) { if ($reshook > 0) {
$result = $hookmanager->resPrint; $result = $hookmanager->resPrint;
@@ -3689,7 +3689,7 @@ class FactureFournisseur extends CommonInvoice
return 0; return 0;
} else { } else {
$this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error; $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? implode(', ', $errorsMsg) : $error;
dol_syslog(__METHOD__." end - ".$this->error, LOG_INFO); dol_syslog(__METHOD__." end - ".$this->error, LOG_INFO);

View File

@@ -69,7 +69,7 @@ if (!$sortfield) {
$search_month = GETPOST('search_month', 'int'); $search_month = GETPOST('search_month', 'int');
$search_year = GETPOST('search_year', 'int'); $search_year = GETPOST('search_year', 'int');
if (GETPOSTISARRAY('search_status')) { if (GETPOSTISARRAY('search_status')) {
$search_status = join(',', GETPOST('search_status', 'array:intcomma')); $search_status = implode(',', GETPOST('search_status', 'array:intcomma'));
} else { } else {
$search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma')); $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma'));
} }
@@ -100,7 +100,7 @@ if ($id > 0 || !empty($ref)) {
$object = $product; $object = $product;
$parameters = array('id'=>$id); $parameters = array('id' => $id);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) { if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');

View File

@@ -69,7 +69,7 @@ if (!$sortfield) {
$search_month = GETPOST('search_month', 'int'); $search_month = GETPOST('search_month', 'int');
$search_year = GETPOST('search_year', 'int'); $search_year = GETPOST('search_year', 'int');
if (GETPOSTISARRAY('search_status')) { if (GETPOSTISARRAY('search_status')) {
$search_status = join(',', GETPOST('search_status', 'array:intcomma')); $search_status = implode(',', GETPOST('search_status', 'array:intcomma'));
} else { } else {
$search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma')); $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma'));
} }

View File

@@ -2,7 +2,7 @@
/* Copyright (C) 2008-2014 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2008-2014 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com> * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@netlogic.fr> * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2020 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2020 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com> * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
* Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr> * Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
@@ -903,14 +903,14 @@ class Task extends CommonObjectLine
{ {
$this->id = 0; $this->id = 0;
$this->fk_project = ''; $this->fk_project = 0;
$this->ref = 'TK01'; $this->ref = 'TK01';
$this->fk_task_parent = null; $this->fk_task_parent = 0;
$this->label = 'Specimen task TK01'; $this->label = 'Specimen task TK01';
$this->duration_effective = ''; $this->duration_effective = '';
$this->fk_user_creat = null; $this->fk_user_creat = 1;
$this->progress = '25'; $this->progress = '25';
$this->status = null; $this->status = 0;
$this->note = 'This is a specimen task not'; $this->note = 'This is a specimen task not';
} }

View File

@@ -937,7 +937,7 @@ class Reception extends CommonObject
$this->fk_user_valid = trim($this->fk_user_valid); $this->fk_user_valid = trim($this->fk_user_valid);
} }
if (isset($this->shipping_method_id)) { if (isset($this->shipping_method_id)) {
$this->shipping_method_id = trim($this->shipping_method_id); $this->shipping_method_id = (int) $this->shipping_method_id;
} }
if (isset($this->tracking_number)) { if (isset($this->tracking_number)) {
$this->tracking_number = trim($this->tracking_number); $this->tracking_number = trim($this->tracking_number);

View File

@@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) - 2013-2015 Jean-François FERRY <jfefe@aternatik.fr> /* Copyright (C) - 2013-2015 Jean-François FERRY <jfefe@aternatik.fr>
* Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr> * Copyright (C) 2019-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es> * Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr> * Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
* *
@@ -80,7 +80,7 @@ class FormResource
* @param bool $multiple add [] in the name of element and add 'multiple' attribute * @param bool $multiple add [] in the name of element and add 'multiple' attribute
* @return string|array HTML string with * @return string|array HTML string with
*/ */
public function select_resource_list($selected = 0, $htmlname = 'fk_resource', array $filter = [], $showempty = 0, $showtype = 0, $forcecombo = 0, $event = [], $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple = false) public function select_resource_list($selected = 0, $htmlname = 'fk_resource', array $filter = [], $showempty = 0, $showtype = 0, $forcecombo = 0, $event = [], $filterkey = [], $outputmode = 0, $limit = 20, $morecss = '', $multiple = false)
{ {
// phpcs:enable // phpcs:enable
global $conf, $user, $langs; global $conf, $user, $langs;

View File

@@ -131,14 +131,20 @@ class CodingPhpTest extends CommonClassTest
//print 'Check php file '.$file['relativename']."\n"; //print 'Check php file '.$file['relativename']."\n";
$filecontent = file_get_contents($file['fullname']); $filecontent = file_get_contents($file['fullname']);
$this->verifyIsModuleEnabledOk($filecontent, "htdocs/{$file['relativename']}"); // We are not interested in the comments
$filecontent = $this->removePhpComments(file_get_contents($file['fullname']));
// File path for reports
$report_filepath = "htdocs/{$file['relativename']}";
$this->verifyIsModuleEnabledOk($filecontent, $report_filepath);
if (preg_match('/\.class\.php/', $file['relativename']) if (preg_match('/\.class\.php/', $file['relativename'])
|| preg_match('/boxes\/box_/', $file['relativename']) || preg_match('/boxes\/box_/', $file['relativename'])
|| preg_match('/modules\/.*\/doc\/(doc|pdf)_/', $file['relativename']) || preg_match('/modules\/.*\/doc\/(doc|pdf)_/', $file['relativename'])
|| preg_match('/modules\/(import|mailings|printing)\//', $file['relativename']) || preg_match('/modules\/(import|mailings|printing)\//', $file['relativename'])
|| in_array($file['name'], array('modules_boxes.php', 'TraceableDB.php'))) { || in_array($file['name'], array('modules_boxes.php', 'TraceableDB.php'))) {
// Check into Class files // Check Class files
if (! in_array($file['name'], array( if (! in_array($file['name'], array(
'api.class.php', 'api.class.php',
'commonobject.class.php', 'commonobject.class.php',
@@ -152,18 +158,18 @@ class CodingPhpTest extends CommonClassTest
// Must not find $db-> // Must not find $db->
$ok = true; $ok = true;
$matches = array(); $matches = array();
// Check string $db-> inside a class.php file (it should be $this->db-> into such classes) // Check string $db-> inside a class.php file (it should be $this->db-> in such classes)
preg_match_all('/'.preg_quote('$db->', '/').'/', $filecontent, $matches, PREG_SET_ORDER); preg_match_all('/'.preg_quote('$db->', '/').'/', $filecontent, $matches, PREG_SET_ORDER);
foreach ($matches as $key => $val) { foreach ($matches as $key => $val) {
$ok = false; $ok = false;
break; break;
} }
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this->assertTrue($ok, 'Found string $db-> into a .class.php file in '.$file['relativename'].'. Inside a .class file, you should use $this->db-> instead.'); $this->assertTrue($ok, 'Found string $db-> in a .class.php file in '.$file['relativename'].'. Inside a .class file, you should use $this->db-> instead.');
//exit; //exit;
} }
if (preg_match('/\.class\.php/', $file['relativename']) && ! in_array($file['relativename'], array( if (preg_match('/\.class\.php$/', $file['relativename']) && ! in_array($file['relativename'], array(
'adherents/canvas/actions_adherentcard_common.class.php', 'adherents/canvas/actions_adherentcard_common.class.php',
'contact/canvas/actions_contactcard_common.class.php', 'contact/canvas/actions_contactcard_common.class.php',
'compta/facture/class/facture.class.php', 'compta/facture/class/facture.class.php',
@@ -191,7 +197,7 @@ class CodingPhpTest extends CommonClassTest
// Must not find GETPOST // Must not find GETPOST
$ok = true; $ok = true;
$matches = array(); $matches = array();
// Check string GETPOSTFLOAT a class.php file (should not be found into classes) // Check string GETPOSTFLOAT a class.php file (should not be found in classes)
preg_match_all('/GETPOST\(["\'](....)/', $filecontent, $matches, PREG_SET_ORDER); preg_match_all('/GETPOST\(["\'](....)/', $filecontent, $matches, PREG_SET_ORDER);
foreach ($matches as $key => $val) { foreach ($matches as $key => $val) {
if (in_array($val[1], array('lang', 'forc', 'mass', 'conf'))) { if (in_array($val[1], array('lang', 'forc', 'mass', 'conf'))) {
@@ -201,11 +207,10 @@ class CodingPhpTest extends CommonClassTest
$ok = false; $ok = false;
break; break;
} }
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; $this->assertTrue($ok, 'Found string GETPOST in a .class.php file in '.$file['relativename'].'.');
$this->assertTrue($ok, 'Found string GETPOST into a .class.php file in '.$file['relativename'].'.');
} }
} else { } else {
// Check into Include files // Check Include files
if (! in_array($file['name'], array( if (! in_array($file['name'], array(
'objectline_view.tpl.php', 'objectline_view.tpl.php',
'extrafieldsinexport.inc.php', 'extrafieldsinexport.inc.php',
@@ -216,7 +221,7 @@ class CodingPhpTest extends CommonClassTest
// Must not found $this->db-> // Must not found $this->db->
$ok = true; $ok = true;
$matches = array(); $matches = array();
// Check string $this->db-> into a non class.php file (it should be $db-> into such classes) // Check string $this->db-> in a non class.php file (it should be $db-> in such classes)
preg_match_all('/'.preg_quote('$this->db->', '/').'/', $filecontent, $matches, PREG_SET_ORDER); preg_match_all('/'.preg_quote('$this->db->', '/').'/', $filecontent, $matches, PREG_SET_ORDER);
foreach ($matches as $key => $val) { foreach ($matches as $key => $val) {
$ok = false; $ok = false;
@@ -228,9 +233,9 @@ class CodingPhpTest extends CommonClassTest
} }
} }
// Check we don't miss top_httphead() into any ajax pages // Check we don't miss top_httphead() in any ajax pages
if (preg_match('/ajax\//', $file['relativename'])) { if (preg_match('/ajax\//', $file['relativename'])) {
print "Analyze ajax page ".$file['relativename']."\n"; //print "Analyze ajax page ".$file['relativename']."\n";
$ok = true; $ok = true;
$matches = array(); $matches = array();
preg_match_all('/top_httphead/', $filecontent, $matches, PREG_SET_ORDER); preg_match_all('/top_httphead/', $filecontent, $matches, PREG_SET_ORDER);
@@ -238,28 +243,13 @@ class CodingPhpTest extends CommonClassTest
$ok = false; $ok = false;
} }
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this->assertTrue($ok, 'Did not find top_httphead into the ajax page '.$file['relativename']); $this->assertTrue($ok, 'Did not find top_httphead in the ajax page '.$file['relativename']);
//exit; //exit;
} }
// Check if a var_dump has been forgotten // Check for unauthorised vardumps
if (!preg_match('/test\/phpunit/', $file['fullname'])) { if (!preg_match('/test\/phpunit/', $file['fullname'])) {
if (! in_array($file['name'], array('class.nusoap_base.php'))) { $this->verifyNoActiveVardump($filecontent, $report_filepath);
$ok = true;
$matches = array();
preg_match_all('/(.)\s*var_dump\(/', $filecontent, $matches, PREG_SET_ORDER);
//var_dump($matches);
foreach ($matches as $key => $val) {
if ($val[1] != '/' && $val[1] != '*') {
$ok = false;
break;
}
break;
}
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this->assertTrue($ok, 'Found string var_dump that is not just after /* or // in '.$file['relativename']);
//exit;
}
} }
// Check get_class followed by __METHOD__ // Check get_class followed by __METHOD__
@@ -311,7 +301,7 @@ class CodingPhpTest extends CommonClassTest
break; break;
} }
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this->assertTrue($ok, 'Found non quoted or not casted var into sql request '.$file['relativename'].' - Bad.'); $this->assertTrue($ok, 'Found non quoted or not casted var in sql request '.$file['relativename'].' - Bad.');
//exit; //exit;
// Check that forged sql string is using ' instead of " as string PHP quotes // Check that forged sql string is using ' instead of " as string PHP quotes
@@ -327,7 +317,7 @@ class CodingPhpTest extends CommonClassTest
//if ($reg[0] != 'db') $ok=false; //if ($reg[0] != 'db') $ok=false;
} }
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this->assertTrue($ok, 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables into file '.$file['relativename'].' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...'); $this->assertTrue($ok, 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables in file '.$file['relativename'].' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...');
//exit; //exit;
// Check that forged sql string is using ' instead of " as string PHP quotes // Check that forged sql string is using ' instead of " as string PHP quotes
@@ -339,7 +329,7 @@ class CodingPhpTest extends CommonClassTest
$ok = false; $ok = false;
break; break;
} }
$this->assertTrue($ok, 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables into file '.$file['relativename'].' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...'); $this->assertTrue($ok, 'Found a forged SQL string that mix on same line the use of \' for PHP string and PHP variables in file '.$file['relativename'].' Use " to forge PHP string like this: $sql = "SELECT ".$myvar...');
// Check sql string VALUES ... , ".$xxx // Check sql string VALUES ... , ".$xxx
// with xxx that is not 'db-' (for $db->escape). It means we forget a ' if string, or an (int) if int, when forging sql request. // with xxx that is not 'db-' (for $db->escape). It means we forget a ' if string, or an (int) if int, when forging sql request.
@@ -358,7 +348,7 @@ class CodingPhpTest extends CommonClassTest
break; break;
} }
//print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n";
$this->assertTrue($ok, 'Found non quoted or not casted var into sql request '.$file['relativename'].' - Bad.'); $this->assertTrue($ok, 'Found non quoted or not casted var in sql request '.$file['relativename'].' - Bad.');
//exit; //exit;
// Check '".$xxx non escaped // Check '".$xxx non escaped
@@ -514,7 +504,7 @@ class CodingPhpTest extends CommonClassTest
break; break;
} }
} }
$this->assertTrue($ok, 'Found a forbidden string sequence into '.$file['relativename'].' : name="token" value="\'.$_SESSION[..., you must use a newToken() instead of $_SESSION[\'newtoken\'].'); $this->assertTrue($ok, 'Found a forbidden string sequence in '.$file['relativename'].' : name="token" value="\'.$_SESSION[..., you must use a newToken() instead of $_SESSION[\'newtoken\'].');
// Test we don't have preg_grep with a param without preg_quote // Test we don't have preg_grep with a param without preg_quote
@@ -589,10 +579,93 @@ class CodingPhpTest extends CommonClassTest
$ok = false; $ok = false;
break; break;
} }
$this->assertTrue($ok, 'Found a CURDATE\(\) into code. Do not use this SQL method in file '.$file['relativename'].'. You must use the PHP function dol_now() instead.'); $this->assertTrue($ok, 'Found a CURDATE\(\) in code. Do not use this SQL method in file '.$file['relativename'].'. You must use the PHP function dol_now() instead.');
} }
/**
* Verify that no active var_dump was left over in the code
*
* @param string $filecontent Contents to check for php code that uses a module name
* @param string $filename File name for the contents (used for reporting)
*
* @return void
*/
private function verifyNoActiveVardump(&$filecontent, $filename)
{
$ok = true;
$matches = array();
// Match!:
// - Line-start, whitespace, var_dump
// - Line-start, no-comment-leader, var_dump
// no-commen-leader=
// - Any character not / or *
// - Any / not preceded with / and not followed by / or *
// - Any * not preceded with /
preg_match_all('{^(?:^|^(?:[ \t]*|(?:(?:[^*/]|(?<![^/])/(?![*/])|(?!/)\*)(\S))))\bvar_dump\(}m', $filecontent, $matches, PREG_SET_ORDER);
$failing_string = "";
foreach ($matches as $key => $val) {
if (!isset($val[1]) || $val[1] != '/' && $val[1] != '*') {
$ok = false;
$failing_string = $val[0];
break;
}
}
$this->assertTrue($ok, "Found string var_dump that is not just after /* or // in '$filename': $failing_string");
}
/**
* Provide test data for testing the method detecting var_dump presence.
*
* @return array<string,array{0:string,1:bool}> Test sets
*/
public function vardumpTesterProvider()
{
return [
'var_dump at start of file' => ["var_dump(\$help)\n", true],
'var_dump at start of line' => ["\nvar_dump(\$help)\n", true],
'var_dump after comment next line' => ["/* Hello */\nvar_dump(\$help)\n", true],
'var_dump with space' => [" var_dump(\$help)\n", true],
'var_dump after comment' => [" // var_dump(\$help)\n", false],
'2 var_dumps after comment' => [" // var_dump(\$help); var_dump(\$help)\n", false],
'var_dump before and after comment' => [" var_dump(\$help); // var_dump(\$help)\n", true],
];
}
/**
* Test that verifyNoActiveVardump generates a notification
*
* @param string $filecontent Fake file content
* @param bool $hasVardump When true, expect var_dump detection
*
* @return void
*
* @dataProvider vardumpTesterProvider
*/
public function testVerifyNoActiveVardump(&$filecontent, $hasVardump)
{
$this->nbLinesToShow = 1;
// Create some dummy file content
$filename = $this->getName(false);
$notification = false;
ob_start(); // Do not disturb the output with tests that are meant to fail.
try {
$this->verifyNoActiveVardump($filecontent, $filename);
} catch (Throwable $e) {
$notification = (string) $e;
}
$output = ob_get_clean();
// Assert that a notification was generated
if ($hasVardump) {
$this->assertStringContainsString("Found string var_dump", $notification ?? '', "Expected notification not found.");
} else {
$this->assertFalse($notification, "Unexpection detection of var_dump");
}
}
/** /**
* Verify that only known modules are used * Verify that only known modules are used
* *
@@ -635,4 +708,72 @@ class CodingPhpTest extends CommonClassTest
); );
} }
} }
/**
* Remove php comments from source string
*
* @param string $string The string from which the PHP comments are removed
*
* @return string The string without the comments
*/
private function removePhpComments($string)
{
return preg_replace_callback(
'{(//.*?$)|(/\*.*?\*/)}ms',
static function ($match) {
if (isset($match[2])) {
// Count the number of newline characters in the comment
$num_newlines = substr_count($match[0], "\n");
// Generate whitespace equivalent to the number of newlines
if ($num_newlines == 0) {
// /* Comment on single line -> space
return " ";
} else {
// /* Comment on multiple lines -> new lines
return str_repeat("\n", $num_newlines);
}
} else {
// Double slash comment, just remove
return "";
}
},
$string
);
}
/**
* Provide test data for testing the comments remover
*
* @return array<string,array{0:string,1:string}> Test sets
*/
public function commentRemovalTestProvider()
{
return [
'complete line 1' => ["/*Comment complete line*/", " "],
'complete line 2' => ["// Comment complete line", ""],
'partial line 1' => ["a/*Comment complete line*/b", "a b"],
'partial line 2' => ["a// Comment complete line", "a"],
'multi line full 1' => ["/*Comment\ncomplete line*/", "\n"],
'multi line full 2' => ["/*Comment\ncomplete line*/\n", "\n\n"],
'multi line partials 1' => ["a/*Comment\ncomplete line*/b", "a\nb"],
];
}
/**
* Test that comments are properly removed
*
* @param string $source Fake file content
* @param bool $expected When true, expect var_dump detection
*
* @return void
*
* @dataProvider commentRemovalTestProvider
*/
public function testRemovePhpComments(&$source, &$expected)
{
$this->nbLinesToShow = 0;
$this->assertEquals($expected, $this->removePhpComments($source), "Comments not removed as expected");
}
} }