From 6b05561ee8a0075637eecb08960683c2ba742086 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 4 Dec 2025 10:22:47 +0100 Subject: [PATCH 01/10] new: defaut to True show unit price on title and sub total --- htdocs/core/tpl/subtotal_create.tpl.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/tpl/subtotal_create.tpl.php b/htdocs/core/tpl/subtotal_create.tpl.php index 1f212f05b59..806a0fb7dc3 100644 --- a/htdocs/core/tpl/subtotal_create.tpl.php +++ b/htdocs/core/tpl/subtotal_create.tpl.php @@ -50,14 +50,14 @@ if ($type == 'title') { $formquestion = array( array('type' => 'text', 'name' => 'subtotallinedesc', 'label' => $langs->trans("SubtotalLineDesc"), 'moreattr' => 'placeholder="' . $langs->trans("Description") . '"'), array('type' => 'select', 'name' => 'subtotallinelevel', 'label' => $langs->trans("SubtotalLineLevel"), 'values' => $depth_array, 'default' => 1, 'select_show_empty' => 0), - array('type' => 'checkbox', 'value' => false, 'name' => 'titleshowuponpdf', 'label' => $langs->trans("ShowUPOnPDF")), - array('type' => 'checkbox', 'value' => false, 'name' => 'titleshowtotalexludingvatonpdf', 'label' => $langs->trans("ShowTotalExludingVATOnPDF")), + array('type' => 'checkbox', 'value' => true, 'name' => 'titleshowuponpdf', 'label' => $langs->trans("ShowUPOnPDF")), + array('type' => 'checkbox', 'value' => true, 'name' => 'titleshowtotalexludingvatonpdf', 'label' => $langs->trans("ShowTotalExludingVATOnPDF")), array('type' => 'checkbox', 'value' => false, 'name' => 'titleforcepagebreak', 'label' => $langs->trans("ForcePageBreak")), ); } elseif ($type == 'subtotal') { $formquestion = array( array('type' => 'select', 'name' => 'subtotaltitleline', 'label' => $langs->trans("CorrespondingTitleLine"), 'values' => $titles, 'select_show_empty' => 0), - array('type' => 'checkbox', 'value' => false, 'name' => 'subtotalshowtotalexludingvatonpdf', 'label' => $langs->trans("ShowTotalExludingVATOnPDF")), + array('type' => 'checkbox', 'value' => true, 'name' => 'subtotalshowtotalexludingvatonpdf', 'label' => $langs->trans("ShowTotalExludingVATOnPDF")), ); } From b530ab7e5d204d39e1044e426ebf4329abb5696d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Dec 2025 12:22:44 +0100 Subject: [PATCH 02/10] Debug v23 - Navigation in timespent and style --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/lib/project.lib.php | 2 +- htdocs/projet/activity/perday.php | 42 +++++++++++------------- htdocs/projet/activity/permonth.php | 14 ++++---- htdocs/projet/activity/perweek.php | 14 ++++---- htdocs/projet/tasks/contact.php | 25 +++++++------- htdocs/projet/tasks/task.php | 15 ++++++--- htdocs/projet/tasks/time.php | 26 ++++++++------- htdocs/theme/eldy/global.inc.php | 8 ++++- htdocs/theme/md/style.css.php | 6 ++++ 10 files changed, 87 insertions(+), 67 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 39ef25cb706..ab80518641f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -9874,7 +9874,7 @@ abstract class CommonObject } } - if (empty($buyPrice) && isset($conf->global->MARGIN_TYPE) && in_array($conf->global->MARGIN_TYPE, array('1', 'pmp', 'costprice'))) { + if (empty($buyPrice) && in_array(getDolGlobalString('MARGIN_TYPE'), array('1', 'pmp', 'costprice'))) { require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($this->db); if (($result = $productFournisseur->find_min_price_product_fournisseur($fk_product)) > 0) { diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 3e898b03ff0..f0ffcf20e1d 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -1771,7 +1771,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr // Note print ''; - print ''; print ''; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index b40e6871f07..93717567f1e 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -27,15 +27,6 @@ */ require "../../main.inc.php"; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; -require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -44,6 +35,14 @@ require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; // Load translation files required by the page $langs->loadLangs(array('projects', 'users', 'companies')); @@ -161,6 +160,7 @@ $search_array_options_task = $extrafields->getOptionalsFromPost($object->table_e /* * Actions */ + $error = 0; $parameters = array('id' => $id, 'taskid' => $taskid, 'projectid' => $projectid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks @@ -460,24 +460,24 @@ $head = project_timesheet_prepare_head($mode, $usertoprocess); print dol_get_fiche_head($head, 'inputperday', $langs->trans('TimeSpent'), -1, $picto); // Show description of content -print '
'; +$s = ''; if ($mine || ($usertoprocess->id == $user->id)) { - print $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } else { if (empty($usertoprocess->id) || $usertoprocess->id < 0) { if ($user->hasRight('projet', 'all', 'lire') && !$socid) { - print $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } else { - print $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } } } if ($mine || ($usertoprocess->id == $user->id)) { - print $langs->trans("OnlyYourTaskAreVisible").'
'; + $s .= $langs->trans("OnlyYourTaskAreVisible").'
'; } else { - print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
'; + $s .= $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
'; } -print '
'; +print info_admin($s, 0, 0, 'info', 'nomargintop'); print dol_get_fiche_end(); @@ -700,7 +700,6 @@ if ($conf->use_javascript_ajax && count($tasksarray) >= getDolGlobalInt('NBLINES print ''; } print ''; - //print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; print ''; print '
 
'; @@ -764,14 +763,11 @@ if (count($tasksarray) > 0) { print ''; print ''; $timeonothertasks = ($totalforeachday[$daytoparse] - $totalforvisibletasks[$daytoparse]); - //if ($timeonothertasks) - //{ print ''; - //} print ''; print ' '; print ' '; @@ -793,9 +789,9 @@ if (count($tasksarray) > 0) { print '
 
'; - print ' - - '; + print ''; + print ''; + print ''; } } else { print ''.$langs->trans("NoAssignedTasks").''; diff --git a/htdocs/projet/activity/permonth.php b/htdocs/projet/activity/permonth.php index f904ffc35cb..c6aa30bba1b 100644 --- a/htdocs/projet/activity/permonth.php +++ b/htdocs/projet/activity/permonth.php @@ -473,24 +473,24 @@ $head = project_timesheet_prepare_head($mode, $usertoprocess); print dol_get_fiche_head($head, 'inputpermonth', $langs->trans('TimeSpent'), -1, $picto); // Show description of content -print '
'; +$s = ''; if ($mine || ($usertoprocess->id == $user->id)) { - print $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } else { if (empty($usertoprocess->id) || $usertoprocess->id < 0) { if ($user->hasRight('projet', 'all', 'lire') && !$socid) { - print $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } else { - print $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } } } if ($mine || ($usertoprocess->id == $user->id)) { - print $langs->trans("OnlyYourTaskAreVisible").'
'; + $s .= $langs->trans("OnlyYourTaskAreVisible").'
'; } else { - print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
'; + $s .= $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
'; } -print '
'; +print info_admin($s, 0, 0, 'info', 'nomargintop'); print dol_get_fiche_end(); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index b8eff5e85dd..2872edbcd73 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -472,24 +472,24 @@ $head = project_timesheet_prepare_head($mode, $usertoprocess); print dol_get_fiche_head($head, 'inputperweek', $langs->trans('TimeSpent'), -1, $picto); // Show description of content -print '
'; +$s = ''; if ($mine || ($usertoprocess->id == $user->id)) { - print $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } else { if (empty($usertoprocess->id) || $usertoprocess->id < 0) { if ($user->hasRight('projet', 'all', 'lire') && !$socid) { - print $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } else { - print $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; + $s .= $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'
'; } } } if ($mine || ($usertoprocess->id == $user->id)) { - print $langs->trans("OnlyYourTaskAreVisible").'
'; + $s .= $langs->trans("OnlyYourTaskAreVisible").'
'; } else { - print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
'; + $s .= $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'
'; } -print '
'; +print info_admin($s, 0, 0, 'info', 'nomargintop'); print dol_get_fiche_end(); diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index 3820d40455a..9654432d60f 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -27,12 +27,6 @@ */ require "../../main.inc.php"; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; -require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -40,14 +34,20 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; // Load translation files required by the page $langs->loadLangs(array('projects', 'companies')); -$id = GETPOSTINT('id'); -$ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); + +$id = GETPOSTINT('id'); // Id of task +$ref = GETPOST('ref', 'alpha'); // Ref of task $withproject = GETPOSTINT('withproject'); $project_ref = GETPOST('project_ref', 'alpha'); @@ -56,6 +56,7 @@ $projectstatic = new Project($db); $hookmanager->initHooks(array('projecttaskcontact', 'globalcard')); +// Load task if ($id > 0 || $ref) { $object->fetch($id, $ref); } @@ -184,11 +185,11 @@ llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-project project-task if ($id > 0 || !empty($ref)) { if ($object->fetch($id, $ref) > 0) { + $id = $object->id; // So when doing a search from ref, id is also set correctly. + if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_TASK') && empty($object->comments)) { $object->fetchComments(); } - $id = $object->id; // So when doing a search from ref, id is also set correctly. - if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) { $projectstatic->fetchComments(); } @@ -227,7 +228,7 @@ if ($id > 0 || !empty($ref)) { $projectstatic->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } - dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); print '
'; print '
'; @@ -270,7 +271,7 @@ if ($id > 0 || !empty($ref)) { // Budget print ''.$langs->trans("Budget").''; if (isset($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) { - print price($projectstatic->budget_amount, 0, $langs, 1, 0, 0, $conf->currency); + print ''.price($projectstatic->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; } print ''; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 667d8fead18..66fd2bb278e 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -95,6 +95,7 @@ restrictedArea($user, 'projet', $object->fk_project, 'projet&project'); /* * Actions */ + $error = 0; if ($action == 'update' && !GETPOST("cancel") && $user->hasRight('projet', 'creer')) { @@ -320,7 +321,6 @@ if ($id > 0 || !empty($ref)) { $object->fetchComments(); } - if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) { $projectstatic->fetchComments(); } @@ -474,9 +474,6 @@ if ($id > 0 || !empty($ref)) { print '
'; } - /* - * Actions - */ // To verify role of users //$userAccess = $projectstatic->restrictedProjectArea($user); // We allow task affected to user even if a not allowed project @@ -494,6 +491,16 @@ if ($id > 0 || !empty($ref)) { print dol_get_fiche_head($head, 'task_task', $langs->trans("Task"), 0, 'projecttask', 0, '', ''); + $param = (GETPOST('withproject') ? '&withproject=1' : ''); + $linkback = GETPOST('withproject') ? ''.$langs->trans("BackToList").'' : ''; + + if (!GETPOST('withproject') || empty($projectstatic->id)) { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1); + $object->next_prev_filter = "fk_projet:IN:".$db->sanitize($projectsListId); + } else { + $object->next_prev_filter = "fk_projet:=:".((int) $projectstatic->id); + } + print ''; // Ref diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 65a29ab0cc8..dfa9ccf541f 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -61,7 +61,7 @@ if (isModEnabled('eventorganization')) { $langs->loadLangs($langsLoad); -$action = GETPOST('action', 'alpha'); +$action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); @@ -72,9 +72,9 @@ $optioncss = GETPOST('optioncss', 'alpha'); $mode = GETPOST('mode', 'alpha'); $id = GETPOSTINT('id'); // Id of task +$ref = GETPOST('ref', 'alpha'); // Ref of task $projectid = GETPOSTINT('projectid'); // Id of project $lineid = GETPOSTINT('lineid'); // Id of time spent line -$ref = GETPOST('ref', 'alpha'); $withproject = GETPOSTINT('withproject'); $project_ref = GETPOST('project_ref', 'alpha'); $tab = GETPOST('tab', 'aZ09'); @@ -140,6 +140,7 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Load task if ($id > 0 || $ref) { $object->fetch($id, $ref); + $id = $object->id; // So when doing a search from ref, id is also set correctly. } @@ -1162,7 +1163,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $head = task_prepare_head($object); print dol_get_fiche_head($head, 'task_time', $langs->trans("Task"), -1, 'projecttask', 0, '', 'reposition'); - $linkback = $withproject ? '' . $langs->trans("BackToList") . '' : ''; + $param = (GETPOST('withproject') ? '&withproject=1' : ''); + $linkback = GETPOST('withproject') ? ''.$langs->trans("BackToList").'' : ''; if ($action == 'deleteline') { $urlafterconfirm = $_SERVER["PHP_SELF"] . "?" . ($object->id > 0 ? "id=" . $object->id : 'projectid=' . $projectstatic->id) . '&lineid=' . GETPOSTINT("lineid") . $param; @@ -1323,6 +1325,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($limit > 0 && $limit != $conf->liste_limit) { $param .= '&limit='.((int) $limit); } + if ($id > 0) { + $param .= '&id='.((int) $id); + } if ($search_month > 0) { $param .= '&search_month=' . urlencode((string) ($search_month)); } @@ -1336,16 +1341,16 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $param .= '&search_task_ref=' . urlencode($search_task_ref); } if ($search_company != '') { - $param .= '&$search_company=' . urlencode($search_company); + $param .= '&search_company=' . urlencode($search_company); } if ($search_company_alias != '') { - $param .= '&$search_company_alias=' . urlencode($search_company_alias); + $param .= '&search_company_alias=' . urlencode($search_company_alias); } if ($search_project_ref != '') { - $param .= '&$search_project_ref=' . urlencode($search_project_ref); + $param .= '&search_project_ref=' . urlencode($search_project_ref); } if ($search_project_label != '') { - $param .= '&$search_project_label=' . urlencode($search_project_label); + $param .= '&search_project_label=' . urlencode($search_project_label); } if ($search_task_label != '') { $param .= '&search_task_label=' . urlencode($search_task_label); @@ -1354,7 +1359,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $param .= '&search_note=' . urlencode($search_note); } if ($search_duration != '') { - $param .= '&search_field2=' . urlencode((string) ($search_duration)); + $param .= '&search_field2=' . urlencode((string) ($search_duration)); } if ($optioncss != '') { $param .= '&optioncss=' . urlencode($optioncss); @@ -1389,7 +1394,6 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($search_timespent_endmin) { $param .= '&search_timespent_duration_endmin=' . urlencode((string) ($search_timespent_endmin)); } - /* // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -2043,7 +2047,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // -------------------------------------------------------------------- print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center maxwidthsearch '); $totalarray['nbfield']++; } if (!empty($arrayfields['t.element_date']['checked'])) { @@ -2113,7 +2117,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center maxwidthsearch '); $totalarray['nbfield']++; } print "\n"; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 404c780b2ef..b501aa9d303 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1190,6 +1190,12 @@ td.wordbreak img, td.wordbreakimp img { .nopaddingbottomimp { padding-bottom: 0 !important; } +.padding2 { + padding: 2px; +} +.padding3 { + padding: 3px; +} .paddingleft { padding-: 4px; } @@ -1278,7 +1284,7 @@ td.wordbreak img, td.wordbreakimp img { .borderimp { border: 1px solid #888 !important; } -.text-warning{ +.text-warning { color : } /* CSS used for long description and extrafield text */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 1b55a2214c9..92b4e1c5297 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1352,6 +1352,12 @@ td.wordbreak img, td.wordbreakimp img { .nopaddingbottomimp { padding-bottom: 0 !important; } +.padding2 { + padding: 2px; +} +.padding3 { + padding: 3px; +} .paddingleft { padding-: 4px; } From 11787eb4ff0261a69701857c7a8a749bc089e6c1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Dec 2025 12:30:17 +0100 Subject: [PATCH 03/10] Trans --- htdocs/langs/en_US/projects.lang | 1 + htdocs/projet/tasks/time.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 9e87ca37962..dcd08c0e875 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -120,6 +120,7 @@ ActivityOnProjectThisYear=Activity on project this year ChildOfProjectTask=Child of project/task ChildOfTask=Child of task TaskHasChild=Task has child +ParentTask=Parent task NotOwnerOfProject=Not owner of this private project AffectedTo=Allocated to CantRemoveProject=This project can't be removed as it is referenced by some other objects (invoice, orders or other). See tab '%s'. diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index dfa9ccf541f..feda29273a2 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1204,7 +1204,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print '
'; // Task parent - print '
' . $langs->trans("ChildOfTask") . ''; + print '
' . $langs->trans("ParentTask") . ''; if ($object->fk_task_parent > 0) { $tasktmp = new Task($db); $tasktmp->fetch($object->fk_task_parent); From 69cfb09b622accbdd0bb5cb1e0ed322a5a3630fd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Dec 2025 12:42:02 +0100 Subject: [PATCH 04/10] Fix detection of security commit --- dev/tools/apstats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tools/apstats.php b/dev/tools/apstats.php index c433043b6c5..3374d7b1545 100755 --- a/dev/tools/apstats.php +++ b/dev/tools/apstats.php @@ -271,7 +271,7 @@ $nbofmonth = 6; $delay = (3600 * 24 * 30 * $nbofmonth); $arrayofalerts = array(); -$commandcheck = "git log --all --shortstat --no-renames --use-mailmap --pretty=".escapeshellarg('format:%cI;%H;%aN;%aE;%ce;%s')." --since=".escapeshellarg(dol_print_date(dol_now() - $delay, '%Y-%m-%d'))." | grep -i -E ".escapeshellarg("(#yogosha|CVE|Sec:|Sec |Sec$)"); +$commandcheck = "git log --all --shortstat --no-renames --use-mailmap --pretty=".escapeshellarg('format:%cI;%H;%aN;%aE;%ce;%s')." --since=".escapeshellarg(dol_print_date(dol_now() - $delay, '%Y-%m-%d'))." | grep -i -E ".escapeshellarg("(#yogosha|CVE|Sec:|Sec |^Sec$)"); print 'Execute git log to get commits related to security: '.$commandcheck."\n"; $output_arrglpu = array(); $resexecglpu = 0; From c635f5f9c5db5ee3a7f7e8cba3d2bafd115c4e1f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Dec 2025 12:42:02 +0100 Subject: [PATCH 05/10] Fix detection of security commit --- dev/tools/apstats.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/tools/apstats.php b/dev/tools/apstats.php index c433043b6c5..13f34b955bd 100755 --- a/dev/tools/apstats.php +++ b/dev/tools/apstats.php @@ -61,7 +61,7 @@ if (empty($argv[1])) { $outputpath = $argv[1]; $outputdir = dirname($outputpath); $outputfile = basename($outputpath); -$outputfilerss = preg_replace('/\.\w+$/i', '', $outputfile).'-security.rss'; +$outputfilerss = preg_replace('/\.\w+$/i', '', $outputfile).'-security.rss'; // Replace the .html by -security.rss if (!is_dir($outputdir)) { print 'Error: dir '.$outputdir.' does not exists or is not writable'."\n"; @@ -271,7 +271,7 @@ $nbofmonth = 6; $delay = (3600 * 24 * 30 * $nbofmonth); $arrayofalerts = array(); -$commandcheck = "git log --all --shortstat --no-renames --use-mailmap --pretty=".escapeshellarg('format:%cI;%H;%aN;%aE;%ce;%s')." --since=".escapeshellarg(dol_print_date(dol_now() - $delay, '%Y-%m-%d'))." | grep -i -E ".escapeshellarg("(#yogosha|CVE|Sec:|Sec |Sec$)"); +$commandcheck = "git log --all --shortstat --no-renames --use-mailmap --pretty=".escapeshellarg('format:%cI;%H;%aN;%aE;%ce;%s')." --since=".escapeshellarg(dol_print_date(dol_now() - $delay, '%Y-%m-%d'))." | grep -i -E ".escapeshellarg("(#yogosha|CVE|Sec:|Sec |^Sec$)"); print 'Execute git log to get commits related to security: '.$commandcheck."\n"; $output_arrglpu = array(); $resexecglpu = 0; @@ -280,7 +280,7 @@ foreach ($output_arrglpu as $valgitlog) { // The most recent lines are first. // Parse the line to split interesting data $tmpval = cleanVal2($valgitlog); - if (preg_match('/(#yogosha|CVE[\s\-]*\d|Sec:|Sec\s|Sec$)/i', $tmpval['title'])) { // Recommended git comment: "Sec: Fix #..." + if (preg_match('/(#yogosha|CVE[\s\-]*\d|Sec:|Sec\s|^Sec$)/i', $tmpval['title'])) { // Recommended git comment: "Sec: Fix #..." $alreadyfound = ''; $alreadyfoundcommitid = ''; foreach ($arrayofalerts as $val) { // Loop on already found alerts @@ -932,7 +932,7 @@ $html .= ''; $html .= ''; $html .= '
'; -$html .= 'Note:Search is done in git repository on regex string "#yogosha|CVE[\s\-]*\d|Sec:|Sec\s" (not case sensitive)
'; +$html .= 'Note:Search is done in git repository on regex string "#yogosha|CVE[\s\-]*\d|Sec:|Sec |^Sec\s" (not case sensitive)
'; $html .= 'You can use this URL for RSS notifications: '.$outputfilerss.'

'; $html .= ''; From e329c11e82e6806b544eecc8ca91d30906122230 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Dec 2025 12:54:56 +0100 Subject: [PATCH 06/10] Fix warning --- htdocs/waf.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/waf.inc.php b/htdocs/waf.inc.php index 60fc4e9c453..d8323180dfa 100644 --- a/htdocs/waf.inc.php +++ b/htdocs/waf.inc.php @@ -309,8 +309,8 @@ function analyseVarsForSqlAndScriptsInjection(&$var, $type, $stopcode = 1) } } -// Prevent the use of method TRACE -if ($_SERVER["REQUEST_METHOD"] == "TRACE") { +// Prevent the use of method TRACE in case of the web server authorizes it (some do it by default). TRACE method can be used by attacker to steal cookies or other sensitive information. +if (!empty($_SERVER["REQUEST_METHOD"]) && $_SERVER["REQUEST_METHOD"] == "TRACE") { print 'Access refused with request method TRACE'; http_response_code(405); exit(); From 39e200eb5027bb8605b9c3acbbe958b4fad565fe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Dec 2025 14:00:34 +0100 Subject: [PATCH 07/10] Debug v23 --- htdocs/compta/index.php | 3 ++- htdocs/core/lib/functions.lib.php | 30 +++++++++++++++++++----------- htdocs/projet/tasks/document.php | 14 +++++++------- htdocs/projet/tasks/note.php | 27 ++++++++++++++++----------- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index 39a070b4cf8..ae8ea1ab4bd 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -801,7 +801,8 @@ if ($sql) { print ''; $parameters = array('user' => $user); -$reshook = $hookmanager->executeHooks('dashboardAccountancy', $parameters, $object); // Note that $action and $object may have been modified by hook +$object = null; +$reshook = $hookmanager->executeHooks('dashboardAccountancy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook // End of page llxFooter(); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c1575a91f69..4e98eb38c74 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -12698,7 +12698,6 @@ function complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, function printCommonFooter($zone = 'private') { global $conf, $hookmanager, $user, $langs; - global $debugbar; global $action; global $micro_start_time; @@ -12712,8 +12711,9 @@ function printCommonFooter($zone = 'private') print "\n\n"; print '' . "\n"; - $parameters = array(); - $reshook = $hookmanager->executeHooks('printCommonFooter', $parameters); // Note that $action and $object may have been modified by some hooks + $parameters = array('zone' => $zone); + $tmpobject = null; + $reshook = $hookmanager->executeHooks('printCommonFooter', $parameters, $tmpobject, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { if (getDolGlobalString('MAIN_HTML_FOOTER')) { print getDolGlobalString('MAIN_HTML_FOOTER') . "\n"; @@ -12907,7 +12907,7 @@ function printCommonFooter($zone = 'private') print "\n" . '' . "\n"; // Google Analytics - // TODO Add a hook here + // TODO Remove this, can be replaced with the hook printCommonFooter if (isModEnabled('google') && getDolGlobalString('MAIN_GOOGLE_AN_ID')) { $tmptagarray = explode(',', getDolGlobalString('MAIN_GOOGLE_AN_ID')); foreach ($tmptagarray as $tmptag) { @@ -12933,15 +12933,23 @@ function printCommonFooter($zone = 'private') print_r(xdebug_get_code_coverage()); } + // Output string from hooks + if (!empty($hookmanager->resPrint)) { + print $hookmanager->resPrint; + } + // Add DebugBar data - if ($user->hasRight('debugbar', 'read') && $debugbar instanceof DebugBar\DebugBar) { - if (isset($debugbar['time'])) { - // @phan-suppress-next-line PhanPluginUnknownObjectMethodCall - $debugbar['time']->stopMeasure('pageaftermaster'); + if ($user->hasRight('debugbar', 'read')) { + global $debugbar; + if ($debugbar instanceof DebugBar\DebugBar) { + if (isset($debugbar['time'])) { + // @phan-suppress-next-line PhanPluginUnknownObjectMethodCall + $debugbar['time']->stopMeasure('pageaftermaster'); + } + print '' . "\n"; + $renderer = $debugbar->getJavascriptRenderer(); + print $renderer->render(); } - print '' . "\n"; - $renderer = $debugbar->getJavascriptRenderer(); - print $renderer->render(); } elseif (count($conf->logbuffer)) { // If there is some logs in buffer to show print "\n"; print "