Qual: Fix multiple phan notices, update baseline (#36022)

* Qual: Fix phan notice with copy of attribute

* Qual: Fix phan notices with cast and updated param definition

* Qual: Fix phan notice with cast

* Qual: Update parameter type hint in utf8_check function

The parameter type hint for the $str parameter in the utf8_check function has been updated to include nullable types (string or int).

* Qual: Update User parameter type to nullable in call_trigger methods

The User parameter in call_trigger methods has been updated to be nullable to accommodate cases where the user object might not be available. This change ensures better flexibility and robustness in the codebase.

* Qual: Update phan baseline

* Qual: phpstan compatible type

* Qual: Add missing type hints for phan

- Add missing type hints for phan
- Fix indentation issues
- Improved consistency in code structure

* Qual: Update field configuration for backward compatibility

Enhanced the field configuration for backward compatibility by adding expected properties to the 'ref' field array.

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
This commit is contained in:
MDW
2025-11-01 17:47:28 +01:00
committed by GitHub
parent 0a3d2c7ddc
commit 073426d97e
9 changed files with 69 additions and 59 deletions

View File

@@ -13,7 +13,7 @@ return [
// PhanTypeMismatchProperty : 100+ occurrences // PhanTypeMismatchProperty : 100+ occurrences
// PhanTypeMismatchArgument : 65+ occurrences // PhanTypeMismatchArgument : 65+ occurrences
// PhanUndeclaredGlobalVariable : 60+ occurrences // PhanUndeclaredGlobalVariable : 60+ occurrences
// PhanTypeMismatchArgumentNullable : 40+ occurrences // PhanTypeMismatchArgumentNullable : 20+ occurrences
// PhanTypeInvalidDimOffset : 15+ occurrences // PhanTypeInvalidDimOffset : 15+ occurrences
// PhanTypeMismatchDimFetch : 10+ occurrences // PhanTypeMismatchDimFetch : 10+ occurrences
// PhanUndeclaredMethod : 8 occurrences // PhanUndeclaredMethod : 8 occurrences
@@ -82,7 +82,7 @@ return [
'htdocs/core/class/cgenericdic.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/cgenericdic.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/commonobject.class.php' => ['PhanParamTooMany', 'PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/class/commonobject.class.php' => ['PhanParamTooMany', 'PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/core/class/commonpeople.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/commonpeople.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/conf.class.php' => ['PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchProperty'], 'htdocs/core/class/conf.class.php' => ['PhanTypeMismatchProperty'],
'htdocs/core/class/ctyperesource.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/ctyperesource.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/dolgraph.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/dolgraph.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/emailsenderprofile.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/emailsenderprofile.class.php' => ['PhanUndeclaredProperty'],
@@ -121,7 +121,7 @@ return [
'htdocs/core/modules/holiday/mod_holiday_immaculate.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/holiday/mod_holiday_immaculate.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php' => ['PhanUndeclaredProperty'],
'htdocs/core/modules/hrm/mod_evaluation_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/hrm/mod_evaluation_advanced.php' => ['PhanUndeclaredProperty'],
'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchProperty'], 'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchProperty'],
'htdocs/core/modules/import/import_xlsx.modules.php' => ['PhanTypeMismatchProperty'], 'htdocs/core/modules/import/import_xlsx.modules.php' => ['PhanTypeMismatchProperty'],
'htdocs/core/modules/member/modules_cards.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/member/modules_cards.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanUndeclaredProperty'],
@@ -162,7 +162,7 @@ return [
'htdocs/expedition/card.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/expedition/card.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/expedition/class/expedition.class.php' => ['PhanUndeclaredProperty'], 'htdocs/expedition/class/expedition.class.php' => ['PhanUndeclaredProperty'],
'htdocs/expensereport/card.php' => ['PhanUndeclaredProperty'], 'htdocs/expensereport/card.php' => ['PhanUndeclaredProperty'],
'htdocs/expensereport/class/expensereport.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/expensereport/class/expensereport.class.php' => ['PhanTypeMismatchArgument'],
'htdocs/expensereport/payment/info.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/expensereport/payment/info.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/externalsite/frames.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/externalsite/frames.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/fichinter/card-rec.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/fichinter/card-rec.php' => ['PhanUndeclaredGlobalVariable'],
@@ -223,7 +223,6 @@ return [
'htdocs/projet/tasks.php' => ['PhanTypeMismatchArgument'], 'htdocs/projet/tasks.php' => ['PhanTypeMismatchArgument'],
'htdocs/projet/tasks/time.php' => ['PhanTypeInvalidDimOffset', 'PhanUndeclaredProperty'], 'htdocs/projet/tasks/time.php' => ['PhanTypeInvalidDimOffset', 'PhanUndeclaredProperty'],
'htdocs/projet/tasks/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/projet/tasks/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/public/members/new.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/public/payment/newpayment.php' => ['PhanUndeclaredProperty'], 'htdocs/public/payment/newpayment.php' => ['PhanUndeclaredProperty'],
'htdocs/public/project/suggestbooth.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/public/project/suggestbooth.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/public/project/suggestconference.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/public/project/suggestconference.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],

View File

@@ -1,6 +1,7 @@
<?php <?php
/* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr> /* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -30,7 +31,7 @@
* @property string $error * @property string $error
* @property string $table_element * @property string $table_element
* @property array<string,mixed> $context * @property array<string,mixed> $context
* @method int call_trigger(string $triggerName, User $user) * @method int call_trigger(string $triggerName, ?User $user)
*/ */
trait CommonSignedObject trait CommonSignedObject
{ {

View File

@@ -76,9 +76,9 @@ trait CommonTrigger
* NB: Error from trigger are stacked in interface->errors * NB: Error from trigger are stacked in interface->errors
* NB2: If return code of triggers are < 0, action calling trigger should cancel all transaction. * NB2: If return code of triggers are < 0, action calling trigger should cancel all transaction.
* *
* @param string $triggerName trigger's name to execute * @param string $triggerName Trigger's name to execute
* @param User $user Object user * @param ?User $user Object user
* @return int Result of run_triggers * @return int Result of run_triggers
*/ */
public function call_trigger($triggerName, $user) public function call_trigger($triggerName, $user)
{ {

View File

@@ -613,6 +613,7 @@ class Conf extends stdClass
} }
if (!empty($newvalue)) { if (!empty($newvalue)) {
// @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal,PhanTypeMismatchProperty
$this->modules_parts[$partname] = array_merge($this->modules_parts[$partname], array($modulename => $newvalue)); // $value may be a string or an array $this->modules_parts[$partname] = array_merge($this->modules_parts[$partname], array($modulename => $newvalue)); // $value may be a string or an array
} }
} elseif (preg_match('/^MAIN_MODULE_([0-9A-Z_]+)$/i', $key, $reg)) { } elseif (preg_match('/^MAIN_MODULE_([0-9A-Z_]+)$/i', $key, $reg)) {

View File

@@ -145,13 +145,13 @@ class Form
* @param string $text Text of label or key to translate * @param string $text Text of label or key to translate
* @param string $htmlname Name of select field ('edit' prefix will be added) * @param string $htmlname Name of select field ('edit' prefix will be added)
* @param string $preselected Value to show/edit (not used in this function) * @param string $preselected Value to show/edit (not used in this function)
* @param object $object Object (on the page we show) * @param ?object $object Object (on the page we show)
* @param int<0,1>|boolean $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field. * @param int<0,1>|boolean $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field.
* @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datehourpicker' 'checkbox:ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datehourpicker' 'checkbox:ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...)
* @param string $moreparam More param to add on a href URL. * @param string $moreparam More param to add on a href URL.
* @param int<0,1> $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. * @param int<0,1> $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS.
* @param int<0,3> $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' * @param int<0,3> $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' '
* @param string $paramid Key of parameter for id ('id', 'socid') * @param 'id'|'socid'|'projectid' $paramid Key of parameter for id ('id', 'socid')
* @param string $help Tooltip help * @param string $help Tooltip help
* @return string HTML edit field * @return string HTML edit field
*/ */
@@ -215,7 +215,7 @@ class Form
if (empty($notabletag) && $perm) { if (empty($notabletag) && $perm) {
$ret .= '<td class="right">'; $ret .= '<td class="right">';
} }
if ($htmlname && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) { if ($htmlname && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm && is_object($object)) {
$ret .= '<a class="editfielda reposition" href="' . dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'edit' . $htmlname, $paramid => $object->id], true) . $moreparam . '">'; $ret .= '<a class="editfielda reposition" href="' . dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'edit' . $htmlname, $paramid => $object->id], true) . $moreparam . '">';
$ret .= img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)); $ret .= img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1));
$ret .= '</a>'; $ret .= '</a>';
@@ -3345,7 +3345,7 @@ class Form
// include search in supplier ref // include search in supplier ref
if (getDolGlobalString('MAIN_SEARCH_PRODUCT_BY_FOURN_REF')) { if (getDolGlobalString('MAIN_SEARCH_PRODUCT_BY_FOURN_REF')) {
$sqlSupplierSearch .= !empty($sqlSupplierSearch) ? ' AND ':''; $sqlSupplierSearch .= !empty($sqlSupplierSearch) ? ' AND ' : '';
$sqlSupplierSearch .= " pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%'"; $sqlSupplierSearch .= " pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%'";
} }
$sql .= ")"; $sql .= ")";
@@ -9142,7 +9142,7 @@ class Form
* Output html form to select an object. * Output html form to select an object.
* Note, this function is called by selectForForms or by ajax selectobject.php * Note, this function is called by selectForForms or by ajax selectobject.php
* *
* @param Object $objecttmp Object to know the table to scan for combo. * @param CommonObject $objecttmp Object to know the table to scan for combo.
* @param string $htmlname Name of HTML select component * @param string $htmlname Name of HTML select component
* @param int $preselectedvalue Preselected value (ID of element) * @param int $preselectedvalue Preselected value (ID of element)
* @param string|int<0,1> $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) * @param string|int<0,1> $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
@@ -9185,7 +9185,7 @@ class Form
} }
} else { } else {
// For backward compatibility // For backward compatibility
$objecttmp->fields['ref'] = array('type' => 'varchar(30)', 'label' => 'Ref', 'showoncombobox' => 1); $objecttmp->fields['ref'] = array('type' => 'varchar(30)', 'label' => 'Ref', 'enabled' => 1, 'position' => 10, 'visible' => 4, 'showoncombobox' => 1);
} }
if (empty($fieldstoshow)) { if (empty($fieldstoshow)) {
@@ -9219,6 +9219,7 @@ class Form
$sql .= " LEFT JOIN " . $this->db->prefix() . $this->db->sanitize($objecttmp->table_element) . "_extrafields as e ON t.rowid = e.fk_object"; $sql .= " LEFT JOIN " . $this->db->prefix() . $this->db->sanitize($objecttmp->table_element) . "_extrafields as e ON t.rowid = e.fk_object";
} }
if (!empty($objecttmp->parent_element)) { // If parent_element is defined if (!empty($objecttmp->parent_element)) { // If parent_element is defined
'@phan-var-force CommonObjectLine $objecttmp';
$parent_properties = getElementProperties($objecttmp->parent_element); $parent_properties = getElementProperties($objecttmp->parent_element);
$sql .= " INNER JOIN " . $this->db->prefix() . $this->db->sanitize($parent_properties['table_element']) . " as o ON o.rowid = t.".$objecttmp->fk_parent_attribute; $sql .= " INNER JOIN " . $this->db->prefix() . $this->db->sanitize($parent_properties['table_element']) . " as o ON o.rowid = t.".$objecttmp->fk_parent_attribute;
} }
@@ -10518,10 +10519,10 @@ class Form
// If we ask a resource form external module (instead of default path) // If we ask a resource form external module (instead of default path)
$module=''; $module = '';
if (preg_match('/^([^@]+)@([^@]+)$/i', $key, $regs)) { // 'myobject@mymodule' if (preg_match('/^([^@]+)@([^@]+)$/i', $key, $regs)) { // 'myobject@mymodule'
$key = $regs[1]; $key = $regs[1];
$module=$regs[2]; $module = $regs[2];
} }
if (!empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || !in_array($key, $excludelinksto))) { if (!empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || !in_array($key, $excludelinksto))) {
@@ -10535,7 +10536,7 @@ class Form
$htmltoenteralink .= '<input type="hidden" name="token" value="' . newToken() . '">'; $htmltoenteralink .= '<input type="hidden" name="token" value="' . newToken() . '">';
$htmltoenteralink .= '<input type="hidden" name="action" value="addlinkbyref">'; $htmltoenteralink .= '<input type="hidden" name="action" value="addlinkbyref">';
$htmltoenteralink .= '<input type="hidden" name="id" value="' . $object->id . '">'; $htmltoenteralink .= '<input type="hidden" name="id" value="' . $object->id . '">';
$htmltoenteralink .= '<input type="hidden" name="addlink" value="' . $key .(!empty($module)?'@'.$module:''). '">'; $htmltoenteralink .= '<input type="hidden" name="addlink" value="' . $key .(!empty($module) ? '@'.$module : ''). '">';
$htmltoenteralink .= '<table class="noborder">'; $htmltoenteralink .= '<table class="noborder">';
$htmltoenteralink .= '<tr class="liste_titre">'; $htmltoenteralink .= '<tr class="liste_titre">';
//print '<td>' . $langs->trans("Ref") . '</td>'; //print '<td>' . $langs->trans("Ref") . '</td>';
@@ -10564,7 +10565,7 @@ class Form
$htmltoenteralink .= '<input type="hidden" name="token" value="' . newToken() . '">'; $htmltoenteralink .= '<input type="hidden" name="token" value="' . newToken() . '">';
$htmltoenteralink .= '<input type="hidden" name="action" value="addlink">'; $htmltoenteralink .= '<input type="hidden" name="action" value="addlink">';
$htmltoenteralink .= '<input type="hidden" name="id" value="' . $object->id . '">'; $htmltoenteralink .= '<input type="hidden" name="id" value="' . $object->id . '">';
$htmltoenteralink .= '<input type="hidden" name="addlink" value="' . $key . (!empty($module)?'@'.$module:''). '">'; $htmltoenteralink .= '<input type="hidden" name="addlink" value="' . $key . (!empty($module) ? '@'.$module : ''). '">';
$htmltoenteralink .= '<table class="noborder">'; $htmltoenteralink .= '<table class="noborder">';
$htmltoenteralink .= '<tr class="liste_titre">'; $htmltoenteralink .= '<tr class="liste_titre">';
$htmltoenteralink .= '<td class="nowrap"></td>'; $htmltoenteralink .= '<td class="nowrap"></td>';
@@ -11055,32 +11056,34 @@ class Form
$email = $object->email; $email = $object->email;
} elseif ($modulepart == 'contact') { } elseif ($modulepart == 'contact') {
$dir = $conf->societe->multidir_output[$entity] . '/contact'; $dir = $conf->societe->multidir_output[$entity] . '/contact';
if (!empty($object->photo)) { $photo = $object->photo; // Copy to help static analysis
if (dolIsAllowedForPreview($object->photo)) { if (!empty($photo)) {
if (dolIsAllowedForPreview($photo)) {
if ((string) $imagesize == 'mini') { if ((string) $imagesize == 'mini') {
$file = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . getImageFileNameForSize($object->photo, '_mini'); $file = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . getImageFileNameForSize($photo, '_mini');
} elseif ((string) $imagesize == 'small') { } elseif ((string) $imagesize == 'small') {
$file = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . getImageFileNameForSize($object->photo, '_small'); $file = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . getImageFileNameForSize($photo, '_small');
} else { } else {
$file = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . $object->photo; $file = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . $photo;
} }
$originalfile = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . $object->photo; $originalfile = get_exdir(0, 0, 0, 0, $object, 'contact') . 'photos/' . $photo;
} }
} }
$email = $object->email; $email = $object->email;
$capture = 'user'; $capture = 'user';
} elseif ($modulepart == 'userphoto') { } elseif ($modulepart == 'userphoto') {
$dir = $conf->user->dir_output; $dir = $conf->user->dir_output;
if (!empty($object->photo)) { $photo = $object->photo; // Copy to help static analysis
if (dolIsAllowedForPreview($object->photo)) { if (!empty($photo)) {
if (dolIsAllowedForPreview($photo)) {
if ((string) $imagesize == 'mini') { if ((string) $imagesize == 'mini') {
$file = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . getImageFileNameForSize($object->photo, '_mini'); $file = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . getImageFileNameForSize($photo, '_mini');
} elseif ((string) $imagesize == 'small') { } elseif ((string) $imagesize == 'small') {
$file = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . getImageFileNameForSize($object->photo, '_small'); $file = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . getImageFileNameForSize($photo, '_small');
} else { } else {
$file = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . $object->photo; $file = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . $photo;
} }
$originalfile = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . $object->photo; $originalfile = get_exdir(0, 0, 0, 0, $object, 'user') . 'photos/' . $photo;
} }
} }
if (getDolGlobalString('MAIN_OLD_IMAGE_LINKS')) { if (getDolGlobalString('MAIN_OLD_IMAGE_LINKS')) {
@@ -11090,16 +11093,17 @@ class Form
$capture = 'user'; $capture = 'user';
} elseif ($modulepart == 'memberphoto') { } elseif ($modulepart == 'memberphoto') {
$dir = $conf->adherent->dir_output; $dir = $conf->adherent->dir_output;
if (!empty($object->photo)) { $photo = $object->photo; // Copy to help static analysis
if (dolIsAllowedForPreview($object->photo)) { if (!empty($photo)) {
if (dolIsAllowedForPreview($photo)) {
if ((string) $imagesize == 'mini') { if ((string) $imagesize == 'mini') {
$file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($object->photo, '_mini'); $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($photo, '_mini');
} elseif ((string) $imagesize == 'small') { } elseif ((string) $imagesize == 'small') {
$file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($object->photo, '_small'); $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($photo, '_small');
} else { } else {
$file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $object->photo; $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $photo;
} }
$originalfile = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $object->photo; $originalfile = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $photo;
} }
} }
if (getDolGlobalString('MAIN_OLD_IMAGE_LINKS')) { if (getDolGlobalString('MAIN_OLD_IMAGE_LINKS')) {

View File

@@ -3474,7 +3474,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi
$object->totaldeposits = $object->getSumDepositsUsed(0); $object->totaldeposits = $object->getSumDepositsUsed(0);
$object->alreadypaid = $object->totalpaid + $object->totalcreditnotes + $object->totaldeposits; $object->alreadypaid = $object->totalpaid + $object->totalcreditnotes + $object->totaldeposits;
} }
$tmptxt = $object->getLibStatut(6, $object->alreadypaid); $tmptxt = $object->getLibStatut(6, (float) $object->alreadypaid);
if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3)) { if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3)) {
$tmptxt = $object->getLibStatut(5, (float) $object->alreadypaid); $tmptxt = $object->getLibStatut(5, (float) $object->alreadypaid);
} }
@@ -5219,7 +5219,7 @@ function dolGetFirstLetters($s, $nbofchar = 1)
/** /**
* Make a strlen call. Works even if mbstring module not enabled * Make a strlen call. Works even if mbstring module not enabled
* *
* @param string $string String to calculate length * @param ?string $string String to calculate length
* @param string $stringencoding Encoding of string * @param string $stringencoding Encoding of string
* @return int Length of string * @return int Length of string
*/ */
@@ -7050,7 +7050,7 @@ function load_fiche_titre($title, $morehtmlright = '', $picto = 'generic', $pict
$return .= '<table ' . ($id ? 'id="' . $id . '" ' : '') . 'class="centpercent notopnoleftnoright table-fiche-title' . ($morecssontable ? ' ' . $morecssontable : '') . '">'; // margin bottom must be same than into print_barre_list $return .= '<table ' . ($id ? 'id="' . $id . '" ' : '') . 'class="centpercent notopnoleftnoright table-fiche-title' . ($morecssontable ? ' ' . $morecssontable : '') . '">'; // margin bottom must be same than into print_barre_list
$return .= '<tr class="toptitle">'; $return .= '<tr class="toptitle">';
if ($picto) { if ($picto) {
$return .= '<td class="nobordernopadding widthpictotitle valignmiddle col-picto">' . img_picto('', $picto, 'class="valignmiddle pictotitle'.($morecssonpicto ? ' '.$morecssonpicto: '').'"', $pictoisfullpath) . '</td>'; $return .= '<td class="nobordernopadding widthpictotitle valignmiddle col-picto">' . img_picto('', $picto, 'class="valignmiddle pictotitle'.($morecssonpicto ? ' '.$morecssonpicto : '').'"', $pictoisfullpath) . '</td>';
} }
$return .= '<td class="nobordernopadding valignmiddle col-title">'; $return .= '<td class="nobordernopadding valignmiddle col-title">';
$return .= '<div class="titre inline-block">'; $return .= '<div class="titre inline-block">';
@@ -10362,7 +10362,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
$liste_factures[] = ' - '.$outputlangs->trans('Invoice').' '. $objp->ref.' '.$outputlangs->trans('AmountPayed').' '.price($objp->multicurrency_amount, 0, $outputlangs, 0, -1, -1, $objp->multicurrency_code); $liste_factures[] = ' - '.$outputlangs->trans('Invoice').' '. $objp->ref.' '.$outputlangs->trans('AmountPayed').' '.price($objp->multicurrency_amount, 0, $outputlangs, 0, -1, -1, $objp->multicurrency_code);
} }
} }
$substitutionarray['__SUPPLIER_PAYMENT_INVOICES_LIST__'] = implode("\n", $liste_factures);; $substitutionarray['__SUPPLIER_PAYMENT_INVOICES_LIST__'] = implode("\n", $liste_factures);
;
$substitutionarray['__SUPPLIER_PAYMENT_INVOICES_TOTAL__'] = price($object->multicurrency_amount, 0, $outputlangs, 0, -1, -1, $object->multicurrency_code ? $object->multicurrency_code : $conf->currency); $substitutionarray['__SUPPLIER_PAYMENT_INVOICES_TOTAL__'] = price($object->multicurrency_amount, 0, $outputlangs, 0, -1, -1, $object->multicurrency_code ? $object->multicurrency_code : $conf->currency);
} }
if (is_object($object) && $object->element == 'shipping') { if (is_object($object) && $object->element == 'shipping') {
@@ -11203,6 +11204,7 @@ function dol_sort_array(&$array, $index, $order = 'asc', $natsort = 0, $case_sen
// Add other keys // Add other keys
if (!empty($tmpmultikey[1])) { if (!empty($tmpmultikey[1])) {
$newindex = $tmpmultikey[1]; $newindex = $tmpmultikey[1];
// @phan-suppress-next-line PhanTypeArraySuspicious,PhanTypeMismatchDimFetch
$temp[$key] .= '__' . (empty($array[$key][$newindex]) ? 0 : $array[$key][$newindex]); $temp[$key] .= '__' . (empty($array[$key][$newindex]) ? 0 : $array[$key][$newindex]);
} }
} }
@@ -11243,8 +11245,8 @@ function dol_sort_array(&$array, $index, $order = 'asc', $natsort = 0, $case_sen
/** /**
* Check if a string is in UTF8. Seems similar to utf8_valid() but in pure PHP. * Check if a string is in UTF8. Seems similar to utf8_valid() but in pure PHP.
* *
* @param string $str String to check * @param null|string|int $str String to check
* @return boolean True if string is UTF8 or ISO compatible with UTF8, False if not (ISO with special non utf8 char or Binary) * @return boolean True if string is UTF8 or ISO compatible with UTF8, False if not (ISO with special non utf8 char or Binary)
* @see utf8_valid() * @see utf8_valid()
*/ */
function utf8_check($str) function utf8_check($str)
@@ -11498,14 +11500,14 @@ function dol_eval_new($s)
{ {
// Only this global variables can be read by eval function and returned to caller // Only this global variables can be read by eval function and returned to caller
global $conf, // Read of const is done with getDolGlobalString() but we need $conf->currency for example global $conf, // Read of const is done with getDolGlobalString() but we need $conf->currency for example
$db, $langs, $user, $website, $websitepage, $db, $langs, $user, $website, $websitepage,
$action, $mainmenu, $leftmenu, $action, $mainmenu, $leftmenu,
$mysoc, $mysoc,
$objectoffield, // To allow the use of $objectoffield in computed fields $objectoffield, // To allow the use of $objectoffield in computed fields
// Old variables used // Old variables used
$object, $object,
$obj; // To get $obj used into list when dol_eval() is used for computed fields and $obj is not yet $object $obj; // To get $obj used into list when dol_eval() is used for computed fields and $obj is not yet $object
// PHP < 7.4.0 // PHP < 7.4.0
defined('T_COALESCE_EQUAL') || define('T_COALESCE_EQUAL', PHP_INT_MAX); defined('T_COALESCE_EQUAL') || define('T_COALESCE_EQUAL', PHP_INT_MAX);
@@ -14187,7 +14189,6 @@ function dolGetButtonAction($label, $text = '', $actionType = 'default', $url =
* *
* @return array<string, string> An array where each key corresponds to the attribute name * @return array<string, string> An array where each key corresponds to the attribute name
* and each value is a full `key="escaped_value"` string ready for HTML output. * and each value is a full `key="escaped_value"` string ready for HTML output.
*
*/ */
function commonHtmlAttributeBuilder($attr, array $unescapedAttr = []) function commonHtmlAttributeBuilder($attr, array $unescapedAttr = [])
{ {
@@ -14199,7 +14200,9 @@ function commonHtmlAttributeBuilder($attr, array $unescapedAttr = [])
foreach ($attr as $key => $value) { foreach ($attr as $key => $value) {
// special boolean attributes case // special boolean attributes case
if (in_array($key, getListOfHtmlBooleanAttributes())) { if (in_array($key, getListOfHtmlBooleanAttributes())) {
if ($value) { $TCompiledAttr[$key] = $key; } if ($value) {
$TCompiledAttr[$key] = $key;
}
continue; continue;
} }

View File

@@ -1005,7 +1005,7 @@ class pdf_squille extends ModelePdfReception
//$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects
$pdf->SetFont('', '', $default_font_size - 2); $pdf->SetFont('', '', $default_font_size - 2);
$text = $linkedobject->ref; $text = (string) $linkedobject->ref;
if (isset($linkedobject->ref_client) && !empty($linkedobject->ref_client)) { if (isset($linkedobject->ref_client) && !empty($linkedobject->ref_client)) {
$text .= ' ('.$linkedobject->ref_client.')'; $text .= ' ('.$linkedobject->ref_client.')';
} }

View File

@@ -59,6 +59,8 @@ if (empty($object) || !is_object($object)) {
' '
@phan-var-force CommonObject|Facture $this @phan-var-force CommonObject|Facture $this
@phan-var-force CommonObject $object @phan-var-force CommonObject $object
@phan-var-force CommonObjectLine $line
@phan-var-force ExtraFields $extrafields
@phan-var-force Societe $buyer @phan-var-force Societe $buyer
@phan-var-force Societe $seller @phan-var-force Societe $seller
@phan-var-force int<0,1> $usehm @phan-var-force int<0,1> $usehm
@@ -514,7 +516,7 @@ if ($nolinesbefore) {
<td class="nobottom linecoluttc_currency right"> <td class="nobottom linecoluttc_currency right">
<input type="text" name="multicurrency_price_ttc" id="multicurrency_price_ttc" class="flat right width50" value="<?php echo(GETPOSTISSET("multicurrency_price_ttc") ? GETPOST("multicurrency_price_ttc", 'alpha', 2) : ''); ?>"> <input type="text" name="multicurrency_price_ttc" id="multicurrency_price_ttc" class="flat right width50" value="<?php echo(GETPOSTISSET("multicurrency_price_ttc") ? GETPOST("multicurrency_price_ttc", 'alpha', 2) : ''); ?>">
</td> </td>
<?php <?php
} }
$coldisplay++; $coldisplay++;
?> ?>
@@ -844,7 +846,7 @@ if (!empty($usemargins) && $user->hasRight('margins', 'creer')) {
} }
} }
}); });
<?php <?php
} ?> } ?>
/* When changing predefined product, we reload list of supplier prices required for margin combo */ /* When changing predefined product, we reload list of supplier prices required for margin combo */
@@ -966,7 +968,7 @@ if (!empty($usemargins) && $user->hasRight('margins', 'creer')) {
if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 1) { if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 1) {
if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) { ?> if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) { ?>
var proddesc = data.desc_trans; var proddesc = data.desc_trans;
<?php <?php
} else { ?> } else { ?>
var proddesc = data.desc; var proddesc = data.desc;
<?php <?php
@@ -981,7 +983,7 @@ if (!empty($usemargins) && $user->hasRight('margins', 'creer')) {
editor.setData(proddesc); editor.setData(proddesc);
} }
} }
<?php <?php
} else { ?> } else { ?>
jQuery('#dp_desc').text(proddesc); jQuery('#dp_desc').text(proddesc);
<?php <?php

View File

@@ -798,8 +798,8 @@ class EcmDirectory extends CommonObject
* NB2: if trigger fail, action should be canceled. * NB2: if trigger fail, action should be canceled.
* NB3: Should be deleted if EcmDirectory extend CommonObject * NB3: Should be deleted if EcmDirectory extend CommonObject
* *
* @param string $triggerName trigger's name to execute * @param string $triggerName Trigger's name to execute
* @param User $user Object user * @param ?User $user Object user
* @return int Result of run_triggers * @return int Result of run_triggers
*/ */
public function call_trigger($triggerName, $user) public function call_trigger($triggerName, $user)