From 6378a99e5af8284b7745c42fd69eb1f1de6b334e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 11 Sep 2025 11:22:11 +0200 Subject: [PATCH 1/7] add src and id when create ecmfiles (#35292) --- htdocs/core/lib/files.lib.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 87057606b7e..4e61a1506a0 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -511,6 +511,10 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir, $object = $ecmfile->label = md5_file(dol_osencode($filearray[$key]['fullname'])); // $destfile is a full path to file $ecmfile->fullpath_orig = $filearray[$key]['fullname']; $ecmfile->gen_or_uploaded = 'unknown'; + if (is_object($object)) { + $ecmfile->src_object_type = $object->element; + $ecmfile->src_object_id = $object->id; + } $ecmfile->description = ''; // indexed content $ecmfile->keywords = ''; // keyword content // When you scan file with dol_dir_list_in_database, you scan for files in entity of object (like with projects), even if you From a44fc7d8439db10fb48c33e74511b4849e020342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 11 Sep 2025 12:08:29 +0200 Subject: [PATCH 2/7] clean code (#35295) * clean code * clean code * clean code * clean code * clean code * clean code * clean code * fix * fix * fix * fix * fix --- dev/build/phpstan/phpstan-baseline.neon | 138 ---------------------- htdocs/ecm/class/ecmfiles.class.php | 43 +++---- htdocs/ecm/file_card.php | 27 ++--- htdocs/ecm/tpl/enablefiletreeajax.tpl.php | 6 +- 4 files changed, 31 insertions(+), 183 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 2b8ebc6ee7b..f3e2d560e47 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -11022,114 +11022,6 @@ parameters: count: 1 path: ../../../htdocs/don/payment/payment.php - - - message: '#^Property EcmFiles\:\:\$acl \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$cover \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$date_c \(int\|string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$date_m \(int\|string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$description \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$filename \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$filepath \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$fk_user_c \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$fk_user_m \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 3 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$fullpath_orig \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$gen_or_uploaded \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$keywords \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$label \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$position \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$share \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 3 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$src_object_id \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - - - message: '#^Property EcmFiles\:\:\$src_object_type \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ecm/class/ecmfiles.class.php - - message: '#^Right side of && is always true\.$#' identifier: booleanAnd.rightAlwaysTrue @@ -11142,36 +11034,6 @@ parameters: count: 1 path: ../../../htdocs/ecm/dir_add_card.php - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 1 - path: ../../../htdocs/ecm/file_card.php - - - - message: '#^If condition is always true\.$#' - identifier: if.alwaysTrue - count: 1 - path: ../../../htdocs/ecm/file_card.php - - - - message: '#^Ternary operator condition is always false\.$#' - identifier: ternary.alwaysFalse - count: 1 - path: ../../../htdocs/ecm/file_card.php - - - - message: '#^Ternary operator condition is always true\.$#' - identifier: ternary.alwaysTrue - count: 1 - path: ../../../htdocs/ecm/file_card.php - - - - message: '#^Variable \$module might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/ecm/file_card.php - - message: '#^If condition is always true\.$#' identifier: if.alwaysTrue diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 33f0e4a7fd0..b5d3abab20d 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2015 Florian Henry * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2018 Francis Appels - * Copyright (C) 2019-2024 Frédéric France + * Copyright (C) 2019-2025 Frédéric France * Copyright (C) 2024-2025 MDW * * This program is free software; you can redistribute it and/or modify @@ -47,48 +47,43 @@ class EcmFiles extends CommonObject public $table_element = 'ecm_files'; /** - * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png + * @var string String with name of icon for ecmfiles. Must be the part after the 'object_' into object_myobject.png */ public $picto = 'folder-open'; - /** - * @var string Ref hash of file path - */ - public $ref; - /** * hash of file content (md5_file(dol_osencode($destfull)) - * @var string Ecm Files label + * @var ?string Ecm Files label, null until fetched or set */ public $label; /** - * @var string hash for file sharing, empty by default (example: getRandomPassword(true)) + * @var ?string hash for file sharing, empty by default (example: getRandomPassword(true)) */ public $share; /** - * @var string filename, Note: Into ecm database record, the entry never ends with .noexe + * @var ?string filename, Note: Into ecm database record, the entry never ends with .noexe */ public $filename; /** - * @var string filepath + * @var ?string filepath */ public $filepath; /** - * @var string fullpath origin + * @var ?string fullpath origin */ public $fullpath_orig; /** - * @var string description + * @var ?string description */ public $description; /** - * @var string keywords + * @var ?string keywords */ public $keywords; @@ -98,17 +93,17 @@ class EcmFiles extends CommonObject public $content; /** - * @var string cover + * @var ?string cover */ public $cover; /** - * @var int position + * @var ?int position */ public $position; /** - * @var 'generated'|'uploaded'|'unknown'|'api'|'copy'|'' + * @var 'generated'|'uploaded'|'unknown'|'api'|'copy'|''|null */ public $gen_or_uploaded; @@ -118,37 +113,37 @@ class EcmFiles extends CommonObject public $extraparams; /** - * @var int|'' date create + * @var null|int|'' date create */ public $date_c = ''; /** - * @var int|'' date modify + * @var null|int|'' date modify */ public $date_m = ''; /** - * @var int ID + * @var ?int ID */ public $fk_user_c; /** - * @var int ID + * @var ?int ID */ public $fk_user_m; /** - * @var string acl + * @var ?string acl, null until fetched or set */ public $acl; /** - * @var string src object type + * @var ?string src object type */ public $src_object_type; /** - * @var int src object id + * @var ?int src object id */ public $src_object_id; diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php index 309819a6284..fa95bea613b 100644 --- a/htdocs/ecm/file_card.php +++ b/htdocs/ecm/file_card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2008-2020 Laurent Destailleur + * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2025 MDW * * This program is free software; you can redistribute it and/or modify @@ -48,6 +48,7 @@ $langs->loadLangs(array('ecm', 'companies', 'other', 'users', 'orders', 'propal' $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); +$module = GETPOST('module', 'alpha'); // Get parameters $socid = GETPOSTINT("socid"); @@ -342,11 +343,7 @@ print ''; print $form->textwithpicto($langs->trans("DirectDownloadInternalLink"), $langs->trans("PrivateDownloadLinkDesc")); print ''; $modulepart = 'ecm'; -$forcedownload = 1; -$rellink = '/document.php?modulepart='.$modulepart; -if ($forcedownload) { - $rellink .= '&attachment=1'; -} +$rellink = '/document.php?modulepart=' . $modulepart . '&attachment=1'; if (!empty($object->entity)) { $rellink .= '&entity='.$object->entity; } @@ -373,17 +370,7 @@ if ($action != 'edit') { print ''; if (!empty($object->share)) { if ($action != 'edit') { - $forcedownload = 0; - - $paramlink = ''; - if (!empty($object->share)) { - $paramlink .= ($paramlink ? '&' : '').'hashp='.$object->share; // Hash for public share - } - if ($forcedownload) { - $paramlink .= ($paramlink ? '&' : '').'attachment=1'; - } - - $fulllink = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : ''); + $fulllink = $urlwithroot.'/document.php?hashp='.$object->share; // Hash for public share //if (!empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path //elseif (!empty($object->label)) $fulllink.='&hashc='.$object->label; // Hash of file content @@ -397,13 +384,13 @@ if (!empty($object->share)) { print ' '.img_picto($langs->trans("Download"), 'download', 'class="opacitymedium paddingrightonly"').''; // No target here } } else { - print 'share ? ' checked="checked"' : '').' /> '; + print ' '; } } else { if ($action != 'edit') { print ''.$langs->trans("FileNotShared").''; } else { - print 'share ? ' checked="checked"' : '').' /> '; + print ' '; } } print ''; diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php index 10840b3f643..fe0e6ae5ecf 100644 --- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php +++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2018 Laurent Destailleur + * Copyright (C) 2025 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,13 +20,16 @@ * $conf, $module, $param, $preopened, $nameforformuserfile may be defined */ +/** + * @var ?Conf $conf + * @var Translate $langs + */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { print "Error, template enablefiletreeajax.tpl.php can't be called as URL"; exit; } // Must have set $module, $nameforformuserfile, $preopened - ?> From db103f37df0b3587e289f80fc49e37ae5da72bf9 Mon Sep 17 00:00:00 2001 From: Fabian Volkers <33686912+FabianVolkers@users.noreply.github.com> Date: Thu, 11 Sep 2025 12:12:18 +0200 Subject: [PATCH 3/7] Add POST /supplierorders/{id}/line endpoint to REST API (#35286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✏️ Fix spelling * ✨ Add postLine endpoint to supplier_orders * 🐛 Fix accessing this->commande instead of this->order --- .../fourn/class/api_supplier_orders.class.php | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index 9cf52085dfe..7a54b3be21d 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -247,7 +247,7 @@ class SupplierOrders extends DolibarrApi public function post($request_data = null) { if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) { - throw new RestException(403, "Insuffisant rights"); + throw new RestException(403, "Insufficiant rights"); } if (!is_array($request_data)) { @@ -334,6 +334,71 @@ class SupplierOrders extends DolibarrApi return false; } + /** + * Add a line to a given supplier order + * + * @param int $id Id of order to update + * @param array $request_data OrderLine data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data + * + * @url POST {id}/lines + * + * @return int + */ + public function postLine($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->hasRight('fournisseur', 'commande', 'creer')) { + throw new RestException(403); + } + + $result = $this->order->fetch($id); + if (!$result) { + throw new RestException(404, 'Supplier order not found'); + } + + if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $request_data = (object) $request_data; + + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + + $updateRes = $this->order->addline( + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + $request_data->fk_product, + $request_data->fk_prod_fourn_price, + $request_data->ref_fourn, + $request_data->remise_percent, + $request_data->price_base_type ? $request_data->price_base_type : 'HT', + $request_data->pu_ttc, + $request_data->product_type, + $request_data->info_bits, + $request_data->notrigger, + $request_data->date_start, + $request_data->date_end, + $request_data->array_options, + $request_data->fk_unit, + $request_data->multicurrency_subprice, + $request_data->origin, + $request_data->origin_id, + $request_data->rang, + $request_data->special_code, + ); + + if ($updateRes > 0) { + return $updateRes; + } else { + throw new RestException(400, $this->order->error); + } + } + /** * Get contacts of given supplier order * From 13dbe2ea58ce3835beb31d189f800a59ce776e37 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 12:12:32 +0200 Subject: [PATCH 4/7] PHPStan > Update baseline (#35285) Co-authored-by: Dolibot --- dev/build/phpstan/phpstan-baseline.neon | 114 ------------------------ 1 file changed, 114 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index f3e2d560e47..083e6a13eb4 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -3138,18 +3138,6 @@ parameters: count: 4 path: ../../../htdocs/comm/propal/class/propal.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/comm/propal/class/propal.class.php - - - - message: '#^Property CommonObject\:\:\$ref_ext \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/comm/propal/class/propal.class.php - - message: '#^Property CommonObject\:\:\$total_ht \(float\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -3306,18 +3294,6 @@ parameters: count: 1 path: ../../../htdocs/commande/class/commande.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/commande/class/commande.class.php - - - - message: '#^Property CommonObject\:\:\$ref_ext \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/commande/class/commande.class.php - - message: '#^Property CommonObject\:\:\$shipping_method_id \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -4050,18 +4026,6 @@ parameters: count: 1 path: ../../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/compta/facture/class/facture.class.php - - - - message: '#^Property CommonObject\:\:\$ref_ext \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/compta/facture/class/facture.class.php - - message: '#^Property Facture\:\:\$fk_facture_source \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -5424,30 +5388,6 @@ parameters: count: 1 path: ../../../htdocs/contrat/contact.php - - - message: '#^Variable \$badgeStatus0 might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/contrat/index.php - - - - message: '#^Variable \$badgeStatus1 might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/contrat/index.php - - - - message: '#^Variable \$badgeStatus4 might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/contrat/index.php - - - - message: '#^Variable \$badgeStatus6 might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/contrat/index.php - - message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable @@ -11460,18 +11400,6 @@ parameters: count: 2 path: ../../../htdocs/expedition/class/expedition.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/expedition/class/expedition.class.php - - - - message: '#^Property CommonObject\:\:\$ref_ext \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/expedition/class/expedition.class.php - - message: '#^Property CommonObject\:\:\$shipping_method_id \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -11892,12 +11820,6 @@ parameters: count: 1 path: ../../../htdocs/fichinter/card.php - - - message: '#^Variable \$line might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/fichinter/card.php - - message: '#^Right side of && is always false\.$#' identifier: booleanAnd.rightAlwaysFalse @@ -12066,12 +11988,6 @@ parameters: count: 1 path: ../../../htdocs/fourn/class/fournisseur.commande.class.php - - - message: '#^Property CommonObject\:\:\$ref_ext \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/fourn/class/fournisseur.commande.class.php - - message: '#^Right side of && is always true\.$#' identifier: booleanAnd.rightAlwaysTrue @@ -12174,12 +12090,6 @@ parameters: count: 1 path: ../../../htdocs/fourn/class/fournisseur.facture.class.php - - - message: '#^Property CommonObject\:\:\$ref_ext \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/fourn/class/fournisseur.facture.class.php - - message: '#^Property FactureFournisseur\:\:\$author \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -16434,12 +16344,6 @@ parameters: count: 3 path: ../../../htdocs/projet/class/task.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/projet/class/task.class.php - - message: '#^Property Task\:\:\$budget_amount \(float\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -17844,12 +17748,6 @@ parameters: count: 4 path: ../../../htdocs/reception/class/reception.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/reception/class/reception.class.php - - message: '#^Property CommonObject\:\:\$shipping_method_id \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -18390,12 +18288,6 @@ parameters: count: 1 path: ../../../htdocs/resource/card.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/resource/class/dolresource.class.php - - message: '#^Property Dolresource\:\:\$busy \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -19590,12 +19482,6 @@ parameters: count: 1 path: ../../../htdocs/ticket/class/ticket.class.php - - - message: '#^Property CommonObject\:\:\$ref \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/ticket/class/ticket.class.php - - message: '#^Property Ticket\:\:\$category_code \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property From fd2ea78e9bfc32d7ae9b4726ba57b956e2aa36da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 11 Sep 2025 12:12:53 +0200 Subject: [PATCH 5/7] clean code bookcal class (#35279) * clean code bookcal class * clean code bookcal class * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix --- dev/build/phpstan/phpstan-baseline.neon | 210 ------------------ htdocs/bookcal/availabilities_note.php | 6 +- htdocs/bookcal/calendar_note.php | 18 +- htdocs/bookcal/class/availabilities.class.php | 106 +++------ htdocs/bookcal/class/calendar.class.php | 132 +++-------- .../lib/bookcal_availabilities.lib.php | 83 +++---- htdocs/bookcal/lib/bookcal_calendar.lib.php | 84 +++---- htdocs/public/bookcal/index.php | 6 +- 8 files changed, 146 insertions(+), 499 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 083e6a13eb4..e4f13da55c9 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -2286,216 +2286,6 @@ parameters: count: 1 path: ../../../htdocs/bookcal/calendar_list.php - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 1 - path: ../../../htdocs/bookcal/calendar_note.php - - - - message: '#^Negated boolean expression is always false\.$#' - identifier: booleanNot.alwaysFalse - count: 1 - path: ../../../htdocs/bookcal/calendar_note.php - - - - message: '#^Call to function method_exists\(\) with \$this\(Availabilities\) and ''getLibStatut'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function method_exists\(\) with \$this\(Availabilities\) and ''getNomUrl'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function property_exists\(\) with \$this\(Availabilities\) and ''label'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function property_exists\(\) with Availabilities and ''date_creation'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function property_exists\(\) with Availabilities and ''date_modification'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function property_exists\(\) with Availabilities and ''label'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function property_exists\(\) with Availabilities and ''ref'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function property_exists\(\) with Availabilities and ''status'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Left side of && is always false\.$#' - identifier: booleanAnd.leftAlwaysFalse - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Method Availabilities\:\:fetchAll\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Method Availabilities\:\:getLinesArray\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Property Availabilities\:\:\$status \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Variable \$url in empty\(\) always exists and is not falsy\.$#' - identifier: empty.variable - count: 2 - path: ../../../htdocs/bookcal/class/availabilities.class.php - - - - message: '#^Call to function method_exists\(\) with \$this\(Calendar\) and ''getLibStatut'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function method_exists\(\) with \$this\(Calendar\) and ''getNomUrl'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with \$this\(Calendar\) and ''fk_soc'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with \$this\(Calendar\) and ''label'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with Calendar and ''date_creation'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with Calendar and ''date_modification'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with Calendar and ''label'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with Calendar and ''ref'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Call to function property_exists\(\) with Calendar and ''status'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Left side of && is always false\.$#' - identifier: booleanAnd.leftAlwaysFalse - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Property Calendar\:\:\$status \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^Variable \$url in empty\(\) always exists and is not falsy\.$#' - identifier: empty.variable - count: 2 - path: ../../../htdocs/bookcal/class/calendar.class.php - - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 3 - path: ../../../htdocs/bookcal/lib/bookcal_availabilities.lib.php - - - - message: '#^If condition is always true\.$#' - identifier: if.alwaysTrue - count: 1 - path: ../../../htdocs/bookcal/lib/bookcal_availabilities.lib.php - - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 2 - path: ../../../htdocs/bookcal/lib/bookcal_calendar.lib.php - - - - message: '#^If condition is always true\.$#' - identifier: if.alwaysTrue - count: 2 - path: ../../../htdocs/bookcal/lib/bookcal_calendar.lib.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType diff --git a/htdocs/bookcal/availabilities_note.php b/htdocs/bookcal/availabilities_note.php index b11f001251b..713e5607a8e 100644 --- a/htdocs/bookcal/availabilities_note.php +++ b/htdocs/bookcal/availabilities_note.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,9 +40,9 @@ $langs->loadLangs(array("agenda", "companies")); // Get parameters $id = GETPOSTINT('id'); -$ref = GETPOST('ref', 'alpha'); +$ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); // Initialize a technical objects diff --git a/htdocs/bookcal/calendar_note.php b/htdocs/bookcal/calendar_note.php index ad0b1486b39..c3c7dcabdc8 100644 --- a/htdocs/bookcal/calendar_note.php +++ b/htdocs/bookcal/calendar_note.php @@ -1,7 +1,7 @@ +/* Copyright (C) 2007-2017 Laurent Destailleur * Copyright (C) 2023 Alice Adminson - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,17 +63,9 @@ if ($id > 0 || !empty($ref)) { // There is several ways to check permission. -// Set $enablepermissioncheck to 1 to enable a minimum low level of checks -$enablepermissioncheck = 0; -if ($enablepermissioncheck) { - $permissiontoread = $user->hasRight('bookcal', 'calendar', 'read'); - $permissiontoadd = $user->hasRight('bookcal', 'calendar', 'write'); - $permissionnote = $user->hasRight('bookcal', 'calendar', 'write'); // Used by the include of actions_setnotes.inc.php -} else { - $permissiontoread = 1; - $permissiontoadd = 1; - $permissionnote = 1; -} +$permissiontoread = $user->hasRight('bookcal', 'calendar', 'read'); +$permissiontoadd = $user->hasRight('bookcal', 'calendar', 'write'); +$permissionnote = $user->hasRight('bookcal', 'calendar', 'write'); // Used by the include of actions_setnotes.inc.php // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); diff --git a/htdocs/bookcal/class/availabilities.class.php b/htdocs/bookcal/class/availabilities.class.php index 630f63a58cc..0613362a613 100644 --- a/htdocs/bookcal/class/availabilities.class.php +++ b/htdocs/bookcal/class/availabilities.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2022 Alice Adminson +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2022 Alice Adminson * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024-2025 MDW * @@ -43,7 +43,13 @@ class Availabilities extends CommonObject public $element = 'availabilities'; /** - * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + * @var string Prefix to check for any trigger code of any business class to prevent bad value for trigger code. + * @see CommonTrigger::call_trigger() + */ + public $TRIGGER_PREFIX = 'AVAILABILITIES'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. */ public $table_element = 'bookcal_availabilities'; @@ -162,10 +168,7 @@ class Availabilities extends CommonObject * @var string */ public $model_pdf; - /** - * @var int - */ - public $status; + /** * @var string */ @@ -192,43 +195,6 @@ class Availabilities extends CommonObject public $fk_bookcal_calendar; // END MODULEBUILDER PROPERTIES - - // If this object has a subtable with lines - - // /** - // * @var string Name of subtable line - // */ - // public $table_element_line = 'bookcal_availabilitiesline'; - - // /** - // * @var string Field with ID of parent key if this object has a parent - // */ - // public $fk_element = 'fk_availabilities'; - - // /** - // * @var string Name of subtable class that manage subtable lines - // */ - // public $class_element_line = 'Availabilitiesline'; - - // /** - // * @var array List of child tables. To test if we can delete object. - // */ - // protected $childtables = array(); - - // /** - // * @var array List of child tables. To know object to delete on cascade. - // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will - // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object - // */ - // protected $childtablesoncascade = array('bookcal_availabilitiesdet'); - - // /** - // * @var AvailabilitiesLine[] Array of subtable lines - // */ - // public $lines = array(); - - - /** * Constructor * @@ -325,23 +291,12 @@ class Availabilities extends CommonObject unset($object->import_key); // Clear fields - if (property_exists($object, 'ref')) { - $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; - } - if (property_exists($object, 'label')) { - // @phan-suppress-next-line PhanTypeInvalidDimOffset - $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; - } - if (property_exists($object, 'status')) { - $object->status = self::STATUS_DRAFT; - } - if (property_exists($object, 'date_creation')) { - $object->date_creation = dol_now(); - } - if (property_exists($object, 'date_modification')) { - $object->date_modification = null; - } - // ... + $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + $object->label = $langs->trans("CopyOf")." ".$object->label; + $object->status = self::STATUS_DRAFT; + $object->date_creation = dol_now(); + $object->date_modification = null; + // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { $extrafields->fetch_name_optionals_label($this->table_element); @@ -423,7 +378,7 @@ class Availabilities extends CommonObject * @param string $filter Filter as an Universal Search string. * Example: '((client:=:1) OR ((client:>=:2) AND (client:<=:3))) AND (client:!=:8) AND (nom:like:'a%')' * @param string $filtermode No more used - * @return array|int int <0 if KO, array of pages if OK + * @return Availabilities[]|int int <0 if KO, array of pages if OK */ public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND') { @@ -551,7 +506,7 @@ class Availabilities extends CommonObject $this->db->begin(); // Define new ref - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life $num = $this->getNextNumRef(); } else { $num = (string) $this->ref; @@ -736,7 +691,7 @@ class Availabilities extends CommonObject if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { $add_save_lastsearch_values = 1; } - if ($url && $add_save_lastsearch_values) { + if ($add_save_lastsearch_values) { $url .= '&save_lastsearch_values=1'; } } @@ -753,13 +708,13 @@ class Availabilities extends CommonObject $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } - if ($option == 'nolink' || empty($url)) { + if ($option == 'nolink') { $linkstart = ''; - if ($option == 'nolink' || empty($url)) { + if ($option == 'nolink') { $linkend = ''; } else { $linkend = ''; @@ -835,20 +790,16 @@ class Availabilities extends CommonObject $return .= img_picto('', $this->picto); $return .= ''; $return .= '
'; - $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= '' . $this->getNomUrl() . ''; if ($selected >= 0) { $return .= ''; } - if (property_exists($this, 'label')) { - $return .= '
'.$this->label.'
'; - } + $return .= '
'.$this->label.'
'; if (property_exists($this, 'amount')) { $return .= '
'; $return .= ''.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).''; } - if (method_exists($this, 'getLibStatut')) { - $return .= '
'.$this->getLibStatut(3).'
'; - } + $return .= '
'.$this->getLibStatut(3).'
'; $return .= '
'; $return .= ''; $return .= ''; @@ -962,7 +913,7 @@ class Availabilities extends CommonObject /** * Create an array of lines * - * @return array|int array of lines if OK, <0 if KO + * @return CommonObject[]|int array of lines if OK, <0 if KO */ public function getLinesArray() { @@ -972,8 +923,7 @@ class Availabilities extends CommonObject $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_availabilities:=:'.((int) $this->id).')'); if (is_numeric($result)) { - $this->error = $objectline->error; - $this->errors = $objectline->errors; + $this->setErrorsFromObject($objectline); return $result; } else { $this->lines = $result; @@ -1018,6 +968,7 @@ class Availabilities extends CommonObject if (class_exists($classname)) { $obj = new $classname(); '@phan-var-force CommonNumRefGenerator $obj'; + /** @var CommonNumRefGenerator $obj */ $numref = $obj->getNextValue($this); @@ -1054,7 +1005,6 @@ class Availabilities extends CommonObject global $conf, $langs; $result = 0; - $includedocgeneration = 0; $langs->load("agenda"); @@ -1070,7 +1020,7 @@ class Availabilities extends CommonObject $modelpath = "core/modules/bookcal/doc/"; - if ($includedocgeneration && !empty($modele)) { + if (!empty($modele)) { $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); } diff --git a/htdocs/bookcal/class/calendar.class.php b/htdocs/bookcal/class/calendar.class.php index f58721b0034..6c96569007d 100644 --- a/htdocs/bookcal/class/calendar.class.php +++ b/htdocs/bookcal/class/calendar.class.php @@ -42,6 +42,12 @@ class Calendar extends CommonObject */ public $element = 'calendar'; + /** + * @var string Prefix to check for any trigger code of any business class to prevent bad value for trigger code. + * @see CommonTrigger::call_trigger() + */ + public $TRIGGER_PREFIX = 'CALENDAR'; + /** * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. */ @@ -124,10 +130,7 @@ class Calendar extends CommonObject * @var int */ public $rowid; - /** - * @var string - */ - public $ref; + /** * @var string */ @@ -148,14 +151,7 @@ class Calendar extends CommonObject * @var string */ public $description; - /** - * @var string - */ - public $note_public; - /** - * @var string - */ - public $note_private; + /** * @var int */ @@ -168,10 +164,7 @@ class Calendar extends CommonObject * @var string */ public $import_key; - /** - * @var int - */ - public $status; + // END MODULEBUILDER PROPERTIES @@ -272,24 +265,12 @@ class Calendar extends CommonObject unset($object->import_key); // Clear fields - if (property_exists($object, 'ref')) { - // @phan-suppress-next-line PhanTypeInvalidDimOffset - $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; - } - if (property_exists($object, 'label')) { - // @phan-suppress-next-line PhanTypeInvalidDimOffset - $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; - } - if (property_exists($object, 'status')) { - $object->status = self::STATUS_DRAFT; - } - if (property_exists($object, 'date_creation')) { - $object->date_creation = dol_now(); - } - if (property_exists($object, 'date_modification')) { - $object->date_modification = null; - } - // ... + $object->ref = "Copy_Of_".$object->ref; + $object->label = $langs->trans("CopyOf")." ".$object->label; + $object->status = self::STATUS_DRAFT; + $object->date_creation = dol_now(); + $object->date_modification = null; + // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { $extrafields->fetch_name_optionals_label($this->table_element); @@ -320,7 +301,7 @@ class Calendar extends CommonObject if (!$error) { // copy external contacts if same company - if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) { + if (!empty($object->socid) && $this->fk_soc == $object->socid) { if ($this->copy_linked_contact($object, 'external') < 0) { $error++; } @@ -507,7 +488,7 @@ class Calendar extends CommonObject $this->db->begin(); // Define new ref - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life $num = $this->getNextNumRef(); } else { $num = (string) $this->ref; @@ -537,7 +518,7 @@ class Calendar extends CommonObject if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('MYOBJECT_VALIDATE', $user); + $result = $this->call_trigger('CALENDAR_VALIDATE', $user); if ($result < 0) { $error++; } @@ -620,7 +601,7 @@ class Calendar extends CommonObject return 0; } - return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE'); + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'CALENDAR_UNVALIDATE'); } /** @@ -637,7 +618,7 @@ class Calendar extends CommonObject return 0; } - return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL'); + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'CALENDAR_CANCEL'); } /** @@ -654,7 +635,7 @@ class Calendar extends CommonObject return 0; } - return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN'); + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'CALENDAR_REOPEN'); } /** @@ -715,7 +696,7 @@ class Calendar extends CommonObject $label = implode($this->getTooltipContentArray($params)); } - $url = dol_buildpath('/bookcal/calendar_card.php', 1).'?id='.$this->id; + $url = DOL_URL_ROOT . '/bookcal/calendar_card.php?id='.$this->id; if ($option !== 'nolink') { // Add param to save lastsearch_values or not @@ -723,7 +704,7 @@ class Calendar extends CommonObject if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { $add_save_lastsearch_values = 1; } - if ($url && $add_save_lastsearch_values) { + if ($add_save_lastsearch_values) { $url .= '&save_lastsearch_values=1'; } } @@ -740,13 +721,13 @@ class Calendar extends CommonObject $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } - if ($option == 'nolink' || empty($url)) { + if ($option == 'nolink') { $linkstart = ''; - if ($option == 'nolink' || empty($url)) { + if ($option == 'nolink') { $linkend = ''; } else { $linkend = ''; @@ -822,20 +803,12 @@ class Calendar extends CommonObject $return .= img_picto('', $this->picto); $return .= ''; $return .= '
'; - $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= '' . $this->getNomUrl() . ''; if ($selected >= 0) { $return .= ''; } - if (property_exists($this, 'label')) { - $return .= '
'.$this->label.'
'; - } - if (property_exists($this, 'amount')) { - $return .= '
'; - $return .= ''.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).''; - } - if (method_exists($this, 'getLibStatut')) { - $return .= '
'.$this->getLibStatut(3).'
'; - } + $return .= '
'.$this->label.'
'; + $return .= '
'.$this->getLibStatut(3).'
'; $return .= '
'; $return .= ''; $return .= ''; @@ -978,15 +951,15 @@ class Calendar extends CommonObject global $langs, $conf; $langs->load("agenda"); - if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) { - $conf->global->BOOKCAL_MYOBJECT_ADDON = 'mod_calendar_standard'; + if (getDolGlobalString('BOOKCAL_CALENDAR_ADDON')) { + $conf->global->BOOKCAL_CALENDAR_ADDON = 'mod_calendar_standard'; } - if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) { + if (getDolGlobalString('BOOKCAL_CALENDAR_ADDON')) { $mybool = false; - $file = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON').".php"; - $classname = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON'); + $file = getDolGlobalString('BOOKCAL_CALENDAR_ADDON').".php"; + $classname = getDolGlobalString('BOOKCAL_CALENDAR_ADDON'); // Include file with class $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); @@ -1038,10 +1011,9 @@ class Calendar extends CommonObject */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) { - global $conf, $langs; + global $langs; $result = 0; - $includedocgeneration = 0; $langs->load("agenda"); @@ -1050,49 +1022,19 @@ class Calendar extends CommonObject if (!empty($this->model_pdf)) { $modele = $this->model_pdf; - } elseif (getDolGlobalString('MYOBJECT_ADDON_PDF')) { - $modele = getDolGlobalString('MYOBJECT_ADDON_PDF'); + } elseif (getDolGlobalString('CALENDAR_ADDON_PDF')) { + $modele = getDolGlobalString('CALENDAR_ADDON_PDF'); } } $modelpath = "core/modules/bookcal/doc/"; - if ($includedocgeneration && !empty($modele)) { + if (!empty($modele)) { $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); } return $result; } - - /** - * Action executed by scheduler - * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' - * Use public function doScheduledJob($param1, $param2, ...) to get parameters - * - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) - */ - public function doScheduledJob() - { - //global $conf, $langs; - - //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; - - $error = 0; - $this->output = ''; - $this->error = ''; - - dol_syslog(__METHOD__, LOG_DEBUG); - - $now = dol_now(); - - $this->db->begin(); - - // ... - - $this->db->commit(); - - return $error; - } } diff --git a/htdocs/bookcal/lib/bookcal_availabilities.lib.php b/htdocs/bookcal/lib/bookcal_availabilities.lib.php index 558470345b6..edd02da67a2 100644 --- a/htdocs/bookcal/lib/bookcal_availabilities.lib.php +++ b/htdocs/bookcal/lib/bookcal_availabilities.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2022 Alice Adminson + * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024 MDW * * This program is free software: you can redistribute it and/or modify @@ -35,11 +35,6 @@ function availabilitiesPrepareHead($object) $langs->load("agenda"); - $showtabofpagecontact = 0; - $showtabofpagenote = 1; - $showtabofpagedocument = 0; - $showtabofpageagenda = 0; - $h = 0; $head = array(); @@ -48,53 +43,45 @@ function availabilitiesPrepareHead($object) $head[$h][2] = 'card'; $h++; - if ($showtabofpagecontact) { - $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_contact.php?id=' . $object->id; - $head[$h][1] = $langs->trans("Contacts"); - $head[$h][2] = 'contact'; - $h++; - } + // $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_contact.php?id=' . $object->id; + // $head[$h][1] = $langs->trans("Contacts"); + // $head[$h][2] = 'contact'; + // $h++; - if ($showtabofpagenote) { - if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { - $nbNote = 0; - if (!empty($object->note_private)) { - $nbNote++; - } - if (!empty($object->note_public)) { - $nbNote++; - } - $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_note.php?id=' . $object->id; - $head[$h][1] = $langs->trans('Notes'); - if ($nbNote > 0) { - $head[$h][1] .= (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') ? '' . $nbNote . '' : ''); - } - $head[$h][2] = 'note'; - $h++; + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; } - } - - if ($showtabofpagedocument) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php'; - $upload_dir = $conf->bookcal->dir_output . "/availabilities/" . dol_sanitizeFileName($object->ref); - $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); - $nbLinks = Link::count($db, $object->element, $object->id); - $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_document.php?id=' . $object->id; - $head[$h][1] = $langs->trans('Documents'); - if (($nbFiles + $nbLinks) > 0) { - $head[$h][1] .= '' . ($nbFiles + $nbLinks) . ''; + if (!empty($object->note_public)) { + $nbNote++; } - $head[$h][2] = 'document'; + $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_note.php?id=' . $object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') ? '' . $nbNote . '' : ''); + } + $head[$h][2] = 'note'; $h++; } - if ($showtabofpageagenda) { - $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_agenda.php?id=' . $object->id; - $head[$h][1] = $langs->trans("Events"); - $head[$h][2] = 'agenda'; - $h++; - } + // require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + // require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php'; + // $upload_dir = $conf->bookcal->dir_output . "/availabilities/" . dol_sanitizeFileName($object->ref); + // $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + // $nbLinks = Link::count($db, $object->element, $object->id); + // $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_document.php?id=' . $object->id; + // $head[$h][1] = $langs->trans('Documents'); + // if (($nbFiles + $nbLinks) > 0) { + // $head[$h][1] .= '' . ($nbFiles + $nbLinks) . ''; + // } + // $head[$h][2] = 'document'; + // $h++; + + // $head[$h][0] = DOL_URL_ROOT . '/bookcal/availabilities_agenda.php?id=' . $object->id; + // $head[$h][1] = $langs->trans("Events"); + // $head[$h][2] = 'agenda'; + // $h++; // Show more tabs from modules // Entries must be declared in modules descriptor with line diff --git a/htdocs/bookcal/lib/bookcal_calendar.lib.php b/htdocs/bookcal/lib/bookcal_calendar.lib.php index 37cdcd18798..0949e896fba 100644 --- a/htdocs/bookcal/lib/bookcal_calendar.lib.php +++ b/htdocs/bookcal/lib/bookcal_calendar.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2023 Alice Adminson + * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024 MDW * * This program is free software: you can redistribute it and/or modify @@ -35,11 +35,6 @@ function calendarPrepareHead($object) $langs->load("agenda"); - $showtabofpagecontact = 0; - $showtabofpagenote = 1; - $showtabofpagedocument = 0; - $showtabofpageagenda = 1; - $h = 0; $head = array(); @@ -55,54 +50,45 @@ function calendarPrepareHead($object) $h++; } + // $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_contact.php?id=' . $object->id; + // $head[$h][1] = $langs->trans("Contacts"); + // $head[$h][2] = 'contact'; + // $h++; - if ($showtabofpagecontact) { - $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_contact.php?id=' . $object->id; - $head[$h][1] = $langs->trans("Contacts"); - $head[$h][2] = 'contact'; - $h++; - } - - if ($showtabofpagenote) { - if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { - $nbNote = 0; - if (!empty($object->note_private)) { - $nbNote++; - } - if (!empty($object->note_public)) { - $nbNote++; - } - $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_note.php?id=' . $object->id; - $head[$h][1] = $langs->trans('Notes'); - if ($nbNote > 0) { - $head[$h][1] .= (!getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') ? '' . $nbNote . '' : ''); - } - $head[$h][2] = 'note'; - $h++; + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; } - } - - if ($showtabofpagedocument) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php'; - $upload_dir = $conf->bookcal->dir_output . "/calendar/" . dol_sanitizeFileName($object->ref); - $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); - $nbLinks = Link::count($db, $object->element, $object->id); - $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_document.php?id=' . $object->id; - $head[$h][1] = $langs->trans('Documents'); - if (($nbFiles + $nbLinks) > 0) { - $head[$h][1] .= '' . ($nbFiles + $nbLinks) . ''; + if (!empty($object->note_public)) { + $nbNote++; } - $head[$h][2] = 'document'; + $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_note.php?id=' . $object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (!getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') ? '' . $nbNote . '' : ''); + } + $head[$h][2] = 'note'; $h++; } - if ($showtabofpageagenda) { - $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_agenda.php?id=' . $object->id; - $head[$h][1] = $langs->trans("Events"); - $head[$h][2] = 'agenda'; - $h++; - } + // require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + // require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php'; + // $upload_dir = $conf->bookcal->dir_output . "/calendar/" . dol_sanitizeFileName($object->ref); + // $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + // $nbLinks = Link::count($db, $object->element, $object->id); + // $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_document.php?id=' . $object->id; + // $head[$h][1] = $langs->trans('Documents'); + // if (($nbFiles + $nbLinks) > 0) { + // $head[$h][1] .= '' . ($nbFiles + $nbLinks) . ''; + // } + // $head[$h][2] = 'document'; + // $h++; + + $head[$h][0] = DOL_URL_ROOT . '/bookcal/calendar_agenda.php?id=' . $object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; // Show more tabs from modules // Entries must be declared in modules descriptor with line diff --git a/htdocs/public/bookcal/index.php b/htdocs/public/bookcal/index.php index b5b32eba91a..737dbe0acc0 100644 --- a/htdocs/public/bookcal/index.php +++ b/htdocs/public/bookcal/index.php @@ -4,7 +4,7 @@ * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2023 anthony Berton * Copyright (C) 2024-2025 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -411,8 +411,8 @@ if ($action == 'afteradd') { setEventMessages($availability->error, $availability->errors, 'errors'); } else { foreach ($arrayofavailabilities as $key => $value) { - $startarray = dol_getdate($value->start); - $endarray = dol_getdate($value->end); + $startarray = dol_getdate((int) $value->start); + $endarray = dol_getdate((int) $value->end); for ($i = $startarray['mday']; $i <= $endarray['mday']; $i++) { if ($todayarray['mon'] >= $startarray['mon'] && $todayarray['mon'] <= $endarray['mon']) { $arrayofavailabledays[dol_mktime(0, 0, 0, $todayarray['mon'], $i, $todayarray['year'])] = dol_mktime(0, 0, 0, $todayarray['mon'], $i, $todayarray['year']); From 6ee966d64d0a03f051c8cbc10ebe31b76599f67e Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Thu, 11 Sep 2025 12:14:32 +0200 Subject: [PATCH 6/7] feat: Subtotal module (#35290) --- htdocs/core/modules/modSubtotals.class.php | 4 +- htdocs/langs/en_US/subtotals.lang | 2 +- htdocs/langs/fr_FR/subtotals.lang | 56 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 htdocs/langs/fr_FR/subtotals.lang diff --git a/htdocs/core/modules/modSubtotals.class.php b/htdocs/core/modules/modSubtotals.class.php index 288d0247c7f..5efe821563a 100644 --- a/htdocs/core/modules/modSubtotals.class.php +++ b/htdocs/core/modules/modSubtotals.class.php @@ -62,9 +62,9 @@ class modSubtotals extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i', '', get_class($this)); // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) - $this->description = "Subtotal and title lines for certain documents"; + $this->description = "SubTotalModuleDesc"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'experimental'; + $this->version = 'dolibarr'; // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of image file used for this module. diff --git a/htdocs/langs/en_US/subtotals.lang b/htdocs/langs/en_US/subtotals.lang index 5e53b76aa52..3744197baab 100644 --- a/htdocs/langs/en_US/subtotals.lang +++ b/htdocs/langs/en_US/subtotals.lang @@ -4,7 +4,7 @@ # Global # Subtotal=Subtotals - +SubTotalModuleDesc=Subtotal and title lines for certain documents # # Admin # diff --git a/htdocs/langs/fr_FR/subtotals.lang b/htdocs/langs/fr_FR/subtotals.lang new file mode 100644 index 00000000000..a83ddb07152 --- /dev/null +++ b/htdocs/langs/fr_FR/subtotals.lang @@ -0,0 +1,56 @@ +# Dolibarr language file - Source file is en_US - subtotal + +# +# Global +# +Subtotal=Titres et sous totaux +SubTotalModuleDesc=Titre et sous totaux pour certain documents + +# +# Admin +# +SubtotalSetup=Configuration de titres et sous totaux +MaxSubtotalLevel=niveaux d'imbrication maximum +SubtotalLineBackColor=Couleur pour les ligne de niveau %s +NotSupportedByAllPDF=Fonctionnera avec les nouveau PDF, ne changera pas les anciens %s + +# +# Card +# +AddTitleLine=Ajouter un titre +AddSubtotalLine=Ajouter un sous-total +TitleNeedDesc=Vous devez saisir une description pour le titre +TitleAddedLevelTooHigh=Niveau de titre ajouté trop élevé (ajouté avec le niveau %s à la place). +TitleEditedLevelTooHigh=Niveau de titre modifié trop élevé (modifié avec le niveau %s à la place). +DeleteSubtotalLine=Supprimer la ligne de sous-total +ConfirmDeleteSubtotalLine=Êtes-vous sûr de vouloir supprimer cette ligne de sous-total ? +DeleteTitleLine=Supprimer la ligne de titre +ConfirmDeleteTitleLine=Êtes-vous sûr de vouloir supprimer cette ligne de titre ? +DeleteCorrespondingSubtotalLine=Supprimer la ligne de sous-total correspondante ? +SubtotalLevel=Niveau %s +SubtotalLineDesc=Description de la ligne +SubtotalLineLevel=Niveau de la ligne +ShowUPOnPDF=Afficher le prix unitaire sur le PDF +ShowTotalExludingVATOnPDF=Afficher le total hors taxes sur le PDF +ForcePageBreak=Forcer un saut de page avant le titre +NoTitleError=Aucune ligne de titre ou toutes les lignes de titre ont déjà une ligne de sous-total correspondante +CorrespondingTitleLine=Ligne de titre correspondante +SelectVATRate=Sélectionner le taux de TVA +EnterRemisePercent=Saisir le pourcentage de remise +ApplyVATForBlock=Appliquer la TVA pour ce bloc +ApplyDiscountForBlock=Appliquer la remise pour ce bloc +TitleUnderSameLevelSTLine=Le titre du même niveau doit être placé sous la ligne de sous-total du titre précédent. +TitleUnderSameLevelOrGreater=Le titre doit être placé sous un titre de même niveau ou supérieur. +TitleAfterStLineOfSameLevelTitle=Le titre doit être placé après la ligne de sous-total du titre précédent. +PreviousTitleLevelTooHigh=Le titre précédent est de deux niveaux ou plus supérieur à la ligne déplacée. +STLineUnderCorrespondingTitleDesc=La ligne de sous-total doit être placée sous un titre de même niveau ayant la même description. +STLineUnderCorrespondingTitle=La ligne de sous-total doit être placée sous un titre de même niveau et de même description. +STLineUnderTitle=La ligne de sous-total doit être placée sous son titre +UnsupportedModuleError=Impossible d'ajouter une ligne de sous-total dans un module non pris en charge +CorrespondingTitleNotFound=Le titre correspondant n'a pas été trouvé + + +# +# PDF +# +SubtotalOf=Sous total de %s: From 0e79fa36ee101e0b3ea9fb35d134017754b403b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 11 Sep 2025 12:14:53 +0200 Subject: [PATCH 7/7] clean code contact class (#35260) * clean code contact class * clean code contact class * clean code * clean code * clean code * clean code * clean code * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix --- dev/build/phpstan/phpstan-baseline.neon | 56 +--------------------- htdocs/contact/class/contact.class.php | 63 +++++++++++-------------- htdocs/societe/class/societe.class.php | 2 +- 3 files changed, 30 insertions(+), 91 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index e4f13da55c9..b1ad19d6bc2 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -5034,60 +5034,6 @@ parameters: count: 1 path: ../../../htdocs/contact/card.php - - - message: '#^Call to function method_exists\(\) with \$this\(Contact\) and ''getLibStatut'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Call to function method_exists\(\) with \$this\(Contact\) and ''getNomUrl'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Call to function property_exists\(\) with \$this\(Contact\) and ''photo'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Call to function property_exists\(\) with \$this\(Contact\) and ''thirdparty'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 3 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Property Contact\:\:\$roles \(array\\>\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Property Contact\:\:\$stcomm_id \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/contact/class/contact.class.php - - - - message: '#^Variable \$url in empty\(\) always exists and is not falsy\.$#' - identifier: empty.variable - count: 2 - path: ../../../htdocs/contact/class/contact.class.php - - message: '#^Loose comparison using \=\= between 0 and 1 will always evaluate to false\.$#' identifier: equal.alwaysFalse @@ -18571,7 +18517,7 @@ parameters: path: ../../../htdocs/societe/class/societe.class.php - - message: '#^Property Contact\:\:\$roles \(array\\) does not accept non\-empty\-list\\.$#' + message: '#^Property Contact\:\:\$roles \(array\|null\) does not accept non\-empty\-list\\.$#' identifier: assign.propertyType count: 1 path: ../../../htdocs/societe/class/societe.class.php diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 9a17e80a3f1..ff4cacd08bb 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -346,7 +346,7 @@ class Contact extends CommonObject // END MODULEBUILDER PROPERTIES /** - * @var array roles + * @var null|array roles, null until fetched or set */ public $roles; @@ -361,7 +361,7 @@ class Contact extends CommonObject public $fk_prospectlevel; /** - * @var int + * @var null|int Is null until fetched or set */ public $stcomm_id; @@ -558,12 +558,10 @@ class Contact extends CommonObject if ($resql) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."socpeople"); - if (!$error) { - $result = $this->update($this->id, $user, 1, 'add'); // This include updateRoles(), ... - if ($result < 0) { - $error++; - $this->error = $this->db->lasterror(); - } + $result = $this->update($this->id, $user, 1, 'add'); // This include updateRoles(), ... + if ($result < 0) { + $error++; + $this->error = $this->db->lasterror(); } if (!$error) { @@ -702,11 +700,9 @@ class Contact extends CommonObject $action = 'update'; // Actions on extra fields - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } + $result = $this->insertExtraFields(); + if ($result < 0) { + $error++; } if (!$error) { @@ -1078,13 +1074,13 @@ class Contact extends CommonObject } elseif ($num) { // $num = 1 $obj = $this->db->fetch_object($resql); - $this->id = $obj->rowid; - $this->entity = $obj->entity; - $this->ref = $obj->rowid; - $this->ref_ext = $obj->ref_ext; + $this->id = $obj->rowid; + $this->entity = $obj->entity; + $this->ref = $obj->rowid; + $this->ref_ext = $obj->ref_ext; - $this->civility_code = $obj->civility_code; - $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : ''; + $this->civility_code = $obj->civility_code; + $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : ''; $this->name_alias = $obj->name_alias; $this->lastname = $obj->lastname; @@ -1093,7 +1089,7 @@ class Contact extends CommonObject $this->zip = $obj->zip; $this->town = $obj->town; - $this->date_creation = $this->db->jdate($obj->date_creation); + $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_modification = $this->db->jdate($obj->date_modification); $this->user_creation_id = $obj->fk_user_creat; $this->user_modification_id = $obj->fk_user_modif; @@ -1121,10 +1117,10 @@ class Contact extends CommonObject $this->statut_commercial = $libelle; // libelle statut commercial $this->stcomm_picto = $obj->stcomm_picto; // Picto statut commercial - $this->phone_pro = trim($obj->phone); - $this->fax = trim($obj->fax); - $this->phone_perso = trim($obj->phone_perso); - $this->phone_mobile = trim($obj->phone_mobile); + $this->phone_pro = trim($obj->phone); + $this->fax = trim($obj->fax); + $this->phone_perso = trim($obj->phone_perso); + $this->phone_mobile = trim($obj->phone_mobile); $this->email = $obj->email; $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array()); @@ -1317,7 +1313,7 @@ class Contact extends CommonObject $this->db->begin(); - if (!$error && !$notrigger) { + if (!$notrigger) { // Call trigger $result = $this->call_trigger('CONTACT_DELETE', $user); if ($result < 0) { @@ -1576,7 +1572,7 @@ class Contact extends CommonObject if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { $add_save_lastsearch_values = 1; } - if ($url && $add_save_lastsearch_values) { + if ($add_save_lastsearch_values) { $url .= '&save_lastsearch_values=1'; } } @@ -1595,13 +1591,13 @@ class Contact extends CommonObject $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } - if ($option == 'nolink' || empty($url)) { + if ($option == 'nolink') { $linkstart = ''; - if ($option == 'nolink' || empty($url)) { + if ($option == 'nolink') { $linkend = ''; } else { $linkend = ''; @@ -2271,19 +2267,18 @@ class Contact extends CommonObject $return = '
'; $return .= '
'; $return .= ''; - //var_dump($this->photo);exit; - if (property_exists($this, 'photo') && !is_null($this->photo)) { + if (!is_null($this->photo)) { $return .= Form::showphoto('contact', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1); } else { $return .= img_picto('', $this->picto); } $return .= ''; $return .= '
'; - $return .= '
'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(0) : $this->ref).'
'; + $return .= '
' . $this->getNomUrl(0) . '
'; if ($selected >= 0) { $return .= ''; } - if (property_exists($this, 'thirdparty') && is_object($this->thirdparty)) { + if (is_object($this->thirdparty)) { $return .= '
'.$this->thirdparty->getNomUrl(1).'
'; } /*if (property_exists($this, 'phone_pro') && !empty($this->phone_pro)) { @@ -2294,9 +2289,7 @@ class Contact extends CommonObject $return .= '
'.$langs->trans("Visibility").''; $return .= ' : '.$this->LibPubPriv($this->priv).''; }*/ - if (method_exists($this, 'getLibStatut')) { - $return .= '
'.$this->getLibStatut(3).'
'; - } + $return .= '
'.$this->getLibStatut(3).'
'; $return .= '
'; $return .= '
'; $return .= '
'; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index bc42d50d81e..94f322af753 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1215,7 +1215,7 @@ class Societe extends CommonObject $contact->zip = $this->zip; $contact->town = $this->town; $this->setUpperOrLowerCase(); - $contact->phone_pro = $this->phone; + $contact->phone_pro = $this->phone; if (getDolGlobalString('CONTACTS_DEFAULT_ROLES')) { $contact->roles = explode(',', getDolGlobalString('CONTACTS_DEFAULT_ROLES')); }