diff --git a/.github/workflows/moderation.yml b/.github/workflows/moderation.yml index d7690a34734..a697c42640e 100644 --- a/.github/workflows/moderation.yml +++ b/.github/workflows/moderation.yml @@ -48,7 +48,6 @@ jobs: console.log('Detected language:', isEnglish ? 'english' : 'not english') - #if (hasYoutubeMusic || !isEnglish) { if (hasYoutubeMusic) { console.log('Deleting comment...') diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 9fd9846589a..9882ac65037 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -8766,18 +8766,6 @@ parameters: count: 1 path: ../../../htdocs/takepos/split.php - - - message: '#^If condition is always true\.$#' - identifier: if.alwaysTrue - count: 1 - path: ../../../htdocs/theme/eldy/manifest.json.php - - - - message: '#^If condition is always true\.$#' - identifier: if.alwaysTrue - count: 1 - path: ../../../htdocs/theme/md/manifest.json.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 0c46703e40b..3fba9dff27a 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -1165,6 +1165,7 @@ if ($action == 'edit') { print load_fiche_titre($langs->trans("DoTestServerAvailability")); include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mail = new CMailFile('test', '', '', '', array(), array(), array(), '', '', 0, 0, '', '', '', $trackid, $sendcontext); $errormsg = ''; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index dd1b9fbaa95..abad013a078 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -35,6 +35,13 @@ if (!defined('CSRFCHECK_WITH_TOKEN') && (empty($_GET['action']) || $_GET['action define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET } +// The modules list is a setup hub: force the menu context to "home" when the +// caller did not provide one, so the previously visited module's menu does not +// stick when the user comes back to this page (issue 38058). +if (!isset($_GET['mainmenu']) && !isset($_POST['mainmenu'])) { + $_GET['mainmenu'] = 'home'; +} + // Load Dolibarr environment require '../main.inc.php'; /** diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 90c9bdb0472..e4cd35e11ad 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -396,11 +396,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Confirmation to delete if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line if ($action == 'deleteline') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'lineid' => $lineid]), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } // Confirmation of validation @@ -438,7 +438,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea ); } if (!$error) { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220); } else { setEventMessage($langs->trans('Error'), 'errors'); $action = ''; @@ -465,7 +465,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea ); } - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220); } // Confirmation of reopen @@ -489,22 +489,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea ); } - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220); } // Clone confirmation if ($action == 'clone') { // Create an array for form $formquestion = array(); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); } - // Confirmation of action xxxx + // Confirmation of action setdraft if ($action == 'setdraft') { $text = $langs->trans('ConfirmSetToDraft', $object->ref); $formquestion = array(); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220); + $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220); } // Call Hook formConfirm @@ -741,14 +741,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Back to draft if ($object->status == $object::STATUS_VALIDATED) { if ($permissiontoadd) { - print ''.$langs->trans("SetToDraft").''."\n"; + print ''.$langs->trans("SetToDraft").''."\n"; } } // Modify if ($object->status == $object::STATUS_DRAFT) { if ($permissiontoadd) { - print ''.$langs->trans("Modify").''."\n"; + print ' $object->id, 'action' => 'edit'], true).'">'.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } @@ -758,7 +758,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($object->status == $object::STATUS_DRAFT) { if ($permissiontoadd) { if (is_array($object->lines) && count($object->lines) > 0) { - print ''.$langs->trans("Validate").''."\n"; + print ''.$langs->trans("Validate").''."\n"; } else { $langs->load("errors"); print ''.$langs->trans("Validate").''."\n"; @@ -768,38 +768,38 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Re-open if ($permissiontoadd && $object->status == $object::STATUS_CANCELED) { - print ''.$langs->trans("ReOpen").''."\n"; + print ''.$langs->trans("ReOpen").''."\n"; } // Create MO if (isModEnabled('mrp')) { if ($object->status == $object::STATUS_VALIDATED && $user->hasRight('mrp', 'write')) { - print ''.$langs->trans("CreateMO").''."\n"; + print ' $object->id])).'">'.$langs->trans("CreateMO").''."\n"; } } // Clone if ($permissiontoadd) { - print dolGetButtonAction($langs->trans("ToClone"), '', 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&object=bom', 'clone', $permissiontoadd); + print dolGetButtonAction($langs->trans("ToClone"), '', 'clone', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'clone', 'object' => 'bom'], true), 'clone', $permissiontoadd); } // Close / Cancel if ($permissiontoadd && $object->status == $object::STATUS_VALIDATED) { - print ''.$langs->trans("Disable").''."\n"; + print ''.$langs->trans("Disable").''."\n"; } /* if ($user->hasRight('bom', 'write')) { if ($object->status == 1) { - print ''.$langs->trans("Disable").''."\n"; + print ' $object->id, 'action' => 'disenable'], true).'">'.$langs->trans("Disable").''."\n"; } else { - print ''.$langs->trans("Enable").''."\n"; + print ' $object->id, 'action' => 'enable'], true).'">'.$langs->trans("Enable").''."\n"; } } */ // Delete - print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete); + print dolGetButtonAction($langs->trans("Delete"), '', 'delete', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'delete'], true), 'delete', $permissiontodelete); } print ''."\n"; } diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index bd951d9adf7..f6c06d7b1c6 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2019 Laurent Destailleur * Copyright (C) 2023 Benjamin Falière * Copyright (C) 2023 Charlene Benke - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024-2026 MDW * * This program is free software; you can redistribute it and/or modify @@ -1159,7 +1159,9 @@ class BOM extends CommonObject $label = implode($this->getTooltipContentArray($params)); } - $url = DOL_URL_ROOT.'/bom/bom_card.php?id='.$this->id; + $baseurl = DOL_URL_ROOT.'/bom/bom_card.php'; + + $query = ['id' => $this->id]; if ($option != 'nolink') { // Add param to save lastsearch_values or not @@ -1168,9 +1170,10 @@ class BOM extends CommonObject $add_save_lastsearch_values = 1; } if ($add_save_lastsearch_values) { - $url .= '&save_lastsearch_values=1'; + $query = array_merge($query, ['save_lastsearch_values' => 1]); } } + $url = dolBuildUrl($baseurl, $query); $linkclose = ''; if (empty($notooltip)) { diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index f86fde0a19c..e06f6490821 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -352,7 +352,18 @@ class FormSetup } $this->setupNotEmpty++; - $out .= ''; + + $tableLineAttr = [ + 'id' => 'setup-line-item_'. preg_replace('/[^a-zA-Z_]/', '', $item->confKey), + 'class' => $trClass + ]; + + if ($item->getType() !== 'title') { + $tableLineAttr['data-conf-key'] = $item->confKey; + } + + $tableLineAttrCompiled = commonHtmlAttributeBuilder($tableLineAttr); + $out .= ''; $out .= ''; $out .= ''; @@ -658,9 +669,15 @@ class FormSetupItem /** @var bool|string set this var to override field input */ public $fieldInputOverride = false; + /** @var callable this will be call before fieldInputOverride */ + public $fieldInputCallBack; + /** @var bool|string set this var to override field output */ public $fieldOutputOverride = false; + /** @var callable this will be call before fieldOutputCallBack */ + public $fieldOutputCallBack; + /** @var int */ public $rank = 0; @@ -771,8 +788,7 @@ class FormSetupItem return $reshook; } - - if (!empty($this->saveCallBack) && is_callable($this->saveCallBack)) { + if ($this->saveCallBack !== null && is_callable($this->saveCallBack)) { return call_user_func($this->saveCallBack, $this); } @@ -818,7 +834,7 @@ class FormSetupItem */ public function setValueFromPost() { - if (!empty($this->setValueFromPostCallBack) && is_callable($this->setValueFromPostCallBack)) { + if ($this->setValueFromPostCallBack !== null && is_callable($this->setValueFromPostCallBack)) { return call_user_func($this->setValueFromPostCallBack); } @@ -898,6 +914,14 @@ class FormSetupItem { global $conf; + if ($this->fieldInputCallBack !== null && is_callable($this->fieldInputCallBack)) { + // can be used to populate fieldInputOverride, fieldOverride or change stuff + $resCallback = call_user_func($this->fieldInputCallBack, $this); + if (!empty($resCallback)) { + return $resCallback; + } + } + if (!empty($this->fieldOverride)) { return $this->fieldOverride; } @@ -1310,6 +1334,14 @@ class FormSetupItem { global $conf, $user, $langs; + if ($this->fieldOutputCallBack !== null && is_callable($this->fieldOutputCallBack)) { + // can be used to populate fieldOutputOverride, fieldOverride or change stuff + $resCallback = call_user_func($this->fieldOutputCallBack, $this); + if (!empty($resCallback)) { + return $resCallback; + } + } + if (!empty($this->fieldOverride)) { return $this->fieldOverride; } diff --git a/htdocs/eventorganization/conferenceorbooth_card.php b/htdocs/eventorganization/conferenceorbooth_card.php index f47d01638a1..a1a6adbe8bf 100644 --- a/htdocs/eventorganization/conferenceorbooth_card.php +++ b/htdocs/eventorganization/conferenceorbooth_card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2021 Florian Henry * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024-2025 MDW * * This program is free software; you can redistribute it and/or modify @@ -28,6 +28,16 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + * + * @var string $dolibarr_main_url_root + */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; @@ -37,16 +47,6 @@ require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorbooth.class require_once DOL_DOCUMENT_ROOT.'/eventorganization/lib/eventorganization_conferenceorbooth.lib.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - * - * @var string $dolibarr_main_url_root - */ - // Load translation files required by the page $langs->loadLangs(array('eventorganization', 'projects')); @@ -66,7 +66,6 @@ $withproject = GETPOSTINT('withproject'); // Initialize a technical objects $object = new ConferenceOrBooth($db); -$extrafields = new ExtraFields($db); $projectstatic = new Project($db); $diroutputmassaction = $conf->eventorganization->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array($contextpage, 'globalcard')); // Note that conf->hooks_modules contains array diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 3a591e0f8cd..308a1fa7e67 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -11,7 +11,7 @@ * Copyright (C) 2015 Claudio Aschieri * Copyright (C) 2016-2018 Ferran Marcet * Copyright (C) 2016 Yasser Carreón - * Copyright (C) 2018-2025 Frédéric France + * Copyright (C) 2018-2026 Frédéric France * Copyright (C) 2020 Lenin Rivas * Copyright (C) 2022 Josep Lluís Amador * Copyright (C) 2024-2026 MDW @@ -43,12 +43,12 @@ require '../main.inc.php'; /** * @var Conf $conf * @var DoliDB $db + * @var ExtraFields $extrafields * @var HookManager $hookmanager * @var Societe $mysoc * @var Translate $langs * @var User $user */ - require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php'; @@ -56,7 +56,6 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/sendings.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/modules/expedition/modules_expedition.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; -require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/stock/class/productlot.class.php'; require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php'; @@ -116,7 +115,6 @@ $hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString( $object = new Expedition($db); $objectorder = new Commande($db); -$extrafields = new ExtraFields($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); diff --git a/htdocs/expedition/contact.php b/htdocs/expedition/contact.php index 8767cb9908a..fa98cef22f1 100644 --- a/htdocs/expedition/contact.php +++ b/htdocs/expedition/contact.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2011 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2023 Christian Foellmann - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2025-2026 MDW * * This program is free software; you can redistribute it and/or modify @@ -28,6 +28,13 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; @@ -38,13 +45,6 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; } -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ // Load translation files required by the page $langs->loadLangs(array('orders', 'sendings', 'companies')); diff --git a/htdocs/expedition/document.php b/htdocs/expedition/document.php index 1955b4b2cd9..8a66a7c58b4 100644 --- a/htdocs/expedition/document.php +++ b/htdocs/expedition/document.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2017 Ferran Marcet - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2025-2026 MDW * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,13 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; @@ -40,14 +47,6 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array('companies', 'other')); diff --git a/htdocs/expedition/index.php b/htdocs/expedition/index.php index e491f4882f2..20143d97ff2 100644 --- a/htdocs/expedition/index.php +++ b/htdocs/expedition/index.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2020 Tobias Sekan - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 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 @@ -28,9 +28,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; -require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -38,6 +35,8 @@ require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; // Load translation files required by the page $langs->loadLangs(array('orders', 'sendings')); diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 665e4966808..541c493aa96 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -10,7 +10,7 @@ * Copyright (C) 2024 Benjamin Falière * Copyright (C) 2024 Vincent Maury * Copyright (C) 2024 William Mead - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 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 @@ -34,6 +34,14 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; @@ -43,14 +51,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("sendings", 'companies', 'bills', 'products', 'orders')); @@ -116,7 +116,6 @@ $object = new Expedition($db); // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $hookmanager->initHooks(array('shipmentlist')); -$extrafields = new ExtraFields($db); // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); diff --git a/htdocs/expedition/note.php b/htdocs/expedition/note.php index ba5a6df7114..ab741b25250 100644 --- a/htdocs/expedition/note.php +++ b/htdocs/expedition/note.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2025-2026 MDW * * This program is free software; you can redistribute it and/or modify @@ -28,13 +28,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; -if (isModEnabled('project')) { - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -} - /** * @var Conf $conf * @var DoliDB $db @@ -42,6 +35,12 @@ if (isModEnabled('project')) { * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; +if (isModEnabled('project')) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} // Load translation files required by the page $langs->loadLangs(array('sendings', 'companies', 'bills', 'orders', 'stocks', 'other', 'propal')); diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index b84ec12aabe..5242ddf3e13 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2012 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012-2015 Juanjo Menent - * Copyright (C) 2018-2025 Frédéric France + * Copyright (C) 2018-2026 Frédéric France * Copyright (C) 2018-2022 Philippe Grand * Copyright (C) 2024-2026 MDW * @@ -29,6 +29,15 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Societe $mysoc + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; @@ -49,15 +58,6 @@ if (isModEnabled("product") || isModEnabled("service")) { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; } -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Societe $mysoc - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array('orders', 'sendings', 'companies', 'bills', 'propal', 'stocks', 'productbatch', 'incoterm', 'other')); @@ -77,7 +77,6 @@ $result = restrictedArea($user, 'commande', $order_id); $object = new Commande($db); $shipment = new Expedition($db); -$extrafields = new ExtraFields($db); $product = null; // fetch optionals attributes and labels diff --git a/htdocs/langs/en_US/quickmemo.lang b/htdocs/langs/en_US/quickmemo.lang index 55565004ce6..7dce47473b1 100644 --- a/htdocs/langs/en_US/quickmemo.lang +++ b/htdocs/langs/en_US/quickmemo.lang @@ -2,6 +2,10 @@ ModuleQuickMemoName = Quick Memo ModuleQuickMemoDesc = Allows adding quick notes on documents QuickMemoSetup = QuickMemo Setup QUICKMEMO_COLORS_PRESET = Define your custom memo colors here +QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE = Disable automatic text resizing based on note content density +QUICKMEMO_AUTO_RESIZE_FONT_SIZE_SECTION = Automatic text resizing settings +QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE = Minimum text size +QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE = Maximum text size QuickMemoSetupPage = QuickMemo Configuration Page QuickMemoAbout = About QuickMemo QuickMemoAboutPage = QuickMemo Home Page diff --git a/htdocs/langs/fr_FR/quickmemo.lang b/htdocs/langs/fr_FR/quickmemo.lang index 07d7d3de1a6..e0b0bf0e120 100644 --- a/htdocs/langs/fr_FR/quickmemo.lang +++ b/htdocs/langs/fr_FR/quickmemo.lang @@ -93,3 +93,7 @@ DialogAskConfirm = Confirmation QuickMemoDeleteModel = Supprimer le modèle ShowMemo = Consulter le mémo QUICKMEMO_COLORS_PRESET=Définissez ici vos couleurs de mémo personnalisées +QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE = Désactiver l’ajustement automatique de la taille du texte selon la densité du contenu de la note +QUICKMEMO_AUTO_RESIZE_FONT_SIZE_SECTION = Options de redimensionnement automatique du texte +QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE = Taille minimale du texte +QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE = Taille maximale du texte diff --git a/htdocs/loan/calcmens.php b/htdocs/loan/calcmens.php index 9ac180674eb..c003d3aa6a7 100644 --- a/htdocs/loan/calcmens.php +++ b/htdocs/loan/calcmens.php @@ -1,7 +1,7 @@ * Copyright (C) 2020 Maxime DEMAREST - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2026 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 @@ -35,7 +35,6 @@ if (!defined('NOREQUIREAJAX')) { // Load Dolibarr environment require '../main.inc.php'; -require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; /** * @var Conf $conf * @var DoliDB $db @@ -43,6 +42,7 @@ require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; * @var Translate $langs * @var User $user */ +require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; $mens = (float) price2num(GETPOST('mens')); $capital = (float) price2num(GETPOST('capital')); diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 3d661cd1ac4..70e81f7bb42 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2015-2025 Frédéric France + * Copyright (C) 2015-2026 Frédéric France * Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2020 Maxime DEMAREST * Copyright (C) 2024-2025 MDW @@ -27,6 +27,13 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; @@ -43,15 +50,6 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } - -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("banks", "bills", "compta", "loan")); diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php index d9c504ad468..12be55e6fa3 100644 --- a/htdocs/loan/document.php +++ b/htdocs/loan/document.php @@ -2,7 +2,7 @@ /* Copyright (C) 2014-2024 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024-2025 MDW - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 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 @@ -26,6 +26,13 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; @@ -36,14 +43,6 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("other", "companies", "compta", "bills", "loan")); diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php index 78757779f42..01a318a04bf 100644 --- a/htdocs/loan/info.php +++ b/htdocs/loan/info.php @@ -2,7 +2,7 @@ /* Copyright (C) 2014-2024 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2026 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 @@ -26,13 +26,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -if (isModEnabled('project')) { - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -} - /** * @var Conf $conf * @var DoliDB $db @@ -40,6 +33,12 @@ if (isModEnabled('project')) { * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +if (isModEnabled('project')) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +} // Load translation files required by the page $langs->loadLangs(array("compta", "bills", "loan")); diff --git a/htdocs/loan/list.php b/htdocs/loan/list.php index ebdd345935e..5871bab5b6c 100644 --- a/htdocs/loan/list.php +++ b/htdocs/loan/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2015-2024 Frédéric France + * Copyright (C) 2015-2026 Frédéric France * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2016 Laurent Destailleur * @@ -26,8 +26,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -35,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; // Load translation files required by the page $langs->loadLangs(array("banks", "bills", "compta", "loan")); diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index 2a4e015b6ac..7ded2fc2100 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2007 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2015-2025 Frédéric France + * Copyright (C) 2015-2026 Frédéric France * Copyright (C) 2016-2025 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024-2025 MDW @@ -30,11 +30,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -42,6 +37,10 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $action = GETPOST('action', 'aZ09'); diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php index 05acdc903f0..23742c2d28b 100644 --- a/htdocs/loan/payment/card.php +++ b/htdocs/loan/payment/card.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2026 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 @@ -25,12 +25,6 @@ // Load Dolibarr environment require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; -if (isModEnabled("bank")) { - require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -} - /** * @var Conf $conf * @var DoliDB $db @@ -38,6 +32,11 @@ if (isModEnabled("bank")) { * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; +if (isModEnabled("bank")) { + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +} // Load translation files required by the page $langs->loadLangs(array("bills", "banks", "companies", "loan")); @@ -102,6 +101,7 @@ $help_url = "EN:Module_Loan|FR:Module_Emprunt"; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-loan page-payment-card'); $h = 0; +$head = []; $head = array(); $head[$h][0] = DOL_URL_ROOT.'/loan/payment/card.php?id='.$id; diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index 28e06ff4bd2..60337fcb99b 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -1,6 +1,6 @@ - * Copyright (C) 2015-2025 Frédéric France + * Copyright (C) 2015-2026 Frédéric France * Copyright (C) 2020 Maxime DEMAREST * Copyright (C) 2025 MDW * @@ -26,12 +26,6 @@ // Load Dolibarr environment require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php'; -require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -39,11 +33,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; $langs->loadLangs(array("bills", "loan")); $action = GETPOST('action', 'aZ09'); -$confirm = GETPOST('confirm', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $chid = GETPOSTINT('id'); diff --git a/htdocs/loan/schedule.php b/htdocs/loan/schedule.php index 0e2ad762c98..0b5318b738d 100644 --- a/htdocs/loan/schedule.php +++ b/htdocs/loan/schedule.php @@ -3,7 +3,7 @@ * Copyright (C) 2018-2024 Alexandre Spangaro * Copyright (C) 2020 Maxime DEMAREST * Copyright (C) 2024-2026 MDW - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 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 @@ -27,6 +27,13 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; @@ -37,14 +44,6 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - $loanid = GETPOSTINT('loanid'); $action = GETPOST('action', 'aZ09'); diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index eed9752de36..3a464b934c5 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2020 Lenin Rivas - * Copyright (C) 2023-2025 Frédéric France + * Copyright (C) 2023-2026 Frédéric France * Copyright (C) 2024-2026 MDW * Copyright (C) 2025 Noé Cendrier * @@ -1543,11 +1543,13 @@ class Mo extends CommonObject $label = implode($this->getTooltipContentArray($params)); } - $url = DOL_URL_ROOT.'/mrp/mo_card.php?id='.$this->id; + $baseurl = DOL_URL_ROOT.'/mrp/mo_card.php'; if ($option == 'production') { - $url = DOL_URL_ROOT.'/mrp/mo_production.php?id='.$this->id; + $baseurl = DOL_URL_ROOT.'/mrp/mo_production.php'; } + $query = ['id' => $this->id]; + if ($option != 'nolink') { // Add param to save lastsearch_values or not $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); @@ -1555,9 +1557,10 @@ class Mo extends CommonObject $add_save_lastsearch_values = 1; } if ($add_save_lastsearch_values) { - $url .= '&save_lastsearch_values=1'; + $query = array_merge($query, ['save_lastsearch_values' => 1]); } } + $url = dolBuildUrl($baseurl, $query); $linkclose = ''; if (empty($notooltip)) { diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index 5067c0260a5..c10f3d10e77 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024-2025 MDW * @@ -26,6 +26,14 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; @@ -35,15 +43,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php'; - -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("mrp", "other")); @@ -91,7 +90,6 @@ if (!$sortorder) { // Initialize a technical objects $object = new Mo($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('moagenda', 'globalcard')); // Note that conf->hooks_modules contains array diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index 232a58f161d..e9192c85597 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2017-2020 Laurent Destailleur * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024-2025 MDW - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 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 @@ -27,7 +27,15 @@ // Load Dolibarr environment require '../main.inc.php'; - +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Societe $mysoc + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; @@ -42,16 +50,6 @@ if (isModEnabled('workstation')) { require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; } - -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Societe $mysoc - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array('mrp', 'other')); @@ -73,7 +71,6 @@ $socid = GETPOSTINT("socid"); $object = new Mo($db); $objectbom = new BOM($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('mocard', 'globalcard')); // Note that conf->hooks_modules contains array diff --git a/htdocs/mrp/mo_document.php b/htdocs/mrp/mo_document.php index 53944f77e15..e2fdcc269f1 100644 --- a/htdocs/mrp/mo_document.php +++ b/htdocs/mrp/mo_document.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2025 MDW * @@ -26,7 +26,14 @@ // Load Dolibarr environment require '../main.inc.php'; - +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -36,14 +43,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php'; -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("mrp", "companies", "other", "mails")); @@ -74,7 +73,6 @@ if (!$sortfield) { // Initialize a technical objects $object = new Mo($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('modocument', 'globalcard')); // Note that conf->hooks_modules contains array diff --git a/htdocs/mrp/mo_list.php b/htdocs/mrp/mo_list.php index bc4c6ab761e..68cb5411a3f 100644 --- a/htdocs/mrp/mo_list.php +++ b/htdocs/mrp/mo_list.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2025 MDW * * This program is free software; you can redistribute it and/or modify @@ -26,7 +26,14 @@ // Load Dolibarr environment require '../main.inc.php'; - +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; @@ -39,14 +46,6 @@ if (isModEnabled('category')) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php'; } -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("mrp", "other")); @@ -59,7 +58,7 @@ $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button $toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $mode = GETPOST('mode', 'alpha'); $groupby = GETPOST('groupby', 'aZ09'); // Example: $groupby = 'p.fk_opp_status' or $groupby = 'p.fk_statut' @@ -92,7 +91,6 @@ $pagenext = $page + 1; // Initialize a technical objects $object = new Mo($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array of activated contexes diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index b8e49048c7e..928e320d95e 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -1,7 +1,7 @@ * Copyright (C) 2022 Ferran Marcet - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024-2025 MDW * @@ -27,6 +27,14 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; @@ -39,14 +47,6 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php'; -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("mrp", "stocks", "other")); @@ -95,7 +95,6 @@ if (!$sortorder) { // Initialize a technical objects $object = new Mo($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('mocard', 'globalcard', 'mocardmovelist' )); // Note that conf->hooks_modules contains array diff --git a/htdocs/mrp/mo_note.php b/htdocs/mrp/mo_note.php index da66e229a6c..edacf43f88d 100644 --- a/htdocs/mrp/mo_note.php +++ b/htdocs/mrp/mo_note.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2025 MDW * @@ -26,20 +26,20 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php'; require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php'; -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("mrp", "companies")); @@ -52,7 +52,6 @@ $backtopage = GETPOST('backtopage', 'alpha'); // Initialize a technical objects $object = new Mo($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('monote', 'globalcard')); // Note that conf->hooks_modules contains array diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 2b38cbcd2b6..2cc6ed2716e 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -2,7 +2,7 @@ /* Copyright (C) 2019-2020 Laurent Destailleur * Copyright (C) 2023 Christian Humpel * Copyright (C) 2023 Vincent de Grandpré - * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2024-2026 Frédéric France * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2025 Noé Cendrier @@ -29,6 +29,14 @@ // Load Dolibarr environment require '../main.inc.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var ExtraFields $extrafields + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; @@ -43,15 +51,6 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; - -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - // Load translation files required by the page $langs->loadLangs(array("mrp", "stocks", "other", "product", "productbatch")); @@ -71,7 +70,6 @@ $collapse = GETPOST('collapse', 'aZ09comma'); // Initialize a technical objects $object = new Mo($db); -$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id; $objectline = new MoLine($db); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 24de6a3c970..9be06a1ce59 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -1416,6 +1416,7 @@ print ''; print ''; // Action column left if ($conf->main_checkbox_left_column) { @@ -1822,7 +1823,7 @@ if (!$conf->main_checkbox_left_column) { print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } -print ''."\n"; +print ''."\n"; $i = 0; diff --git a/htdocs/public/includes/dolibarr-js-context/dolibarr-tool.langs.js b/htdocs/public/includes/dolibarr-js-context/dolibarr-tool.langs.js index 08b5f976246..2e6136afa69 100644 --- a/htdocs/public/includes/dolibarr-js-context/dolibarr-tool.langs.js +++ b/htdocs/public/includes/dolibarr-js-context/dolibarr-tool.langs.js @@ -107,31 +107,56 @@ document.addEventListener('Dolibarr:Init', function(e) { /** * Clear all cached translations in IndexedDB and in-memory */ - async function clearCache(clearMemory = false) { - if(clearMemory) { - translations = {}; - domainsLoaded = {}; - } + async function clearCache(clearMemory = false, rebuildDatabase = false) { + try { const db = await openDB(true); - const tx = db.transaction('langs', 'readwrite'); - const store = tx.objectStore('langs'); - await store.clear(); + await new Promise((resolve, reject) => { + const tx = db.transaction('langs', 'readwrite'); + const store = tx.objectStore('langs'); + + store.clear(); + + tx.oncomplete = resolve; + tx.onerror = () => reject(tx.error); + tx.onabort = () => reject(tx.error); + }); + db.close(); // Delete database - const dbName = await getSafeDbName(); - const deleteRequest = indexedDB.deleteDatabase(dbName); - deleteRequest.onsuccess = () => Dolibarr.log('Dolibarr.tools.langs: database deleted'); - deleteRequest.onerror = () => console.error('Dolibarr.tools.langs:Failed to delete DB', deleteRequest.error); - deleteRequest.onblocked = () => console.warn('Dolibarr.tools.langs: DB deletion blocked, maybe open connections exist'); + if(rebuildDatabase) { + const dbName = await getSafeDbName(); + await new Promise((resolve, reject) => { + const deleteRequest = indexedDB.deleteDatabase(dbName); - // Try Delete all langs database - deleteAllDolibarrLangsDbs(); + deleteRequest.onsuccess = () => { + Dolibarr.log('tools: langs: database deleted'); + if (clearMemory) { + translations = {}; + domainsLoaded = {}; + } + resolve(); + }; - Dolibarr.log('Dolibarr.tools.langs: cache cleared'); + deleteRequest.onerror = () => { + console.error('Dolibarr: tools: langs Failed to delete DB', deleteRequest.error); + reject(deleteRequest.error); + }; + + deleteRequest.onblocked = () => { + console.warn('Dolibarr: tools: langs DB deletion blocked, maybe open connections exist'); + }; + }); + + // Try Delete all langs database + deleteAllDolibarrLangsDbs(); + } + + Dolibarr.log('tools: langs: cache cleared'); + Dolibarr.executeHook('tools:langs:CacheCleared'); } catch (err) { - console.error('Dolibarr.tools.langs: failed to clear cache', err); + console.error('Dolibarr: tools: langs failed to clear cache', err); } } @@ -146,9 +171,9 @@ document.addEventListener('Dolibarr:Init', function(e) { for (const dbInfo of dolibarrDbs) { const deleteRequest = indexedDB.deleteDatabase(dbInfo.name); - deleteRequest.onsuccess = () => console.log(`Database ${dbInfo.name} deleted`); - deleteRequest.onerror = () => console.error(`Failed to delete database ${dbInfo.name}`, deleteRequest.error); - deleteRequest.onblocked = () => console.warn(`Deletion of database ${dbInfo.name} blocked, maybe open connections exist`); + deleteRequest.onsuccess = () => Dolibarr.log(`Database ${dbInfo.name} deleted`); + deleteRequest.onerror = () => console.error(`Dolibarr: tools: langs Failed to delete database ${dbInfo.name}`, deleteRequest.error); + deleteRequest.onblocked = () => console.warn(`Dolibarr: tools: langs Deletion of database ${dbInfo.name} blocked, maybe open connections exist`); } } @@ -164,17 +189,17 @@ document.addEventListener('Dolibarr:Init', function(e) { const dolibarrVersion = Dolibarr.getContextVar('DOL_VERSION', 0); if (cache && cache.data && (now - cache.timestamp < CACHE_MSTIME) && cache.dolibarrVersion === dolibarrVersion) { - Dolibarr.log('Langs tool : Load lang from cache'); + Dolibarr.log('tools: langs: Load lang from cache'); return cache.data; } const langInterfaceUrl = Dolibarr.getContextVar('DOL_LANG_INTERFACE_URL', false); if(!langInterfaceUrl) { - console.error('Dolibarr langs: missing DOL_LANG_INTERFACE_URL') + console.error('Dolibarr: tools: langs missing DOL_LANG_INTERFACE_URL') return; } - Dolibarr.log('Langs tool : Load lang from interface'); + Dolibarr.log('tools: langs: Load lang from interface'); const params = new URLSearchParams({ domain, local: locale }); const resp = await fetch(`${langInterfaceUrl}?${params.toString()}`); const json = await resp.json(); @@ -236,7 +261,7 @@ document.addEventListener('Dolibarr:Init', function(e) { } } - Dolibarr.log(`Locale changed: ${prev} -> ${locale}`); + Dolibarr.log(`tools:langs: Locale changed: ${prev} -> ${locale}`); } @@ -296,18 +321,25 @@ document.addEventListener('Dolibarr:Init', function(e) { * Clear cache automatically under specific conditions * Support for Hard Reload (Shift or Ctrl) and Debug Mode */ + document.addEventListener('keydown', (e) => { + if (e.key === 'F5' && (e.ctrlKey || e.shiftKey)) { + sessionStorage.setItem('lang_hard_reload', '1'); + Dolibarr.log('Lang tool : Hard reload detected'); + } + }); + (async () => { const navEntries = performance?.getEntriesByType?.("navigation"); - const isReload = navEntries?.[0]?.type === "reload" || performance.navigation.type === 1; + const isReload = navEntries?.[0]?.type === "reload" || performance.navigation?.type === 1; - if (isReload) { - window.addEventListener('keydown', async (e) => { - // Check if user is holding Shift OR Control OR if Dolibarr Debug is enabled - if (e.shiftKey || e.ctrlKey) { - await clearCache(true); - Dolibarr.log('Langs tool: Cache cleared (Reason: Hard Reload or Debug Mode)'); - } - }, { once: true }); + if (!isReload) return; + + const isHardReload = sessionStorage.getItem('lang_hard_reload') === '1'; + sessionStorage.removeItem('lang_hard_reload'); + + if (isHardReload) { + await clearCache(true); + Dolibarr.log('Lang tool : Lang cache cleared (hard reload detected)'); } })(); diff --git a/htdocs/quickmemo/admin/setup.php b/htdocs/quickmemo/admin/setup.php index 5393257f58f..bbf49e2ab9a 100644 --- a/htdocs/quickmemo/admin/setup.php +++ b/htdocs/quickmemo/admin/setup.php @@ -73,28 +73,94 @@ if (!class_exists('FormSetup')) { $formSetup = new FormSetup($db); $item = $formSetup->newItem('QUICKMEMO_COLORS_PRESET'); -$item->fieldInputOverride = ' -
-
- - - - -
+/** + * Callback used to generate the custom HTML input field. + * + * @param FormSetupItem $item Current form/configuration item. + * @return string Generated HTML content. + */ +$item->fieldInputCallBack = function ($item) { + global $langs; -
+ $item->fieldInputOverride = ' +
+
+ + + + +
-
+
+ +
+ + +
'; + return $item->fieldInputOverride; +}; + + + +$formSetup->newItem('QUICKMEMO_AUTO_RESIZE_FONT_SIZE_SECTION')->setAsTitle(); + +$formSetup->newItem('QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE')->setAsYesNo(); +$item = $formSetup->newItem('QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE'); +$item->defaultFieldValue = '1'; +/** + * Callback used to generate the custom HTML input field. + * + * @param FormSetupItem $item Current form/configuration item. + * @return string Generated HTML content. + */ +$item->fieldInputCallBack = function ($item) { + $item->fieldInputOverride = ' + +
Lorem ipsum dolor sit amet
+ '; + return $item->fieldInputOverride; +}; + +$item = $formSetup->newItem('QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE'); +$item->defaultFieldValue = '1.4'; +/** + * Callback used to generate the custom HTML input field. + * + * @param FormSetupItem $item Current form/configuration item. + * @return string Generated HTML content. + */ +$item->fieldInputCallBack = function ($item) { + $item->fieldInputOverride = ' + + +
Lorem ipsum dolor sit amet
+ + '; + + return $item->fieldInputOverride; +}; - -
'; $setupnotempty += count($formSetup->items); @@ -134,6 +200,9 @@ llxHeader('', $langs->trans($title), $help_url, '', 0, 0, '', ['quickmemo/css/se '; } - $this->date_archived = dol_now(); - $this->fk_user_archived = (int) $this->user->id; - - $return .= ''; @@ -1646,6 +1642,18 @@ class Memo extends CommonObject return false; } + $autoResizeFontMin = getDolGlobalFloat('QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE', 1); + $autoResizeFontMax = getDolGlobalFloat('QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE', 1.4); + + // Apply safety limits + $autoResizeFontMin = max($autoResizeFontMin, 0.3); + $autoResizeFontMax = min($autoResizeFontMax, 5); + + // Ensure min value is always lower than max value + if ($autoResizeFontMin >= $autoResizeFontMax) { + $autoResizeFontMin = max(0.3, $autoResizeFontMax - 0.1); + } + $defaultJsConfVars = [ 'interfaceUrl' => dol_buildpath('quickmemo/interface.php', 1), 'archivesUrl' => dol_buildpath('quickmemo/memo_list.php', 1) . '?mode=kanban&search_status='.Memo::STATUS_ARCHIVED . ($jsConfVars['archivesUrlParams'] ?? ''), @@ -1656,7 +1664,10 @@ class Memo extends CommonObject 'colors' => Memo::getColorPreset(), 'userReadRight' => $user->hasRight('quickmemo', 'memo', 'read'), 'userWriteRight' => $user->hasRight('quickmemo', 'memo', 'write'), - 'userDeleteRight' => $user->hasRight('quickmemo', 'memo', 'delete') + 'userDeleteRight' => $user->hasRight('quickmemo', 'memo', 'delete'), + 'autoResizeFontSize' => !getDolGlobalInt('QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE'), + 'autoResizeFontMin' => $autoResizeFontMin, + 'autoResizeFontMax' => $autoResizeFontMax, ]; $jsConfVars = array_merge($defaultJsConfVars, $jsConfVars); diff --git a/htdocs/quickmemo/css/setup.css b/htdocs/quickmemo/css/setup.css index 68e198af862..e9975072dfe 100644 --- a/htdocs/quickmemo/css/setup.css +++ b/htdocs/quickmemo/css/setup.css @@ -70,3 +70,10 @@ border-radius: 50%; cursor: pointer; } + +.quickmemo-fontsize-config { + width: 100%; +} +.example-of-memo-text-size{ + font-size: 14px; +} diff --git a/htdocs/quickmemo/js/QuickMemo.js b/htdocs/quickmemo/js/QuickMemo.js index ccd44385ec1..dc549d7d872 100644 --- a/htdocs/quickmemo/js/QuickMemo.js +++ b/htdocs/quickmemo/js/QuickMemo.js @@ -21,6 +21,8 @@ class QuickMemo { userDeleteRight: false, elementId: 0, autoResizeFontSize: true, + autoResizeFontMin: 1, + autoResizeFontMax: 1.2, elementType: '', context: '', token: '', @@ -67,9 +69,14 @@ class QuickMemo { */ async init() { // Load translation files via Dolibarr tools - await Dolibarr.tools.langs.load('quickmemo'); - await Dolibarr.tools.langs.load('main'); - await Dolibarr.tools.langs.load('other'); + const loadLangs = async function () { + await Dolibarr.tools.langs.load('quickmemo'); + await Dolibarr.tools.langs.load('main'); + await Dolibarr.tools.langs.load('other'); + } + + await loadLangs(); + Dolibarr.on('tools:langs:CacheCleared', loadLangs); // Load existing memos from server this.loadMemos(); @@ -336,12 +343,66 @@ class QuickMemo { actions.className = 'quickmemo-actions'; /* ===== ARCHIVE ===== */ + const btnArchiveTitleLangs = { + QuickMemoActionDelete : await Dolibarr.tools.langs.transNoEntities('QuickMemoActionDelete'), + QuickMemoActionDeleteEmpty : await Dolibarr.tools.langs.transNoEntities('QuickMemoActionDeleteEmpty'), + QuickMemoActionArchive : await Dolibarr.tools.langs.transNoEntities('QuickMemoActionArchive'), + } const btnArchive = document.createElement('button'); btnArchive.className = 'btn-low-emphasis --btn-icon quickmemo-btn-archive'; btnArchive.innerHTML = ``; - btnArchive.title = await Dolibarr.tools.langs.transNoEntities('QuickMemoActionArchive'); + btnArchive.title = btnArchiveTitleLangs.QuickMemoActionArchive; this.initTooltips(btnArchive); + + /** Updates btn txt based onshift key */ + const updateBtnArchiveTitle = async () => { + let isHoverArchive = false; + + const updateArchiveTitle = (forceDelete = false) => { + const textarea = note.querySelector('textarea'); + const textLength = textarea.value.trim().length; + + if (forceDelete) { + btnArchive.title = btnArchiveTitleLangs.QuickMemoActionDelete; + } else if (textLength === 0) { + btnArchive.title = btnArchiveTitleLangs.QuickMemoActionDeleteEmpty; + } else { + btnArchive.title = btnArchiveTitleLangs.QuickMemoActionArchive; + } + + // Refresh tooltip if needed + btnArchive._quickmemoTooltipSync?.(); + }; + + btnArchive.addEventListener('mouseenter', async (e) => { + isHoverArchive = true; + + updateArchiveTitle(e.shiftKey); + }); + + btnArchive.addEventListener('mouseleave', () => { + isHoverArchive = false; + }); + + document.addEventListener('keydown', async (e) => { + if (e.key !== 'Shift' || !isHoverArchive) { + return; + } + + updateArchiveTitle(true); + }); + + document.addEventListener('keyup', async (e) => { + if (e.key !== 'Shift' || !isHoverArchive) { + return; + } + + updateArchiveTitle(false); + }); + }; + updateBtnArchiveTitle(); + btnArchive.addEventListener('click', async (e) => { e.stopPropagation(); this.removeTooltips(btnArchive); // JQUERY tooltip need to be destroy because it active at this moment @@ -349,7 +410,7 @@ class QuickMemo { try { // If empty, delete permanently, otherwise archive const textarea = note.querySelector('textarea'); - const actionDelete = textarea.value.length ? 'archive' : 'delete'; + const actionDelete = (e.shiftKey || textarea.value.length === 0) ? 'delete' : 'archive'; if (actionDelete === 'delete') { this.deleteWithAnimation(note); @@ -957,6 +1018,8 @@ class QuickMemo { const btnArchive = noteEl.querySelector('.quickmemo-btn-archive'); if (btnArchive) { btnArchive.title = await Dolibarr.tools.langs.transNoEntities(textLength > 0 ? 'QuickMemoActionArchive' : 'QuickMemoActionDeleteEmpty'); + // Refresh tooltip if needed + btnArchive._quickmemoTooltipSync?.(); } // Calculate density @@ -965,8 +1028,8 @@ class QuickMemo { // Linearly map density to font-size const densityMin = 0.0002; const densityMax = 0.005; - const fontMin = 0.8; - const fontMax = 1.2; + const fontMin = this.param.autoResizeFontMin; + const fontMax = this.param.autoResizeFontMax; // Clamp density between min & max const clampedDensity = Math.max(densityMin, Math.min(densityMax, density)); diff --git a/htdocs/subtotals/core/substitutions/functions_subtotals.lib.php b/htdocs/subtotals/core/substitutions/functions_subtotals.lib.php index b3b1cc35432..c11ac7c012f 100644 --- a/htdocs/subtotals/core/substitutions/functions_subtotals.lib.php +++ b/htdocs/subtotals/core/substitutions/functions_subtotals.lib.php @@ -1,7 +1,7 @@ + * Copyright (C) 2025-2026 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 diff --git a/htdocs/workstation/class/workstationresource.class.php b/htdocs/workstation/class/workstationresource.class.php index b72bf804de1..73225f01fa0 100644 --- a/htdocs/workstation/class/workstationresource.class.php +++ b/htdocs/workstation/class/workstationresource.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2020 Gauthier VERDOL * Copyright (C) 2024-2026 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2026 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 @@ -95,7 +95,12 @@ class WorkstationResource extends CommonObject { global $db; $obj = new self($db); - return array_map('intval', parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_resource', 'fk_workstation', $obj->table_element)); + $all_items = parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_resource', 'fk_workstation', $obj->table_element); + if (!is_array($all_items)) { + return []; + } + + return array_map('intval', $all_items); } /** diff --git a/htdocs/workstation/class/workstationusergroup.class.php b/htdocs/workstation/class/workstationusergroup.class.php index 9b62594540a..ef5f5925d32 100644 --- a/htdocs/workstation/class/workstationusergroup.class.php +++ b/htdocs/workstation/class/workstationusergroup.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2020 Gauthier VERDOL * Copyright (C) 2024-2026 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2026 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 @@ -95,7 +95,12 @@ class WorkstationUserGroup extends CommonObject global $db; $obj = new self($db); - return array_map('intval', parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_usergroup', 'fk_workstation', $obj->table_element)); + $all_items = parent::getAllItemsLinkedByObjectID($fk_workstation, 'fk_usergroup', 'fk_workstation', $obj->table_element); + if (!is_array($all_items)) { + return []; + } + + return array_map('intval', $all_items); } /**