diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 79f24ebac07..2f748665dd9 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -8946,12 +8946,6 @@ parameters: count: 2 path: ../../../htdocs/eventorganization/conferenceorboothattendee_list.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../../htdocs/expedition/card.php - - message: '#^Variable \$rowEnd might not be defined\.$#' identifier: variable.undefined @@ -12102,54 +12096,6 @@ parameters: count: 1 path: ../../../htdocs/product/class/productfournisseurprice.class.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 3 - path: ../../../htdocs/product/class/propalmergepdfproduct.class.php - - - - message: '#^Property Propalmergepdfproduct\:\:\$file_name \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/product/class/propalmergepdfproduct.class.php - - - - message: '#^Property Propalmergepdfproduct\:\:\$fk_product \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/product/class/propalmergepdfproduct.class.php - - - - message: '#^Property Propalmergepdfproduct\:\:\$fk_user_author \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/product/class/propalmergepdfproduct.class.php - - - - message: '#^Property Propalmergepdfproduct\:\:\$fk_user_mod \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 2 - path: ../../../htdocs/product/class/propalmergepdfproduct.class.php - - - - message: '#^Property Propalmergepdfproduct\:\:\$lang \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 4 - path: ../../../htdocs/product/class/propalmergepdfproduct.class.php - - - - message: '#^Variable \$i might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/composition/card.php - - - - message: '#^Variable \$num might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/composition/card.php - - message: '#^If condition is always true\.$#' identifier: if.alwaysTrue @@ -14010,12 +13956,6 @@ parameters: count: 1 path: ../../../htdocs/public/recruitment/index.php - - - message: '#^Variable \$dolibarr_main_url_root might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/public/recruitment/index.php - - message: '#^Left side of && is always true\.$#' identifier: booleanAnd.leftAlwaysTrue @@ -14292,12 +14232,6 @@ parameters: count: 1 path: ../../../htdocs/reception/card.php - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 2 - path: ../../../htdocs/reception/card.php - - message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''commande'' will always evaluate to false\.$#' identifier: equal.alwaysFalse @@ -14328,30 +14262,12 @@ parameters: count: 1 path: ../../../htdocs/reception/card.php - - - message: '#^Variable \$objectsrc might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../../htdocs/reception/card.php - - - - message: '#^Variable \$originid might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/reception/card.php - - message: '#^Variable \$reception might not be defined\.$#' identifier: variable.undefined count: 1 path: ../../../htdocs/reception/card.php - - - message: '#^Variable \$result might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/reception/card.php - - message: '#^Call to function method_exists\(\) with \$this\(Reception\) and ''getLibStatut'' will always evaluate to true\.$#' identifier: function.alreadyNarrowedType diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index f2036f4b053..5f9fce951de 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -71,6 +71,7 @@ class Categorie extends CommonObject const TYPE_SUPPLIER_INVOICE = 'supplier_invoice'; const TYPE_SUPPLIER_PROPOSAL = 'supplier_proposal'; const TYPE_PROPOSAL = 'propal'; + const TYPE_PROJECT_TASK = 'project_task'; /** @@ -104,6 +105,7 @@ class Categorie extends CommonObject 'supplier_invoice' => 21, 'supplier_proposal' => 22, 'propal' => 23, + 'project_task' => 24, ); /** @@ -131,7 +133,10 @@ class Categorie extends CommonObject 16 => 'order', 17 => 'invoice', 20 => 'supplier_order', - 21 => 'supplier_invoice' + 21 => 'supplier_invoice', + 22 => 'supplier_proposal', + 23 => 'propal', + 24 => 'project_task' ); */ @@ -178,7 +183,8 @@ class Categorie extends CommonObject 'supplier_order' => 'CommandeFournisseur', 'supplier_invoice' => 'FactureFournisseur', 'supplier_proposal' => 'SupplierProposal', - 'propal' => 'Propal' + 'propal' => 'Propal', + 'project_task' => 'Task', ); /** @@ -206,7 +212,8 @@ class Categorie extends CommonObject 'supplier_order' => 'SuppliersOrders', 'supplier_invoice' => 'SuppliersInvoices', 'propal' => 'Proposals', - 'supplier_proposal' => 'SupplierProposals' + 'supplier_proposal' => 'SupplierProposals', + 'project_task' => 'Tasks' ); /** @@ -227,6 +234,7 @@ class Categorie extends CommonObject 'invoice' => 'facture', 'supplier_order' => 'commande_fournisseur', 'supplier_invoice' => 'facture_fourn', + 'project_task' => 'projet_task' ); /** @@ -295,6 +303,7 @@ class Categorie extends CommonObject * @see Categorie::TYPE_INVOICE * @see Categorie::TYPE_SUPPLIER_ORDER * @see Categorie::TYPE_SUPPLIER_INVOICE + * @see Categorie::TYPE_PROJECT_TASK */ public $type; @@ -769,6 +778,7 @@ class Categorie extends CommonObject 'categorie_user' => 'fk_categorie', 'categorie_product' => 'fk_categorie', 'categorie_project' => 'fk_categorie', + 'categorie_project_task' => 'fk_categorie', 'categorie_societe' => 'fk_categorie', 'categorie_ticket' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('ticket')), 'categorie_warehouse' => 'fk_categorie', diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 317616ae18a..a723d3e6a47 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -11051,6 +11051,16 @@ abstract class CommonObject } } + if (!$error) { + $dir = getMultidirOutput($this)."/".dol_sanitizeFileName($this->ref); + // For remove dir + if (dol_is_dir($dir)) { + if (!dol_delete_dir_recursive($dir)) { + $this->errors[] = 'ErrorFailToDeleteDir'; + } + } + } + // Delete linked object $res = $this->deleteObjectLinked(); if ($res < 0) { diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index eec2df4bed4..fd8056dd8e2 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -2448,7 +2448,7 @@ class ExtraFields $tmpobject->fetch($value); if (get_class($tmpobject) == 'Categorie') { - // For category object, rendering must use the same method than the one deinfed into showCategories() + // For category object, rendering must use the same method than the one defined into showCategories() $color = $tmpobject->color; $sfortag = ''; $sfortag .= $tmpobject->getNomUrl(3); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1eb95fc007e..366afdaaae1 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -137,6 +137,7 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu { global $conf; + $subdirectory = ''; if (!is_object($object) && empty($module)) { return null; } @@ -151,6 +152,12 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu $module = 'supplier_invoice'; } elseif ($module == 'order_supplier') { $module = 'supplier_order'; + } elseif ($module == 'recruitmentjobposition') { + $module = 'recruitment'; + $subdirectory = '/recruitmentjobposition'; + } elseif ($module == 'recruitmentcandidature') { + $module = 'recruitment'; + $subdirectory = '/recruitmentcandidature'; } // Get the relative path of directory @@ -158,7 +165,7 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu if (isset($conf->$module) && property_exists($conf->$module, 'multidir_output')) { $s = ''; if ($mode != 'outputrel') { - $s = $conf->$module->multidir_output[(empty($object->entity) ? $conf->entity : $object->entity)]; + $s = $conf->$module->multidir_output[(empty($object->entity) ? $conf->entity : $object->entity)] . $subdirectory; } if ($forobject && $object->id > 0) { $s .= ($mode != 'outputrel' ? '/' : '') . get_exdir(0, 0, 0, 0, $object); @@ -167,7 +174,7 @@ function getMultidirOutput($object, $module = '', $forobject = 0, $mode = 'outpu } elseif (isset($conf->$module) && property_exists($conf->$module, 'dir_output')) { $s = ''; if ($mode != 'outputrel') { - $s = $conf->$module->dir_output; + $s = $conf->$module->dir_output . $subdirectory; } if ($forobject && $object->id > 0) { $s .= ($mode != 'outputrel' ? '/' : '') . get_exdir(0, 0, 0, 0, $object); diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index 5eb60c031fe..5031f88399a 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -639,7 +639,7 @@ class Don extends CommonObject // For remove dir if (dol_is_dir($dir)) { if (!dol_delete_dir_recursive($dir)) { - $this->errors[] = $this->error; + $this->errors[] = 'ErrorFailToDeleteDir'; } } } diff --git a/htdocs/holiday/card_group.php b/htdocs/holiday/card_group.php index f6c3df2aadb..18207f16c5b 100644 --- a/htdocs/holiday/card_group.php +++ b/htdocs/holiday/card_group.php @@ -5,7 +5,7 @@ * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2017-2024 Alexandre Spangaro * Copyright (C) 2014-2017 Ferran Marcet - * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2020-2021 Udo Tamm * Copyright (C) 2022 Anthony Berton * Copyright (C) 2024-2025 MDW @@ -609,8 +609,8 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { if (empty($include_users)) { print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays"); } else { - // Defined default approver (the forced approved of user or the supervisor if no forced value defined) - // Note: This use will be set only if the deinfed approvr has permission to approve so is inside include_users + // Defined default approver (the forced approver of user or the supervisor if no forced value defined) + // Note: This use will be set only if the defined approver has permission to approve so is inside include_users $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); if (getDolGlobalString('HOLIDAY_DEFAULT_VALIDATOR')) { $defaultselectuser = getDolGlobalString('HOLIDAY_DEFAULT_VALIDATOR'); // Can force default approver diff --git a/htdocs/product/class/propalmergepdfproduct.class.php b/htdocs/product/class/propalmergepdfproduct.class.php index cb8219c42d1..f15c932016b 100644 --- a/htdocs/product/class/propalmergepdfproduct.class.php +++ b/htdocs/product/class/propalmergepdfproduct.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2015 Florian HENRY - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -44,22 +44,22 @@ class Propalmergepdfproduct extends CommonObject public $table_element = 'propal_merge_pdf_product'; /** - * @var int Id of product + * @var ?int Id of product */ public $fk_product; /** - * @var string Filename + * @var ?string Filename */ public $file_name; /** - * @var int Id user + * @var ?int Id user */ public $fk_user_author; /** - * @var int Id user + * @var ?int Id user */ public $fk_user_mod; /** @@ -68,7 +68,7 @@ class Propalmergepdfproduct extends CommonObject public $datec = ''; /** - * @var string lang code + * @var ?string lang code */ public $lang; @@ -381,16 +381,14 @@ class Propalmergepdfproduct extends CommonObject $this->db->begin(); - if (!$error) { - $sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product"; - $sql .= " WHERE rowid=".((int) $this->id); + $sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product"; + $sql .= " WHERE rowid=".((int) $this->id); - dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } + dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = "Error ".$this->db->lasterror(); } // Commit or rollback @@ -425,20 +423,18 @@ class Propalmergepdfproduct extends CommonObject $this->db->begin(); - if (!$error) { - $sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product"; - $sql .= " WHERE fk_product = ".((int) $product_id); + $sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product"; + $sql .= " WHERE fk_product = ".((int) $product_id); - if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($lang_id)) { - $sql .= " AND lang = '".$this->db->escape($lang_id)."'"; - } + if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($lang_id)) { + $sql .= " AND lang = '".$this->db->escape($lang_id)."'"; + } - dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } + dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = "Error ".$this->db->lasterror(); } // Commit or rollback @@ -470,16 +466,14 @@ class Propalmergepdfproduct extends CommonObject $this->db->begin(); - if (!$error) { - $sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product"; - $sql .= " WHERE fk_product = ".((int) $this->fk_product)." AND file_name = '".$this->db->escape($this->file_name)."'"; + $sql = "DELETE FROM ".$this->db->prefix()."propal_merge_pdf_product"; + $sql .= " WHERE fk_product = ".((int) $this->fk_product)." AND file_name = '".$this->db->escape($this->file_name)."'"; - dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } + dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = "Error ".$this->db->lasterror(); } // Commit or rollback diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index 83cd89f20f7..1fdc73043ce 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -7,7 +7,7 @@ * Copyright (C) 2011-2014 Juanjo Menent * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2023 Benjamin Falière - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * Copyright (C) 2024-2025 MDW * * This program is free software; you can redistribute it and/or modify @@ -434,9 +434,10 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("Qty").''; print ''.$langs->trans('ComposedProductIncDecStock').''; print ''; + $i = 0; + $num = 0; if ($resql) { $num = $db->num_rows($resql); - $i = 0; if ($num == 0) { print ''.$langs->trans("NoMatchFound").''; diff --git a/htdocs/public/recruitment/index.php b/htdocs/public/recruitment/index.php index 953eaf5ff6d..8b41a4986b9 100644 --- a/htdocs/public/recruitment/index.php +++ b/htdocs/public/recruitment/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 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 @@ -38,26 +38,28 @@ if (!defined('NOBROWSERNOTIF')) { // Load Dolibarr environment require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; - /** * @var Conf $conf * @var DoliDB $db * @var HookManager $hookmanager * @var Societe $mysoc * @var Translate $langs + * + * @var string $dolibarr_main_url_root */ +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + // Load translation files required by the page $langs->loadLangs(array("companies", "other", "recruitment")); // Get parameters -$action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'alpha'); $SECUREKEY = GETPOST("securekey"); $entity = GETPOSTINT('entity') ? GETPOSTINT('entity') : $conf->entity; $backtopage = ''; @@ -90,7 +92,7 @@ $object = new RecruitmentJobPosition($db); $urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost. // Security check -if (empty($conf->recruitment->enabled)) { +if (!isModEnabled('recruitment')) { httponly_accessforbidden('Module Recruitment not enabled'); } @@ -204,7 +206,7 @@ if (is_array($results)) { $text = ''; if (getDolGlobalString('RECRUITMENT_NEWFORM_TEXT')) { $reg = array(); - if (preg_match('/^\((.*)\)$/', $conf->global->RECRUITMENT_NEWFORM_TEXT, $reg)) { + if (preg_match('/^\((.*)\)$/', getDolGlobalString('RECRUITMENT_NEWFORM_TEXT'), $reg)) { $text .= $langs->trans($reg[1])."
\n"; } else { $text .= getDolGlobalString('RECRUITMENT_NEWFORM_TEXT') . "
\n"; diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index d726c1ea48a..50e4d590292 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -504,7 +504,6 @@ class RecruitmentJobPosition extends CommonObject public function delete(User $user, $notrigger = 0) { return $this->deleteCommon($user, $notrigger); - //return $this->deleteCommon($user, $notrigger, 1); } /** diff --git a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php index b3e2ef87827..c101836404c 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php @@ -4,7 +4,7 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2016 Charlie Benke * Copyright (C) 2018-2021 Philippe Grand - * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -251,7 +251,9 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi $outputlangs->loadLangs(array("main", "dict", "companies", "bills")); - if ($conf->recruitment->dir_output) { + $dir = getMultidirOutput($object); + + if ($dir) { // If $object is id instead of object if (!is_object($object)) { $id = $object; @@ -263,7 +265,6 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi } } - $dir = $conf->recruitment->multidir_output[isset($object->entity) ? $object->entity : 1].'/recruitmentjobposition/'; $objectref = dol_sanitizeFileName($object->ref); if (!preg_match('/specimen/i', $objectref)) { $dir .= "/".$objectref; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index c2cdd5d3d89..f0beb83b971 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -226,16 +226,16 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $hidetop = getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE'); } - if ($conf->recruitment->dir_output.'/recruitmentjobposition') { + $dir = getMultidirOutput($object); + if ($dir) { $object->fetch_thirdparty(); // Definition of $dir and $file if ($object->specimen) { - $dir = $conf->recruitment->dir_output.'/recruitmentjobposition'; $file = $dir."/SPECIMEN.pdf"; } else { $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->recruitment->dir_output.'/recruitmentjobposition/'.$objectref; + $dir .= '/'.$objectref; $file = $dir."/".$objectref.".pdf"; } if (!file_exists($dir)) {