From f4ff437026dc1601c552ed26272479cac5851082 Mon Sep 17 00:00:00 2001 From: MDW Date: Wed, 30 Oct 2024 21:33:30 +0100 Subject: [PATCH] Qual: Fix phan/phpstan notices in class files (part 4) (#31598) * Qual: Fix phan notices for DolibarrModules.class * Qual: Fix notices for classes actioncomm..task.class.php * fixup! Qual: Fix notices for classes actioncomm..task.class.php * Qual: Fix new notices blocking PR --- dev/tools/phan/baseline.txt | 39 +++----- htdocs/comm/action/class/actioncomm.class.php | 6 +- htdocs/core/class/menubase.class.php | 2 +- htdocs/core/class/timespent.class.php | 2 +- htdocs/core/lib/parsemd.lib.php | 11 +-- htdocs/core/menus/standard/eldy_menu.php | 1 + htdocs/core/modules/DolibarrModules.class.php | 65 ++++++++------ .../modules/barcode/modules_barcode.class.php | 3 + .../generate/modGeneratePassPerso.class.php | 31 +++++++ .../core/triggers/dolibarrtriggers.class.php | 4 +- htdocs/modulebuilder/index.php | 2 +- .../service/actions_card_service.class.php | 68 +++++++++++++- htdocs/product/price.php | 18 ++-- htdocs/product/stock/movement_list.php | 3 + htdocs/projet/activity/perday.php | 8 +- htdocs/projet/activity/perweek.php | 7 +- htdocs/projet/class/task.class.php | 90 +++++++++++++++---- phpstan.neon.dist | 8 +- 18 files changed, 265 insertions(+), 103 deletions(-) diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 5aa893ed558..25bd8357ad0 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -10,24 +10,24 @@ return [ // # Issue statistics: // PhanUndeclaredProperty : 560+ occurrences - // PhanPossiblyUndeclaredGlobalVariable : 540+ occurrences - // PhanPluginUnknownPropertyType : 410+ occurrences - // PhanTypeMismatchArgumentProbablyReal : 350+ occurrences + // PhanPossiblyUndeclaredGlobalVariable : 520+ occurrences // PhanUndeclaredGlobalVariable : 350+ occurrences + // PhanPluginUnknownPropertyType : 330+ occurrences + // PhanTypeMismatchArgumentProbablyReal : 330+ occurrences // PhanPluginUnknownArrayMethodReturnType : 230+ occurrences // PhanPossiblyUndeclaredVariable : 180+ occurrences // PhanPluginUnknownArrayMethodParamType : 160+ occurrences // PhanTypeMismatchProperty : 160+ occurrences - // PhanPluginUnknownArrayFunctionParamType : 90+ occurrences // PhanPluginUndeclaredVariableIsset : 65+ occurrences + // PhanPluginUnknownArrayFunctionParamType : 60+ occurrences // PhanTypeMismatchArgumentNullableInternal : 60+ occurrences // PhanPluginUnknownArrayFunctionReturnType : 50+ occurrences - // PhanRedefineFunction : 50+ occurrences // PhanPluginEmptyStatementIf : 45+ occurrences + // PhanRedefineFunction : 45+ occurrences // PhanTypeExpectedObjectPropAccess : 40+ occurrences // PhanTypeInvalidDimOffset : 35+ occurrences // PhanTypeMismatchDimFetch : 30+ occurrences - // PhanPluginUnknownArrayPropertyType : 20+ occurrences + // PhanPluginUnknownArrayPropertyType : 15+ occurrences // PhanPluginUnknownObjectMethodCall : 15+ occurrences // PhanUndeclaredConstant : 15+ occurrences // PhanEmptyForeach : 10+ occurrences @@ -290,14 +290,11 @@ return [ 'htdocs/core/lib/treeview.lib.php' => ['PhanPluginUnknownArrayFunctionParamType'], 'htdocs/core/lib/xcal.lib.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], 'htdocs/core/menus/standard/auguria.lib.php' => ['PhanTypeInvalidDimOffset'], - 'htdocs/core/menus/standard/eldy_menu.php' => ['PhanTypeInvalidDimOffset'], - 'htdocs/core/modules/DolibarrModules.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownArrayPropertyType', 'PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/action/doc/pdf_standard_actions.class.php' => ['PhanPluginUnknownArrayPropertyType'], 'htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/asset/mod_asset_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/barcode/doc/phpbarcode.modules.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/barcode/mod_barcode_product_standard.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/barcode/modules_barcode.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/bom/mod_bom_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/cheque/doc/pdf_blochet.class.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/cheque/modules_chequereceipts.php' => ['PhanParamTooFew', 'PhanPluginSuspiciousParamPosition'], @@ -343,7 +340,6 @@ return [ 'htdocs/core/modules/propale/modules_propale.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/rapport/pdf_paiement.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/reception/doc/pdf_squille.modules.php' => ['PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/security/generate/modGeneratePassPerso.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/societe/mod_codecompta_aquarium.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/societe/mod_codecompta_digitaria.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/core/modules/stock/doc/pdf_standard_stock.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], @@ -386,9 +382,8 @@ return [ 'htdocs/core/tpl/passwordreset.tpl.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/core/tpl/resource_add.tpl.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], 'htdocs/core/tpl/resource_view.tpl.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/triggers/dolibarrtriggers.class.php' => ['PhanPluginUnknownArrayPropertyType'], 'htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php' => ['PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], - 'htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php' => ['PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], + 'htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/triggers/interface_50_modNotification_Notification.class.php' => ['PhanPluginUnknownArrayMethodReturnType'], 'htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeExpectedObjectPropAccess'], @@ -429,9 +424,7 @@ return [ 'htdocs/ecm/class/ecmfiles.class.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/ecm/class/htmlecm.form.class.php' => ['PhanPluginUnknownArrayMethodParamType'], 'htdocs/ecm/dir_card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/ecm/index.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/ecm/index_auto.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/ecm/index_medias.php' => ['PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/ecm/index.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], 'htdocs/emailcollector/class/emailcollectoraction.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/emailcollector/class/emailcollectorfilter.class.php' => ['PhanPluginUnknownPropertyType'], @@ -520,7 +513,7 @@ return [ 'htdocs/imports/import.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/install/check.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/install/fileconf.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/install/inc.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanRedefineFunction'], + 'htdocs/install/inc.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/install/index.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/install/repair.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/install/step2.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredProperty'], @@ -533,7 +526,7 @@ return [ 'htdocs/knowledgemanagement/knowledgerecord_card.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/knowledgemanagement/knowledgerecord_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/loan/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], - 'htdocs/loan/class/loan.class.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/loan/class/loan.class.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/loan/class/loanschedule.class.php' => ['PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType'], 'htdocs/loan/class/paymentloan.class.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/loan/document.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], @@ -573,7 +566,6 @@ return [ 'htdocs/printing/index.php' => ['PhanUndeclaredProperty'], 'htdocs/product/admin/product.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/product/ajax/products.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/product/canvas/service/actions_card_service.class.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/product/card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/product/class/api_products.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanUndeclaredProperty'], 'htdocs/product/class/html.formproduct.class.php' => ['PhanUndeclaredProperty'], @@ -604,7 +596,7 @@ return [ 'htdocs/product/stock/info.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/product/stock/movement_card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/product.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/product/stock/productlot_card.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/productlot_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -620,14 +612,11 @@ return [ 'htdocs/product/stock/tpl/stockcorrection.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/tpl/stocktransfer.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/projet/activity/index.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeExpectedObjectPropAccessButGotNull', 'PhanUndeclaredGlobalVariable'], - 'htdocs/projet/activity/perday.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/projet/activity/perweek.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/admin/project.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/ajax/projects.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/projet/class/api_tasks.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/projet/class/projectstats.class.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], - 'htdocs/projet/class/task.class.php' => ['PhanPluginEmptyStatementIf', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType'], 'htdocs/projet/class/taskstats.class.php' => ['PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType'], 'htdocs/projet/contact.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeComparisonFromArray', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/element.php' => ['PhanUndeclaredProperty'], @@ -718,7 +707,6 @@ return [ 'htdocs/societe/checkvat/checkVatPopup.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/societe/class/api_contacts.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty'], 'htdocs/societe/class/api_thirdparties.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/societe/class/client.class.php' => ['PhanPluginUnknownArrayPropertyType'], 'htdocs/societe/class/societe.class.php' => ['PhanTypeMismatchProperty'], 'htdocs/societe/class/societeaccount.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/societe/consumption.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], @@ -733,7 +721,6 @@ return [ 'htdocs/supplier_proposal/class/api_supplier_proposals.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanUndeclaredProperty'], 'htdocs/supplier_proposal/class/supplier_proposal.class.php' => ['PhanUndeclaredProperty'], 'htdocs/supplier_proposal/list.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/support/inc.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanRedefineFunction'], 'htdocs/takepos/admin/orderprinters.php' => ['PhanTypeMismatchDimFetch'], 'htdocs/takepos/ajax/ajax.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/takepos/floors.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -789,10 +776,10 @@ return [ 'htdocs/webservices/server_contact.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/webservices/server_invoice.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/webservices/server_order.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeExpectedObjectPropAccess', 'PhanUndeclaredProperty'], - 'htdocs/webservices/server_payment.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanTypeExpectedObjectPropAccess', 'PhanUndeclaredProperty'], + 'htdocs/webservices/server_payment.php' => ['PhanTypeExpectedObjectPropAccess', 'PhanUndeclaredProperty'], 'htdocs/webservices/server_productorservice.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanUndeclaredProperty'], 'htdocs/webservices/server_project.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/webservices/server_supplier_invoice.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanUndeclaredProperty'], + 'htdocs/webservices/server_supplier_invoice.php' => ['PhanPluginUnknownArrayFunctionReturnType', 'PhanUndeclaredProperty'], 'htdocs/webservices/server_thirdparty.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/webservices/server_user.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanUndeclaredProperty'], 'htdocs/website/class/website.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPossiblyNullTypeMismatchProperty', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal'], diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index e4858c21f94..fc30d2820a4 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -231,7 +231,7 @@ class ActionComm extends CommonObject public $userownerid; /** - * @var array,answer_status:int,transparency:int<0,1>}> Array of contact ids + * @var array,answer_status:int,transparency:int<0,1>}|int> Array of contact ids */ public $socpeopleassigned = array(); @@ -2707,7 +2707,9 @@ class ActionComm extends CommonObject // Load event $res = $this->fetch($actionCommReminder->fk_actioncomm); - if ($res > 0) $res = $this->fetch_thirdparty(); + if ($res > 0) { + $res = $this->fetch_thirdparty(); + } if ($res > 0) { // PREPARE EMAIL $errormesg = ''; diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php index 545bfb52f32..319e6d50422 100644 --- a/htdocs/core/class/menubase.class.php +++ b/htdocs/core/class/menubase.class.php @@ -138,7 +138,7 @@ class Menubase public $perms; /** - * @var string Condition to show or hide + * @var string|int<0,1> Condition to show or hide */ public $enabled; diff --git a/htdocs/core/class/timespent.class.php b/htdocs/core/class/timespent.class.php index 8a9cf36b9a7..91ac9930a66 100644 --- a/htdocs/core/class/timespent.class.php +++ b/htdocs/core/class/timespent.class.php @@ -152,7 +152,7 @@ class TimeSpent extends CommonObject */ public $element_date_withhour; /** - * @var float + * @var int Note seems to be int (seconds) even if declared as double in DB. */ public $element_duration; /** diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 26a268cd738..7b025d589c5 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 MDW * * 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 @@ -24,10 +25,10 @@ /** * Function to parse MD content into HTML * - * @param string $content MD content - * @param string $parser 'parsedown' or 'nl2br' - * @param string $replaceimagepath Replace path to image with another path. Example: ('doc/'=>'xxx/aaa/') - * @return string Parsed content + * @param string $content MD content + * @param 'parsedown'|'nl2br' $parser 'parsedown' or 'nl2br' + * @param ?array $replaceimagepath Replace path to image with another path. Example: ('doc/'=>'xxx/aaa/') + * @return string Parsed content */ function dolMd2Html($content, $parser = 'parsedown', $replaceimagepath = null) { @@ -72,7 +73,7 @@ function dolMd2Html($content, $parser = 'parsedown', $replaceimagepath = null) * * @param string $content MD content * @param string $parser 'dolibarr' - * @param string $replaceimagepath Replace path to image with another path. Example: ('doc/'=>'xxx/aaa/') + * @param ?array $replaceimagepath Replace path to image with another path. Example: ('doc/'=>'xxx/aaa/') * @return string Parsed content */ function dolMd2Asciidoc($content, $parser = 'dolibarr', $replaceimagepath = null) diff --git a/htdocs/core/menus/standard/eldy_menu.php b/htdocs/core/menus/standard/eldy_menu.php index 220be3817f7..a7e08363ec6 100644 --- a/htdocs/core/menus/standard/eldy_menu.php +++ b/htdocs/core/menus/standard/eldy_menu.php @@ -285,6 +285,7 @@ class MenuManager */ $lastlevel2 = array(); + '@phan-var-force array $lastlevel2'; foreach ($submenu->liste as $key2 => $val2) { // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu','prefix'] $showmenu = true; if (getDolGlobalString('MAIN_MENU_HIDE_UNAUTHORIZED') && empty($val2['enabled'])) { diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 3f0891d0c0a..7a3404aa961 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -120,17 +120,17 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it public $const = array(); /** - * @var array Module cron jobs entries + * @var array Module cron jobs entries */ public $cronjobs = array(); /** - * @var array Module access rights + * @var array,string|int>> Module access rights */ public $rights; /** - * @var int 1=Admin is always granted of permission of modules (even when module is disabled) + * @var int<0,1> 1=Admin is always granted of permission of modules (even when module is disabled) */ public $rights_admin_allowed; @@ -149,7 +149,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it const KEY_ENABLED = 7; /** - * @var array|int Module menu entries (1 means the menu entries are not declared into module descriptor but are hardcoded into menu manager) + * @var array|int<1,1> Module menu entries (1 means the menu entries are not declared into module descriptor but are hardcoded into menu manager) */ public $menu = array(); @@ -232,12 +232,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it public $descriptionlong; /** - * @var array dictionaries description + * @var array{}|array{langs:string,tabname:string[],tablib:string[],tabsql:string[],tabsqlsort:string[],tabfield:string[],tabfieldvalue:string[],tabfieldinsert:string[],tabrowid:string[],tabcond:array>,tabhelp:array>} dictionaries description */ public $dictionaries = array(); /** - * @var array tabs description + * @var array tabs description */ public $tabs; @@ -485,12 +485,18 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it */ public $need_dolibarr_version; + /** + * @var int<0,1> + */ public $need_javascript_ajax; + /** + * @var bool + */ public $enabled_bydefault; /** - * @var bool|int Whether to hide the module. + * @var bool|int<0,1> Whether to hide the module. */ public $hidden = false; @@ -520,8 +526,8 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it * Enables a module. * Inserts all information into database. * - * @param array $array_sql SQL requests to be executed when enabling module - * @param string $options String with options when disabling module: + * @param array}>|array $array_sql SQL requests to be executed when enabling module + * @param string $options String with options when disabling module: * - 'noboxes' = Do all actions but do not insert boxes * - 'newboxdefonly' = Do all actions but for boxes, insert def of boxes only and not boxes activation * @return int 1 if OK, 0 if KO @@ -1113,7 +1119,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it /** * Gives the last author of activation * - * @return array Array array('authorid'=>Id of last activation user, 'lastactivationdate'=>Date of last activation) + * @return array{}|array{authorid:int|'',ip:string,lastactivationdate:int|'',lastactivationversion:string} Array array('authorid'=>Id of last activation user, 'lastactivationdate'=>Date of last activation) */ public function getLastActivationInfo() { @@ -1137,10 +1143,10 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $tmp = json_decode($obj->note, true); } return array( - 'authorid' => empty($tmp['authorid']) ? '' : $tmp['authorid'], - 'ip' => empty($tmp['ip']) ? '' : $tmp['ip'], + 'authorid' => empty($tmp['authorid']) ? '' : (int) $tmp['authorid'], + 'ip' => empty($tmp['ip']) ? '' : (string) $tmp['ip'], 'lastactivationdate' => $this->db->jdate($obj->tms), - 'lastactivationversion' => (!empty($tmp['lastactivationversion']) ? $tmp['lastactivationversion'] : 'unknown'), + 'lastactivationversion' => (!empty($tmp['lastactivationversion']) ? (string) $tmp['lastactivationversion'] : 'unknown'), ); } } @@ -1937,10 +1943,10 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it /** * Adds access rights * - * @param int $reinitadminperms If 1, we also grant them to all admin users - * @param int $force_entity Force current entity - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int Error count (0 if OK) + * @param int<0,1> $reinitadminperms If 1, we also grant them to all admin users + * @param ?int $force_entity Force current entity + * @param int<0,1> $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int Error count (0 if OK) */ public function insert_permissions($reinitadminperms = 0, $force_entity = null, $notrigger = 0) { @@ -2770,18 +2776,18 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it /** * Helper method to declare dictionaries one at a time (rather than declaring dictionaries property by property). * - * @param array $dictionaryArray Array describing one dictionary. Keys are: - * 'name', table name (without prefix) - * 'lib', dictionary label - * 'sql', query for select - * 'sqlsort', sort order - * 'field', comma-separated list of fields to select - * 'fieldvalue', list of columns used for editing existing rows - * 'fieldinsert', list of columns used for inserting new rows - * 'rowid', name of the technical ID (primary key) column, usually 'rowid' - * 'cond', condition for the dictionary to be shown / active - * 'help', optional array of translation keys by column for tooltips - * 'fieldcheck' (appears to be unused) + * @param array{name:string,lib:string,sql:string,sqlsort:string,field:string,fieldvalue:string,fieldinsert:string,rowid:string,cond:bool,help:array,fieldcheck?:null} $dictionaryArray Array describing one dictionary. Keys are: + * 'name', table name (without prefix) + * 'lib', dictionary label + * 'sql', query for select + * 'sqlsort', sort order + * 'field', comma-separated list of fields to select + * 'fieldvalue', list of columns used for editing existing rows + * 'fieldinsert', list of columns used for inserting new rows + * 'rowid', name of the technical ID (primary key) column, usually 'rowid' + * 'cond', condition for the dictionary to be shown / active + * 'help', optional array of translation keys by column for tooltips + * 'fieldcheck' (appears to be unused) * @param string $langs Optional translation file to include (appears to be unused) * @return void */ @@ -2791,6 +2797,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it foreach ($fields as $field) { if (isset($dictionaryArray[$field])) { + // @phan-suppress-next-line PhanTypeMismatchProperty $this->dictionaries['tab'.$field][] = $dictionaryArray[$field]; } } diff --git a/htdocs/core/modules/barcode/modules_barcode.class.php b/htdocs/core/modules/barcode/modules_barcode.class.php index 16232e783eb..0c1caa9cd3e 100644 --- a/htdocs/core/modules/barcode/modules_barcode.class.php +++ b/htdocs/core/modules/barcode/modules_barcode.class.php @@ -93,6 +93,9 @@ abstract class ModeleBarCode abstract class ModeleNumRefBarCode extends CommonNumRefGenerator { // variables inherited from CommonNumRefGenerator + /** + * @var int<0,1> + */ public $code_null; diff --git a/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php b/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php index a588e62eeef..de7096bb176 100644 --- a/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php +++ b/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com> * Copyright (C) 2017 Regis Houssin * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 MDW * * 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 @@ -40,9 +41,21 @@ class modGeneratePassPerso extends ModeleGenPassword public $picto = 'fa-shield-alt'; + /** + * @var string + */ public $NbMaj; + /** + * @var string + */ public $NbNum; + /** + * @var string + */ public $NbSpe; + /** + * @var string + */ public $NbRepeat; /** @@ -52,11 +65,29 @@ class modGeneratePassPerso extends ModeleGenPassword */ public $WithoutAmbi = 0; + /** + * @var string + */ public $Maj; + /** + * @var string + */ public $Min; + /** + * @var string + */ public $Nb; + /** + * @var string + */ public $Spe; + /** + * @var array + */ public $Ambi; + /** + * @var string + */ public $All; /** diff --git a/htdocs/core/triggers/dolibarrtriggers.class.php b/htdocs/core/triggers/dolibarrtriggers.class.php index a84fac7c0cd..ad8bd1fa159 100644 --- a/htdocs/core/triggers/dolibarrtriggers.class.php +++ b/htdocs/core/triggers/dolibarrtriggers.class.php @@ -68,7 +68,7 @@ abstract class DolibarrTriggers /** * Errors reported by the trigger - * @var array + * @var string[] */ public $errors; @@ -94,7 +94,7 @@ abstract class DolibarrTriggers const VERSION_DOLIBARR = 'dolibarr'; /** - * @var array dictionary of possible module states + * @var array dictionary of possible module states */ const VERSIONS = [ 'dev' => 'development', diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 9440b466b58..5365167ab6d 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2196,7 +2196,7 @@ if (($dirins && $action == 'confirm_deletedictionary' && $dicname) || ($dirins & $error++; setEventMessages($langs->trans("ErrorDictionaryNotFound", ucfirst($dicname)), null, 'errors'); } - if (!$error) { + if (!$error && $newdicname !== null) { // delete table $_results = $db->DDLDropTable(MAIN_DB_PREFIX.strtolower($newdicname)); if ($_results < 0) { diff --git a/htdocs/product/canvas/service/actions_card_service.class.php b/htdocs/product/canvas/service/actions_card_service.class.php index 1749ddc4462..a0e41be87fb 100644 --- a/htdocs/product/canvas/service/actions_card_service.class.php +++ b/htdocs/product/canvas/service/actions_card_service.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 MDW * * 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 @@ -34,22 +35,63 @@ class ActionsCardService */ public $db; + /** + * @var string + */ public $dirmodule; + /** + * @var string + */ public $module; + /** + * @var string + */ public $label; + /** + * @var string + */ public $price_base_type; + /** + * @var string + */ public $accountancy_code_sell; + /** + * @var string + */ public $accountancy_code_buy; + /** + * @var string + */ public $targetmodule; + /** + * @var string + */ public $canvas; + /** + * @var string + */ public $card; + /** + * @var string + */ public $name; + /** + * @var string + */ public $definition; + /** + * @var string + */ public $fieldListName; + /** + * @var string + */ public $next_prev_filter; - //! Object container + /** + * @var Product Object container + */ public $object; //! Template container @@ -58,11 +100,29 @@ class ActionsCardService // List of fields for action=list public $field_list = array(); + /** + * @var string + */ public $id; + /** + * @var string + */ public $ref; + /** + * @var string + */ public $description; + /** + * @var string + */ public $note; + /** + * @var float + */ public $price; + /** + * @var float + */ public $price_min; /** @@ -156,7 +216,7 @@ class ActionsCardService $this->tpl['price_base_type'] = $form->selectPriceBaseType($this->price_base_type, "price_base_type"); // VAT - $this->tpl['tva_tx'] = $form->load_tva("tva_tx", -1, $mysoc, ''); + $this->tpl['tva_tx'] = $form->load_tva("tva_tx", -1, $mysoc, null); } if ($action == 'view') { @@ -233,9 +293,9 @@ class ActionsCardService // Duration $dur = array(); if ($this->object->duration_value > 1) { - $dur = array("h"=>$langs->trans("Hours"), "d"=>$langs->trans("Days"), "w"=>$langs->trans("Weeks"), "m"=>$langs->trans("Months"), "y"=>$langs->trans("Years")); + $dur = array("h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years")); } elseif ($this->object->duration_value > 0) { - $dur = array("h"=>$langs->trans("Hour"), "d"=>$langs->trans("Day"), "w"=>$langs->trans("Week"), "m"=>$langs->trans("Month"), "y"=>$langs->trans("Year")); + $dur = array("h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year")); } $this->tpl['duration_unit'] = $langs->trans($dur[$this->object->duration_unit]); diff --git a/htdocs/product/price.php b/htdocs/product/price.php index a31ed63e283..13fc35e183a 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -45,6 +45,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_expression.cl require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +$prodcustprice = null; if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php'; @@ -687,7 +688,7 @@ if (empty($reshook)) { * Price by customer * **************************************************** */ - if ($action == 'add_customer_price_confirm' && !$cancel && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) { + if ($action == 'add_customer_price_confirm' && !$cancel && $prodcustprice !== null && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) { $maxpricesupplier = $object->min_recommended_price(); $update_child_soc = GETPOSTINT('updatechildprice'); @@ -818,7 +819,7 @@ if (empty($reshook)) { } } - if ($action == 'delete_customer_price' && ($user->hasRight('produit', 'supprimer') || $user->hasRight('service', 'supprimer'))) { + if ($action == 'delete_customer_price' && $prodcustprice !== null && ($user->hasRight('produit', 'supprimer') || $user->hasRight('service', 'supprimer'))) { // Delete price by customer $prodcustprice->id = GETPOSTINT('lineid'); $result = $prodcustprice->delete($user); @@ -839,7 +840,7 @@ if (empty($reshook)) { $action = ''; } - if ($action == 'update_customer_price_confirm' && !$cancel && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) { + if ($action == 'update_customer_price_confirm' && !$cancel && $prodcustprice !== null && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) { $maxpricesupplier = $object->min_recommended_price(); $update_child_soc = GETPOSTINT('updatechildprice'); @@ -1014,6 +1015,7 @@ print ''; // Price per customer segment/level if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { + $soc = null; // Price and min price are variable (depends on level of company). if (!empty($socid)) { $soc = new Societe($db); @@ -1622,7 +1624,7 @@ if ($action == 'edit_vat' && ($user->hasRight('produit', 'creer') || $user->hasR // VAT print ''; print '
'.$langs->trans("DefaultTaxRate").''; - print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); + print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, null, $object->id, $object->tva_npr, $object->type, false, 1); print '
'; @@ -1652,7 +1654,7 @@ if (($action == 'edit_price' || $action == 'edit_level_price') && $object->getRi // VAT print ''.$langs->trans("DefaultTaxRate").''; - print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); + print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, null, $object->id, $object->tva_npr, $object->type, false, 1); print ''; // Price base @@ -2054,7 +2056,7 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT // VAT print ''.$langs->trans("DefaultTaxRate").''; - print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); + print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, null, $object->id, $object->tva_npr, $object->type, false, 1); print ''; // Price base @@ -2171,7 +2173,7 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT // VAT print ''.$langs->trans("DefaultTaxRate").''; - print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly, $object->type, false, 1); + print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, null, $object->id, $prodcustprice->recuperableonly, $object->type, false, 1); print ''; // Price base @@ -2731,7 +2733,7 @@ if ((!getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || $action == 'showlog_defau $sql .= " WHERE fk_product = ".((int) $object->id); $sql .= " AND p.entity IN (".getEntity('productprice').")"; $sql .= " AND p.fk_user_author = u.rowid"; - if (!empty($socid) && (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES'))) { + if (!empty($socid) && (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && $soc !== null) { $sql .= " AND p.price_level = ".((int) $soc->price_level); } $sql .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC"; diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index c876eab1a56..642475dc3f7 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -495,6 +495,9 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { if ($product->hasbatch()) { $pdluo = new Productbatch($db); + $srcwarehouseid = 0; + $eatby = -1; + $sellby = -1; if ($pdluoid > 0) { $result = $pdluo->fetch($pdluoid); if ($result) { diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index d5c9d691b46..3ad148bd564 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -398,9 +398,11 @@ $search_options_pattern = 'search_task_options_'; $extrafieldsobjectkey = 'projet_task'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -$tasksarray = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. + +$tasksarraywithoutfilter = array(); if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks - $tasksarraywithoutfilter = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. + $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. } $projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? $project->id : 0), 0, $onlyopenedproject); $tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject); @@ -510,7 +512,7 @@ if (!$user->hasRight('user', 'user', 'lire')) { $includeonly = array($user->id); } $selecteduser = $search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id; -$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200'); if ($form->num > 1 || empty($conf->dol_optimize_smallscreen)) { $moreforfilter .= '
'; $moreforfilter .= '
'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 97aa291a3d3..65c29e17740 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -413,9 +413,10 @@ $search_options_pattern = 'search_task_options_'; $extrafieldsobjectkey = 'projet_task'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -$tasksarray = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +$tasksarraywithoutfilter = array(); if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks - $tasksarraywithoutfilter = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. + $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. } $projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? $project->id : 0), 0, $onlyopenedproject); $tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject); @@ -561,7 +562,7 @@ if (!$user->hasRight('user', 'user', 'lire')) { $includeonly = array($user->id); } $selecteduser = $search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id; -$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200'); if ($form->num > 1 || empty($conf->dol_optimize_smallscreen)) { $moreforfilter .= '
'; $moreforfilter .= '
'; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index f34c39cbb19..0cc137c60a1 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -161,26 +161,80 @@ class Task extends CommonObjectLine */ public $rang; + /** + * @var int|string + */ public $timespent_min_date; + /** + * @var int|string + */ public $timespent_max_date; + /** + * @var int + */ public $timespent_total_duration; + /** + * @var float + */ public $timespent_total_amount; + /** + * @var int + */ public $timespent_nblinesnull; + /** + * @var int + */ public $timespent_nblines; // For detail of lines of timespent record, there is the property ->lines in common // Var used to call method addTimeSpent(). Bad practice. + /** + * @var int + */ public $timespent_id; + /** + * @var int + */ public $timespent_duration; + /** + * @var int + */ public $timespent_old_duration; + /** + * @var int|string + */ public $timespent_date; + /** + * @var int|string + */ public $timespent_datehour; // More accurate start date (same than timespent_date but includes hours, minutes and seconds) + /** + * @var int + */ public $timespent_withhour; // 1 = we entered also start hours for timesheet line + /** + * @var int + */ public $timespent_fk_user; + /** + * @var float + */ public $timespent_thm; + /** + * @var string + */ public $timespent_note; + /** + * @var int + */ public $timespent_fk_product; + /** + * @var int + */ public $timespent_invoiceid; + /** + * @var int + */ public $timespent_invoicelineid; public $comments = array(); @@ -227,6 +281,9 @@ class Task extends CommonObjectLine */ public $fk_opp_status; + /** + * @var int + */ public $usage_bill_time; /** @@ -234,6 +291,9 @@ class Task extends CommonObjectLine */ public $public; + /** + * @var array + */ public $array_options_project; // Properties to store thirdparty of project information @@ -1316,12 +1376,12 @@ class Task extends CommonObjectLine /** * Return list of roles for a user for each projects or each tasks (or a particular project or a particular task). * - * @param User|null $userp Return roles on project for this internal user. If set, usert and taskid must not be defined. - * @param User|null $usert Return roles on task for this internal user. If set userp must NOT be defined. -1 means no filter. + * @param ?User $userp Return roles on project for this internal user. If set, usert and taskid must not be defined. + * @param ?User $usert Return roles on task for this internal user. If set userp must NOT be defined. -1 means no filter. * @param string $projectid Project id list separated with , to filter on project * @param int $taskid Task id to filter on a task - * @param integer $filteronprojstatus Filter on project status if userp is set. Not used if userp not defined. - * @return array|int Array (projectid => 'list of roles for project' or taskid => 'list of roles for task') + * @param int $filteronprojstatus Filter on project status if userp is set. Not used if userp not defined. + * @return array|int<-1,-1> Array (projectid => 'list of roles for project' or taskid => 'list of roles for task') */ public function getUserRolesForProjectsOrTasks($userp, $usert, $projectid = '', $taskid = 0, $filteronprojstatus = -1) { @@ -1429,7 +1489,7 @@ class Task extends CommonObjectLine * Return list of id of contacts of task * * @param string $source Source - * @return array Array of id of contacts + * @return array Array of id of contacts */ public function getListContactId($source = 'internal') { @@ -1729,9 +1789,9 @@ class Task extends CommonObjectLine /** * Calculate total of time spent for task * - * @param User|int $userobj Filter on user. null or 0=No filter + * @param null|User|int<0,0> $userobj Filter on user. null or 0=No filter * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') - * @return array|int Array of info for task array('min_date', 'max_date', 'total_duration', 'total_amount', 'nblines', 'nblinesnull') + * @return int<-1,-1>|array{}|array{min_date:int|string,max_date:int|string,total_duration:int} Array of info for task array('min_date', 'max_date', 'total_duration', 'total_amount', 'nblines', 'nblinesnull') */ public function getSummaryOfTimeSpent($userobj = null, $morewherefilter = '') { @@ -1794,10 +1854,10 @@ class Task extends CommonObjectLine /** * Calculate quantity and value of time consumed using the thm (hourly amount value of work for user entering time) * - * @param User|string $fuser Filter on a dedicated user - * @param string $dates Start date (ex 00:00:00) - * @param string $datee End date (ex 23:59:59) - * @return array Array of info for task array('amount','nbseconds','nblinesnull') + * @param User|string $fuser Filter on a dedicated user + * @param string $dates Start date (ex 00:00:00) + * @param string $datee End date (ex 23:59:59) + * @return array{}|array{amount:float,nbseconds:int,nblinesnull:int} Array of info for task array('amount','nbseconds','nblinesnull') */ public function getSumOfAmount($fuser = '', $dates = '', $datee = '') { @@ -1876,7 +1936,7 @@ class Task extends CommonObjectLine * * @param User $userobj User object * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') - * @return array|int Return integer <0 if KO, array of time spent if OK + * @return stdClass[]|int Return integer <0 if KO, array of time spent if OK */ public function fetchAllTimeSpent(User $userobj, $morewherefilter = '') { @@ -2670,9 +2730,9 @@ class Task extends CommonObjectLine //$return .= '
'.$tmpproject->getNomProject().''; $return .= '
'.$arraydata['projectlink'].''; } - if (property_exists($this, 'budget_amount')) { - //$return .= '
'.$langs->trans("Budget").' : '.price($this->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; - } + //if (property_exists($this, 'budget_amount')) { + //$return .= '
'.$langs->trans("Budget").' : '.price($this->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; + //} if (property_exists($this, 'duration_effective')) { $return .= '
'.getTaskProgressView($this, false, true).'
'; } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 225f2184b8a..74aca131aa2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -94,6 +94,7 @@ parameters: - '#::HTML2OpenIDServer\(\) expects string, array given.#' - '# dol_stringtotime expects string, DateTime given.#' - '#expects string, bool\|mysqli_result\|resource given.#' + - '#(?: DoliDBPgsql::fetch_row\(\)) expects resource, PgSql\\Result given\.#' - '#( |::)((multi)?selectarray)\(\) expects array#' - '# (reWriteAllMenus|check_authentication) expects array#' - '#::(_validateMyObject|select_company)\(\) expects array