From 993c1d28c4c0fd93f069b71d9692382eae5a7d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 30 Jan 2023 23:24:23 +0100 Subject: [PATCH 001/137] work on ajax tooltip --- htdocs/commande/class/commande.class.php | 58 ++++++- htdocs/core/ajax/ajaxtooltip.php | 200 +++++++++++++++++++++++ htdocs/core/class/commonobject.class.php | 51 ++++++ htdocs/core/js/lib_foot.js.php | 71 +++++--- htdocs/product/class/product.class.php | 120 +++++++++++++- htdocs/user/class/user.class.php | 108 +++++++++++- 6 files changed, 578 insertions(+), 30 deletions(-) create mode 100644 htdocs/core/ajax/ajaxtooltip.php diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 2a462f77bc4..4dcae469aaa 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3714,6 +3714,48 @@ class Commande extends CommonOrder return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode, '', array('tooltip' => $labelTooltip)); } + /** + * getTooltipContentArray + * @param array $parameters + * @since v18 + * @return array + */ + public function getTooltipContentArray($parameters) + { + global $conf, $langs, $user; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("Order")]; + } + + if ($user->rights->commande->lire) { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Order").''; + if (isset($this->statut)) { + $datas[] = ' '.$this->getLibStatut(5); + } + $datas['Ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + $datas['RefCustomer'] = '
'.$langs->trans('RefCustomer').': '.(empty($this->ref_customer) ? (empty($this->ref_client) ? '' : $this->ref_client) : $this->ref_customer); + if (!empty($this->total_ht)) { + $datas['AmountHT'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['VAT'] = '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['AmountTTC'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->date)) { + $datas['Date'] = '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); + } + if (!empty($this->delivery_date)) { + $datas['DeliveryDate'] = '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); + } + } + + return $datas; + } /** * Return clicable link of object (with eventually picto) @@ -3795,10 +3837,20 @@ class Commande extends CommonOrder $label = $langs->trans("Order"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="order-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } - $target_value=array('_self', '_blank', '_parent', '_top'); + $target_value = array('_self', '_blank', '_parent', '_top'); if (in_array($target, $target_value)) { $linkclose .= ' target="'.dol_escape_htmltag($target).'"'; } diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php new file mode 100644 index 00000000000..2342bcf35f1 --- /dev/null +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -0,0 +1,200 @@ + + * Copyright (C) 2018-2023 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/ajax/ajaxtooltip.php + * \ingroup tooltip + * \brief This script returns content of tooltip + */ + + +if (!defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', 1); // Disables token renewal +} +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); +} +if (!defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); +} +if (!defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +include '../../main.inc.php'; +include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + +top_httphead(); + +$id = GETPOST('id', 'int'); +$objecttype = GETPOST('objecttype', 'aZ09'); + +$html = ''; +$regs = array(); +$params = array(); +if (GETPOSTISSET('infologin')) { + $params['infologin'] = GETPOST('infologin', 'int'); +} +if (GETPOSTISSET('option')) { + $params['option'] = GETPOST('option', 'restricthtml'); +} +// If we ask a resource form external module (instead of default path) +if (preg_match('/^([^@]+)@([^@]+)$/i', $objecttype, $regs)) { + $myobject = $regs[1]; + $module = $regs[2]; +} else { + // Parse $objecttype (ex: project_task) + $module = $myobject = $objecttype; + if (preg_match('/^([^_]+)_([^_]+)/i', $objecttype, $regs)) { + $module = $regs[1]; + $myobject = $regs[2]; + } +} + +// Generic case for $classpath +$classpath = $module.'/class'; + +// Special cases, to work with non standard path +if ($objecttype == 'facture' || $objecttype == 'invoice') { + $langs->load('bills'); + $classpath = 'compta/facture/class'; + $module = 'facture'; + $myobject = 'facture'; +} elseif ($objecttype == 'commande' || $objecttype == 'order') { + $langs->load('orders'); + $classpath = 'commande/class'; + $module = 'commande'; + $myobject = 'commande'; +} elseif ($objecttype == 'propal') { + $langs->load('propal'); + $classpath = 'comm/propal/class'; +} elseif ($objecttype == 'supplier_proposal') { + $langs->load('supplier_proposal'); + $classpath = 'supplier_proposal/class'; +} elseif ($objecttype == 'shipping') { + $langs->load('sendings'); + $classpath = 'expedition/class'; + $myobject = 'expedition'; + $module = 'expedition_bon'; +} elseif ($objecttype == 'delivery') { + $langs->load('deliveries'); + $classpath = 'delivery/class'; + $myobject = 'delivery'; + $module = 'delivery_note'; +} elseif ($objecttype == 'contract') { + $langs->load('contracts'); + $classpath = 'contrat/class'; + $module = 'contrat'; + $myobject = 'contrat'; +} elseif ($objecttype == 'member') { + $langs->load('members'); + $classpath = 'adherents/class'; + $module = 'adherent'; + $myobject = 'adherent'; +} elseif ($objecttype == 'cabinetmed_cons') { + $classpath = 'cabinetmed/class'; + $module = 'cabinetmed'; + $myobject = 'cabinetmedcons'; +} elseif ($objecttype == 'fichinter') { + $langs->load('interventions'); + $classpath = 'fichinter/class'; + $module = 'ficheinter'; + $myobject = 'fichinter'; +} elseif ($objecttype == 'project') { + $langs->load('projects'); + $classpath = 'projet/class'; + $module = 'projet'; +} elseif ($objecttype == 'task') { + $langs->load('projects'); + $classpath = 'projet/class'; + $module = 'projet'; + $myobject = 'task'; +} elseif ($objecttype == 'stock') { + $classpath = 'product/stock/class'; + $module = 'stock'; + $myobject = 'stock'; +} elseif ($objecttype == 'inventory') { + $classpath = 'product/inventory/class'; + $module = 'stock'; + $myobject = 'inventory'; +} elseif ($objecttype == 'mo') { + $classpath = 'mrp/class'; + $module = 'mrp'; + $myobject = 'mo'; +} elseif ($objecttype == 'productlot') { + $classpath = 'product/stock/class'; + $module = 'stock'; + $myobject = 'productlot'; +} + +// Generic case for $classfile and $classname +$classfile = strtolower($myobject); +$classname = ucfirst($myobject); +//print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname." classpath=".$classpath; + +if ($objecttype == 'invoice_supplier') { + $classfile = 'fournisseur.facture'; + $classname = 'FactureFournisseur'; + $classpath = 'fourn/class'; + $module = 'fournisseur'; +} elseif ($objecttype == 'order_supplier') { + $classfile = 'fournisseur.commande'; + $classname = 'CommandeFournisseur'; + $classpath = 'fourn/class'; + $module = 'fournisseur'; +} elseif ($objecttype == 'supplier_proposal') { + $classfile = 'supplier_proposal'; + $classname = 'SupplierProposal'; + $classpath = 'supplier_proposal/class'; + $module = 'supplier_proposal'; +} elseif ($objecttype == 'stock') { + $classpath = 'product/stock/class'; + $classfile = 'entrepot'; + $classname = 'Entrepot'; +} elseif ($objecttype == 'facturerec') { + $classpath = 'compta/facture/class'; + $classfile = 'facture-rec'; + $classname = 'FactureRec'; + $module = 'facture'; +} elseif ($objecttype == 'mailing') { + $classpath = 'comm/mailing/class'; + $classfile = 'mailing'; + $classname = 'Mailing'; +} + +if (isModEnabled($module)) { + $res = dol_include_once('/'.$classpath.'/'.$classfile.'.class.php'); + if ($res) { + if (class_exists($classname)) { + $object = new $classname($db); + $res = $object->fetch($id); + if ($res > 0) { + $html = $object->getTooltipContent($params); + } elseif ($res == 0) { + $html = $langs->trans('Deleted'); + } + unset($object); + } else { + dol_syslog("Class with classname ".$classname." is unknown even after the include", LOG_ERR); + } + } +} + +print $html; + +$db->close(); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 25f16cbbdb4..416e1ca737b 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -664,6 +664,57 @@ abstract class CommonObject } return -1; } + /** + * getTooltipContentArray + * + * @since v18 + * @param array $params + * @return array + */ + public function getTooltipContentArray($params) + { + return []; + } + + /** + * getTooltipContent + * + * @param array $params + * @since v18 + * @return string + */ + public function getTooltipContent($params) + { + global $action, $extrafields, $langs, $hookmanager; + + $datas = $this->getTooltipContentArray($params); + + if (!empty($extrafields->attributes[$this->table_element]['label'])) { + foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) { + if (!empty($extrafields->attributes[$this->table_element]['langfile'][$key])) { + $langs->load($extrafields->attributes[$this->table_element]['langfile'][$key]); + } + $labelextra = $langs->trans((string) $extrafields->attributes[$this->table_element]['label'][$key]); + if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate') { + $datas[$key]= '
'. $labelextra . ''; + } else { + $value = $this->array_options['options_' . $key]; + $datas[$key]= '
'. $labelextra . ': ' . $extrafields->showOutputField($key, $value, '', $this->table_element); + } + } + } + + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array( + 'tooltipcontentarray' => &$datas + ); + // Note that $action and $object may have been modified by some hooks + $hookmanager->executeHooks('getTooltipContent', $parameters, $this, $action); + + $label = implode($datas); + + return $label; + } /** diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index c037b86a7b9..7ec398f3368 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -65,38 +65,63 @@ if (empty($dolibarr_nocache)) { // Wrapper to show tooltips (html or onclick popup) -print "\n/* JS CODE TO ENABLE Tooltips on all object with class classfortooltip */\n"; -print "jQuery(document).ready(function () {\n"; +print "\n/* JS CODE TO ENABLE Tooltips on all object with class classfortooltip */ +jQuery(document).ready(function () {\n"; if (empty($conf->dol_no_mouse_hover)) { - print 'jQuery(".classfortooltip").tooltip({ + print ' + jQuery(".classfortooltip").tooltip({ show: { collision: "flipfit", effect:"toggle", delay:50, duration: 20 }, hide: { delay: 250, duration: 20 }, tooltipClass: "mytooltip", content: function () { - console.log("Return title for popup"); - return $(this).prop("title"); /* To force to get title as is */ - } - });'."\n"; + console.log("Return title for popup"); + return $(this).prop("title"); /* To force to get title as is */ + } + }); + jQuery(".classforajaxtooltip").tooltip({ + show: { collision: "flipfit", effect:"toggle", delay:50, duration: 20 }, + hide: { delay: 250, duration: 20 }, + tooltipClass: "mytooltip", + open: function (event, ui) { + var id = $(this).attr("id"); + var params = $(this).attr("data-params"); + $.ajax({ + url:"' . dol_buildpath('/core/ajax/ajaxtooltip.php', 1) . '", + type: "post", + data: JSON.parse(params), + success: function(response){ + // Setting content option + $("#"+id).tooltip("option","content",response); + } + }); + console.log(event); + } + }); + jQuery(".classforajaxtooltip").mouseout(function(){ + console.log("hide ajax tooltip"); + $(this).tooltip("close"); + }); + '; } print ' -jQuery(".classfortooltiponclicktext").dialog({ - closeOnEscape: true, classes: { "ui-dialog": "highlight" }, - maxHeight: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? max($_SESSION['dol_screenwidth'] - 20, 320) : 700).', - modal: true, - autoOpen: false - }).css("z-index: 5000"); -jQuery(".classfortooltiponclick").click(function () { - console.log("We click on tooltip for element with dolid="+$(this).attr(\'dolid\')); - if ($(this).attr(\'dolid\')) { - obj=$("#idfortooltiponclick_"+$(this).attr(\'dolid\')); /* obj is a div component */ - obj.dialog("open"); - return false; - } -});'."\n"; - -print "});\n"; + jQuery(".classfortooltiponclicktext").dialog({ + closeOnEscape: true, classes: { "ui-dialog": "highlight" }, + maxHeight: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? max($_SESSION['dol_screenwidth'] - 20, 320) : 700).', + modal: true, + autoOpen: false + }).css("z-index: 5000"); + jQuery(".classfortooltiponclick").click(function () { + console.log("We click on tooltip for element with dolid="+$(this).attr(\'dolid\')); + if ($(this).attr(\'dolid\')) { + obj=$("#idfortooltiponclick_"+$(this).attr(\'dolid\')); /* obj is a div component */ + obj.dialog("open"); + return false; + } + }); +}); +'; // Wrapper to manage dropdown diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 60de90d819d..e7160ef467a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4999,6 +4999,112 @@ class Product extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowProduct")]; + } + + if (!empty($this->entity)) { + $tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80); + if ($this->nbphoto > 0) { + $datas['photo'] = '
' . $tmpphoto . '
'; + //$label .= '
'; + } + } + + if ($this->type == Product::TYPE_PRODUCT) { + $datas['picto'] = img_picto('', 'product').' '.$langs->trans("Product").''; + } elseif ($this->type == Product::TYPE_SERVICE) { + $datas['picto']= img_picto('', 'service').' '.$langs->trans("Service").''; + } + if (isset($this->status) && isset($this->status_buy)) { + $datas['status']= ' '.$this->getLibStatut(5, 0) . ' '.$this->getLibStatut(5, 1); + } + + if (!empty($this->ref)) { + $datas['ref']= '
'.$langs->trans('ProductRef').': '.$this->ref; + } + if (!empty($this->label)) { + $datas['label']= '
'.$langs->trans('ProductLabel').': '.$this->label; + } + if ($this->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + if (isModEnabled('productbatch')) { + $langs->load("productbatch"); + $datas['batchstatus']= "
".$langs->trans("ManageLotSerial").': '.$this->getLibStatut(0, 2); + } + } + if (isModEnabled('barcode')) { + $datas['barcode']= '
'.$langs->trans('BarCode').': '.$this->barcode; + } + + if ($this->type == Product::TYPE_PRODUCT) { + if ($this->weight) { + $datas['weight']= "
".$langs->trans("Weight").': '.$this->weight.' '.measuringUnitString(0, "weight", $this->weight_units); + } + $labelsize = ""; + if ($this->length) { + $labelsize .= ($labelsize ? " - " : "")."".$langs->trans("Length").': '.$this->length.' '.measuringUnitString(0, 'size', $this->length_units); + } + if ($this->width) { + $labelsize .= ($labelsize ? " - " : "")."".$langs->trans("Width").': '.$this->width.' '.measuringUnitString(0, 'size', $this->width_units); + } + if ($this->height) { + $labelsize .= ($labelsize ? " - " : "")."".$langs->trans("Height").': '.$this->height.' '.measuringUnitString(0, 'size', $this->height_units); + } + if ($labelsize) { + $datas['size']= "
".$labelsize; + } + + $labelsurfacevolume = ""; + if ($this->surface) { + $labelsurfacevolume .= ($labelsurfacevolume ? " - " : "")."".$langs->trans("Surface").': '.$this->surface.' '.measuringUnitString(0, 'surface', $this->surface_units); + } + if ($this->volume) { + $labelsurfacevolume .= ($labelsurfacevolume ? " - " : "")."".$langs->trans("Volume").': '.$this->volume.' '.measuringUnitString(0, 'volume', $this->volume_units); + } + if ($labelsurfacevolume) { + $datas['surface']= "
" . $labelsurfacevolume; + } + } + if (!empty($this->pmp) && $this->pmp) { + $datas['pmp'] = "
".$langs->trans("PMPValue").': '.price($this->pmp, 0, '', 1, -1, -1, $conf->currency); + } + + if (isModEnabled('accounting')) { + if ($this->status && isset($this->accountancy_code_sell)) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + $selllabel = '
'; + $selllabel .= '
'.$langs->trans('ProductAccountancySellCode').': '.length_accountg($this->accountancy_code_sell); + $selllabel .= '
'.$langs->trans('ProductAccountancySellIntraCode').': '.length_accountg($this->accountancy_code_sell_intra); + $selllabel .= '
'.$langs->trans('ProductAccountancySellExportCode').': '.length_accountg($this->accountancy_code_sell_export); + $datas['accountancysell'] = $selllabel; + } + if ($this->status_buy && isset($this->accountancy_code_buy)) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + if (empty($this->status)) { + $buylabel = '
'; + } + $buylabel .= '
'.$langs->trans('ProductAccountancyBuyCode').': '.length_accountg($this->accountancy_code_buy); + $buylabel .= '
'.$langs->trans('ProductAccountancyBuyIntraCode').': '.length_accountg($this->accountancy_code_buy_intra); + $buylabel .= '
'.$langs->trans('ProductAccountancyBuyExportCode').': '.length_accountg($this->accountancy_code_buy_export); + $datas['accountancybuy'] = $buylabel; + } + } + + return $datas; + } + /** * Return clicable link of object (with eventually picto) * @@ -5119,8 +5225,18 @@ class Product extends CommonObject $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; - $linkclose .= ' class="nowraponall classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="product-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="nowraponall classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; + $linkclose .= ' class="nowraponall classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } else { $linkclose = ' class="nowraponall'.($morecss ? ' '.$morecss : '').'"'; } diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 2893378bdd9..0a963da1f5d 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2744,6 +2744,99 @@ class User extends CommonObject return $result; } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $menumanager; + + $infologin = $params['infologin'] ?? 0; + $option = $params['option'] ?? ''; + + $datas = []; + if (!empty($this->photo)) { + $photo = '
'; + $photo .= Form::showphoto('userphoto', $this, 0, 60, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1); // Force height to 60 so we total height of tooltip can be calculated and collision can be managed + $photo .= '
'; + $datas['photo'] = $photo; + //$label .= '
'; + } + + // Info Login + $datas['opendiv'] = '
'; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("User").' '.$this->getLibStatut(4); + $datas['name'] = '
'.$langs->trans('Name').': '.dol_string_nohtmltag($this->getFullName($langs, '')); + if (!empty($this->login)) { + $datas['login'] = '
'.$langs->trans('Login').': '.dol_string_nohtmltag($this->login); + } + if (!empty($this->job)) { + $datas['job'] = '
'.$langs->trans("Job").': '.dol_string_nohtmltag($this->job); + } + $datas['email'] = '
'.$langs->trans("Email").': '.dol_string_nohtmltag($this->email); + if (!empty($this->office_phone) || !empty($this->office_fax) || !empty($this->fax)) { + $phonelist = array(); + if ($this->office_phone) { + $phonelist[] = dol_print_phone($this->office_phone, $this->country_code, $this->id, 0, '', ' ', 'phone'); + } + if ($this->office_fax) { + $phonelist[] = dol_print_phone($this->office_fax, $this->country_code, $this->id, 0, '', ' ', 'fax'); + } + if ($this->user_mobile) { + $phonelist[] = dol_print_phone($this->user_mobile, $this->country_code, $this->id, 0, '', ' ', 'mobile'); + } + $datas['phones'] = '
'.$langs->trans('Phone').': '.implode(' ', $phonelist); + } + if (!empty($this->admin)) { + $datas['administrator'] = '
'.$langs->trans("Administrator").': '.yn($this->admin); + } + if (!empty($this->accountancy_code) || $option == 'accountancy') { + $datas['accountancycode'] = '
'.$langs->trans("AccountancyCode").': '.$this->accountancy_code; + } + $company = ''; + if (!empty($this->socid)) { // Add thirdparty for external users + $thirdpartystatic = new Societe($this->db); + $thirdpartystatic->fetch($this->socid); + if (empty($hidethirdpartylogo)) { + $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink') ? 'nolink' : '')); // picto only of company + } + $company = ' ('.$langs->trans("Company").': '.img_picto('', 'company').' '.dol_string_nohtmltag($thirdpartystatic->name).')'; + } + $type = ($this->socid ? $langs->trans("ExternalUser").$company : $langs->trans("InternalUser")); + $datas['type'] = '
'.$langs->trans("Type").': '.$type; + $datas['closediv'] = '
'; + if ($infologin > 0) { + $datas['newlinelogin'] = '
'; + $datas['session'] = '
'.$langs->trans("Session").''; + $datas['ip'] = '
'.$langs->trans("IPAddress").': '.dol_string_nohtmltag(getUserRemoteIP()); + if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) { + $datas['multicompany'] = '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (User entity '.$this->entity.')'; + } + $datas['authentication'] = '
'.$langs->trans("AuthenticationMode").': '.dol_string_nohtmltag($_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)')); + $datas['connectedsince'] = '
'.$langs->trans("ConnectedSince").': '.dol_print_date($this->datelastlogin, "dayhour", 'tzuser'); + $datas['previousconnexion'] = '
'.$langs->trans("PreviousConnexion").': '.dol_print_date($this->datepreviouslogin, "dayhour", 'tzuser'); + $datas['currenttheme'] = '
'.$langs->trans("CurrentTheme").': '.dol_string_nohtmltag($conf->theme); + $datas['currentmenumanager'] = '
'.$langs->trans("CurrentMenuManager").': '.dol_string_nohtmltag($menumanager->name); + $s = picto_from_langcode($langs->getDefaultLang()); + $datas['currentuserlang'] = '
'.$langs->trans("CurrentUserLanguage").': '.dol_string_nohtmltag(($s ? $s.' ' : '').$langs->getDefaultLang()); + $datas['browser'] = '
'.$langs->trans("Browser").': '.dol_string_nohtmltag($conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')'); + $datas['layout'] = '
'.$langs->trans("Layout").': '.dol_string_nohtmltag($conf->browser->layout); + $datas['screen'] = '
'.$langs->trans("Screen").': '.dol_string_nohtmltag($_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']); + if ($conf->browser->layout == 'phone') { + $datas['phone'] = '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); + } + if (!empty($_SESSION["disablemodules"])) { + $datas['disabledmodules'] = '
'.$langs->trans("DisabledModules").':
'.dol_string_nohtmltag(join(', ', explode(',', $_SESSION["disablemodules"]))); + } + } + + return $datas; + } + /** * Return a HTML link to the user card (with optionaly the picto) * Use this->id,this->lastname, this->firstname @@ -2877,8 +2970,19 @@ class User extends CommonObject $label = $langs->trans("ShowUser"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'infologin' => $infologin, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="user-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } $linkstart .= $linkclose.'>'; From 7eb0b712520f97e84a2c6ebb76ca0116d08ab79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 31 Jan 2023 22:43:54 +0100 Subject: [PATCH 002/137] work on ajax tooltip --- htdocs/commande/class/commande.class.php | 8 ++++---- htdocs/core/ajax/ajaxtooltip.php | 4 ---- htdocs/core/class/commonobject.class.php | 4 ++-- htdocs/product/class/product.class.php | 2 +- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 4dcae469aaa..16f22c80c91 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3716,11 +3716,11 @@ class Commande extends CommonOrder /** * getTooltipContentArray - * @param array $parameters + * @param array $params params to construct tooltip data * @since v18 * @return array */ - public function getTooltipContentArray($parameters) + public function getTooltipContentArray($params) { global $conf, $langs, $user; @@ -3730,7 +3730,7 @@ class Commande extends CommonOrder return ['optimize' => $langs->trans("Order")]; } - if ($user->rights->commande->lire) { + if ($user->hasRight('commande', 'lire')) { $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Order").''; if (isset($this->statut)) { $datas[] = ' '.$this->getLibStatut(5); @@ -3807,7 +3807,7 @@ class Commande extends CommonOrder $label = ''; - if ($user->rights->commande->lire) { + if ($user->hasRight('commande', 'lire')) { $label = img_picto('', $this->picto).' '.$langs->trans("Order").''; if (isset($this->statut)) { $label .= ' '.$this->getLibStatut(5); diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index 2342bcf35f1..569f2fc6ad7 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -106,10 +106,6 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'adherents/class'; $module = 'adherent'; $myobject = 'adherent'; -} elseif ($objecttype == 'cabinetmed_cons') { - $classpath = 'cabinetmed/class'; - $module = 'cabinetmed'; - $myobject = 'cabinetmedcons'; } elseif ($objecttype == 'fichinter') { $langs->load('interventions'); $classpath = 'fichinter/class'; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 416e1ca737b..b209d7450f4 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -668,7 +668,7 @@ abstract class CommonObject * getTooltipContentArray * * @since v18 - * @param array $params + * @param array $params params to construct tooltip data * @return array */ public function getTooltipContentArray($params) @@ -679,7 +679,7 @@ abstract class CommonObject /** * getTooltipContent * - * @param array $params + * @param array $params params * @since v18 * @return string */ diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e7160ef467a..ab9d33a0500 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5001,7 +5001,7 @@ class Product extends CommonObject /** * getTooltipContentArray - * @param array $params + * @param array $params params to construct tooltip data * @since v18 * @return array */ From 8d71b8101384b15d6563d2f388cb5fdb996a9d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 1 Feb 2023 20:58:40 +0100 Subject: [PATCH 003/137] ajax tooltip on propal --- htdocs/comm/propal/class/propal.class.php | 62 +++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index c4328328f18..dba4e0e84d6 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3690,6 +3690,52 @@ class Propal extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("Proposal")]; + } + if ($user->hasRight('propal', 'lire')) { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Proposal").''; + if (isset($this->statut)) { + $datas['status'] = ' '.$this->getLibStatut(5); + } + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->ref_client)) { + $datas['refcustomer'] = '
'.$langs->trans('RefCustomer').': '.$this->ref_client; + } + if (!empty($this->total_ht)) { + $datas['amountht'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['vat'] = '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['amountttc'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->date)) { + $datas['date'] = '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); + } + if (!empty($this->delivery_date)) { + $datas['deliverydate'] = '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); + } + } + + return $datas; + } + /** * Return clicable link of object (with eventually picto) * @@ -3737,7 +3783,7 @@ class Propal extends CommonObject $label .= '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); } if (!empty($this->delivery_date)) { - $label .= '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); + $label .= '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); } if ($option == '') { @@ -3768,8 +3814,18 @@ class Propal extends CommonObject $label = $langs->trans("Proposal"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="propal-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } } $linkstart = ' Date: Wed, 1 Feb 2023 21:29:50 +0100 Subject: [PATCH 004/137] ajax tooltip on contact --- htdocs/contact/class/contact.class.php | 63 ++++++++++++++++++++++++-- htdocs/core/ajax/ajaxtooltip.php | 5 +- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 52ea2b69c8d..9d585245f0f 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1404,6 +1404,52 @@ class Contact extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowContact")]; + } + if (!empty($this->photo) && class_exists('Form')) { + $photo = '
'; + $photo .= Form::showphoto('contact', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. + $photo .= '
'; + $datas['photo'] = $photo; + } + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Contact").' ' . $this->getLibStatut(4); + $datas['name'] = '
'.$langs->trans("Name").': '.$this->getFullName($langs); + // if ($this->civility_id) $datas['civility'] = '
' . $langs->trans("Civility") . ': '.$this->civility_id; // TODO Translate civilty_id code + if (!empty($this->poste)) { + $datas['job'] = '
'.$langs->trans("Poste").': '.$this->poste; + } + $datas['email'] = '
'.$langs->trans("EMail").': '.$this->email; + $phonelist = array(); + $country_code = empty($this->country_code) ? '': $this->country_code; + if ($this->phone_pro) { + $phonelist[] = dol_print_phone($this->phone_pro, $country_code, $this->id, 0, '', ' ', 'phone'); + } + if ($this->phone_mobile) { + $phonelist[] = dol_print_phone($this->phone_mobile, $country_code, $this->id, 0, '', ' ', 'mobile'); + } + if ($this->phone_perso) { + $phonelist[] = dol_print_phone($this->phone_perso, $country_code, $this->id, 0, '', ' ', 'phone'); + } + $datas['phonelist'] = '
'.$langs->trans("Phone").': '.implode(' ', $phonelist); + $datas['address'] = '
'.$langs->trans("Address").': '.dol_format_address($this, 1, ' ', $langs); + + return $datas; + } + /** * Return name of contact with link (and eventually picto) * Use $this->id, $this->lastname, $this->firstname, this->civility_id @@ -1421,7 +1467,8 @@ class Contact extends CommonObject { global $conf, $langs, $hookmanager; - $result = ''; $label = ''; + $result = ''; + $label = ''; if (!empty($this->photo) && class_exists('Form')) { $label .= '
'; $label .= Form::showphoto('contact', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. @@ -1472,8 +1519,18 @@ class Contact extends CommonObject $label = $langs->trans("ShowContact"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="contact-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } $linkstart = ' Date: Wed, 1 Feb 2023 21:57:45 +0100 Subject: [PATCH 005/137] ajax tooltip on thirdparty --- htdocs/societe/class/societe.class.php | 148 ++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index fa6d77ad485..8cd49efe0b6 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2597,6 +2597,140 @@ class Societe extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $langs->loadLangs(['companies, commercial']); + + $datas = []; + + $option = $params['option'] ?? ''; + $name = $this->name; + + if (!empty($this->name_alias) && empty($noaliasinname)) { + $name .= ' ('.$this->name_alias.')'; + } + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowCompany")]; + } + + $label = ''; + $label2 = ''; + + if (!empty($this->logo) && class_exists('Form')) { + $photo = '
'; + $photo .= Form::showphoto('societe', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. + $photo .= '
'; + $datas['photo'] = $photo; + } elseif (!empty($this->logo_squarred) && class_exists('Form')) { + /*$label.= '
'; + $label.= Form::showphoto('societe', $this, 0, 40, 0, 'photowithmargin', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. + $label.= '
';*/ + } + + $datas['divopen'] = '
'; + + if ($option == 'customer' || $option == 'compta' || $option == 'category') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Customer").''; + } elseif ($option == 'prospect' && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Prospect").''; + } elseif ($option == 'supplier' || $option == 'category_supplier') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Supplier").''; + } elseif ($option == 'agenda') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; + } elseif ($option == 'project') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; + } elseif ($option == 'margin') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; + } elseif ($option == 'contact') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; + } elseif ($option == 'ban') { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; + } + + // By default + if (empty($datas['picto'] )) { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; + } + if (isset($this->status)) { + $datas['status'] = ' '.$this->getLibStatut(5); + } + if (isset($this->client) && isset($this->fournisseur)) { + $datas['type'] = '   ' . $this->getTypeUrl(1); + } + + $datas['name'] = '
'.$langs->trans('Name').': '.dol_escape_htmltag($this->name); + if (!empty($this->name_alias)) { + $datas['namealias'] = ' ('.dol_escape_htmltag($this->name_alias).')'; + } + + if ($this->email) { + $datas['email'] = '
'.img_picto('', 'email', 'class="pictofixedwidth"').$this->email; + } + if (!empty($this->phone) || !empty($this->fax)) { + $phonelist = array(); + if ($this->phone) { + $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', ' ', 'phone'); + } + if ($this->fax) { + $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', ' ', 'fax'); + } + $datas['phonelist'] = '
'.implode(' ', $phonelist); + } + + if (!empty($this->address)) { + $datas['address'] = '
'.$langs->trans("Address").': '.dol_format_address($this, 1, ' ', $langs); // Address + country + } elseif (!empty($this->country_code)) { + $datas['address'] = '
'.$langs->trans('Country').': '.$this->country_code; + } + if (!empty($this->tva_intra) || (!empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP) && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) { + $datas['vatintra'] = '
'.$langs->trans('VATIntra').': '.dol_escape_htmltag($this->tva_intra); + } + + if (!empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP)) { + if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false && $langs->trans('ProfId1'.$this->country_code) != '-') { + $datas['profid1'] = '
'.$langs->trans('ProfId1'.$this->country_code).': '.$this->idprof1; + } + if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false && $langs->trans('ProfId2'.$this->country_code) != '-') { + $datas['profid2'] = '
'.$langs->trans('ProfId2'.$this->country_code).': '.$this->idprof2; + } + if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false && $langs->trans('ProfId3'.$this->country_code) != '-') { + $datas['profid3'] = '
'.$langs->trans('ProfId3'.$this->country_code).': '.$this->idprof3; + } + if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false && $langs->trans('ProfId4'.$this->country_code) != '-') { + $datas['profid4'] = '
'.$langs->trans('ProfId4'.$this->country_code).': '.$this->idprof4; + } + if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false && $langs->trans('ProfId5'.$this->country_code) != '-') { + $datas['profid5'] = '
'.$langs->trans('ProfId5'.$this->country_code).': '.$this->idprof5; + } + if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false && $langs->trans('ProfId6'.$this->country_code) != '-') { + $datas['profid6'] = '
'.$langs->trans('ProfId6'.$this->country_code).': '.$this->idprof6; + } + } + if (!empty($this->code_client) && ($this->client == 1 || $this->client == 3)) { + $datas['customercode'] = '
'.$langs->trans('CustomerCode').': '.$this->code_client; + } + if (!empty($this->code_fournisseur) && $this->fournisseur) { + $datas['suppliercode'] = '
'.$langs->trans('SupplierCode').': '.$this->code_fournisseur; + } + if (isModEnabled('accounting') && ($this->client == 1 || $this->client == 3)) { + $datas['accountancycustomercode'] = '
'.$langs->trans('CustomerAccountancyCode').': '.($this->code_compta ? $this->code_compta : $this->code_compta_client); + } + if (isModEnabled('accounting') && $this->fournisseur) { + $datas['accountancysuppliercode'] = '
'.$langs->trans('SupplierAccountancyCode').': '.$this->code_compta_fournisseur; + } + + $datas['divclose'] = '
'; + + return $datas; + } /** * Return a link on thirdparty (with picto) @@ -2787,8 +2921,18 @@ class Societe extends CommonObject $label = $langs->trans("ShowCompany"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip refurl valignmiddle"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="societe-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip refurl valignmiddle"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip refurl valignmiddle"'; + } $target_value = array('_self', '_blank', '_parent', '_top'); if (in_array($target, $target_value)) { $linkclose .= ' target="'.dol_escape_htmltag($target).'"'; From 29d1197cbb73c5f98f06777aeb0fc4e40fcb2f1f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 1 Feb 2023 21:03:52 +0000 Subject: [PATCH 006/137] Fixing style errors. --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 8cd49efe0b6..9481fb52e3f 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2656,7 +2656,7 @@ class Societe extends CommonObject } // By default - if (empty($datas['picto'] )) { + if (empty($datas['picto'])) { $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ThirdParty").''; } if (isset($this->status)) { From 2df357c7c2e3987380e75a88a8e381803b411a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 1 Feb 2023 22:28:29 +0100 Subject: [PATCH 007/137] do not use cache for thirdparty in order list --- htdocs/commande/list.php | 6 +++++- htdocs/societe/class/societe.class.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 119d88e7cf4..9c06f86e8c3 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -2077,7 +2077,11 @@ if ($resql) { // Third party if (!empty($arrayfields['s.nom']['checked'])) { print ''; - print $getNomUrl_cache[$obj->socid]; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + print $companystatic->getNomUrl(1, 'customer', 100, 0, 1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1); + } else { + print $getNomUrl_cache[$obj->socid]; + } // If module invoices enabled and user with invoice creation permissions if (isModEnabled('facture') && !empty($conf->global->ORDER_BILLING_ALL_CUSTOMER)) { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 9481fb52e3f..13da1bd6c03 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2927,7 +2927,7 @@ class Societe extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="societe-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' id="' . uniqid('societe-') . '" title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip refurl valignmiddle"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; From e96cafa952b4e9e4384c5a3434c7f2a8e10c181a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 11:03:08 +0100 Subject: [PATCH 008/137] add ajaxtooltip on member type --- .../adherents/class/adherent_type.class.php | 35 +++++++++++++++++-- htdocs/core/ajax/ajaxtooltip.php | 9 ++++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index f5a5a8933d0..639f417bb94 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -688,6 +688,27 @@ class AdherentType extends CommonObject //return $morphy; } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $datas = []; + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("MemberType").' '.$this->getLibStatut(4); + $datas['label'] = '
'.$langs->trans("Label").': '.$this->label; + if (isset($this->subscription)) { + $datas['subscription'] = '
'.$langs->trans("SubscriptionRequired").': '.yn($this->subscription); + } + + return $datas; + } + /** * Return clicable name (with picto eventually) * @@ -725,8 +746,16 @@ class AdherentType extends CommonObject $url .= '&save_lastsearch_values=1'; } } - - $linkstart = '
'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkstart = ''; + } else { + $linkstart = ''; + } $linkend = ''; $result .= $linkstart; @@ -741,7 +770,6 @@ class AdherentType extends CommonObject return $result; } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return label of status (activity, closed) * @@ -753,6 +781,7 @@ class AdherentType extends CommonObject return $this->LibStatut($this->status, $mode); } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return the label of a given status * diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index 516794896dc..e52d3cfd3d9 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -141,7 +141,6 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { // Generic case for $classfile and $classname $classfile = strtolower($myobject); $classname = ucfirst($myobject); -// print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname." classpath=".$classpath."\n"; if ($objecttype == 'invoice_supplier') { $classfile = 'fournisseur.facture'; @@ -171,9 +170,17 @@ if ($objecttype == 'invoice_supplier') { $classpath = 'comm/mailing/class'; $classfile = 'mailing'; $classname = 'Mailing'; +} elseif ($objecttype == 'adherent_type') { + $langs->load('members'); + $classpath = 'adherents/class'; + $classfile = 'adherent_type'; + $module = 'adherent'; + $myobject = 'adherent_type'; + $classname = 'AdherentType'; } elseif ($objecttype == 'contact') { $module = 'societe'; } +// print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname." classpath=".$classpath."\n"; if (isModEnabled($module)) { $res = dol_include_once('/'.$classpath.'/'.$classfile.'.class.php'); From 1e305c4f860a3d0ae262b40fff0a4657182bfd0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 20:53:26 +0100 Subject: [PATCH 009/137] add ajax tooltip on member --- htdocs/adherents/class/adherent.class.php | 61 ++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index a9db33b9980..dd7fe7f33b5 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2250,6 +2250,53 @@ class Adherent extends CommonObject return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code); } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $langs->load("users"); + return ['optimize' => $langs->trans("ShowUser")]; + } + if (!empty($this->photo)) { + $photo = '
'; + $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1); + $photo .= '
'; + $datas['photo'] = $photo; + //$label .= '
'; + } + + $datas['divopen'] = '
'; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Member").' '.$this->getLibStatut(4); + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->login)) { + $datas['login'] = '
'.$langs->trans('Login').': '.$this->login; + } + if (!empty($this->firstname) || !empty($this->lastname)) { + $datas['name'] = '
'.$langs->trans('Name').': '.$this->getFullName($langs); + } + if (!empty($this->company)) { + $datas['company'] = '
'.$langs->trans('Company').': '.$this->company; + } + if (!empty($this->email)) { + $datas['email'] = '
'.$langs->trans("EMail").': '.$this->email; + } + $datas['address'] = '
'.$langs->trans("Address").': '.dol_format_address($this, 1, ' ', $langs); + $datas['divclose'] = '
'; + + return $datas; + } + /** * Return clicable name (with picto eventually) * @@ -2324,8 +2371,18 @@ class Adherent extends CommonObject $label = $langs->trans("ShowUser"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="' . uniqid('member') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } $linkstart .= $linkclose.'>'; From a367fd24b7bb9df02b37ae469d522e1e7a7372e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 21:16:09 +0100 Subject: [PATCH 010/137] add ajax tooltip on account --- htdocs/compta/bank/class/account.class.php | 49 ++++++++++++++++++++-- htdocs/core/ajax/ajaxtooltip.php | 7 +++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index e144677832f..b72767fdcc4 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -9,7 +9,7 @@ * Copyright (C) 2015-2017 Alexandre Spangaro * Copyright (C) 2016 Ferran Marcet * Copyright (C) 2019 JC Prieto - * Copyright (C) 2022 Frédéric France + * Copyright (C) 2022-2023 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 @@ -1367,6 +1367,40 @@ class Account extends CommonObject return $nb; } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $langs; + include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; + + $datas = []; + + $pictos = img_picto('', $this->picto).' '.$langs->trans("BankAccount").''; + if (isset($this->status)) { + $pictos .= ' '.$this->getLibStatut(5); + } + $datas['picto'] = $pictos; + $datas['label'] = '
'.$langs->trans('Label').': '.$this->label; + $datas['accountnumber'] = '
'.$langs->trans('AccountNumber').': '.$this->number; + $datas['iban'] = '
'.$langs->trans('IBAN').': '.getIbanHumanReadable($this); + $datas['bic'] = '
'.$langs->trans('BIC').': '.$this->bic; + $datas['accountcurrency'] = '
'.$langs->trans("AccountCurrency").': '.$this->currency_code; + + if (isModEnabled('accounting')) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + $langs->load("accountancy"); + $datas['accountaccounting'] = '
'.$langs->trans('AccountAccounting').': '.length_accountg($this->account_number); + $datas['accountancyjournal'] = '
'.$langs->trans('AccountancyJournal').': '.$this->accountancy_journal; + } + + return $datas; + } + /** * Return clicable name (with picto eventually) * @@ -1403,8 +1437,17 @@ class Account extends CommonObject $label .= '
'.$langs->trans('AccountAccounting').': '.length_accountg($this->account_number); $label .= '
'.$langs->trans('AccountancyJournal').': '.$this->accountancy_journal; } - - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose = '" data-params='.json_encode($params).' id="' . uniqid('member') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip"'; + } else { + $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + } $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id; if ($mode == 'transactions') { diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index e52d3cfd3d9..2656a788631 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -75,6 +75,11 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'compta/facture/class'; $module = 'facture'; $myobject = 'facture'; +} elseif ($objecttype == 'bank_account') { + $langs->loadLangs(['banks', 'compta']); + $classpath = 'compta/bank/class'; + $module = 'banque'; + $myobject = 'account'; } elseif ($objecttype == 'commande' || $objecttype == 'order') { $langs->load('orders'); $classpath = 'commande/class'; @@ -180,7 +185,7 @@ if ($objecttype == 'invoice_supplier') { } elseif ($objecttype == 'contact') { $module = 'societe'; } -// print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname." classpath=".$classpath."\n"; +// print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname." classpath=".$classpath."
"; if (isModEnabled($module)) { $res = dol_include_once('/'.$classpath.'/'.$classfile.'.class.php'); From a5b1f8c20e2095eebca96952ce43b771f0d66336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 21:29:23 +0100 Subject: [PATCH 011/137] add ajax tooltip on bom --- htdocs/bom/class/bom.class.php | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index d7982a44069..2bbd1759453 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -16,7 +16,7 @@ */ /** - * \file bom/class/bom.class.php + * \file htdocs/bom/class/bom.class.php * \ingroup bom * \brief This file is a CRUD class file for BOM (Create/Read/Update/Delete) */ @@ -1064,6 +1064,43 @@ class BOM extends CommonObject return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'BOM_REOPEN'); } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $langs->load('mrp'); + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowBillOfMaterials")]; + } + $picto = img_picto('', $this->picto).' '.$langs->trans("BillOfMaterials").''; + if (isset($this->status)) { + $picto .= ' '.$this->getLibStatut(5); + } + $datas['picto'] = $picto; + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + if (isset($this->label)) { + $datas['label'] = '
'.$langs->trans('Label').': '.$this->label; + } + if (!empty($this->fk_product) && $this->fk_product > 0) { + include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $product = new Product($this->db); + $resultFetch = $product->fetch($this->fk_product); + if ($resultFetch > 0) { + $datas['product'] = "
".$langs->trans("Product").': '.$product->ref.' - '.$product->label; + } + } + + return $datas; + } /** * Return a link to the object card (with optionaly the picto) @@ -1123,8 +1160,18 @@ class BOM extends CommonObject $label = $langs->trans("ShowBillOfMaterials"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="' . uniqid('bom') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } From 9f365ac568a447387e690ef175c25be55ddf7f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 21:35:40 +0100 Subject: [PATCH 012/137] add ajax tooltip on modulebuilder --- .../template/class/myobject.class.php | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index c988da72b3f..1ae0991b5f2 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2023 Frédéric France * Copyright (C) ---Put here your own copyright and developer email--- * * This program is free software; you can redistribute it and/or modify @@ -750,6 +751,30 @@ class MyObject extends CommonObject return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN'); } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowMyObject")]; + } + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("MyObject").''; + if (isset($this->status)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['ref'] .= '
'.$langs->trans('Ref').': '.$this->ref; + + return $datas; + } + /** * Return a link to the object card (with optionaly the picto) * @@ -796,8 +821,18 @@ class MyObject extends CommonObject $label = $langs->trans("ShowMyObject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' id="propal-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } From ba2f87d307c4cb52091acc5e64a5d5ce93f22517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 21:57:34 +0100 Subject: [PATCH 013/137] add ajax tooltip on contract --- htdocs/bom/class/bom.class.php | 2 +- htdocs/contrat/class/contrat.class.php | 90 +++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 2bbd1759453..d96274ede59 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1074,7 +1074,7 @@ class BOM extends CommonObject { global $conf, $langs, $user; - $langs->load('mrp'); + $langs->loadLangs(['product', 'mrp']); $datas = []; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index ad2cbcea84b..66b7bd083bf 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -9,7 +9,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018-2023 Frédéric France * Copyright (C) 2015-2018 Ferran Marcet * * This program is free software; you can redistribute it and/or modify @@ -185,6 +185,7 @@ class Contrat extends CommonObject public $nbofserviceswait; public $nbofservicesopened; public $nbofservicesexpired; + public $nbofservicesclosed; //public $lower_planned_end_date; //public $higher_planner_end_date; @@ -1981,6 +1982,42 @@ class Contrat extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $datas = []; + + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowContract")]; + } + if ($user->hasRight('contrat', 'lire')) { + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Contract").''; + /* Status of a contract is status of all services, so disabled + if (isset($this->statut)) { + $label .= ' '.$this->getLibStatut(5); + }*/ + $datas['ref'] = '
'.$langs->trans('Ref').': '.($this->ref ? $this->ref : $this->id); + $datas['refcustomer'] = '
'.$langs->trans('RefCustomer').': '. $this->ref_customer; + $datas['refsupplier'] = '
'.$langs->trans('RefSupplier').': '.$this->ref_supplier; + if (!empty($this->total_ht)) { + $datas['amountht'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['vatamount'] = '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['amounttc'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + } + return $datas; + } /** * Return clicable name (with picto eventually) @@ -2013,7 +2050,7 @@ class Contrat extends CommonObject $label = ''; - if ($user->rights->contrat->lire) { + if ($user->hasRight('contrat', 'lire')) { $label = img_picto('', $this->picto).' '.$langs->trans("Contract").''; /* Status of a contract is status of all services, so disabled if (isset($this->statut)) { @@ -2037,11 +2074,20 @@ class Contrat extends CommonObject $linkclose = ''; if (empty($notooltip) && $user->rights->contrat->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $label = $langs->trans("ShowOrder"); + $label = $langs->trans("ShowContract"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $linkclose .= '" data-params='.json_encode($params).' id="' . uniqid('contract') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } } $linkstart = 'trans("ShowContractOfService").': '.$this->label; + if (empty($datas['label'])) { + $datas['label'] = $this->description; + } + + return $datas; + } + + /** + * Return clicable name (with picto eventually) for ContratLigne * * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param int $maxlength Max length @@ -3087,8 +3152,17 @@ class ContratLigne extends CommonObjectLine if (empty($label)) { $label = $this->description; } - - $link = ''; + $link = ''; + } $linkend = ''; $picto = 'service'; From ffa9e1e52f20a4c3864cd91ed7ae3be311037ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 22:23:43 +0100 Subject: [PATCH 014/137] add ajax tooltip on categories --- htdocs/categories/class/categorie.class.php | 38 +++++++++++++++++++-- htdocs/core/ajax/ajaxtooltip.php | 7 +++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 4d6e3e1736f..5dcad42d936 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -10,7 +10,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Charlie Benke - * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2018-2023 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 @@ -1597,6 +1597,23 @@ class Categorie extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $datas = []; + + $datas['label'] = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label); + + return $datas; + } + /** * Return name and link of category (with picto) * Use ->id, ->ref, ->label, ->color @@ -1622,7 +1639,22 @@ class Categorie extends CommonObject } } - $link = ''; + $link = ''; + $link2 .= '" data-params='.json_encode($params).' id="' . uniqid('category') . '" title="' . $langs->trans('Loading') . '"'; + $link2 .= ' class="classforajaxtooltip '.$forced_color.'">'; + } else { + $link .= '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip '.$forced_color.'">'; + $link2 = $link; + } $linkend = ''; $picto = 'category'; @@ -1635,7 +1667,7 @@ class Categorie extends CommonObject $result .= ' '; } if ($withpicto != 2) { - $result .= $link.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend; + $result .= $link2.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend; } global $action; $hookmanager->initHooks(array($this->element . 'dao')); diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index 2656a788631..ae4f17246d1 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -75,11 +75,16 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'compta/facture/class'; $module = 'facture'; $myobject = 'facture'; -} elseif ($objecttype == 'bank_account') { +} elseif ($objecttype == 'bank_accoun') { $langs->loadLangs(['banks', 'compta']); $classpath = 'compta/bank/class'; $module = 'banque'; $myobject = 'account'; +} elseif ($objecttype == 'category') { + $langs->loadLangs(['categories']); + $classpath = 'categories/class'; + $module = 'categorie'; + $myobject = 'categorie'; } elseif ($objecttype == 'commande' || $objecttype == 'order') { $langs->load('orders'); $classpath = 'commande/class'; From 41dd574b1623974225e9f070d65cd0f0045f5602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 22:59:54 +0100 Subject: [PATCH 015/137] clean js --- htdocs/adherents/class/adherent.class.php | 2 +- htdocs/adherents/class/adherent_type.class.php | 2 +- htdocs/bom/class/bom.class.php | 2 +- htdocs/categories/class/categorie.class.php | 8 ++------ htdocs/comm/propal/class/propal.class.php | 2 +- htdocs/commande/class/commande.class.php | 2 +- htdocs/compta/bank/class/account.class.php | 2 +- htdocs/contact/class/contact.class.php | 2 +- htdocs/contrat/class/contrat.class.php | 4 ++-- htdocs/core/js/lib_foot.js.php | 4 ++-- htdocs/modulebuilder/template/class/myobject.class.php | 2 +- htdocs/product/class/product.class.php | 2 +- htdocs/societe/class/societe.class.php | 2 +- htdocs/user/class/user.class.php | 2 +- 14 files changed, 17 insertions(+), 21 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index dd7fe7f33b5..4dffa624719 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2377,7 +2377,7 @@ class Adherent extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="' . uniqid('member') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 639f417bb94..5543a6e8e76 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -752,7 +752,7 @@ class AdherentType extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkstart = ''; + $linkstart = ''; } else { $linkstart = ''; } diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index d96274ede59..39fcb1650f0 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1166,7 +1166,7 @@ class BOM extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="' . uniqid('bom') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5dcad42d936..618a31df34f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1646,14 +1646,10 @@ class Categorie extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $link2 = $link; - $link .= '" data-params='.json_encode($params).' id="' . uniqid('category') . '" title="' . $langs->trans('Loading') . '"'; + $link .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $link .= ' class="classforajaxtooltip '.$forced_color.'">'; - $link2 .= '" data-params='.json_encode($params).' id="' . uniqid('category') . '" title="' . $langs->trans('Loading') . '"'; - $link2 .= ' class="classforajaxtooltip '.$forced_color.'">'; } else { $link .= '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip '.$forced_color.'">'; - $link2 = $link; } $linkend = ''; @@ -1667,7 +1663,7 @@ class Categorie extends CommonObject $result .= ' '; } if ($withpicto != 2) { - $result .= $link2.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend; + $result .= $link.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend; } global $action; $hookmanager->initHooks(array($this->element . 'dao')); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index dba4e0e84d6..0876b3ea6d6 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3820,7 +3820,7 @@ class Propal extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="propal-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 16f22c80c91..f14989ab3ea 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3843,7 +3843,7 @@ class Commande extends CommonOrder 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="order-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index b72767fdcc4..ed44d13dfae 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1443,7 +1443,7 @@ class Account extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose = '" data-params='.json_encode($params).' id="' . uniqid('member') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose = '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip"'; } else { $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 9d585245f0f..c6bf780be8b 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1525,7 +1525,7 @@ class Contact extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="contact-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 66b7bd083bf..b3da9b1ad49 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2082,7 +2082,7 @@ class Contrat extends CommonObject 'id' => $this->id, 'objecttype' => $this->element, ]; - $linkclose .= '" data-params='.json_encode($params).' id="' . uniqid('contract') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; @@ -3158,7 +3158,7 @@ class ContratLigne extends CommonObjectLine 'id' => $this->fk_contrat, 'objecttype' => $this->element, ]; - $link .= '" data-params='.json_encode($params).' id="' . uniqid('contract') . '" title="' . $langs->trans('Loading') . '"'; + $link .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $link .= ' class="classforajaxtooltip"'; } else { $link = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index 7ec398f3368..8efda4e3812 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -84,7 +84,7 @@ if (empty($conf->dol_no_mouse_hover)) { hide: { delay: 250, duration: 20 }, tooltipClass: "mytooltip", open: function (event, ui) { - var id = $(this).attr("id"); + var elem = $(this); var params = $(this).attr("data-params"); $.ajax({ url:"' . dol_buildpath('/core/ajax/ajaxtooltip.php', 1) . '", @@ -92,7 +92,7 @@ if (empty($conf->dol_no_mouse_hover)) { data: JSON.parse(params), success: function(response){ // Setting content option - $("#"+id).tooltip("option","content",response); + elem.tooltip("option","content",response); } }); console.log(event); diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 1ae0991b5f2..3fd978e2069 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -827,7 +827,7 @@ class MyObject extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="propal-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index ab9d33a0500..e585d35ebae 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5231,7 +5231,7 @@ class Product extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="product-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="nowraponall classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 13da1bd6c03..269bae466bd 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2927,7 +2927,7 @@ class Societe extends CommonObject 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="' . uniqid('societe-') . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip refurl valignmiddle"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 0a963da1f5d..1516769f387 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2977,7 +2977,7 @@ class User extends CommonObject 'infologin' => $infologin, 'option' => $option, ]; - $linkclose .= ' data-params='.json_encode($params).' id="user-' . uniqid() . '" title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; From 22fb5a4e6a8d1930cf8ebc2034e29adb2e026291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 23:12:54 +0100 Subject: [PATCH 016/137] add ajax tooltip on delivery --- htdocs/delivery/class/delivery.class.php | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 3b560ce1026..717696ac430 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -720,6 +720,24 @@ class Delivery extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $datas = []; + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ShowReceiving").':
'; + $datas['picto'] .= ''.$langs->trans("Status").': '.$this->ref; + + return $datas; + } + /** * Return clicable name (with picto eventually) * @@ -750,8 +768,16 @@ class Delivery extends CommonObject } //} - - $linkstart = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $linkstart = ''; + } $linkend = ''; if ($withpicto) { From a4a541a146f52f0b1daaafddc4c8a03f04bae897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 23:19:55 +0100 Subject: [PATCH 017/137] add ajax tooltip on delivery --- htdocs/core/ajax/ajaxtooltip.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index ae4f17246d1..93244c89050 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -75,7 +75,7 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'compta/facture/class'; $module = 'facture'; $myobject = 'facture'; -} elseif ($objecttype == 'bank_accoun') { +} elseif ($objecttype == 'bank_account') { $langs->loadLangs(['banks', 'compta']); $classpath = 'compta/bank/class'; $module = 'banque'; @@ -205,7 +205,6 @@ if (isModEnabled($module)) { } unset($object); } else { - print "Class with classname ".$classname." is unknown even after the include"; dol_syslog("Class with classname ".$classname." is unknown even after the include", LOG_ERR); } } From a32a0cc25a3164726a83f32b6edd40e5ab43972e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 2 Feb 2023 23:28:09 +0100 Subject: [PATCH 018/137] add ajax tooltip on warehouse --- htdocs/product/stock/class/entrepot.class.php | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 3ce244a4bb1..080abfa6605 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -689,6 +689,32 @@ class Entrepot extends CommonObject } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + $langs->load('stocks'); + $datas = []; + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("Warehouse")]; + } + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Warehouse").''; + if (isset($this->statut)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['ref'] .= '
'.$langs->trans('Ref').': '.(empty($this->ref) ? $this->label : $this->ref); + if (!empty($this->lieu)) { + $datas['locationsummary'] .= '
'.$langs->trans('LocationSummary').': '.$this->lieu; + } + + return $datas; + } + /** * Return clickable name (possibility with the pictogram) * @@ -743,8 +769,18 @@ class Entrepot extends CommonObject $label = $langs->trans("Warehouse"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } } $linkstart = ' Date: Thu, 2 Feb 2023 23:47:01 +0100 Subject: [PATCH 019/137] add ajax tooltip on actioncomm --- htdocs/comm/action/class/actioncomm.class.php | 83 ++++++++++++++++++- htdocs/core/ajax/ajaxtooltip.php | 5 ++ htdocs/product/stock/class/entrepot.class.php | 1 - 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index af98356ab18..23a6b5a67c5 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2011-2017 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2018-2023 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 @@ -1568,6 +1568,73 @@ class ActionComm extends CommonObject return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode); } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + $langs->load('agenda'); + $datas = []; + + // Set label of type + $labeltype = ''; + if ($this->type_code) { + $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label; + } + if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) { + if ($this->type_code != 'AC_OTH_AUTO') { + $labeltype = $langs->trans('ActionAC_MANUAL'); + } + } + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans('Action').''; + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.dol_escape_htmltag($this->ref); + } + if (!empty($this->label)) { + $datas['title'] = '
'.$langs->trans('Title').': '.dol_escape_htmltag($this->label); + } + if (!empty($labeltype)) { + $datas['labeltype'] = '
'.$langs->trans('Type').': '.dol_escape_htmltag($labeltype); + } + if (!empty($this->location)) { + $datas['location'] = '
'.$langs->trans('Location').': '.dol_escape_htmltag($this->location); + } + if (isset($this->transparency)) { + $datas['transparency'] = '
'.$langs->trans('Busy').': '.yn($this->transparency); + } + if (!empty($this->email_msgid)) { + $langs->load("mails"); + $datas['space'] = '
'; + // $datas['email'] = '
'.img_picto('', 'email').' '.$langs->trans("Email").''; + $datas['mailtopic'] = '
'.$langs->trans('MailTopic').': '.dol_escape_htmltag($this->email_subject); + $datas['mailfrom'] = '
'.$langs->trans('MailFrom').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_from); + $datas['mailto'] = '
'.$langs->trans('MailTo').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_to); + if (!empty($this->email_tocc)) { + $datas['mailcc'] = '
'.$langs->trans('MailCC').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_tocc); + } + /* Disabled because bcc must remain by defintion not visible + if (!empty($this->email_tobcc)) { + $datas['mailccc'] = '
'.$langs->trans('MailCCC').': '.$this->email_tobcc; + } */ + } + if (!empty($this->note_private)) { + $datas['description'] = '
'.$langs->trans('Description').':
'; + // Try to limit length of content + $texttoshow = dolGetFirstLineOfText($this->note_private, 10); + // Restrict height of content into the tooltip + $datas['note'] = '
'; + $datas['note'] .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '
', $texttoshow)); + $datas['note'] .= '
'; + } + + return $datas; + } + /** * Return URL of event * Use $this->id, $this->type_code, $this->label and $this->type_label @@ -1668,8 +1735,18 @@ class ActionComm extends CommonObject $label = $langs->trans("ShowAction"); $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, '', 1).'"'; - $linkclose .= ' class="'.$classname.' classfortooltip"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="'.$classname.' classforajaxtooltip"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, '', 1).'"'; + $linkclose .= ' class="'.$classname.' classfortooltip"'; + } } else { $linkclose .= ' class="'.$classname.'"'; } diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index 93244c89050..84dd613d1b5 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -93,6 +93,11 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { } elseif ($objecttype == 'propal') { $langs->load('propal'); $classpath = 'comm/propal/class'; +} elseif ($objecttype == 'action') { + $langs->load('agenda'); + $classpath = 'comm/action/class'; + $module = 'agenda'; + $myobject = 'actioncomm'; } elseif ($objecttype == 'supplier_proposal') { $langs->load('supplier_proposal'); $classpath = 'supplier_proposal/class'; diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 080abfa6605..78e2ba0a173 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -688,7 +688,6 @@ class Entrepot extends CommonObject return dolGetStatus($label, $labelshort, '', $statusType, $mode); } - /** * getTooltipContentArray * @param array $params params to construct tooltip data From 140a3b462d8348db9be5884bfc1c2aa8e1fad158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 3 Feb 2023 09:29:02 +0100 Subject: [PATCH 020/137] add ajax tooltip on usergroup --- htdocs/core/ajax/ajaxtooltip.php | 4 +++ htdocs/user/card.php | 8 ++--- htdocs/user/class/usergroup.class.php | 44 +++++++++++++++++++++++++-- htdocs/user/passwordforgotten.php | 2 +- test/phpunit/AllTests.php | 2 +- 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index 84dd613d1b5..d5461b0dc1b 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -151,6 +151,10 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'product/stock/class'; $module = 'stock'; $myobject = 'productlot'; +} elseif ($objecttype == 'usergroup') { + $classpath = 'user/class'; + $module = 'user'; + $myobject = 'usergroup'; } // Generic case for $classfile and $classname diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 964f4b9a67f..f7ea29d6720 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -50,7 +50,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; -if (!empty($conf->ldap->enabled)) { +if (isModEnabled('ldap')) { require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; } if (isModEnabled('adherent')) { @@ -785,7 +785,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
"; - if (!empty($conf->ldap->enabled) && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) { + if (isModEnabled('ldap')et($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) { // Show form to add an account from LDAP if sync LDAP -> Dolibarr is set $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -1375,7 +1375,7 @@ if ($action == 'create' || $action == 'adduserldap') { // Connexion ldap // pour recuperer passDoNotExpire et userChangePassNextLogon - if (!empty($conf->ldap->enabled) && !empty($object->ldap_sid)) { + if (isModEnabled('ldap') && !empty($object->ldap_sid)) { $ldap = new Ldap(); $result = $ldap->connect_bind(); if ($result > 0) { @@ -2896,7 +2896,7 @@ if ($action == 'create' || $action == 'adduserldap') { print '
'; } - if (!empty($conf->ldap->enabled) && !empty($object->ldap_sid)) { + if (isModEnabled('ldap') && !empty($object->ldap_sid)) { $ldap->unbind(); } } diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index a9884ca59d1..327de8def0b 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2014 Alexis Algoud * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2019 Abbes Bahfir + * Copyright (C) 2023 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,7 +29,7 @@ */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; -if (!empty($conf->ldap->enabled)) { +if (isModEnabled('ldap')) { require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"; } @@ -706,6 +707,33 @@ class UserGroup extends CommonObject return ''; } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $menumanager; + + $option = $params['option'] ?? ''; + + $datas = []; + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $langs->load("users"); + return ['optimize' => $langs->trans("ShowGroup")]; + } + $datas['divopen'] = '
'; + $datas['picto'] = img_picto('', 'group').' '.$langs->trans("Group").'
'; + $datas['name'] = ''.$langs->trans('Name').': '.$this->name; + $datas['description'] = '
'.$langs->trans("Description").': '.$this->note; + $datas['divclose'] = '
'; + + return $datas; + } + /** * Return a link to the user card (with optionaly the picto) * Use this->id,this->lastname, this->firstname @@ -759,8 +787,18 @@ class UserGroup extends CommonObject $label = $langs->trans("ShowGroup"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } } $linkstart = '
ldap->enabled)) { +if (isModEnabled('ldap')) { require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; } diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 1d57db17ffc..ec419ad9987 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -41,7 +41,7 @@ if (empty($conf->adherent->enabled)) { print "Error: Module member must be enabled to have significant results.\n"; exit(1); } -if (!empty($conf->ldap->enabled)) { +if (isModEnabled('ldap')) { print "Error: LDAP module should not be enabled.\n"; exit(1); } From ba27b8c24ce97a2c2baae28c09751baec5490c55 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 3 Feb 2023 08:29:51 +0000 Subject: [PATCH 021/137] Fixing style errors. --- htdocs/user/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index f7ea29d6720..bf66b29cf5b 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -785,7 +785,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
"; - if (isModEnabled('ldap')et($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) { + if (isModEnabled('ldap')et($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR) {) // Show form to add an account from LDAP if sync LDAP -> Dolibarr is set $ldap = new Ldap(); $result = $ldap->connect_bind(); From 6ab742a530451b408b711cb11f5cee41d4355c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 3 Feb 2023 09:46:04 +0100 Subject: [PATCH 022/137] add ajax tooltip on usergroup --- htdocs/user/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index f7ea29d6720..b3d83ddb239 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -785,7 +785,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
"; - if (isModEnabled('ldap')et($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) { + if (isModEnabled('ldap') && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) { // Show form to add an account from LDAP if sync LDAP -> Dolibarr is set $ldap = new Ldap(); $result = $ldap->connect_bind(); From c2f91b2e15cec9f680041aef260d348a2b2213cd Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 3 Feb 2023 14:02:46 +0100 Subject: [PATCH 023/137] FIX attach file and send by mail in ticket --- htdocs/core/class/html.formticket.class.php | 8 ++++---- htdocs/ticket/class/ticket.class.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index cea007f8e61..cd6b9ecd7fc 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -910,7 +910,7 @@ class FormTicket $langs->loadLangs(array('other', 'mails')); // Clear temp files. Must be done at beginning, before call of triggers - if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { + if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { $this->clear_attached_files(); } @@ -943,10 +943,10 @@ class FormTicket $listofmimes = array(); $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined - if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { - if (!empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit'])) { + if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { + if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) { foreach ($this->param['fileinit'] as $file) { - $this->add_attached_files($file, basename($file), dol_mimetype($file)); + $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); } } } diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index e03bdabe617..d12df619bb0 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2454,7 +2454,7 @@ class Ticket extends CommonObject $maxheightmini = 72; $formmail = new FormMail($this->db); - + $formmail->trackid = 'tic'.$this->id; $attachedfiles = $formmail->get_attached_files(); $filepath = $attachedfiles['paths']; From 73bbf57db0032541a7d96d24cdc2418572f8716a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 4 Feb 2023 19:14:08 +0100 Subject: [PATCH 024/137] add ajax tooltip on supplier proposal --- .../class/supplier_proposal.class.php | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index f2e6d19afa8..98dc1e66af2 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -13,7 +13,7 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2016 Ferran Marcet * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2019-2022 Frédéric France + * Copyright (C) 2019-2023 Frédéric France * Copyright (C) 2020 Tobias Sekan * Copyright (C) 2022 Gauthier VERDOL * @@ -2468,6 +2468,46 @@ class SupplierProposal extends CommonObject } } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $menumanager; + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + return ['optimize' => $langs->trans("ShowSupplierProposal")]; + } + + $option = $params['option'] ?? ''; + $datas = []; + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("SupplierProposal").''; + if (isset($this->status)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->ref_fourn)) { + $datas['ref_supplier'] = '
'.$langs->trans('RefSupplier').': '.$this->ref_fourn; + } + if (!empty($this->total_ht)) { + $datas['amount_ht'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['amount_vat'] = '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['amount_ttc'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + + return $datas; + } + /** * Return clicable link of object (with eventually picto) * @@ -2534,8 +2574,18 @@ class SupplierProposal extends CommonObject $label = $langs->trans("ShowSupplierProposal"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; + $linkclose .= ' class="classforajaxtooltip"'; + } else { + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } } $linkstart = '
Date: Sat, 4 Feb 2023 21:22:30 +0100 Subject: [PATCH 025/137] fix for double tooltip --- htdocs/user/class/user.class.php | 30 ++++++++++++++------------- htdocs/user/class/usergroup.class.php | 28 +++++++++++++------------ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 053ba1359fc..26b3ad3860d 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2947,25 +2947,27 @@ class User extends CommonObject $linkstart = ' $this->id, + 'objecttype' => $this->element, + 'infologin' => $infologin, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); $label = $langs->trans("ShowUser"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'infologin' => $infologin, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams . ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } $linkstart .= $linkclose.'>'; @@ -2980,7 +2982,7 @@ class User extends CommonObject } // Only picto if ($withpictoimg > 0) { - $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1).''; + $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams.' class="paddingright '.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1).''; } else { // Picto must be a photo $picto = ''.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg == -3 ? 'small' : ''), 'mini', 0, 1).''; diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 45028ca993e..dcc5ca3bb39 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -793,24 +793,26 @@ class UserGroup extends CommonObject } $linkclose = ""; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); $label = $langs->trans("ShowGroup"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } $linkstart = 'picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.'class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->name; From 5a33e40667510b3edee0677dfa94844f28ba2ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 4 Feb 2023 21:34:48 +0100 Subject: [PATCH 026/137] fix for double tooltip --- .../template/class/myobject.class.php | 28 ++++++++++--------- htdocs/product/stock/class/entrepot.class.php | 28 ++++++++++--------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 0e17492ba80..157b8079808 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -816,23 +816,25 @@ class MyObject extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMyObject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -853,7 +855,7 @@ class MyObject extends CommonObject if (empty($this->showphoto_on_popup)) { if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } } else { if ($withpicto) { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 78e2ba0a173..deb7f8c8d52 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -763,23 +763,25 @@ class Entrepot extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Warehouse"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.'"'; } $linkstart = 'picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= (($showfullpath || !empty($conf->global->STOCK_ALWAYS_SHOW_FULL_ARBO)) ? $this->get_full_arbo() : $this->label); From 7928bfd6cff8128b53be90a8e39afaf7df90ff46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 4 Feb 2023 21:48:02 +0100 Subject: [PATCH 027/137] add ajax tooltip on societeaccount --- htdocs/societe/class/societe.class.php | 28 +++++++------- htdocs/societe/class/societeaccount.class.php | 37 ++++++++++++++++++- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index adc08af21c4..c7e0e568b39 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2916,23 +2916,25 @@ class Societe extends CommonObject $linkstart .= '"'; $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowCompany"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip refurl valignmiddle"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip refurl valignmiddle"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.' refurl valignmiddle"'; $target_value = array('_self', '_blank', '_parent', '_top'); if (in_array($target, $target_value)) { $linkclose .= ' target="'.dol_escape_htmltag($target).'"'; @@ -2951,7 +2953,7 @@ class Societe extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name); diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php index 09fee02c8a3..110f0826516 100644 --- a/htdocs/societe/class/societeaccount.class.php +++ b/htdocs/societe/class/societeaccount.class.php @@ -362,6 +362,27 @@ class SocieteAccount extends CommonObject return $this->deleteCommon($user, $notrigger); } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $langs->loadLangs(['companies, commercial']); + + $datas = []; + $option = $params['option'] ?? ''; + + $datas['picto'] = ''.$langs->trans("WebsiteAccount").''; + $datas['login'] = '
'.$langs->trans('Login').': '.$this->login; + + return $datas; + } + /** * Return a link to the object card (with optionaly the picto) * @@ -405,13 +426,25 @@ class SocieteAccount extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("WebsiteAccount"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -422,7 +455,7 @@ class SocieteAccount extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 83b4fde50c2c02914a1a6e867fff8af1447bbfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 4 Feb 2023 22:00:47 +0100 Subject: [PATCH 028/137] add ajax tooltip on salaries --- htdocs/core/ajax/ajaxtooltip.php | 3 ++ htdocs/salaries/class/salary.class.php | 52 ++++++++++++++++++++------ 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index d5461b0dc1b..a72b57c4ebe 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -198,6 +198,9 @@ if ($objecttype == 'invoice_supplier') { $classname = 'AdherentType'; } elseif ($objecttype == 'contact') { $module = 'societe'; +} elseif ($objecttype == 'salary') { + $classpath = 'salaries/class'; + $module = 'salaries'; } // print "objecttype=".$objecttype." module=".$module." subelement=".$subelement." classfile=".$classfile." classname=".$classname." classpath=".$classpath."
"; diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index 2f7bb36869e..4eb403a71a1 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -479,6 +479,25 @@ class Salary extends CommonObject } } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $langs->loadLangs(['salaries']); + + $datas = []; + $option = $params['option'] ?? ''; + $datas['picto'] = ''.$langs->trans("Salary").''; + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + + return $datas; + } /** * Send name clicable (with possibly the picto) @@ -523,29 +542,40 @@ class Salary extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMyObject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ - } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } $linkstart = '
'; $linkend = ''; $result .= $linkstart; - if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright pictofixedwidth"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip pictofixedwidth"'), 0, 0, $notooltip ? 0 : 1); - if ($withpicto != 2) $result .= $this->ref; + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright pictofixedwidth"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.' pictofixedwidth"'), 0, 0, $notooltip ? 0 : 1); + } + if ($withpicto != 2) { + $result .= $this->ref; + } $result .= $linkend; //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); From 473690f49b804fcd1a39121affc95bae11e30084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 4 Feb 2023 22:09:18 +0100 Subject: [PATCH 029/137] fix for double tooltip --- htdocs/comm/propal/class/propal.class.php | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 109cf8368e9..b3271309855 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3809,23 +3809,25 @@ class Propal extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip) && $user->rights->propal->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Proposal"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.'"'; } $linkstart = 'picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From a501ae8961ced3e3ee9871a1bc779721c4899933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 09:46:29 +0100 Subject: [PATCH 030/137] fix tooltip --- htdocs/product/class/product.class.php | 31 +++++++++++++------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e585d35ebae..4077fadeb5e 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5219,24 +5219,25 @@ class Product extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowProduct"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="nowraponall classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; - $linkclose .= ' class="nowraponall classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"'; + $linkclose .= $dataparams.' class="nowraponall '.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ' class="nowraponall'.($morecss ? ' '.$morecss : '').'"'; } @@ -5269,10 +5270,10 @@ class Product extends CommonObject $result .= $linkstart; if ($withpicto) { if ($this->type == Product::TYPE_PRODUCT) { - $result .= (img_object(($notooltip ? '' : $label), 'product', ($notooltip ? 'class="paddingright"' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1)); + $result .= (img_object(($notooltip ? '' : $label), 'product', ($notooltip ? 'class="paddingright"' : $dataparams.' class="paddingright '.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1)); } if ($this->type == Product::TYPE_SERVICE) { - $result .= (img_object(($notooltip ? '' : $label), 'service', ($notooltip ? 'class="paddingright"' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1)); + $result .= (img_object(($notooltip ? '' : $label), 'service', ($notooltip ? 'class="paddingright"' : $dataparams.' class="paddingright '.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1)); } } $result .= dol_escape_htmltag($newref); From 661c82473e677b661da0b528fe80042ddd309b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 10:00:48 +0100 Subject: [PATCH 031/137] add ajax tooltip on productlot --- .../stock/class/mouvementstock.class.php | 10 ++++- .../product/stock/class/productlot.class.php | 44 ++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 43760d808b2..2b7c1c025f1 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -46,10 +46,18 @@ class MouvementStock extends CommonObject */ public $product_id; + /** + * @var int ID warehouse + * @deprecated + * @see $warehouse_id + */ + public $entrepot_id; + /** * @var int ID warehouse */ public $warehouse_id; + public $qty; /** @@ -541,7 +549,7 @@ class MouvementStock extends CommonObject } elseif (empty($fk_product_stock)) { $fk_product_stock = $this->db->last_insert_id($this->db->prefix()."product_stock"); } - } + }entrepot_id // Update detail of stock for the lot. if (!$error && isModEnabled('productbatch') && $product->hasbatch() && !$skip_batch) { diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 649c5578fa4..890a9fbd0f6 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -585,6 +585,34 @@ class Productlot extends CommonObject } + /** + * getTooltipContentArray + * @param array $params params to construct tooltip data + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $langs->loadLangs(['stocks', 'productbatch']); + + $datas = []; + $option = $params['option'] ?? ''; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Batch").''; + $datas['divopen'] = '
'; + $datas['batch'] = ''.$langs->trans('Batch').': '.$this->batch; + if ($this->eatby && empty($conf->global->PRODUCT_DISABLE_EATBY)) { + $datas['eatby'] = '
'.$langs->trans('EatByDate').': '.dol_print_date($this->eatby, 'day'); + } + if ($this->sellby && empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + $datas['sellby'] = '
'.$langs->trans('SellByDate').': '.dol_print_date($this->sellby, 'day'); + } + $datas['divclose'] = '
'; + + return $datas; + } + /** * Return a link to the a lot card (with optionaly the picto) * Use this->id,this->lastname, this->firstname @@ -629,13 +657,25 @@ class Productlot extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMyObject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -654,7 +694,7 @@ class Productlot extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->batch; From 9ab6c3114199d22617684650d9a24a4068fddc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 14:13:20 +0100 Subject: [PATCH 032/137] fix tooltip --- htdocs/adherents/class/adherent.class.php | 28 ++++++++++--------- .../adherents/class/adherent_type.class.php | 26 +++++++++-------- .../stock/class/mouvementstock.class.php | 2 +- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 4dffa624719..d51035d500e 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2365,24 +2365,26 @@ class Adherent extends CommonObject $linkstart .= '
$this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); $label = $langs->trans("ShowUser"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } $linkstart .= $linkclose.'>'; @@ -2400,7 +2402,7 @@ class Adherent extends CommonObject // Only picto if ($withpictoimg > 0) { $picto = ''. - img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1).''; + img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams.' class="'.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1).''; } else { // Picto must be a photo $picto = ''; diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 9a27b87f249..1a8c6c7b26c 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -735,7 +735,18 @@ class AdherentType extends CommonObject $option = ''; $url = DOL_URL_ROOT.'/adherents/type.php?rowid='.((int) $this->id); - + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if ($option != 'nolink') { // Add param to save lastsearch_values or not $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); @@ -746,21 +757,12 @@ class AdherentType extends CommonObject $url .= '&save_lastsearch_values=1'; } } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkstart = ''; - } else { - $linkstart = ''; - } + $linkstart = ''; $linkend = ''; $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= ($maxlen ?dol_trunc($this->label, $maxlen) : $this->label); diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 2b7c1c025f1..2392962a500 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -549,7 +549,7 @@ class MouvementStock extends CommonObject } elseif (empty($fk_product_stock)) { $fk_product_stock = $this->db->last_insert_id($this->db->prefix()."product_stock"); } - }entrepot_id + } // Update detail of stock for the lot. if (!$error && isModEnabled('productbatch') && $product->hasbatch() && !$skip_batch) { From 8b6bb4161cc592e1433a72a986915925ef5ae6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 16:02:03 +0100 Subject: [PATCH 033/137] fix tooltip --- htdocs/bom/class/bom.class.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 553372a31f8..109e01818e4 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1155,23 +1155,25 @@ class BOM extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowBillOfMaterials"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1182,7 +1184,7 @@ class BOM extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 6e07cee3fcbf3a0c5a952ccc10e16cbe2d28de60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 17:04:26 +0100 Subject: [PATCH 034/137] fix tooltip --- htdocs/categories/class/categorie.class.php | 15 ++++---- htdocs/contact/class/contact.class.php | 30 ++++++++------- htdocs/contrat/class/contrat.class.php | 41 +++++++++++---------- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 618a31df34f..5dc7d53cc49 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1638,26 +1638,27 @@ class Categorie extends CommonObject $forced_color = 'categtextblack'; } } - - $link = ''; - } else { - $link .= '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip '.$forced_color.'">'; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); } + $link = ''; $linkend = ''; $picto = 'category'; if ($withpicto) { - $result .= ($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); + $result .= ($link.img_object($label, $picto, $dataparams.' class="'.$classfortooltip.'"').$linkend); } if ($withpicto && $withpicto != 2) { $result .= ' '; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 459c7807c43..103b8177994 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1514,23 +1514,25 @@ class Contact extends CommonObject $url .= $moreparam; $linkclose = ""; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowContact"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip'.($morecss ? ' '.$morecss : '').'"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } $linkstart = ''; + $linkstart = ''; $linkend = ''; } @@ -1547,7 +1549,7 @@ class Contact extends CommonObject if ($withpicto < 0) { $result .= ''.Form::showphoto('contact', $this, 0, 0, 0, 'userphoto'.($withpicto == -3 ? 'small' : ''), 'mini', 0, 1).''; } else { - $result .= img_object(($notooltip ? '' : $label), ( $this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ( $this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } } if ($withpicto != 2 && $withpicto != -2) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 7785a8ad3e7..981d7d71f02 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2072,31 +2072,32 @@ class Contrat extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip) && $user->rights->contrat->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowContract"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - ]; - $linkclose .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.'"'; } - $linkstart = ''; $linkend = ''; $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= ($this->ref ? $this->ref : $this->id); @@ -3152,17 +3153,19 @@ class ContratLigne extends CommonObjectLine if (empty($label)) { $label = $this->description; } - $link = ''; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); } + $link = ''; $linkend = ''; $picto = 'service'; @@ -3171,7 +3174,7 @@ class ContratLigne extends CommonObjectLine } if ($withpicto) { - $result .= ($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); + $result .= ($link.img_object($label, $picto, $dataparams.' class="'.$classfortooltip.'"').$linkend); } if ($withpicto && $withpicto != 2) { $result .= ' '; From 19631fef742d73fd7502df071a2497c080a611ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 20:41:29 +0100 Subject: [PATCH 035/137] fix tooltip --- htdocs/comm/action/class/actioncomm.class.php | 28 ++++++++++--------- htdocs/commande/class/commande.class.php | 28 ++++++++++--------- htdocs/product/class/product.class.php | 2 ++ htdocs/societe/class/societe.class.php | 7 +++-- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 23a6b5a67c5..a127cc2d3f2 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1727,6 +1727,18 @@ class ActionComm extends CommonObject $tooltip .= ''; } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) // $linkclose = ' style="background-color:#'.$this->type_color.'"'; @@ -1735,18 +1747,8 @@ class ActionComm extends CommonObject $label = $langs->trans("ShowAction"); $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="'.$classname.' classforajaxtooltip"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, '', 1).'"'; - $linkclose .= ' class="'.$classname.' classfortooltip"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, '', 1).'"'; + $linkclose .= $dataparams.' class="'.$classname.' '.$classfortooltip.'"'; } else { $linkclose .= ' class="'.$classname.'"'; } @@ -1806,7 +1808,7 @@ class ActionComm extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$label), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$label), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } $result .= dol_escape_htmltag($labelshort); $result .= $linkend; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index d5e6fff5fce..f44a545c879 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3832,23 +3832,25 @@ class Commande extends CommonOrder } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip) && $user->rights->commande->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Order"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; - } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= $dataparams.' class="'.$classfortooltip.'"'; $target_value = array('_self', '_blank', '_parent', '_top'); if (in_array($target, $target_value)) { @@ -3867,7 +3869,7 @@ class Commande extends CommonOrder $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 4077fadeb5e..00e745cff47 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5009,6 +5009,8 @@ class Product extends CommonObject { global $conf, $langs; + $langs->load('products'); + $datas = []; if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index c7e0e568b39..1541ca8e8bb 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2665,15 +2665,16 @@ class Societe extends CommonObject if (isset($this->client) && isset($this->fournisseur)) { $datas['type'] = '   ' . $this->getTypeUrl(1); } - $datas['name'] = '
'.$langs->trans('Name').': '.dol_escape_htmltag($this->name); if (!empty($this->name_alias)) { $datas['namealias'] = ' ('.dol_escape_htmltag($this->name_alias).')'; } - - if ($this->email) { + if (!empty($this->email)) { $datas['email'] = '
'.img_picto('', 'email', 'class="pictofixedwidth"').$this->email; } + if (!empty($this->url)) { + $datas['url'] = '
'.img_picto('', 'globe', 'class="pictofixedwidth"').$this->url; + } if (!empty($this->phone) || !empty($this->fax)) { $phonelist = array(); if ($this->phone) { From c0c10866e909af56003c5c347249fe6597b2b044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 20:54:18 +0100 Subject: [PATCH 036/137] fix tooltip --- htdocs/compta/bank/class/account.class.php | 12 ++++---- htdocs/core/class/commonobject.class.php | 2 +- htdocs/delivery/class/delivery.class.php | 12 ++++---- .../class/supplier_proposal.class.php | 28 ++++++++++--------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index b978d9cba56..230b0336631 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1460,17 +1460,19 @@ class Account extends CommonObject $label .= '
'.$langs->trans('AccountAccounting').': '.length_accountg($this->account_number); $label .= '
'.$langs->trans('AccountancyJournal').': '.$this->accountancy_journal; } + $classfortooltip = 'classfortooltip'; + $dataparams = ''; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { $params = [ 'id' => $this->id, 'objecttype' => $this->element, 'option' => $option, ]; - $linkclose = '" data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip"'; - } else { - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); } + $linkclose = '"'.$dataparams.' title="'.dol_escape_htmltag($label, 1).'" class="'.$classfortooltip.'">'; $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id; if ($mode == 'transactions') { @@ -1500,7 +1502,7 @@ class Account extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : ''); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e30ef60b124..f3bde4fe826 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -696,7 +696,7 @@ abstract class CommonObject } $labelextra = $langs->trans((string) $extrafields->attributes[$this->table_element]['label'][$key]); if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate') { - $datas[$key]= '
'. $labelextra . ''; + $datas[$key]= '
'. $labelextra . ''; } else { $value = $this->array_options['options_' . $key]; $datas[$key]= '
'. $labelextra . ': ' . $extrafields->showOutputField($key, $value, '', $this->table_element); diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 717696ac430..525d5458891 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -768,20 +768,22 @@ class Delivery extends CommonObject } //} + $classfortooltip = 'classfortooltip'; + $dataparams = ''; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { $params = [ 'id' => $this->id, 'objecttype' => $this->element, ]; - $linkstart = ''; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); } + $linkstart = ''; $linkend = ''; if ($withpicto) { - $result .= ($linkstart.img_object($label, $this->picto, 'class="classfortooltip"').$linkend); + $result .= ($linkstart.img_object($label, $this->picto, $dataparams.' class="'.$classfortooltip.'"').$linkend); } if ($withpicto && $withpicto != 2) { $result .= ' '; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 98dc1e66af2..db3070f8b8d 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2569,23 +2569,25 @@ class SupplierProposal extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip) && $user->rights->propal->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowSupplierProposal"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $linkclose .= ' data-params='.json_encode($params).' title="' . $langs->trans('Loading') . '"'; - $linkclose .= ' class="classforajaxtooltip"'; - } else { - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; - } + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.'"'; } $linkstart = 'picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 1ad1889d98125dacfc3768b41ea2964240c36381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 21:06:30 +0100 Subject: [PATCH 037/137] fix tooltip --- htdocs/compta/bank/class/account.class.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 230b0336631..7032f9c40e2 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -244,6 +244,20 @@ class Account extends CommonObject */ public $date_solde; + /** + * Balance. Used in Account::create + * @var float + * @deprecated + * @see $balance + */ + public $solde; + + /** + * Balance. Used in Account::create + * @var float + */ + public $balance; + /** * Creditor Identifier CI. Some banks use different ICS for direct debit and bank tranfer * @var string From b7b4737ef8228fe1c789ce98205e15b5c7a82828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 21:28:27 +0100 Subject: [PATCH 038/137] add ajax tooltip on holidays --- htdocs/holiday/class/holiday.class.php | 40 +++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index e4a82be6ea7..dc4e09d6fe9 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2012-2016 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2016 Juanjo Menent - * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018-2023 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 @@ -1299,6 +1299,28 @@ class Holiday extends CommonObject return $result; } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('holiday'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Holiday").''; + if (isset($this->statut)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['label'] = '
'.$langs->trans('Ref').': '.$this->ref; + + return $datas; + } /** * Return clicable name (with picto eventually) @@ -1333,13 +1355,23 @@ class Holiday extends CommonObject $url .= '&save_lastsearch_values=1'; } //} - - $linkstart = '
'; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } + $linkstart = ''; $linkend = ''; $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 1e0125540a5eb0b70f6b3ab1f18874e9d32356aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 21:43:18 +0100 Subject: [PATCH 039/137] add ajax tooltip on invoices --- htdocs/compta/facture/class/facture.class.php | 84 ++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 75869a900dd..ed2c729b424 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1766,6 +1766,71 @@ class Facture extends CommonInvoice return $deposit; } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $mysoc, $user; + + $langs->load('bills'); + + $datas = []; + $moretitle = $params['moretitle'] ?? ''; + $picto = $this->picto; + if ($this->type == self::TYPE_REPLACEMENT) { + $picto .= 'r'; // Replacement invoice + } + if ($this->type == self::TYPE_CREDIT_NOTE) { + $picto .= 'a'; // Credit note + } + if ($this->type == self::TYPE_DEPOSIT) { + $picto .= 'd'; // Deposit invoice + } + + if ($user->hasRight("facture", "read")) { + $datas['picto'] = img_picto('', $picto).' '.$langs->trans("Invoice").''; + if (isset($this->statut) && isset($this->alreadypaid)) { + $datas['picto'] .= ' '.$this->getLibStatut(5, $this->alreadypaid); + } + $datas['picto'] .= ' '.$this->getLibType(1); + if ($moretitle) { + $datas['picto'] = ' - '.$moretitle; + } + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->ref_customer)) { + $datas['refcustomer'] = '
'.$langs->trans('RefCustomer').': '.$this->ref_customer; + } + if (!empty($this->date)) { + $datas['date'] = '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); + } + if (!empty($this->total_ht)) { + $datas['amountht'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['amountvat'] = '
'.$langs->trans('AmountVAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) { + // We keep test != 0 because $this->total_localtax1 can be '0.00000000' + $datas['amountlt1'] = '
'.$langs->transcountry('AmountLT1', $mysoc->country_code).': '.price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) { + $datas['amountlt2'] = '
'.$langs->transcountry('AmountLT2', $mysoc->country_code).': '.price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['amountttc'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + } + + return $datas; + } + /** * Return clicable link of object (with eventually picto) * @@ -1863,13 +1928,26 @@ class Facture extends CommonInvoice } $linkclose = ($target ? ' target="'.$target.'"' : ''); + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'moretitle' => $moretitle, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip) && $user->hasRight("facture", "read")) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Invoice"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.'"'; } $linkstart = 'ref, $max) : $this->ref); From c1b959cdc806db2721ef209dfb2a97c824ab3918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 22:56:46 +0100 Subject: [PATCH 040/137] add ajax tooltip on supplier_order --- .../class/fournisseur.commande.class.php | 63 +++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index c7357813d43..600c0c09915 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -9,7 +9,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2018-2023 Frédéric France * Copyright (C) 2018-2022 Ferran Marcet * Copyright (C) 2021 Josep Lluís Amador * Copyright (C) 2022 Gauthier VERDOL @@ -818,6 +818,49 @@ class CommandeFournisseur extends CommonOrder return dolGetStatus($statusLong, $statusShort, '', $statusClass, $mode); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs, $user; + + $langs->loadLangs(['bills', 'orders']); + + $datas = []; + if ($user->hasRight("fournisseur", "commande", "read")) { + $datas['picto'] = ''.$langs->trans("SupplierOrder").''; + if (isset($this->statut)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->ref_supplier)) { + $datas['refsupplier'] = '
'.$langs->trans('RefSupplier').': '.$this->ref_supplier; + } + if (!empty($this->total_ht)) { + $datas['totalht'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['totaltva'] = '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['totalttc'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->date)) { + $datas['date'] = '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); + } + if (!empty($this->delivery_date)) { + $datas['deliverydate'] = '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); + } + } + return $datas; + } /** * Return clicable name (with picto eventually) @@ -880,13 +923,25 @@ class CommandeFournisseur extends CommonOrder } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowOrder"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.'"'; } $linkstart = '
picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From b238830c82e62b7e10ed2f56a45f1d872805bca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 23:19:56 +0100 Subject: [PATCH 041/137] keep original label --- htdocs/adherents/class/adherent.class.php | 2 +- htdocs/bom/class/bom.class.php | 2 +- htdocs/categories/class/categorie.class.php | 2 +- htdocs/comm/action/class/actioncomm.class.php | 2 +- htdocs/comm/propal/class/propal.class.php | 2 +- htdocs/commande/class/commande.class.php | 2 +- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/contact/class/contact.class.php | 2 +- htdocs/contrat/class/contrat.class.php | 4 +- htdocs/delivery/class/delivery.class.php | 2 +- .../class/fournisseur.commande.class.php | 2 +- .../fourn/class/fournisseur.facture.class.php | 89 ++++++++++++++++++- htdocs/holiday/class/holiday.class.php | 2 +- .../template/class/myobject.class.php | 2 +- htdocs/product/class/product.class.php | 2 +- htdocs/product/stock/class/entrepot.class.php | 2 +- .../product/stock/class/productlot.class.php | 2 +- htdocs/salaries/class/salary.class.php | 2 +- htdocs/societe/class/societe.class.php | 2 +- htdocs/societe/class/societeaccount.class.php | 2 +- .../class/supplier_proposal.class.php | 2 +- htdocs/user/class/user.class.php | 2 +- htdocs/user/class/usergroup.class.php | 2 +- 23 files changed, 108 insertions(+), 27 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index d51035d500e..0b645571947 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2375,7 +2375,7 @@ class Adherent extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 109e01818e4..4420950af30 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1165,7 +1165,7 @@ class BOM extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5dc7d53cc49..f57bca581bd 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1648,7 +1648,7 @@ class Categorie extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } $link = ''; diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a127cc2d3f2..fd5b55e70fe 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1737,7 +1737,7 @@ class ActionComm extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) // $linkclose = ' style="background-color:#'.$this->type_color.'"'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index b3271309855..51c8c4518b5 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3819,7 +3819,7 @@ class Propal extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip) && $user->rights->propal->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index f44a545c879..5f810a8610a 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3842,7 +3842,7 @@ class Commande extends CommonOrder ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip) && $user->rights->commande->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index ed2c729b424..82ef9fc5b06 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1939,7 +1939,7 @@ class Facture extends CommonInvoice ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip) && $user->hasRight("facture", "read")) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 103b8177994..d0e9a2200f3 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1524,7 +1524,7 @@ class Contact extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 981d7d71f02..c3177bd2b1e 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2081,7 +2081,7 @@ class Contrat extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip) && $user->rights->contrat->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { @@ -3162,7 +3162,7 @@ class ContratLigne extends CommonObjectLine ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } $link = ''; diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 525d5458891..b9c301806f9 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -777,7 +777,7 @@ class Delivery extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } $linkstart = ''; $linkend = ''; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 600c0c09915..2ba0097af33 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -933,7 +933,7 @@ class CommandeFournisseur extends CommonOrder ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index dd9ba7a6248..6572fc29cbb 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2015-2022 Ferran Marcet * Copyright (C) 2016-2021 Alexandre Spangaro * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2018-2023 Frédéric France * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify @@ -2700,6 +2700,74 @@ class FactureFournisseur extends CommonInvoice } } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('bills'); + + $datas = []; + $moretitle = $params['moretitle'] ?? ''; + $picto = $this->picto; + if ($this->type == self::TYPE_REPLACEMENT) { + $picto .= 'r'; // Replacement invoice + } + if ($this->type == self::TYPE_CREDIT_NOTE) { + $picto .= 'a'; // Credit note + } + if ($this->type == self::TYPE_DEPOSIT) { + $picto .= 'd'; // Deposit invoice + } + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("SupplierInvoice").''; + if ($this->type == self::TYPE_REPLACEMENT) { + $datas['picto'] .= ''.$langs->transnoentitiesnoconv("InvoiceReplace").''; + } elseif ($this->type == self::TYPE_CREDIT_NOTE) { + $datas['picto'] .= ''.$langs->transnoentitiesnoconv("CreditNote").''; + } elseif ($this->type == self::TYPE_DEPOSIT) { + $datas['picto'] .= ''.$langs->transnoentitiesnoconv("Deposit").''; + } + if (isset($this->status)) { + $alreadypaid = -1; + if (isset($this->alreadypaid)) { + $alreadypaid = $this->alreadypaid; + } + + $$datas['picto'] .= ' '.$this->getLibStatut(5, $alreadypaid); + } + if ($moretitle) { + $datas['picto'] .= ' - '.$moretitle; + } + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->ref_supplier)) { + $datas['refsupplier'] = '
'.$langs->trans('RefSupplier').': '.$this->ref_supplier; + } + if (!empty($this->label)) { + $datas['label'] = '
'.$langs->trans('Label').': '.$this->label; + } + if (!empty($this->date)) { + $datas['date'] = '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); + } + if (!empty($this->total_ht)) { + $datas['amountht'] = '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_tva)) { + $datas['totaltva'] = '
'.$langs->trans('AmountVAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + } + if (!empty($this->total_ttc)) { + $datas['totalttc'] = '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + } + return $datas; + } /** * Return clicable name (with picto eventually) @@ -2801,13 +2869,26 @@ class FactureFournisseur extends CommonInvoice } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + 'moretitle' => $moretitle, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowSupplierInvoice"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.'"'; } $linkstart = 'trans('Loading'); + // $label = $langs->trans('Loading'); } $linkstart = ''; $linkend = ''; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 157b8079808..8ad88bdec8a 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -826,7 +826,7 @@ class MyObject extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 00e745cff47..877bcedecdd 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5231,7 +5231,7 @@ class Product extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index deb7f8c8d52..5af056d8080 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -773,7 +773,7 @@ class Entrepot extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 890a9fbd0f6..1ddcb073d3f 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -667,7 +667,7 @@ class Productlot extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index 4eb403a71a1..d201c4f44c0 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -552,7 +552,7 @@ class Salary extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 1541ca8e8bb..7860ef161c3 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2927,7 +2927,7 @@ class Societe extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php index 110f0826516..a10fee1666e 100644 --- a/htdocs/societe/class/societeaccount.class.php +++ b/htdocs/societe/class/societeaccount.class.php @@ -436,7 +436,7 @@ class SocieteAccount extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index db3070f8b8d..d7013c596b0 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2579,7 +2579,7 @@ class SupplierProposal extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip) && $user->rights->propal->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 26b3ad3860d..17123f7e40a 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2958,7 +2958,7 @@ class User extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index dcc5ca3bb39..8d5a054f646 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -803,7 +803,7 @@ class UserGroup extends CommonObject ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { From e5190ef6a575976cce91904e87bff13e902fb17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 23:28:54 +0100 Subject: [PATCH 042/137] add ajax tooltip on mo --- htdocs/mrp/class/mo.class.php | 45 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index 9a7ba6007cc..3ea38f28251 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -1077,6 +1077,33 @@ class Mo extends CommonObject return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MRP_MO_REOPEN'); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('mrp'); + + $datas = []; + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ManufacturingOrder").''; + if (isset($this->status)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + if (isset($this->label)) { + $datas['label'] = '
'.$langs->trans('Label').': '.$this->label; + } + + return $datas; + } + /** * Return a link to the object card (with optionaly the picto) * @@ -1124,13 +1151,25 @@ class Mo extends CommonObject } $linkclose = ''; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMo"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1141,7 +1180,7 @@ class Mo extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 06904246f86511f83c1d2fbb24843b96917b49e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 5 Feb 2023 23:40:02 +0100 Subject: [PATCH 043/137] clean code --- htdocs/holiday/class/holiday.class.php | 26 +++++++--------- .../template/class/myobject.class.php | 30 ++++++++----------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 9666b1642ef..e3a605a09aa 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -1336,11 +1336,18 @@ class Holiday extends CommonObject $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("Holiday").''; - if (isset($this->statut)) { - $label .= ' '.$this->getLibStatut(5); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - $label .= '
'.$langs->trans('Ref').': '.$this->ref; + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id; @@ -1355,17 +1362,6 @@ class Holiday extends CommonObject $url .= '&save_lastsearch_values=1'; } //} - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } $linkstart = ''; $linkend = ''; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 8ad88bdec8a..e4594e6d615 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -794,13 +794,19 @@ class MyObject extends CommonObject } $result = ''; - - $label = img_picto('', $this->picto).' '.$langs->trans("MyObject").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; + $label = implode($this->getTooltipContentArray($params)); $url = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$this->id; @@ -816,18 +822,6 @@ class MyObject extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMyObject"); From 1c24804f06f36b95f212bfbcf2e90901f377271a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 14:14:15 +0100 Subject: [PATCH 044/137] clean code --- htdocs/core/js/lib_foot.js.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index 8efda4e3812..b319185909a 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -95,13 +95,8 @@ if (empty($conf->dol_no_mouse_hover)) { elem.tooltip("option","content",response); } }); - console.log(event); } }); - jQuery(".classforajaxtooltip").mouseout(function(){ - console.log("hide ajax tooltip"); - $(this).tooltip("close"); - }); '; } From 394c3f847c4ffb1fb62a08d2d3f45450fb387797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20David?= Date: Mon, 6 Feb 2023 17:03:51 +0100 Subject: [PATCH 045/137] FIX clicktodial backtopage --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index f9adc7bcf40..dafa33242df 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3410,7 +3410,7 @@ function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addli $type = 'AC_FAX'; } if (!empty($conf->global->AGENDA_ADDACTIONFORPHONE)) { - $link = ''.img_object($langs->trans("AddAction"), "calendar").''; + $link = ''.img_object($langs->trans("AddAction"), "calendar").''; } if ($link) { $newphone = '
'.$newphone.' '.$link.'
'; From fc767cbfbef84278a5998dd0d08c649133d01eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Fali=C3=A8re?= Date: Mon, 6 Feb 2023 17:56:21 +0100 Subject: [PATCH 046/137] FIX discount wasn't taken into account when adding a line in BOM --- htdocs/bom/class/bom.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 0e57bebd922..e414954d1a5 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1058,8 +1058,10 @@ class BOM extends CommonObject return -1; } $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); - if (empty($line->unit_cost)) { - if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { + if ((empty($line->unit_cost)) && ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0)) { + if ($productFournisseur->fourn_remise_percent != "0") { + $line->unit_cost = $productFournisseur->fourn_unitprice_with_discount; + } else { $line->unit_cost = $productFournisseur->fourn_unitprice; } } From 016d1117a69f3818485b3b7ad8e8c0d4a321fa7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Fali=C3=A8re?= Date: Mon, 6 Feb 2023 18:02:28 +0100 Subject: [PATCH 047/137] added my name to the file --- htdocs/bom/class/bom.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index e414954d1a5..8b866e221de 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2019 Laurent Destailleur + * Copyright (C) 2023 Benjamin Falière * * 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 From adb97f5622e5932ac68832f78474a5600f489c0b Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 6 Feb 2023 19:44:58 +0100 Subject: [PATCH 048/137] fix : Warning: Attempt to read property default_lang on null in /home/httpd/vhosts/aflac.fr/domains/dev.aflac.fr/httpdocs/expensereport/card.php on line 1193 --- htdocs/expensereport/card.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index e258f057e69..9a13ba4c30c 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1190,7 +1190,9 @@ if (empty($reshook)) { $outputlangs = $langs; $newlang = GETPOST('lang_id', 'alpha'); if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $newlang = $object->thirdparty->default_lang; + $user = new User($db); + $user->fetch($object->fk_user_author); + $newlang = $user->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); From f4972997325eea9595c1612da9fd5b2e647a65f8 Mon Sep 17 00:00:00 2001 From: Jean-Patrice Clerc <81645374+jpclerc-beep@users.noreply.github.com> Date: Mon, 6 Feb 2023 21:04:40 +0100 Subject: [PATCH 049/137] Ajout de la ligne pour enregistrer l'email du formulaire --- htdocs/public/project/new.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index c44002340d6..a15b8a6131f 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -222,6 +222,7 @@ if (empty($reshook) && $action == 'add') { } else { $thirdparty->name = dolGetFirstLastname(GETPOST('firstname'), GETPOST('lastname')); } + $thirdparty->email = GETPOST('email'); $thirdparty->address = GETPOST('address'); $thirdparty->zip = GETPOST('zip'); $thirdparty->town = GETPOST('town'); From 1b9f8d46b05def1bbc900db192d5bcafd4a418e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 21:14:24 +0100 Subject: [PATCH 050/137] clean code --- htdocs/adherents/class/adherent.class.php | 48 +++++-------------- .../adherents/class/adherent_type.class.php | 25 ++++------ 2 files changed, 22 insertions(+), 51 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 0b645571947..e2b7cda5e07 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2319,33 +2319,21 @@ class Adherent extends CommonObject } $result = ''; - $label = ''; $linkstart = ''; $linkend = ''; - - if (!empty($this->photo)) { - $label .= '
'; - $label .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1); - $label .= '
'; - //$label .= '
'; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - - $label .= '
'; - $label .= img_picto('', $this->picto).' '.$langs->trans("Member").''; - $label .= ' '.$this->getLibStatut(4); - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->login)) { - $label .= '
'.$langs->trans('Login').': '.$this->login; - } - if (!empty($this->firstname) || !empty($this->lastname)) { - $label .= '
'.$langs->trans('Name').': '.$this->getFullName($langs); - } - if (!empty($this->company)) { - $label .= '
'.$langs->trans('Company').': '.$this->company; - } - $label .= '
'; + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.((int) $this->id); if ($option == 'subscription') { @@ -2365,18 +2353,6 @@ class Adherent extends CommonObject $linkstart .= ' $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 1a8c6c7b26c..9819110e6bc 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -724,29 +724,24 @@ class AdherentType extends CommonObject global $langs; $result = ''; - - $label = img_picto('', $this->picto).' '.$langs->trans("MemberType").''; - $label .= ' '.$this->getLibStatut(4); - $label .= '
'.$langs->trans("Label").': '.$this->label; - if (isset($this->subscription)) { - $label .= '
'.$langs->trans("SubscriptionRequired").': '.yn($this->subscription); - } - $option = ''; - $url = DOL_URL_ROOT.'/adherents/type.php?rowid='.((int) $this->id); $classfortooltip = 'classfortooltip'; $dataparams = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); - $label = $langs->trans('Loading'); + // $label = $langs->trans('Loading'); } + + $label = implode($this->getTooltipContentArray($params)); + + $url = DOL_URL_ROOT.'/adherents/type.php?rowid='.((int) $this->id); if ($option != 'nolink') { // Add param to save lastsearch_values or not $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); From dc15349e83784bbdb8df41a7bd1a1833e40d2f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 21:43:50 +0100 Subject: [PATCH 051/137] clean code --- htdocs/bom/class/bom.class.php | 42 +++------ htdocs/categories/class/categorie.class.php | 28 +++--- htdocs/contact/class/contact.class.php | 98 +++++++++------------ 3 files changed, 71 insertions(+), 97 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 4420950af30..8746999e00b 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1121,24 +1121,20 @@ class BOM extends CommonObject } $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = img_picto('', $this->picto).' '.$langs->trans("BillOfMaterials").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); - } - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; - if (isset($this->label)) { - $label .= '
'.$langs->trans('Label').': '.$this->label; - } - if (!empty($this->fk_product) && $this->fk_product > 0) { - include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $product = new Product($db); - $resultFetch = $product->fetch($this->fk_product); - if ($resultFetch > 0) { - $label .= "
".$langs->trans("Product").': '.$product->ref.' - '.$product->label; - } - } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/bom/bom_card.php?id='.$this->id; @@ -1155,18 +1151,6 @@ class BOM extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowBillOfMaterials"); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index f57bca581bd..592b0204983 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1605,7 +1605,7 @@ class Categorie extends CommonObject */ public function getTooltipContentArray($params) { - global $conf, $langs, $user; + global $langs; $datas = []; @@ -1629,7 +1629,19 @@ class Categorie extends CommonObject global $langs, $hookmanager; $result = ''; - $label = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } + $label = implode($this->getTooltipContentArray($params)); // Check contrast with background and correct text color $forced_color = 'categtextwhite'; @@ -1638,18 +1650,6 @@ class Categorie extends CommonObject $forced_color = 'categtextblack'; } } - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } $link = '
'; $linkend = ''; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index d0e9a2200f3..b44d22da312 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -133,6 +133,11 @@ class Contact extends CommonObject public $civility_code; public $civility; + /** + * @var string gender + */ + public $gender; + /** * @var int egroupware_id */ @@ -193,6 +198,11 @@ class Contact extends CommonObject public $socid; // both socid and fk_soc are used public $fk_soc; // both socid and fk_soc are used + /** + * @var string thirdparty name + */ + public $socname; + /** * @var int 0=inactive, 1=active */ @@ -206,6 +216,14 @@ class Contact extends CommonObject */ public $email; + /** + * Email + * @var string + * @deprecated + * @see $email + */ + public $mail; + /** * URL * @var string @@ -1045,12 +1063,12 @@ class Contact extends CommonObject $this->country_id = $obj->country_id; $this->country_code = $obj->country_id ? $obj->country_code : ''; - $this->country = $obj->country_id ? ($langs->trans('Country'.$obj->country_code) != 'Country'.$obj->country_code ? $langs->transnoentities('Country'.$obj->country_code) : $obj->country) : ''; + $this->country = $obj->country_id ? ($langs->trans('Country'.$obj->country_code) != 'Country'.$obj->country_code ? $langs->transnoentities('Country'.$obj->country_code) : $obj->country) : ''; - $this->fk_soc = $obj->fk_soc; // Both fk_soc and socid are used - $this->socid = $obj->fk_soc; // Both fk_soc and socid are used - $this->socname = $obj->socname; - $this->poste = $obj->poste; + $this->fk_soc = $obj->fk_soc; // Both fk_soc and socid are used + $this->socid = $obj->fk_soc; // Both fk_soc and socid are used + $this->socname = $obj->socname; + $this->poste = $obj->poste; $this->statut = $obj->statut; $this->fk_prospectlevel = $obj->fk_prospectlevel; @@ -1066,22 +1084,22 @@ class Contact extends CommonObject $this->phone_perso = trim($obj->phone_perso); $this->phone_mobile = trim($obj->phone_mobile); - $this->email = $obj->email; + $this->email = $obj->email; $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array()); - $this->photo = $obj->photo; - $this->priv = $obj->priv; - $this->mail = $obj->email; + $this->photo = $obj->photo; + $this->priv = $obj->priv; + $this->mail = $obj->email; $this->birthday = $this->db->jdate($obj->birthday); - $this->note = $obj->note_private; // deprecated - $this->note_private = $obj->note_private; + $this->note = $obj->note_private; // deprecated + $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; - $this->default_lang = $obj->default_lang; + $this->default_lang = $obj->default_lang; $this->user_id = $obj->user_id; - $this->user_login = $obj->user_login; + $this->user_login = $obj->user_login; $this->canvas = $obj->canvas; - $this->import_key = $obj->import_key; + $this->import_key = $obj->import_key; // Define gender according to civility $this->setGenderFromCivility(); @@ -1468,35 +1486,19 @@ class Contact extends CommonObject global $conf, $langs, $hookmanager; $result = ''; - $label = ''; - if (!empty($this->photo) && class_exists('Form')) { - $label .= '
'; - $label .= Form::showphoto('contact', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. - $label .= '
'; - //$label .= '
'; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - - $label .= img_picto('', $this->picto).' '.$langs->trans("Contact").''; - $label .= ' '.$this->getLibStatut(4); - $label .= '
'.$langs->trans("Name").': '.$this->getFullName($langs); - //if ($this->civility_id) $label.= '
' . $langs->trans("Civility") . ': '.$this->civility_id; // TODO Translate cibilty_id code - if (!empty($this->poste)) { - $label .= '
'.$langs->trans("Poste").': '.$this->poste; - } - $label .= '
'.$langs->trans("EMail").': '.$this->email; - $phonelist = array(); - $country_code = empty($this->country_code) ? '': $this->country_code; - if ($this->phone_pro) { - $phonelist[] = dol_print_phone($this->phone_pro, $country_code, $this->id, 0, '', ' ', 'phone'); - } - if ($this->phone_mobile) { - $phonelist[] = dol_print_phone($this->phone_mobile, $country_code, $this->id, 0, '', ' ', 'mobile'); - } - if ($this->phone_perso) { - $phonelist[] = dol_print_phone($this->phone_perso, $country_code, $this->id, 0, '', ' ', 'phone'); - } - $label .= '
'.$langs->trans("Phone").': '.implode(' ', $phonelist); - $label .= '
'.$langs->trans("Address").': '.dol_format_address($this, 1, ' ', $langs); + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/contact/card.php?id='.$this->id; @@ -1514,18 +1516,6 @@ class Contact extends CommonObject $url .= $moreparam; $linkclose = ""; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowContact"); From f3b5990d2b8012909fb24614ee4aa89d5eefdcf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 21:49:23 +0100 Subject: [PATCH 052/137] clean code --- htdocs/contrat/class/contrat.class.php | 37 ++++++-------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index c3177bd2b1e..97b586a2cde 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2047,42 +2047,21 @@ class Contrat extends CommonObject $url .= '&save_lastsearch_values=1'; } //} - - $label = ''; - - if ($user->hasRight('contrat', 'lire')) { - $label = img_picto('', $this->picto).' '.$langs->trans("Contract").''; - /* Status of a contract is status of all services, so disabled - if (isset($this->statut)) { - $label .= ' '.$this->getLibStatut(5); - }*/ - $label .= '
'.$langs->trans('Ref').': '.($this->ref ? $this->ref : $this->id); - $ref_customer = (!empty($this->ref_customer) ? $this->ref_customer : (empty($this->ref_client) ? '' : $this->ref_client)); - $label .= '
'.$langs->trans('RefCustomer').': '.$ref_customer; - $label .= '
'.$langs->trans('RefSupplier').': '.$this->ref_supplier; - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - } - - $linkclose = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; $classfortooltip = 'classfortooltip'; $dataparams = ''; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); // $label = $langs->trans('Loading'); } + + $label = implode($this->getTooltipContentArray($params)); + + $linkclose = ''; if (empty($notooltip) && $user->rights->contrat->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowContract"); From 4a74e7d87519f686f2322c0310a848a6d1fb7a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 21:59:32 +0100 Subject: [PATCH 053/137] clean code --- htdocs/compta/facture/class/facture.class.php | 53 ++++--------------- htdocs/delivery/class/delivery.class.php | 30 ++++++----- 2 files changed, 26 insertions(+), 57 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 82ef9fc5b06..8505af85ce5 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1890,57 +1890,22 @@ class Facture extends CommonInvoice if ($this->type == self::TYPE_DEPOSIT) { $picto .= 'd'; // Deposit invoice } - $label = ''; - - if ($user->hasRight("facture", "read")) { - $label = img_picto('', $picto).' '.$langs->trans("Invoice").''; - if (isset($this->statut) && isset($this->alreadypaid)) { - $label .= ' '.$this->getLibStatut(5, $this->alreadypaid); - } - $label .= '   '.$this->getLibType(1); - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->ref_client)) { - $label .= '
'.$langs->trans('RefCustomer').': '.$this->ref_client; - } - if (!empty($this->date)) { - $label .= '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); - } - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('AmountVAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) { // We keep test != 0 because $this->total_localtax1 can be '0.00000000' - $label .= '
'.$langs->transcountry('AmountLT1', $mysoc->country_code).': '.price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) { - $label .= '
'.$langs->transcountry('AmountLT2', $mysoc->country_code).': '.price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - if ($moretitle) { - $label .= ' - '.$moretitle; - } - } - - $linkclose = ($target ? ' target="'.$target.'"' : ''); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'moretitle' => $moretitle, + 'option' => $option, + ]; $classfortooltip = 'classfortooltip'; $dataparams = ''; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'moretitle' => $moretitle, - 'option' => $option, - ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); // $label = $langs->trans('Loading'); } + $label = implode($this->getTooltipContentArray($params)); + + $linkclose = ($target ? ' target="'.$target.'"' : ''); if (empty($notooltip) && $user->hasRight("facture", "read")) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Invoice"); diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 8fa0094f219..bb0d8ac162d 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -108,6 +108,11 @@ class Delivery extends CommonObject public $commande_id; + /** + * @var array statuts labels + */ + public $statuts; + public $lines = array(); @@ -751,8 +756,18 @@ class Delivery extends CommonObject $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("ShowReceiving").':
'; - $label .= ''.$langs->trans("Status").': '.$this->ref; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/delivery/card.php?id='.$this->id; @@ -768,17 +783,6 @@ class Delivery extends CommonObject } //} - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } $linkstart = ''; $linkend = ''; From 8a5e983d7ea3f8c8ecfffe630510bf6c9fd0e1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 22:21:54 +0100 Subject: [PATCH 054/137] clean code --- htdocs/comm/propal/class/propal.class.php | 54 +++------ htdocs/commande/class/commande.class.php | 42 ++----- htdocs/mrp/class/mo.class.php | 34 +++--- htdocs/product/class/product.class.php | 106 ++---------------- htdocs/product/stock/class/entrepot.class.php | 33 +++--- .../product/stock/class/productlot.class.php | 34 +++--- 6 files changed, 72 insertions(+), 231 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 51c8c4518b5..3a48230de40 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3756,36 +3756,22 @@ class Propal extends CommonObject } $result = ''; - $label = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } + $label = implode($this->getTooltipContentArray($params)); + $url = ''; - if ($user->rights->propal->lire) { - $label = img_picto('', $this->picto).' '.$langs->trans("Proposal").''; - if (isset($this->statut)) { - $label .= ' '.$this->getLibStatut(5); - } - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->ref_client)) { - $label .= '
'.$langs->trans('RefCustomer').': '.$this->ref_client; - } - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->date)) { - $label .= '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); - } - if (!empty($this->delivery_date)) { - $label .= '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); - } - if ($option == '') { $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$this->id.$get_params; } elseif ($option == 'compta') { // deprecated @@ -3809,18 +3795,6 @@ class Propal extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip) && $user->rights->propal->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Proposal"); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 5f810a8610a..5b111f67e6c 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3804,46 +3804,22 @@ class Commande extends CommonOrder if ($short) { return $url; } - - $label = ''; - - if ($user->hasRight('commande', 'lire')) { - $label = img_picto('', $this->picto).' '.$langs->trans("Order").''; - if (isset($this->statut)) { - $label .= ' '.$this->getLibStatut(5); - } - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - $label .= '
'.$langs->trans('RefCustomer').': '.(empty($this->ref_customer) ? (empty($this->ref_client) ? '' : $this->ref_client) : $this->ref_customer); - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->date)) { - $label .= '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); - } - if (!empty($this->delivery_date)) { - $label .= '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); - } - } - - $linkclose = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; $classfortooltip = 'classfortooltip'; $dataparams = ''; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); // $label = $langs->trans('Loading'); } + + $label = implode($this->getTooltipContentArray($params)); + + $linkclose = ''; if (empty($notooltip) && $user->rights->commande->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Order"); diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index 3ea38f28251..ddfd8a7f57b 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -1123,16 +1123,20 @@ class Mo extends CommonObject } $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = img_picto('', $this->picto).' '.$langs->trans("ManufacturingOrder").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); - } - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; - if (isset($this->label)) { - $label .= '
'.$langs->trans('Label').': '.$this->label; - } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/mrp/mo_card.php?id='.$this->id; if ($option == 'production') { @@ -1151,18 +1155,6 @@ class Mo extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMo"); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 877bcedecdd..6686b4fce8d 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5125,114 +5125,28 @@ class Product extends CommonObject global $conf, $langs, $hookmanager; include_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; - $result = ''; $label = ''; + $result = ''; $newref = $this->ref; if ($maxlength) { $newref = dol_trunc($newref, $maxlength, 'middle'); } - - if (!empty($this->entity)) { - $tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80); - if ($this->nbphoto > 0) { - $label .= '
'; - $label .= $tmpphoto; - $label .= '
'; - //$label .= '
'; - } - } - - if ($this->type == Product::TYPE_PRODUCT) { - $label .= img_picto('', 'product').' '.$langs->trans("Product").''; - } elseif ($this->type == Product::TYPE_SERVICE) { - $label .= img_picto('', 'service').' '.$langs->trans("Service").''; - } - if (isset($this->status) && isset($this->status_buy)) { - $label .= ' '.$this->getLibStatut(5, 0); - $label .= ' '.$this->getLibStatut(5, 1); - } - - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('ProductRef').': '.$this->ref; - } - if (!empty($this->label)) { - $label .= '
'.$langs->trans('ProductLabel').': '.$this->label; - } - if ($this->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - if (isModEnabled('productbatch')) { - $langs->load("productbatch"); - $label .= "
".$langs->trans("ManageLotSerial").': '.$this->getLibStatut(0, 2); - } - } - if (isModEnabled('barcode')) { - $label .= '
'.$langs->trans('BarCode').': '.$this->barcode; - } - - if ($this->type == Product::TYPE_PRODUCT) { - if ($this->weight) { - $label .= "
".$langs->trans("Weight").': '.$this->weight.' '.measuringUnitString(0, "weight", $this->weight_units); - } - $labelsize = ""; - if ($this->length) { - $labelsize .= ($labelsize ? " - " : "")."".$langs->trans("Length").': '.$this->length.' '.measuringUnitString(0, 'size', $this->length_units); - } - if ($this->width) { - $labelsize .= ($labelsize ? " - " : "")."".$langs->trans("Width").': '.$this->width.' '.measuringUnitString(0, 'size', $this->width_units); - } - if ($this->height) { - $labelsize .= ($labelsize ? " - " : "")."".$langs->trans("Height").': '.$this->height.' '.measuringUnitString(0, 'size', $this->height_units); - } - if ($labelsize) { - $label .= "
".$labelsize; - } - - $labelsurfacevolume = ""; - if ($this->surface) { - $labelsurfacevolume .= ($labelsurfacevolume ? " - " : "")."".$langs->trans("Surface").': '.$this->surface.' '.measuringUnitString(0, 'surface', $this->surface_units); - } - if ($this->volume) { - $labelsurfacevolume .= ($labelsurfacevolume ? " - " : "")."".$langs->trans("Volume").': '.$this->volume.' '.measuringUnitString(0, 'volume', $this->volume_units); - } - if ($labelsurfacevolume) { - $label .= "
".$labelsurfacevolume; - } - } - if (!empty($this->pmp) && $this->pmp) { - $label .= "
".$langs->trans("PMPValue").': '.price($this->pmp, 0, '', 1, -1, -1, $conf->currency); - } - - if (isModEnabled('accounting')) { - if ($this->status && isset($this->accountancy_code_sell)) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; - $label .= '
'; - $label .= '
'.$langs->trans('ProductAccountancySellCode').': '.length_accountg($this->accountancy_code_sell); - $label .= '
'.$langs->trans('ProductAccountancySellIntraCode').': '.length_accountg($this->accountancy_code_sell_intra); - $label .= '
'.$langs->trans('ProductAccountancySellExportCode').': '.length_accountg($this->accountancy_code_sell_export); - } - if ($this->status_buy && isset($this->accountancy_code_buy)) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; - if (empty($this->status)) { - $label .= '
'; - } - $label .= '
'.$langs->trans('ProductAccountancyBuyCode').': '.length_accountg($this->accountancy_code_buy); - $label .= '
'.$langs->trans('ProductAccountancyBuyIntraCode').': '.length_accountg($this->accountancy_code_buy_intra); - $label .= '
'.$langs->trans('ProductAccountancyBuyExportCode').': '.length_accountg($this->accountancy_code_buy_export); - } - } - - $linkclose = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; $classfortooltip = 'classfortooltip'; $dataparams = ''; if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; $classfortooltip = 'classforajaxtooltip'; $dataparams = ' data-params='.json_encode($params); // $label = $langs->trans('Loading'); } + + $label = implode($this->getTooltipContentArray($params)); + + $linkclose = ''; if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowProduct"); diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 5af056d8080..e6d3ecbd236 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -739,15 +739,20 @@ class Entrepot extends CommonObject } $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = img_picto('', $this->picto).' '.$langs->trans("Warehouse").''; - if (isset($this->statut)) { - $label .= ' '.$this->getLibStatut(5); - } - $label .= '
'.$langs->trans('Ref').': '.(empty($this->ref) ? $this->label : $this->ref); - if (!empty($this->lieu)) { - $label .= '
'.$langs->trans('LocationSummary').': '.$this->lieu; - } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/product/stock/card.php?id='.$this->id; @@ -763,18 +768,6 @@ class Entrepot extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("Warehouse"); diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 1ddcb073d3f..39a8d5721a9 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -632,16 +632,20 @@ class Productlot extends CommonObject global $menumanager; $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = img_picto('', $this->picto).' '.$langs->trans("Batch").''; - $label .= '
'; - $label .= ''.$langs->trans('Batch').': '.$this->batch; - if ($this->eatby && empty($conf->global->PRODUCT_DISABLE_EATBY)) { - $label .= '
'.$langs->trans('EatByDate').': '.dol_print_date($this->eatby, 'day'); - } - if ($this->sellby && empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - $label .= '
'.$langs->trans('SellByDate').': '.dol_print_date($this->sellby, 'day'); - } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/product/stock/productlot_card.php?id='.$this->id; @@ -657,18 +661,6 @@ class Productlot extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMyObject"); From e5a1b226f3f33c955f6af5e45f8f5596a93948b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 22:28:03 +0100 Subject: [PATCH 055/137] clean code --- htdocs/salaries/class/salary.class.php | 59 ++++++++++++++------------ 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index d201c4f44c0..acf811b4f88 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -79,6 +79,17 @@ class Salary extends CommonObject */ public $fk_bank; + /** + * @var int + * @see $accountid + */ + public $fk_account; + + /** + * @var int + */ + public $accountid; + /** * @var int ID */ @@ -250,7 +261,8 @@ class Salary extends CommonObject $this->fk_bank = $obj->fk_bank; $this->fk_user_author = $obj->fk_user_author; $this->fk_user_modif = $obj->fk_user_modif; - $this->fk_account = $this->accountid = $obj->fk_account; + $this->fk_account = $obj->fk_account; + $this->accountid = $obj->fk_account; // Retrieve all extrafield // fetch optionals attributes and labels @@ -518,42 +530,35 @@ class Salary extends CommonObject if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = ''.$langs->trans("Salary").''; - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; - if ($this->label) { - $label .= '
'.$langs->trans('Label').': '.$this->label; - } - if ($this->datesp && $this->dateep) { - $label .= '
'.$langs->trans('Period').': '.dol_print_date($this->datesp, 'day').' - '.dol_print_date($this->dateep, 'day'); - } - if (isset($this->amount)) { - $label .= '
'.$langs->trans('Amount').': '.price($this->amount); - } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/salaries/card.php?id='.$this->id; if ($option != 'nolink') { // Add param to save lastsearch_values or not $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; - if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { + $add_save_lastsearch_values = 1; + } + if ($add_save_lastsearch_values) { + $url .= '&save_lastsearch_values=1'; + } } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowMyObject"); From 3238d82386f7bca056dad365df819d6c5b10ebc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 22:50:36 +0100 Subject: [PATCH 056/137] clean code --- .../class/fournisseur.commande.class.php | 109 ++++++++------- .../fourn/class/fournisseur.facture.class.php | 67 ++-------- htdocs/societe/class/societe.class.php | 124 +++--------------- 3 files changed, 88 insertions(+), 212 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 2ba0097af33..335bd6b2df4 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -100,14 +100,37 @@ class CommandeFournisseur extends CommonOrder */ public $ref; + /** + * @var string ref supplier + */ public $ref_supplier; + + /** + * @var string ref supplier + * @deprecated + * @see $ref_supplier + */ + public $ref_fourn; + public $brouillon; + /** + * @var int + */ public $statut; // 0=Draft -> 1=Validated -> 2=Approved -> 3=Ordered/Process runing -> 4=Received partially -> 5=Received totally -> (reopen) 4=Received partially // -> 7=Canceled/Never received -> (reopen) 3=Process runing // -> 6=Canceled -> (reopen) 2=Approved // -> 9=Refused -> (reopen) 1=Validated // Note: billed or not is on another field "billed" - public $statuts; // List of status + + /** + * @var array List of status + */ + public $statuts; + + /** + * @var array List of status short + */ + public $statuts_short; public $billed; @@ -169,7 +192,12 @@ class CommandeFournisseur extends CommonOrder */ public $lines = array(); - //Add for supplier_proposal + /** + * @var CommandeFournisseurLigne + */ + public $line; + + // Add for supplier_proposal public $origin; public $origin_id; public $linked_objects = array(); @@ -389,9 +417,9 @@ class CommandeFournisseur extends CommonOrder $this->ref_supplier = $obj->ref_supplier; $this->socid = $obj->fk_soc; $this->fourn_id = $obj->fk_soc; - $this->statut = $obj->fk_statut; - $this->status = $obj->fk_statut; - $this->billed = $obj->billed; + $this->statut = $obj->fk_statut; + $this->status = $obj->fk_statut; + $this->billed = $obj->billed; $this->user_author_id = $obj->fk_user_author; $this->user_valid_id = $obj->fk_user_valid; $this->user_approve_id = $obj->fk_user_approve; @@ -587,10 +615,10 @@ class CommandeFournisseur extends CommonOrder // Multicurrency $line->fk_multicurrency = $objp->fk_multicurrency; $line->multicurrency_code = $objp->multicurrency_code; - $line->multicurrency_subprice = $objp->multicurrency_subprice; - $line->multicurrency_total_ht = $objp->multicurrency_total_ht; - $line->multicurrency_total_tva = $objp->multicurrency_total_tva; - $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc; + $line->multicurrency_subprice = $objp->multicurrency_subprice; + $line->multicurrency_total_ht = $objp->multicurrency_total_ht; + $line->multicurrency_total_tva = $objp->multicurrency_total_tva; + $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc; $line->special_code = $objp->special_code; $line->fk_parent_line = $objp->fk_parent_line; @@ -877,38 +905,21 @@ class CommandeFournisseur extends CommonOrder global $langs, $conf, $user, $hookmanager; $result = ''; - - $label = ''; - - if ($user->hasRight("fournisseur", "commande", "read")) { - $label = ''.$langs->trans("SupplierOrder").''; - if (isset($this->statut)) { - $label .= ' '.$this->getLibStatut(5); - } - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->ref_supplier)) { - $label .= '
'.$langs->trans('RefSupplier').': '.$this->ref_supplier; - } - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->date)) { - $label .= '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); - } - if (!empty($this->delivery_date)) { - $label .= '
'.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); - } + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - $picto = 'order'; + $label = implode($this->getTooltipContentArray($params)); + $url = DOL_URL_ROOT.'/fourn/commande/card.php?id='.$this->id; if ($option !== 'nolink') { @@ -923,18 +934,6 @@ class CommandeFournisseur extends CommonOrder } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowOrder"); @@ -3702,6 +3701,14 @@ class CommandeFournisseurLigne extends CommonOrderLine * @var string */ public $ref_supplier; + + /** + * @var string ref supplier + * @deprecated + * @see $ref_supplier + */ + public $ref_fourn; + public $remise; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 6572fc29cbb..c6cc2acc722 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2821,47 +2821,21 @@ class FactureFournisseur extends CommonInvoice if ($this->type == self::TYPE_DEPOSIT) { $picto .= 'd'; // Deposit invoice } + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + 'moretitle' => $moretitle, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = img_picto('', $this->picto).' '.$langs->trans("SupplierInvoice").''; - if ($this->type == self::TYPE_REPLACEMENT) { - $label = ''.$langs->transnoentitiesnoconv("InvoiceReplace").''; - } elseif ($this->type == self::TYPE_CREDIT_NOTE) { - $label = ''.$langs->transnoentitiesnoconv("CreditNote").''; - } elseif ($this->type == self::TYPE_DEPOSIT) { - $label = ''.$langs->transnoentitiesnoconv("Deposit").''; - } - if (isset($this->status)) { - $alreadypaid = -1; - if (isset($this->alreadypaid)) { - $alreadypaid = $this->alreadypaid; - } - - $label .= ' '.$this->getLibStatut(5, $alreadypaid); - } - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->ref_supplier)) { - $label .= '
'.$langs->trans('RefSupplier').': '.$this->ref_supplier; - } - if (!empty($this->label)) { - $label .= '
'.$langs->trans('Label').': '.$this->label; - } - if (!empty($this->date)) { - $label .= '
'.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); - } - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('AmountVAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - if ($moretitle) { - $label .= ' - '.$moretitle; - } + $label = implode($this->getTooltipContentArray($params)); $ref = $this->ref; if (empty($ref)) { @@ -2869,19 +2843,6 @@ class FactureFournisseur extends CommonInvoice } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - 'moretitle' => $moretitle, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowSupplierInvoice"); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 7860ef161c3..bc0e8cff3bd 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2607,7 +2607,7 @@ class Societe extends CommonObject { global $conf, $langs, $user; - $langs->loadLangs(['companies, commercial']); + $langs->loadLangs(['companies', 'commercial']); $datas = []; @@ -2621,9 +2621,6 @@ class Societe extends CommonObject return ['optimize' => $langs->trans("ShowCompany")]; } - $label = ''; - $label2 = ''; - if (!empty($this->logo) && class_exists('Form')) { $photo = '
'; $photo .= Form::showphoto('societe', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. @@ -2787,122 +2784,45 @@ class Societe extends CommonObject $name .= ' ('.$this->name_alias.')'; } - $result = ''; $label = ''; $label2 = ''; - $linkstart = ''; $linkend = ''; - - if (!empty($this->logo) && class_exists('Form')) { - $label .= '
'; - $label .= Form::showphoto('societe', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. - $label .= '
'; - //$label .= '
'; - } elseif (!empty($this->logo_squarred) && class_exists('Form')) { - /*$label.= '
'; - $label.= Form::showphoto('societe', $this, 0, 40, 0, 'photowithmargin', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. - $label.= '
';*/ + $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - - $label .= '
'; + $label = implode($this->getTooltipContentArray($params)); + $linkstart = ''; + $linkend = ''; if ($option == 'customer' || $option == 'compta' || $option == 'category') { - $label .= img_picto('', $this->picto).' '.$langs->trans("Customer").''; $linkstart = ''.$langs->trans("Prospect").''; $linkstart = ''.$langs->trans("Supplier").''; $linkstart = ''.$langs->trans("ThirdParty").''; $linkstart = ''.$langs->trans("ThirdParty").''; $linkstart = ''.$langs->trans("ThirdParty").''; $linkstart = ''.$langs->trans("ThirdParty").''; $linkstart = ''.$langs->trans("ThirdParty").''; $linkstart = ''.$langs->trans("ThirdParty").''; $linkstart = 'email; - } - if (!empty($this->phone) || !empty($this->fax)) { - $phonelist = array(); - if ($this->phone) { - $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', ' ', 'phone'); - } - if ($this->fax) { - $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', ' ', 'fax'); - } - $label .= '
'.implode(' ', $phonelist); - } - - if (!empty($this->address)) { - $label2 .= '
'.$langs->trans("Address").': '.dol_format_address($this, 1, ' ', $langs); // Address + country - } elseif (!empty($this->country_code)) { - $label2 .= '
'.$langs->trans('Country').': '.$this->country_code; - } - if (!empty($this->tva_intra) || (!empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP) && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) { - $label2 .= '
'.$langs->trans('VATIntra').': '.dol_escape_htmltag($this->tva_intra); - } - - if (!empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP)) { - if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false && $langs->trans('ProfId1'.$this->country_code) != '-') { - $label2 .= '
'.$langs->trans('ProfId1'.$this->country_code).': '.$this->idprof1; - } - if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false && $langs->trans('ProfId2'.$this->country_code) != '-') { - $label2 .= '
'.$langs->trans('ProfId2'.$this->country_code).': '.$this->idprof2; - } - if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false && $langs->trans('ProfId3'.$this->country_code) != '-') { - $label2 .= '
'.$langs->trans('ProfId3'.$this->country_code).': '.$this->idprof3; - } - if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false && $langs->trans('ProfId4'.$this->country_code) != '-') { - $label2 .= '
'.$langs->trans('ProfId4'.$this->country_code).': '.$this->idprof4; - } - if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false && $langs->trans('ProfId5'.$this->country_code) != '-') { - $label2 .= '
'.$langs->trans('ProfId5'.$this->country_code).': '.$this->idprof5; - } - if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false && $langs->trans('ProfId6'.$this->country_code) != '-') { - $label2 .= '
'.$langs->trans('ProfId6'.$this->country_code).': '.$this->idprof6; - } - } - if (!empty($this->code_client) && ($this->client == 1 || $this->client == 3)) { - $label2 .= '
'.$langs->trans('CustomerCode').': '.$this->code_client; - } - if (!empty($this->code_fournisseur) && $this->fournisseur) { - $label2 .= '
'.$langs->trans('SupplierCode').': '.$this->code_fournisseur; - } - if (isModEnabled('accounting') && ($this->client == 1 || $this->client == 3)) { - $label2 .= '
'.$langs->trans('CustomerAccountancyCode').': '.($this->code_compta ? $this->code_compta : $this->code_compta_client); - } - if (isModEnabled('accounting') && $this->fournisseur) { - $label2 .= '
'.$langs->trans('SupplierAccountancyCode').': '.$this->code_compta_fournisseur; - } - $label .= ($label2 ? '
'.$label2 : '').'
'; // Add type of canvas $linkstart .= (!empty($this->canvas) ? '&canvas='.$this->canvas : ''); @@ -2917,18 +2837,6 @@ class Societe extends CommonObject $linkstart .= '"'; $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowCompany"); From ff94600d8f37c16f8425fadb2b081dffe88b015d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 23:00:42 +0100 Subject: [PATCH 057/137] clean code --- htdocs/user/class/user.class.php | 99 +++++---------------------- htdocs/user/class/usergroup.class.php | 38 +++++----- 2 files changed, 36 insertions(+), 101 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 17123f7e40a..ff92cc54ede 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2849,82 +2849,30 @@ class User extends CommonObject $withpictoimg = 0; } - $result = ''; $label = ''; $companylink = ''; - - if (!empty($this->photo)) { - $label .= '
'; - $label .= Form::showphoto('userphoto', $this, 0, 60, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1); // Force height to 60 so we total height of tooltip can be calculated and collision can be managed - $label .= '
'; - //$label .= '
'; + $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'infologin' => $infologin, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - - // Info Login - $label .= '
'; - $label .= img_picto('', $this->picto).' '.$langs->trans("User").''; - $label .= ' '.$this->getLibStatut(4); - $label .= '
'.$langs->trans('Name').': '.dol_string_nohtmltag($this->getFullName($langs, '')); - if (!empty($this->login)) { - $label .= '
'.$langs->trans('Login').': '.dol_string_nohtmltag($this->login); - } - if (!empty($this->job)) { - $label .= '
'.$langs->trans("Job").': '.dol_string_nohtmltag($this->job); - } - $label .= '
'.$langs->trans("Email").': '.dol_string_nohtmltag($this->email); - if (!empty($this->office_phone) || !empty($this->office_fax) || !empty($this->fax)) { - $phonelist = array(); - if ($this->office_phone) { - $phonelist[] = dol_print_phone($this->office_phone, $this->country_code, $this->id, 0, '', ' ', 'phone'); - } - if ($this->office_fax) { - $phonelist[] = dol_print_phone($this->office_fax, $this->country_code, $this->id, 0, '', ' ', 'fax'); - } - if ($this->user_mobile) { - $phonelist[] = dol_print_phone($this->user_mobile, $this->country_code, $this->id, 0, '', ' ', 'mobile'); - } - $label .= '
'.$langs->trans('Phone').': '.implode(' ', $phonelist); - } - if (!empty($this->admin)) { - $label .= '
'.$langs->trans("Administrator").': '.yn($this->admin); - } - if (!empty($this->accountancy_code) || $option == 'accountancy') { - $label .= '
'.$langs->trans("AccountancyCode").': '.$this->accountancy_code; - } - $company = ''; + $label = implode($this->getTooltipContentArray($params)); + $companylink = ''; if (!empty($this->socid)) { // Add thirdparty for external users - $thirdpartystatic = new Societe($db); + $thirdpartystatic = new Societe($this->db); $thirdpartystatic->fetch($this->socid); if (empty($hidethirdpartylogo)) { $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink') ? 'nolink' : '')); // picto only of company } - $company = ' ('.$langs->trans("Company").': '.img_picto('', 'company').' '.dol_string_nohtmltag($thirdpartystatic->name).')'; - } - $type = ($this->socid ? $langs->trans("ExternalUser").$company : $langs->trans("InternalUser")); - $label .= '
'.$langs->trans("Type").': '.$type; - $label .= '
'; - if ($infologin > 0) { - $label .= '
'; - $label .= '
'.$langs->trans("Session").''; - $label .= '
'.$langs->trans("IPAddress").': '.dol_string_nohtmltag(getUserRemoteIP()); - if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) { - $label .= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (User entity '.$this->entity.')'; - } - $label .= '
'.$langs->trans("AuthenticationMode").': '.dol_string_nohtmltag($_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)')); - $label .= '
'.$langs->trans("ConnectedSince").': '.dol_print_date($this->datelastlogin, "dayhour", 'tzuser'); - $label .= '
'.$langs->trans("PreviousConnexion").': '.dol_print_date($this->datepreviouslogin, "dayhour", 'tzuser'); - $label .= '
'.$langs->trans("CurrentTheme").': '.dol_string_nohtmltag($conf->theme); - $label .= '
'.$langs->trans("CurrentMenuManager").': '.dol_string_nohtmltag($menumanager->name); - $s = picto_from_langcode($langs->getDefaultLang()); - $label .= '
'.$langs->trans("CurrentUserLanguage").': '.dol_string_nohtmltag(($s ? $s.' ' : '').$langs->getDefaultLang()); - $label .= '
'.$langs->trans("Browser").': '.dol_string_nohtmltag($conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')'); - $label .= '
'.$langs->trans("Layout").': '.dol_string_nohtmltag($conf->browser->layout); - $label .= '
'.$langs->trans("Screen").': '.dol_string_nohtmltag($_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']); - if ($conf->browser->layout == 'phone') { - $label .= '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); - } - if (!empty($_SESSION["disablemodules"])) { - $label .= '
'.$langs->trans("DisabledModules").':
'.dol_string_nohtmltag(join(', ', explode(',', $_SESSION["disablemodules"]))); - } } + if ($infologin < 0) { $label = ''; } @@ -2947,19 +2895,6 @@ class User extends CommonObject $linkstart = '
$this->id, - 'objecttype' => $this->element, - 'infologin' => $infologin, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 8d5a054f646..04554b282d0 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -105,6 +105,11 @@ class UserGroup extends CommonObject private $_tab_loaded = array(); // Array of cache of already loaded permissions + /** + * @var int all_permissions_are_loaded + */ + public $all_permissions_are_loaded; + public $oldcopy; // To contains a clone of this when we need to save old properties of object public $fields = array( @@ -767,13 +772,20 @@ class UserGroup extends CommonObject $withpicto = 0; } - $result = ''; $label = ''; - - $label .= '
'; - $label .= img_picto('', 'group').' '.$langs->trans("Group").'
'; - $label .= ''.$langs->trans('Name').': '.$this->name; - $label .= '
'.$langs->trans("Description").': '.$this->note; - $label .= '
'; + $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } + $label = implode($this->getTooltipContentArray($params)); if ($option == 'permissions') { $url = DOL_URL_ROOT.'/user/group/perms.php?id='.$this->id; @@ -793,18 +805,6 @@ class UserGroup extends CommonObject } $linkclose = ""; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); From 769e28e3c0e4d53c506e049889f059d48ac70e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 23:08:34 +0100 Subject: [PATCH 058/137] clean code --- htdocs/core/class/commonobject.class.php | 5 +++ .../workstation/class/workstation.class.php | 45 +++++++++++++++---- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b22424d1171..f1b83861ef5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -593,6 +593,11 @@ abstract class CommonObject protected $labelStatus; protected $labelStatusShort; + /** + * @var int showphoto_on_popup + */ + public $showphoto_on_popup; + /** * @var array nb used in load_stateboard */ diff --git a/htdocs/workstation/class/workstation.class.php b/htdocs/workstation/class/workstation.class.php index ac51aeae1d2..3adf2f3cd8a 100644 --- a/htdocs/workstation/class/workstation.class.php +++ b/htdocs/workstation/class/workstation.class.php @@ -683,6 +683,29 @@ class Workstation extends CommonObject return $this->setStatusCommon($user, self::STATUS_DISABLED, $notrigger, 'WORKSTATION_DISABLED'); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('holiday'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Workstation").''; + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $datas['status'] = '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + return $datas; + } + /** * Return a link to the object card (with optionaly the picto) * @@ -703,12 +726,18 @@ class Workstation extends CommonObject $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("Workstation").''; - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; - if (isset($this->status)) { - $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } + $label = implode($this->getTooltipContentArray($params)); $url = dol_buildpath('/workstation/workstation_card.php', 1).'?id='.$this->id; @@ -729,8 +758,8 @@ class Workstation extends CommonObject $label = $langs->trans("ShowWorkstation"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -743,7 +772,7 @@ class Workstation extends CommonObject if (empty($this->showphoto_on_popup)) { if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'mrp'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'mrp'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } } else { if ($withpicto) { From fe38c5817d4f268dd5fd6e3038e19ec71d727d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Feb 2023 23:24:06 +0100 Subject: [PATCH 059/137] doc --- htdocs/ticket/class/ticket.class.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 5faea34ad6c..a304ffe7f78 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2016 Christophe Battarel - * Copyright (C) 2019-2022 Frédéric France + * Copyright (C) 2019-2023 Frédéric France * Copyright (C) 2020 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -198,6 +198,26 @@ class Ticket extends CommonObject */ public $cache_category_tickets; + /** + * @var array tickets severity + */ + public $cache_severity_tickets; + + /** + * @var array cache msgs ticket + */ + public $cache_msgs_ticket; + + /** + * @var array statuts labels + */ + public $statuts; + + /** + * @var array statuts short labels + */ + public $statuts_short; + /** * @var int Notify thirdparty at create */ @@ -1251,7 +1271,7 @@ class Ticket extends CommonObject { global $conf, $langs; - if (!empty($this->cache_category_ticket) && count($this->cache_category_tickets)) { + if (!empty($this->cache_category_tickets) && count($this->cache_category_tickets)) { // Cache already loaded return 0; } From 4d0217fb18df618cb11f2eebdd779868a90d7bd0 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 6 Feb 2023 22:25:14 +0000 Subject: [PATCH 060/137] Fixing style errors. --- htdocs/ticket/class/ticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index a304ffe7f78..693a239feac 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -214,7 +214,7 @@ class Ticket extends CommonObject public $statuts; /** - * @var array statuts short labels + * @var array statuts short labels */ public $statuts_short; From 614a9c2a1e6b68804a5c64f2245117fb51180405 Mon Sep 17 00:00:00 2001 From: "Esteban L. Castro" <43482256+elcf@users.noreply.github.com> Date: Mon, 6 Feb 2023 18:29:50 -0400 Subject: [PATCH 061/137] Added key name to unique constraint --- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index d5deec862d0..fd4368b78af 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -688,7 +688,7 @@ ALTER TABLE llx_actioncomm MODIFY COLUMN note mediumtext; DELETE FROM llx_boxes WHERE box_id IN (select rowid FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year')); DELETE FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year'); -ALTER TABLE llx_takepos_floor_tables ADD UNIQUE(entity,label); +ALTER TABLE llx_takepos_floor_tables ADD UNIQUE uk_takepos_floor_tables (entity,label); ALTER TABLE llx_partnership ADD COLUMN url_to_check varchar(255); ALTER TABLE llx_c_partnership_type ADD COLUMN keyword varchar(128); From bce55fc3b4252c5f012df34700c21e18c02120a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 01:40:20 +0100 Subject: [PATCH 062/137] Trans --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 28d2c7593fc..009dd47dbb5 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -451,7 +451,7 @@ ExtrafieldCheckBox=Checkboxes ExtrafieldCheckBoxFromList=Checkboxes from table ExtrafieldLink=Link to an object ComputedFormula=Computed field -ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: $db, $conf, $langs, $mysoc, $user, $object.
WARNING: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.
Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.

Example of formula:
$object->id < 10 ? round($object->id / 2, 2): ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)

Example to reload object
(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($obj->id ? $obj->id: ($obj->rowid ? $obj->rowid: $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1'

Other example of formula to force load of object and its parent object:
(($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref: 'Parent project not found' +ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: $db, $conf, $langs, $mysoc, $user, $objectoffield.
WARNING: If you need properties of an object not loaded, just fetch yourself the object into your formula like in the second example.
Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.

Example of formula:
$objectoffield->id < 10 ? round($objectoffield->id / 2, 2): ($objectoffield->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)

Example to reload object
(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($objectoffield->id) > 0 ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1')

Other example of formula to force load of object and its parent object:
(($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($objectoffield->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref: 'Parent project not found' Computedpersistent=Store computed field ComputedpersistentDesc=Computed extra fields will be stored in the database, however, the value will only be recalculated when the object of this field is changed. If the computed field depends on other objects or global data this value might be wrong!! ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).
Set 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value) From 7553a99fcb2d2469848ca1175054081a91fb1822 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 01:43:38 +0100 Subject: [PATCH 063/137] Doc --- ChangeLog | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4da3132248c..1b877e2b4b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,15 +3,6 @@ English Dolibarr ChangeLog -------------------------------------------------------------- -***** ChangeLog for 18.0.0 compared to 17.0.0 ***** - -WARNING: - -Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: -* The deprecated method escapeunderscore() of database handlers has been removed. You must use escapeforlike instead. - - - ***** ChangeLog for 17.0.0 compared to 16.0.0 ***** @@ -218,7 +209,8 @@ Following changes may create regressions for some external modules, but were nec * Tables llx_prelevement_facture and llx_prelevement_facture_demande have been renamed into llx_prelevement and llx_prelevement_demande. * Rename MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and rename MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES * Rename the substitution for "project label" instead of "project title" in substitution variables - +* You must use "$objectoffield" to manipulate the current object inside the formulare of computed custom extrafields instead of $obj/$object. + ***** ChangeLog for 16.0.4 compared to 16.0.3 ***** From 9d52783e8a4a24fac6edf05b02a4cfc0e4aeaedf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 09:09:47 +0100 Subject: [PATCH 064/137] Update ticket.class.php --- htdocs/ticket/class/ticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 693a239feac..ba8590dc8a5 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -239,7 +239,7 @@ class Ticket extends CommonObject public $oldcopy; /** - * @var array array of TicketsLine + * @var TicketsLine[] array of TicketsLine */ public $lines; From 7c4858fdc3ae5d42db94b4a63582aa788666b115 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 11:05:09 +0100 Subject: [PATCH 065/137] Add page with help for ingoing email setup --- htdocs/admin/mails_ingoing.php | 137 +++++++++++++++++++++++++++++++++ htdocs/core/lib/admin.lib.php | 5 ++ htdocs/langs/en_US/mails.lang | 1 + 3 files changed, 143 insertions(+) create mode 100644 htdocs/admin/mails_ingoing.php diff --git a/htdocs/admin/mails_ingoing.php b/htdocs/admin/mails_ingoing.php new file mode 100644 index 00000000000..010d933821e --- /dev/null +++ b/htdocs/admin/mails_ingoing.php @@ -0,0 +1,137 @@ + + * Copyright (C) 2009-2012 Regis Houssin + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2016 Jonathan TISSEAU + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/mails_ingoing.php + * \brief Page to setup emails entry + */ + +// Load Dolibarr environment +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("companies", "products", "admin", "mails", "other", "errors")); + +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); + +$trackid = GETPOST('trackid'); + +if (!$user->admin) { + accessforbidden(); +} + + +/* + * Actions + */ + +if ($action == 'update' && !$cancel) { +} + + + +/* + * View + */ + +$form = new Form($db); + +$linuxlike = 1; +if (preg_match('/^win/i', PHP_OS)) { + $linuxlike = 0; +} +if (preg_match('/^mac/i', PHP_OS)) { + $linuxlike = 0; +} + + +//$wikihelp = 'EN:Setup_EMails|FR:Paramétrage_EMails|ES:Configuración_EMails'; +$wikihelp = ''; +llxHeader('', $langs->trans("Setup"), $wikihelp); + +print load_fiche_titre($langs->trans("EMailsSetup"), '', 'title_setup'); + +$head = email_admin_prepare_head(); + +// List of sending methods +$listofmethods = array(); +$listofmethods['mail'] = 'PHP mail function'; +$listofmethods['smtps'] = 'SMTP/SMTPS socket library'; +if (version_compare(phpversion(), '7.0', '>=')) { + $listofmethods['swiftmailer'] = 'Swift Mailer socket library'; +} + +// List of oauth services +$oauthservices = array(); + +foreach ($conf->global as $key => $val) { + if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) { + $key = preg_replace('/^OAUTH_/', '', $key); + $key = preg_replace('/_ID$/', '', $key); + if (preg_match('/^.*-/', $key)) { + $name = preg_replace('/^.*-/', '', $key); + } else { + $name = $langs->trans("NoName"); + } + $provider = preg_replace('/-.*$/', '', $key); + $provider = ucfirst(strtolower($provider)); + + $oauthservices[$key] = $name." (".$provider.")"; + } +} + +print dol_get_fiche_head($head, 'common_ingoing', '', -1); + +print '
'; +print ''.$langs->trans("EMailsInGoingDesc", $langs->transnoentitiesnoconv("EmailCollector"))."
\n"; +print "

\n"; + +/* +print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print ''; +print ''; + +print '
'; + +print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + +// SMTPS oauth service +if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail'), array('smtps', 'swiftmailer')) && getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE') === "XOAUTH2") { + $text = $oauthservices[$conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE]; + if (empty($text)) { + $text = $langs->trans("Undefined").img_warning(); + } + print ''; +} + +print '
'.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").''.$text.'
'; +print '
'; +*/ + +print dol_get_fiche_end(); + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 71bcc082961..b3ee5dc259a 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -2054,6 +2054,11 @@ function email_admin_prepare_head() $head[$h][2] = 'templates'; $h++; + $head[$h][0] = DOL_URL_ROOT."/admin/mails_ingoing.php"; + $head[$h][1] = $langs->trans("InGoingEmailSetup", $langs->transnoentitiesnoconv("EMailing")); + $head[$h][2] = 'common_ingoing'; + $h++; + complete_head_from_modules($conf, $langs, null, $head, $h, 'email_admin', 'remove'); return $head; diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index f83637c9c40..a112de8ceb2 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -179,3 +179,4 @@ RecordCreatedByEmailCollector=Record created by the Email Collector %s from emai DefaultBlacklistMailingStatus=Default value for field '%s' when creating a new contact DefaultStatusEmptyMandatory=Empty but mandatory WarningLimitSendByDay=WARNING: The setup or contract of your instance limits your number of emails per day to %s. Trying to send more may result in having your instance slow down or suspended. Please contact your support if you need a higher quota. +EMailsInGoingDesc=Incoming emails are managed by the module %s. You must enable and configure it if you need to support ingoing emails. From c545b98a24deb842c72bc303d41b66a0cdfe059a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 11:39:29 +0100 Subject: [PATCH 066/137] The Use of PHP-IMAP lib must be enabled from interface --- htdocs/admin/emailcollector_list.php | 60 +++++++++++++++++----------- htdocs/langs/en_US/admin.lang | 1 + 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php index fb09143412f..de18b57b297 100644 --- a/htdocs/admin/emailcollector_list.php +++ b/htdocs/admin/emailcollector_list.php @@ -273,25 +273,6 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; - -/* If a group by is required -$sql.= " GROUP BY "; -foreach ($object->fields as $key => $val) { - $sql .= "t.".$db->escape($key).", "; -} -// Add fields from extrafields -if (!empty($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); - } -} -// Add where from hooks -$parameters=array(); -$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook -$sql .= $hookmanager->resPrint; -$sql = preg_replace('/,\s*$/', '', $sql); -*/ - // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { @@ -333,6 +314,22 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +$linkback = '
'.$langs->trans("BackToModuleList").''; +print load_fiche_titre($title, $linkback, 'title_setup'); + + +$head = array(); +$h = 0; +$head[$h][0] = DOL_URL_ROOT."/admin/emailcollector_list.php"; +$head[$h][1] = $langs->trans("Setup"); +$head[$h][2] = 'common'; +$h++; + +print dol_get_fiche_head($head, 'common', '', -1); + + + $arrayofselected = is_array($toselect) ? $toselect : array(); $param = ''; @@ -388,11 +385,9 @@ print ''; print ''; print ''; -$linkback = ''.$langs->trans("BackToModuleList").''; - $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'emailcollector_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'email', 0, $newcardbutton.' '.$linkback, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'email', 0, $newcardbutton, '', $limit, 0, 0, 1); // Add code for pre mass action (confirmation or email presend form) /*$topicmail=""; @@ -699,7 +694,22 @@ print ''.$langs->trans("Parameter").''; print ''; print "\n"; -// Hide e-mail headers from collected messages +// MAIN_IMAP_USE_PHPIMAP: Enable use of the PHP Imap library +print ''; +//print $form->textwithpicto($langs->trans("MAIN_IMAP_USE_PHPIMAP"), $langs->transnoentitiesnoconv("MAIN_IMAP_USE_PHPIMAPDesc")); +print $langs->trans("MAIN_IMAP_USE_PHPIMAP"); +print ''; +print ''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_IMAP_USE_PHPIMAP'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("MAIN_IMAP_USE_PHPIMAP", $arrval, $conf->global->MAIN_IMAP_USE_PHPIMAP); +} +print ''; +print ''; + +// MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER: Hide e-mail headers from collected messages print ''.$form->textwithpicto($langs->trans("EmailCollectorHideMailHeaders"), $langs->transnoentitiesnoconv("EmailCollectorHideMailHeadersHelp")).''; print ''; if ($conf->use_javascript_ajax) { @@ -738,6 +748,10 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n print $formfile->showdocuments('massfilesarea_emailcollector', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } + +dol_get_fiche_end(); + + // End of page llxFooter(); $db->close(); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 009dd47dbb5..66210ef9d52 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2348,3 +2348,4 @@ AllowExternalDownload=Allow external download (without login, using a shared lin DeadlineDayVATSubmission=Deadline day for vat submission on the next month MaxNumberOfAttachementOnForms=Max number of joinded files in a form IfDefinedUseAValueBeetween=If defined, use a value between %s and %s +MAIN_IMAP_USE_PHPIMAP=Use the PHP-IMAP library for IMAP instead of native PHP IMAP. This also allow the use of OAuth2 connection for IMAP. \ No newline at end of file From 2190dcc9f7e390d6e739fb3450dbd080c0f74c00 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 13:40:28 +0100 Subject: [PATCH 067/137] Fix status of website --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 3aa1b622f6e..3a625818ba4 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2807,7 +2807,7 @@ if (!GETPOST('hide_websitemenu')) { $atleastonepage = (is_array($array) && count($array) > 0); $websitepage = new WebSitePage($db); - if ($pageid > 0 && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')) { + if ($pageid > 0) { $websitepage->fetch($pageid); } From 31d5547e33e96dde2e74b0ca2e18dfaea5dca479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 13:48:07 +0100 Subject: [PATCH 068/137] clean code --- .../class/supplier_proposal.class.php | 44 ++++++------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index d7013c596b0..fbd95b25738 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2529,26 +2529,20 @@ class SupplierProposal extends CommonObject $url = ''; $result = ''; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } - $label = img_picto('', $this->picto).' '.$langs->trans("SupplierProposal").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); - } - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->ref_fourn)) { - $label .= '
'.$langs->trans('RefSupplier').': '.$this->ref_fourn; - } - if (!empty($this->total_ht)) { - $label .= '
'.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $label .= '
'.$langs->trans('VAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } + $label = implode($this->getTooltipContentArray($params)); if ($option == '') { $url = DOL_URL_ROOT.'/supplier_proposal/card.php?id='.$this->id.$get_params; @@ -2569,18 +2563,6 @@ class SupplierProposal extends CommonObject } $linkclose = ''; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'option' => $option, - ]; - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params='.json_encode($params); - // $label = $langs->trans('Loading'); - } if (empty($notooltip) && $user->rights->propal->lire) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowSupplierProposal"); From 2fd6b9438fb835bd865d86cc32e3c67ae62abc5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 13:55:36 +0100 Subject: [PATCH 069/137] add ajax tooltip on ticket --- htdocs/ticket/class/ticket.class.php | 57 +++++++++++++++++++++------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 5faea34ad6c..3be6e282875 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1400,6 +1400,34 @@ class Ticket extends CommonObject return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode, '', $params); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $langs; + + $langs->load('ticket'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Ticket").''; + $datas['picto'] .= ' '.$this->getLibStatut(4); + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + $datas['track_id'] = '
'.$langs->trans('TicketTrackId').': '.$this->track_id; + $datas['subject'] = '
'.$langs->trans('Subject').': '.$this->subject; + if ($this->date_creation) { + $datas['date_creation'] = '
'.$langs->trans('DateCreation').': '.$this->date_creation; + } + if ($this->date_modification) { + $datas['date_modification'] = '
'.$langs->trans('DateModification').': '.$this->date_modification; + } + + return $datas; + } /** * Return a link to the object card (with optionaly the picto) @@ -1423,18 +1451,19 @@ class Ticket extends CommonObject $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("Ticket").''; - $label .= ' '.$this->getLibStatut(4); - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref.'
'; - $label .= ''.$langs->trans('TicketTrackId').': '.$this->track_id.'
'; - $label .= ''.$langs->trans('Subject').': '.$this->subject; - if ($this->date_creation) { - $label .= '
'.$langs->trans('DateCreation').': '.$this->date_creation; - } - if ($this->date_modification) { - $label .= '
'.$langs->trans('DateModification').': '.$this->date_modification; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } + $label = implode($this->getTooltipContentArray($params)); + $url = DOL_URL_ROOT.'/ticket/card.php?id='.$this->id; if ($option != 'nolink') { @@ -1454,8 +1483,8 @@ class Ticket extends CommonObject $label = $langs->trans("ShowTicket"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1466,7 +1495,7 @@ class Ticket extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From df411abe414edf82363c00a1346f45e02c7f7218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 14:07:27 +0100 Subject: [PATCH 070/137] add ajax tooltip on task --- htdocs/core/ajax/ajaxtooltip.php | 3 +- htdocs/projet/class/task.class.php | 56 +++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index a72b57c4ebe..7afbc88ae17 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -130,8 +130,7 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $langs->load('projects'); $classpath = 'projet/class'; $module = 'projet'; -} elseif ($objecttype == 'task') { - $langs->load('projects'); +} elseif ($objecttype == 'project_task') { $classpath = 'projet/class'; $module = 'projet'; $myobject = 'task'; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 597e680f8f0..1a4f96bacc6 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2008-2014 Laurent Destailleur * Copyright (C) 2010-2012 Regis Houssin * Copyright (C) 2014 Marcos García - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2023 Frédéric France * Copyright (C) 2020 Juanjo Menent * Copyright (C) 2022 Charlene Benke * @@ -696,6 +696,34 @@ class Task extends CommonObjectLine } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $langs; + + $langs->load('projects'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Task").''; + if (!empty($this->ref)) { + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + } + if (!empty($this->label)) { + $datas['label'] = '
'.$langs->trans('LabelTask').': '.$this->label; + } + if ($this->date_start || $this->date_end) { + $datas['range'] = "
".get_date_range($this->date_start, $this->date_end, '', $langs, 0); + } + + return $datas; + } + /** * Return clicable name (with picto eventually) * @@ -717,16 +745,18 @@ class Task extends CommonObjectLine } $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("Task").''; - if (!empty($this->ref)) { - $label .= '
'.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->label)) { - $label .= '
'.$langs->trans('LabelTask').': '.$this->label; - } - if ($this->date_start || $this->date_end) { - $label .= "
".get_date_range($this->date_start, $this->date_end, '', $langs, 0); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/projet/tasks/'.$mode.'.php?id='.$this->id.($option == 'withproject' ? '&withproject=1' : ''); // Add param to save lastsearch_values or not @@ -744,8 +774,8 @@ class Task extends CommonObjectLine $label = $langs->trans("ShowTask"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip nowraponall"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.' nowraponall"'; } else { $linkclose .= ' class="nowraponall"'; } @@ -758,7 +788,7 @@ class Task extends CommonObjectLine $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 8d1a84d56c8fece9c540247c7e2b3037f0193818 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Tue, 7 Feb 2023 14:56:38 +0100 Subject: [PATCH 071/137] fix : Warning: Undefined property: ExpenseReport:: in /home/httpd/vhosts/aflac.fr/domains/dev.aflac.fr/httpdocs/core/lib/pdf.lib.php on line 2289 --- .../expensereport/class/expensereport.class.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 2c4b4bec855..74d668f9d59 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -133,6 +133,21 @@ class ExpenseReport extends CommonObject public $statuts_short = array(); public $statuts_logo; + // Multicurrency + /** + * @var int Currency ID + */ + public $fk_multicurrency; + + /** + * @var string multicurrency code + */ + public $multicurrency_code; + public $multicurrency_tx; + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; + /** * Draft status From 495a8656522df4c752c4f48ddbf5ed39d268889b Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Tue, 7 Feb 2023 14:59:02 +0100 Subject: [PATCH 072/137] fix : Warning: Undefined property: ExpenseReportLine:: in /home/httpd/vhosts/aflac.fr/domains/dev.aflac.fr/httpdocs/core/lib/pdf.lib.php on line 2289 --- .../expensereport/class/expensereport.class.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 74d668f9d59..5526b5564c4 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -2754,6 +2754,21 @@ class ExpenseReportLine extends CommonObjectLine public $total_localtax1; public $total_localtax2; + // Multicurrency + /** + * @var int Currency ID + */ + public $fk_multicurrency; + + /** + * @var string multicurrency code + */ + public $multicurrency_code; + public $multicurrency_tx; + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; + /** * @var int ID into llx_ecm_files table to link line to attached file */ From 4cd7f7bedaceaaea1898bb04cf141127ef9c5fc6 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Tue, 7 Feb 2023 15:56:28 +0100 Subject: [PATCH 073/137] fix : Warning: Undefined property: pdf_standard:: in /home/httpd/vhosts/aflac.fr/domains/dev.aflac.fr/httpdocs/core/modules/expensereport/doc/pdf_standard.modules.php on line 582 --- htdocs/core/modules/expensereport/doc/pdf_standard.modules.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index f365173ddbe..80418a86f91 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -92,6 +92,7 @@ class pdf_standard extends ModeleExpenseReport public $posxtva; public $posxup; public $posxqty; + public $posxtype; public $postotalht; public $postotalttc; From 9ad29faa32520163fe8e461c093891201f45146e Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Tue, 7 Feb 2023 16:01:09 +0100 Subject: [PATCH 074/137] fix : Warning: Undefined property: pdf_standard:: in /home/httpd/vhosts/aflac.fr/domains/dev.aflac.fr/httpdocs/core/modules/expensereport/doc/pdf_standard.modules.php on line 589 --- htdocs/core/modules/expensereport/doc/pdf_standard.modules.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index 80418a86f91..4363a7e90f1 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -1,7 +1,7 @@ * Copyright (C) 2015 Alexandre Spangaro - * Copyright (C) 2016-2022 Philippe Grand + * Copyright (C) 2016-2023 Philippe Grand * Copyright (C) 2018-2020 Frédéric France * Copyright (C) 2018 Francis Appels * Copyright (C) 2019 Markus Welters @@ -93,6 +93,7 @@ class pdf_standard extends ModeleExpenseReport public $posxup; public $posxqty; public $posxtype; + public $posxprojet; public $postotalht; public $postotalttc; From 6f8c26fa4741b8d491d78c8937aeb3bfcf2da50f Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Tue, 7 Feb 2023 16:18:13 +0100 Subject: [PATCH 075/137] NEW can stay on edit field when errors occurs --- htdocs/core/class/html.form.class.php | 8 ++++++-- htdocs/product/stock/productlot_card.php | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c6cf71fbe44..7de2938e299 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -202,9 +202,10 @@ class Form * @param string $paramid Key of parameter for id ('id', 'socid') * @param string $gm 'auto' or 'tzuser' or 'tzuserrel' or 'tzserver' (when $typeofdata is a date) * @param array $moreoptions Array with more options. For example array('addnowlink'=>1), array('valuealreadyhtmlescaped'=>1) + * @param string $editaction [=''] use GETPOST default action or set action to edit mode * @return string HTML edit field */ - public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 1, $formatfunc = '', $paramid = 'id', $gm = 'auto', $moreoptions = array()) + public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 1, $formatfunc = '', $paramid = 'id', $gm = 'auto', $moreoptions = array(), $editaction = '') { global $conf, $langs; @@ -233,7 +234,10 @@ class Form if (!empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && !preg_match('/^select;|day|datepicker|dayhour|datehourpicker/', $typeofdata)) { // TODO add jquery timepicker and support select $ret .= $this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg); } else { - $editmode = (GETPOST('action', 'aZ09') == 'edit'.$htmlname); + if ($editaction == '') { + $editaction = GETPOST('action', 'aZ09'); + } + $editmode = ($editaction == 'edit'.$htmlname); if ($editmode) { $ret .= "\n"; $ret .= '
'; diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php index acf2f526773..a39d92f93aa 100644 --- a/htdocs/product/stock/productlot_card.php +++ b/htdocs/product/stock/productlot_card.php @@ -469,7 +469,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print $form->editfieldkey($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker'); print ''; - print $form->editfieldval($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker'); + print $form->editfieldval($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker', '', null, null, '', 1, '', 'id', 'auto', array(), $action); print ''; print ''; } @@ -479,7 +479,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print $form->editfieldkey($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker'); print ''; - print $form->editfieldval($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker'); + print $form->editfieldval($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker', '', null, null, '', 1, '', 'id', 'auto', array(), $action); print ''; print ''; } From 55d6e2ead026cf7dde9124e26432d97e3b63a9b5 Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 7 Feb 2023 17:24:16 +0100 Subject: [PATCH 076/137] Fix prelevement line : the link to the facture was to a customer facture, even when it was a facturefourn. --- htdocs/compta/prelevement/line.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/prelevement/line.php b/htdocs/compta/prelevement/line.php index cba7777b734..6eb10ce6a1a 100644 --- a/htdocs/compta/prelevement/line.php +++ b/htdocs/compta/prelevement/line.php @@ -309,7 +309,11 @@ if ($id) { print img_object($langs->trans("ShowBill"), "bill"); print ' '; - print ''.$obj->ref."\n"; + if ($type == 'bank-transfer') { + print ''.$obj->ref."\n"; + } else { + print ''.$obj->ref."\n"; + } print ''; print img_object($langs->trans("ShowCompany"), "company").' '.$obj->name."\n"; From e71ad2e23bd937ee3d448c365a997f3357dfd63a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 20:12:53 +0100 Subject: [PATCH 077/137] Maxi debug of OAuth module --- htdocs/admin/oauth.php | 21 +- htdocs/admin/oauthlogintokens.php | 31 ++- htdocs/core/lib/functions.lib.php | 4 +- htdocs/core/lib/oauth.lib.php | 12 +- .../modules/oauth/generic_oauthcallback.php | 49 ++-- .../modules/oauth/github_oauthcallback.php | 23 +- .../modules/oauth/google_oauthcallback.php | 5 +- .../modules/oauth/microsoft_oauthcallback.php | 211 ++++++++++++++++++ .../oauth/stripelive_oauthcallback.php | 27 +-- .../oauth/stripetest_oauthcallback.php | 27 +-- .../OAuth/Common/Storage/DoliStorage.php | 6 + .../OAuth/OAuth2/Service/AbstractService.php | 4 +- .../OAuth/OAuth2/Service/Microsoft.php | 64 +++--- htdocs/langs/en_US/admin.lang | 3 +- htdocs/langs/en_US/mails.lang | 1 - htdocs/langs/en_US/oauth.lang | 1 + 16 files changed, 348 insertions(+), 141 deletions(-) create mode 100644 htdocs/core/modules/oauth/microsoft_oauthcallback.php diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index 217dfd63cc9..2425f12d9bd 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -84,6 +84,11 @@ if ($action == 'update') { $error++; } } + if (GETPOSTISSET($constvalue.'_TENANT')) { + if (!dolibarr_set_const($db, $constvalue.'_TENANT', GETPOST($constvalue.'_TENANT'), 'chaine', 0, '', $conf->entity)) { + $error++; + } + } if (GETPOSTISSET($constvalue.'_SCOPE')) { if (is_array(GETPOST($constvalue.'_SCOPE'))) { $scopestring = implode(',', GETPOST($constvalue.'_SCOPE')); @@ -128,6 +133,8 @@ if ($action == 'confirm_delete') { $callbacktodel .= '/core/modules/oauth/stripelive_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl); } elseif ($label == 'OAUTH_STRIPE_TEST') { $callbacktodel .= '/core/modules/oauth/stripetest_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl); + } elseif ($label == 'OAUTH_MICROSOFT') { + $callbacktodel .= '/core/modules/oauth/microsoft_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl); } elseif ($label == 'OAUTH_OTHER') { $callbacktodel .= '/core/modules/oauth/generic_oauthcallback.php?action=delete&keyforprovider='.$provider.'&token='.newToken().'&backtourl='.urlencode($backtourl); } @@ -242,8 +249,10 @@ if (count($listinsetup) > 0) { $keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array); $keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array); if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { + $keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); } else { + $keybeforeprovider = $keyforsupportedoauth2array; $keyforprovider = ''; } $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); @@ -337,6 +346,16 @@ if (count($listinsetup) > 0) { print ''; print ''; + // Tenant + if ($keybeforeprovider == 'MICROSOFT') { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + // TODO Move this into token generation ? if ($supported) { if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') { @@ -386,7 +405,7 @@ if (count($listinsetup) > 0) { print '
'; - print $form->buttonsSaveCancel("Modify", ''); + print $form->buttonsSaveCancel("Save", ''); print ''; } diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index 9a0532880cd..d6fcc9e0f7c 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -162,8 +162,10 @@ if ($mode == 'setup' && $user->admin) { $keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array); $keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array); if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { + $keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); } else { + $keybeforeprovider = $keyforsupportedoauth2array; $keyforprovider = ''; } $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); @@ -179,13 +181,12 @@ if ($mode == 'setup' && $user->admin) { $state = $shortscope; // TODO USe a better state // Define $urltorenew, $urltodelete, $urltocheckperms - // TODO Use array $supportedoauth2array if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // We pass this param list in to 'state' because we need it before and after the redirect. // Note: github does not accept csrf key inside the state parameter (only known values) - $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://github.com/settings/applications/'; } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') { @@ -195,17 +196,9 @@ if ($mode == 'setup' && $user->admin) { $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://security.google.com/settings/security/permissions'; - } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') { - $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); - $urltodelete = ''; - $urltocheckperms = ''; - } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') { - $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); - $urltodelete = ''; - $urltocheckperms = ''; - } elseif ($keyforsupportedoauth2array = 'OAUTH_OTHER_NAME') { - $urltorenew = $urlwithroot.'/core/modules/oauth/generic_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); - $urltodelete = ''; + } elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) { + $urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = ''; } else { $urltorenew = ''; @@ -220,17 +213,19 @@ if ($mode == 'setup' && $user->admin) { $urltodelete .= '&keyforprovider='.urlencode($keyforprovider); } - // Show value of token $tokenobj = null; // Token require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; // Dolibarr storage - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { + // $OAUTH_SERVICENAME is for example 'Google-keyforprovider' + print $OAUTH_SERVICENAME; $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); } catch (Exception $e) { // Return an error if token not found + //print $e->getMessage(); } // Set other properties @@ -321,7 +316,11 @@ if ($mode == 'setup' && $user->admin) { // Links to delete/checks token if (is_object($tokenobj)) { //test on $storage->hasAccessToken($OAUTH_SERVICENAME) ? - print ''.$langs->trans('DeleteAccess').'
'; + if ($urltodelete) { + print ''.$langs->trans('DeleteAccess').'
'; + } else { + print ''.$langs->trans('GoOnTokenProviderToDeleteToken').'
'; + } } // Request remote token if ($urltorenew) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index d47b71d39cf..e94b9d5e4c0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4102,7 +4102,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'proposal', 'puce', 'stock', 'resize', 'service', 'stats', 'trip', 'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench', - 'github', 'google', 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', + 'github', 'google', 'jabber', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', 'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies', 'generic', 'home', 'hrm', 'members', 'products', 'invoicing', 'partnership', 'payment', 'payment_vat', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region', @@ -4123,7 +4123,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ if (in_array($pictowithouttext, array('card', 'bell', 'clock', 'establishment', 'generic', 'minus-square', 'object_generic', 'pdf', 'plus-square', 'timespent', 'note', 'off', 'on', 'object_bookmark', 'bookmark', 'vcard'))) { $fa = 'far'; } - if (in_array($pictowithouttext, array('black-tie', 'github', 'google', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) { + if (in_array($pictowithouttext, array('black-tie', 'github', 'google', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) { $fa = 'fab'; } diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php index 83359ef1c65..4f504196b47 100644 --- a/htdocs/core/lib/oauth.lib.php +++ b/htdocs/core/lib/oauth.lib.php @@ -25,15 +25,17 @@ // Supported OAUTH (a provider is supported when a file xxx_oauthcallback.php is available into htdocs/core/modules/oauth) $supportedoauth2array = array( - 'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google', 'urlforcredentials'=>'https://console.developers.google.com/', 'availablescopes'=> 'userinfo_email,userinfo_profile,openid,email,profile,cloud_print,admin_directory_user,gmail_full'), + 'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google', 'urlforcredentials'=>'https://console.developers.google.com/', 'availablescopes'=> 'userinfo_email,userinfo_profile,openid,email,profile,cloud_print,admin_directory_user,gmail_full', 'returnurl'=>'/core/modules/oauth/google_oauthcallback.php'), ); if (isModEnabled('stripe')) { - $supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest', 'urlforcredentials'=>'', 'availablescopes'=>'read_write'); - $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'availablescopes'=>'read_write'); + $supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest', 'urlforcredentials'=>'', 'availablescopes'=>'read_write', 'returnurl'=>'/core/modules/oauth/stripetest_oauthcallback.php'); + $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'availablescopes'=>'read_write', 'returnurl'=>'/core/modules/oauth/stripelive_oauthcallback.php'); } -$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'availablescopes'=>'user,public_repo'); +$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'availablescopes'=>'user,public_repo', 'returnurl'=>'/core/modules/oauth/github_oauthcallback.php'); if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { - $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard'); + $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard', 'returnurl'=>'/core/modules/oauth/generic_oauthcallback.php'); + // See https://learn.microsoft.com/fr-fr/azure/active-directory/develop/quickstart-register-app#register-an-application + $supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); } diff --git a/htdocs/core/modules/oauth/generic_oauthcallback.php b/htdocs/core/modules/oauth/generic_oauthcallback.php index 34422111d5d..a394c7f4986 100644 --- a/htdocs/core/modules/oauth/generic_oauthcallback.php +++ b/htdocs/core/modules/oauth/generic_oauthcallback.php @@ -66,7 +66,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient(); $serviceFactory->setHttpClient($httpClient); // Dolibarr storage -$storage = new DoliStorage($db, $conf); +$storage = new DoliStorage($db, $conf, $keyforprovider); // Setup the credentials for the requests $keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID'; @@ -77,9 +77,11 @@ $credentials = new Credentials( $currentUri->getAbsoluteUri() ); +$state = GETPOST('state'); + $requestedpermissionsarray = array(); -if (GETPOST('state')) { - $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back +if ($state) { + $requestedpermissionsarray = explode(',', $state); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back } if ($action != 'delete' && empty($requestedpermissionsarray)) { print 'Error, parameter state is not defined'; @@ -88,7 +90,8 @@ if ($action != 'delete' && empty($requestedpermissionsarray)) { //var_dump($requestedpermissionsarray);exit; // Instantiate the Api service using the credentials, http client and storage mechanism for the token -$apiService = $serviceFactory->createService($genericstring, $credentials, $storage, $requestedpermissionsarray); +// ucfirst(strtolower($genericstring)) must be the name of a class into OAuth/OAuth2/Services/Xxxx +$apiService = $serviceFactory->createService(ucfirst(strtolower($genericstring)), $credentials, $storage, $requestedpermissionsarray); /* var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : '')); @@ -128,35 +131,25 @@ if ($action == 'delete') { exit(); } -if (GETPOST('code')) { // We are coming from oauth provider page +if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provider page // We should have //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) - dol_syslog("We are coming from the oauth provider page"); - //llxHeader('',$langs->trans("OAuthSetup")); - - //$linkback=''.$langs->trans("BackToModuleList").''; - //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup'); - - //print dol_get_fiche_head(); - // retrieve the CSRF state parameter - $state = GETPOSTISSET('state') ? GETPOST('state') : null; - //print ''; + dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)." error=".GETPOST('error')); // This was a callback request from service, get the token try { - //var_dump($_GET['code']); //var_dump($state); - //var_dump($apiService); // OAuth\OAuth2\Service\GitHub + //var_dump($apiService); // OAuth\OAuth2\Service\Xxx - //$token = $apiService->requestAccessToken(GETPOST('code'), $state); - $token = $apiService->requestAccessToken(GETPOST('code')); - // Github is a service that does not need state to be stored. - // Into constructor of GitHub, the call - // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) - // has not the ending parameter to true like the Google class constructor. + if (GETPOST('error')) { + setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors'); + } else { + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); + $token = $apiService->requestAccessToken(GETPOST('code')); - setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + } $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; unset($_SESSION["backtourlsavedbeforeoauthjump"]); @@ -166,15 +159,17 @@ if (GETPOST('code')) { // We are coming from oauth provider page } catch (Exception $e) { print $e->getMessage(); } -} else { // If entry on page with no parameter, we arrive here +} else { + // If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect + // to the OAuth provider login page. $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl; $_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider; $_SESSION['oauthstateanticsrf'] = $state; // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). - if (GETPOST('state')) { - $url = $apiService->getAuthorizationUri(array('state' => GETPOST('state'))); + if ($state) { + $url = $apiService->getAuthorizationUri(array('state' => $state)); } else { $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated } diff --git a/htdocs/core/modules/oauth/github_oauthcallback.php b/htdocs/core/modules/oauth/github_oauthcallback.php index 24140718880..7656a1cda37 100644 --- a/htdocs/core/modules/oauth/github_oauthcallback.php +++ b/htdocs/core/modules/oauth/github_oauthcallback.php @@ -65,7 +65,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient(); $serviceFactory->setHttpClient($httpClient); // Dolibarr storage -$storage = new DoliStorage($db, $conf); +$storage = new DoliStorage($db, $conf, $keyforprovider); // Setup the credentials for the requests $keyforparamid = 'OAUTH_GITHUB'.($keyforprovider ? '-'.$keyforprovider : '').'_ID'; @@ -115,30 +115,21 @@ if ($action == 'delete') { exit(); } -if (!empty($_GET['code'])) { // We are coming from oauth provider page +if (GETPOST('code')) { // We are coming from oauth provider page // We should have //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) - dol_syslog("We are coming from the oauth provider page"); - //llxHeader('',$langs->trans("OAuthSetup")); - - //$linkback=''.$langs->trans("BackToModuleList").''; - //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup'); - - //print dol_get_fiche_head(); - // retrieve the CSRF state parameter - $state = isset($_GET['state']) ? $_GET['state'] : null; - //print '
'; + dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)); // This was a callback request from service, get the token try { - //var_dump($_GET['code']); //var_dump($state); //var_dump($apiService); // OAuth\OAuth2\Service\GitHub - //$token = $apiService->requestAccessToken($_GET['code'], $state); - $token = $apiService->requestAccessToken($_GET['code']); - // Github is a service that does not need state to be stored. + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); + $token = $apiService->requestAccessToken(GETPOST('code')); + // Github is a service that does not need state to be stored as second paramater of requestAccessToken + // Into constructor of GitHub, the call // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) // has not the ending parameter to true like the Google class constructor. diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index ed0caa1a4ff..c26187e4475 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -137,7 +137,7 @@ if ($action == 'delete') { } if (GETPOST('code')) { // We are coming from oauth provider page. - dol_syslog("We are coming from the oauth provider page keyforprovider=".$keyforprovider); + dol_syslog("We are coming from the oauth provider page keyforprovider=".$keyforprovider." code=".dol_trunc(GETPOST('code'), 5)); // We must validate that the $state is the same than the one into $_SESSION['oauthstateanticsrf'], return error if not. if (isset($_SESSION['oauthstateanticsrf']) && $state != $_SESSION['oauthstateanticsrf']) { @@ -146,7 +146,6 @@ if (GETPOST('code')) { // We are coming from oauth provider page. } else { // This was a callback request from service, get the token try { - //var_dump($_GET['code']); //var_dump($state); //var_dump($apiService); // OAuth\OAuth2\Service\Google @@ -193,7 +192,7 @@ if (GETPOST('code')) { // We are coming from oauth provider page. } } } else { - // If we enter this page without 'code' parameter, we arrive here. this is the case when we want to get the redirect + // If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect // to the OAuth provider login page. $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl; $_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider; diff --git a/htdocs/core/modules/oauth/microsoft_oauthcallback.php b/htdocs/core/modules/oauth/microsoft_oauthcallback.php new file mode 100644 index 00000000000..ed47eec06e1 --- /dev/null +++ b/htdocs/core/modules/oauth/microsoft_oauthcallback.php @@ -0,0 +1,211 @@ + + * Copyright (C) 2015 Frederic 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/modules/oauth/microsoft_oauthcallback.php + * \ingroup oauth + * \brief Page to get oauth callback + */ + +// Load Dolibarr environment +require '../../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; +use OAuth\Common\Storage\DoliStorage; +use OAuth\Common\Consumer\Credentials; +use OAuth\OAuth2\Service\GitHub; + +// Define $urlwithroot +$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); +$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + +$action = GETPOST('action', 'aZ09'); +$backtourl = GETPOST('backtourl', 'alpha'); +$keyforprovider = GETPOST('keyforprovider', 'aZ09'); +if (empty($keyforprovider) && !empty($_SESSION["oauthkeyforproviderbeforeoauthjump"]) && (GETPOST('code') || $action == 'delete')) { + $keyforprovider = $_SESSION["oauthkeyforproviderbeforeoauthjump"]; +} +$genericstring = 'MICROSOFT'; + + +/** + * Create a new instance of the URI class with the current URI, stripping the query string + */ +$uriFactory = new \OAuth\Common\Http\Uri\UriFactory(); +//$currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER); +//$currentUri->setQuery(''); +$currentUri = $uriFactory->createFromAbsolute($urlwithroot.'/core/modules/oauth/microsoft_oauthcallback.php'); + + +/** + * Load the credential for the service + */ + +/** @var $serviceFactory \OAuth\ServiceFactory An OAuth service factory. */ +$serviceFactory = new \OAuth\ServiceFactory(); +$httpClient = new \OAuth\Common\Http\Client\CurlClient(); +// TODO Set options for proxy and timeout +// $params=array('CURLXXX'=>value, ...) +//$httpClient->setCurlParameters($params); +$serviceFactory->setHttpClient($httpClient); + +// Dolibarr storage +$storage = new DoliStorage($db, $conf, $keyforprovider); + +// Setup the credentials for the requests +$keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID'; +$keyforparamsecret = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_SECRET'; +$keyforparamtenant = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_TENANT'; +$credentials = new Credentials( + getDolGlobalString($keyforparamid), + getDolGlobalString($keyforparamsecret), + $currentUri->getAbsoluteUri() +); + +$state = GETPOST('state'); + +$requestedpermissionsarray = array(); +if ($state) { + $requestedpermissionsarray = explode(',', $state); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back +} +if ($action != 'delete' && empty($requestedpermissionsarray)) { + print 'Error, parameter state is not defined'; + exit; +} +//var_dump($requestedpermissionsarray);exit; + +// Instantiate the Api service using the credentials, http client and storage mechanism for the token +// ucfirst(strtolower($genericstring)) must be the name of a class into OAuth/OAuth2/Services/Xxxx +// $requestedpermissionsarray contains list of scopes. +// Conversion into URL is done by Reflection on constant with name SCOPE_scope_in_uppercase +try { + $apiService = $serviceFactory->createService(ucfirst(strtolower($genericstring)), $credentials, $storage, $requestedpermissionsarray); +} catch (Exception $e) { + print $e->getMessage(); + exit; +} +/* +var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : '')); +var_dump($credentials); +var_dump($storage); +var_dump($requestedpermissionsarray); +*/ + +if (empty($apiService)) { + print 'Error, failed to create serviceFactory'; + exit; +} + +// access type needed to have oauth provider refreshing token +//$apiService->setAccessType('offline'); + +$langs->load("oauth"); + +if (!getDolGlobalString($keyforparamid)) { + accessforbidden('Setup of service is not complete. Customer ID is missing'); +} +if (!getDolGlobalString($keyforparamsecret)) { + accessforbidden('Setup of service is not complete. Secret key is missing'); +} + + +/* + * Actions + */ + +if ($action == 'delete') { + $storage->clearToken($genericstring); + + setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs'); + + header('Location: '.$backtourl); + exit(); +} + +//dol_syslog("GET=".join(',', $_GET)); + + +if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provider page + // We should have + //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) + + dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)." error=".GETPOST('error')); + + // This was a callback request from service, get the token + try { + //var_dump($state); + //var_dump($apiService); // OAuth\OAuth2\Service\Microsoft + + if (GETPOST('error')) { + setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors'); + } else { + $apiService->tenant = getDolGlobalString($keyforparamtenant); + + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); + $token = $apiService->requestAccessToken(GETPOST('code')); + // Microsoft is a service that does not need state to be stored as second paramater of requestAccessToken + + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + } + + $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; + unset($_SESSION["backtourlsavedbeforeoauthjump"]); + + header('Location: '.$backtourl); + exit(); + } catch (Exception $e) { + print $e->getMessage(); + } +} else { + // If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect + // to the OAuth provider login page. + $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl; + $_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider; + $_SESSION['oauthstateanticsrf'] = $state; + + //if (!preg_match('/^forlogin/', $state)) { + // $apiService->setApprouvalPrompt('auto'); + //} + $apiService->tenant = getDolGlobalString($keyforparamtenant); + + // This may create record into oauth_state before the header redirect. + // Creation of record with state in this tables depend on the Provider used (see its constructor). + if ($state) { + $url = $apiService->getAuthorizationUri(array('state' => $state)); + } else { + $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated + } + + // Show url to get authorization + //var_dump((string) $url);exit; + dol_syslog("Redirect to url=".$url); + + // we go on oauth provider authorization page + header('Location: '.$url); + exit(); +} + + +/* + * View + */ + +// No view at all, just actions + +$db->close(); diff --git a/htdocs/core/modules/oauth/stripelive_oauthcallback.php b/htdocs/core/modules/oauth/stripelive_oauthcallback.php index ef35b6573cc..bc16b44461a 100644 --- a/htdocs/core/modules/oauth/stripelive_oauthcallback.php +++ b/htdocs/core/modules/oauth/stripelive_oauthcallback.php @@ -65,7 +65,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient(); $serviceFactory->setHttpClient($httpClient); // Dolibarr storage -$storage = new DoliStorage($db, $conf); +$storage = new DoliStorage($db, $conf, $keyforprovider); // Setup the credentials for the requests $keyforparamid = 'OAUTH_STRIPE_LIVE'.($keyforprovider ? '-'.$keyforprovider : '').'_ID'; @@ -121,33 +121,20 @@ if ($action == 'delete') { exit(); } -if (!empty($_GET['code'])) { // We are coming from oauth provider page +if (GETPOST('code')) { // We are coming from oauth provider page // We should have //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) - dol_syslog("We are coming from the oauth provider page"); - //llxHeader('',$langs->trans("OAuthSetup")); - - //$linkback=''.$langs->trans("BackToModuleList").''; - //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup'); - - //print dol_get_fiche_head(); - // retrieve the CSRF state parameter - $state = isset($_GET['state']) ? $_GET['state'] : null; - //print '
'; + dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)); // This was a callback request from service, get the token try { - //var_dump($_GET['code']); //var_dump($state); - //var_dump($apiService); // OAuth\OAuth2\Service\GitHub + //var_dump($apiService); // OAuth\OAuth2\Service\Stripe - //$token = $apiService->requestAccessToken($_GET['code'], $state); - $token = $apiService->requestAccessToken($_GET['code']); - // Github is a service that does not need state to be stored. - // Into constructor of GitHub, the call - // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) - // has not the ending parameter to true like the Google class constructor. + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); + $token = $apiService->requestAccessToken(GETPOST('code')); + // Stripe is a service that does not need state to be stored as second paramater of requestAccessToken setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token diff --git a/htdocs/core/modules/oauth/stripetest_oauthcallback.php b/htdocs/core/modules/oauth/stripetest_oauthcallback.php index a5d481dbef5..12d133da14c 100644 --- a/htdocs/core/modules/oauth/stripetest_oauthcallback.php +++ b/htdocs/core/modules/oauth/stripetest_oauthcallback.php @@ -65,7 +65,7 @@ $httpClient = new \OAuth\Common\Http\Client\CurlClient(); $serviceFactory->setHttpClient($httpClient); // Dolibarr storage -$storage = new DoliStorage($db, $conf); +$storage = new DoliStorage($db, $conf, $keyforprovider); // Setup the credentials for the requests $keyforparamid = 'OAUTH_STRIPE_TEST'.($keyforprovider ? '-'.$keyforprovider : '').'_ID'; @@ -121,33 +121,20 @@ if ($action == 'delete') { exit(); } -if (!empty($_GET['code'])) { // We are coming from oauth provider page +if (GETPOST('code')) { // We are coming from oauth provider page // We should have //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) - dol_syslog("We are coming from the oauth provider page"); - //llxHeader('',$langs->trans("OAuthSetup")); - - //$linkback=''.$langs->trans("BackToModuleList").''; - //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup'); - - //print dol_get_fiche_head(); - // retrieve the CSRF state parameter - $state = isset($_GET['state']) ? $_GET['state'] : null; - //print '
'; + dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)); // This was a callback request from service, get the token try { - //var_dump($_GET['code']); //var_dump($state); - //var_dump($apiService); // OAuth\OAuth2\Service\GitHub + //var_dump($apiService); // OAuth\OAuth2\Service\Stripe - //$token = $apiService->requestAccessToken($_GET['code'], $state); - $token = $apiService->requestAccessToken($_GET['code']); - // Github is a service that does not need state to be stored. - // Into constructor of GitHub, the call - // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) - // has not the ending parameter to true like the Google class constructor. + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); + $token = $apiService->requestAccessToken(GETPOST('code')); + // Stripe is a service that does not need state to be stored as second paramater of requestAccessToken setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token diff --git a/htdocs/includes/OAuth/Common/Storage/DoliStorage.php b/htdocs/includes/OAuth/Common/Storage/DoliStorage.php index 3e09e53fbe6..cf280262e99 100644 --- a/htdocs/includes/OAuth/Common/Storage/DoliStorage.php +++ b/htdocs/includes/OAuth/Common/Storage/DoliStorage.php @@ -126,6 +126,9 @@ class DoliStorage implements TokenStorageInterface $sql.= " SET token = '".$this->db->escape($serializedToken)."'"; $sql.= " WHERE rowid = ".((int) $obj['rowid']); $resql = $this->db->query($sql); + if (!$resql) { + dol_print_error($this->db); + } } else { // save $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity, datec)"; @@ -133,6 +136,9 @@ class DoliStorage implements TokenStorageInterface $sql .= " '".$this->db->idate(dol_now())."'"; $sql .= ")"; $resql = $this->db->query($sql); + if (!$resql) { + dol_print_error($this->db); + } } //print $sql; diff --git a/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php b/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php index 996506afbec..0de0219306a 100644 --- a/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php +++ b/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php @@ -56,8 +56,8 @@ abstract class AbstractService extends BaseAbstractService implements ServiceInt $this->stateParameterInAuthUrl = $stateParameterInAutUrl; foreach ($scopes as $scope) { - if (!$this->isValidScope($scope)) { - throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this)); + if (!$this->isValidScope($scope)) { + throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this)); } } diff --git a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php index c815b22bd44..b1b6a042c01 100644 --- a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php +++ b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php @@ -12,30 +12,35 @@ use OAuth\Common\Http\Uri\UriInterface; class Microsoft extends AbstractService { - const SCOPE_BASIC = 'wl.basic'; - const SCOPE_OFFLINE = 'wl.offline_access'; - const SCOPE_SIGNIN = 'wl.signin'; - const SCOPE_BIRTHDAY = 'wl.birthday'; - const SCOPE_CALENDARS = 'wl.calendars'; - const SCOPE_CALENDARS_UPDATE = 'wl.calendars_update'; - const SCOPE_CONTACTS_BIRTHDAY = 'wl.contacts_birthday'; - const SCOPE_CONTACTS_CREATE = 'wl.contacts_create'; - const SCOPE_CONTACTS_CALENDARS = 'wl.contacts_calendars'; - const SCOPE_CONTACTS_PHOTOS = 'wl.contacts_photos'; - const SCOPE_CONTACTS_SKYDRIVE = 'wl.contacts_skydrive'; - const SCOPE_EMAILS = 'wl.emails'; - const SCOPE_EVENTS_CREATE = 'wl.events_create'; - const SCOPE_MESSENGER = 'wl.messenger'; - const SCOPE_PHONE_NUMBERS = 'wl.phone_numbers'; - const SCOPE_PHOTOS = 'wl.photos'; - const SCOPE_POSTAL_ADDRESSES = 'wl.postal_addresses'; - const SCOPE_SHARE = 'wl.share'; - const SCOPE_SKYDRIVE = 'wl.skydrive'; - const SCOPE_SKYDRIVE_UPDATE = 'wl.skydrive_update'; - const SCOPE_WORK_PROFILE = 'wl.work_profile'; - const SCOPE_APPLICATIONS = 'wl.applications'; - const SCOPE_APPLICATIONS_CREATE = 'wl.applications_create'; - const SCOPE_IMAP = 'wl.imap'; + const SCOPE_BASIC = 'basic'; + const SCOPE_OFFLINE_ACCESS = 'offline_access'; + const SCOPE_SIGNIN = 'signin'; + const SCOPE_BIRTHDAY = 'birthday'; + const SCOPE_CALENDARS = 'calendars'; + const SCOPE_CALENDARS_UPDATE = 'calendars_update'; + const SCOPE_CONTACTS_BIRTHDAY = 'contacts_birthday'; + const SCOPE_CONTACTS_CREATE = 'contacts_create'; + const SCOPE_CONTACTS_CALENDARS = 'contacts_calendars'; + const SCOPE_CONTACTS_PHOTOS = 'contacts_photos'; + const SCOPE_CONTACTS_SKYDRIVE = 'contacts_skydrive'; + const SCOPE_EMAIL = 'email'; + const SCOPE_EVENTS_CREATE = 'events_create'; + const SCOPE_MESSENGER = 'messenger'; + const SCOPE_OPENID = 'openid'; + const SCOPE_PHONE_NUMBERS = 'phone_numbers'; + const SCOPE_PHOTOS = 'photos'; + const SCOPE_POSTAL_ADDRESSES = 'postal_addresses'; + const SCOPE_PROFILE = 'profile'; + const SCOPE_SHARE = 'share'; + const SCOPE_SKYDRIVE = 'skydrive'; + const SCOPE_SKYDRIVE_UPDATE = 'skydrive_update'; + const SCOPE_WORK_PROFILE = 'work_profile'; + const SCOPE_APPLICATIONS = 'applications'; + const SCOPE_APPLICATIONS_CREATE = 'applications_create'; + const SCOPE_IMAP = 'imap'; + const SOCPE_IMAP_AccessAsUser_All='IMAP.AccessAsUser.All'; + + public string $tenant; /** * MS uses some magical not officialy supported scope to get even moar info like full emailaddresses. @@ -48,7 +53,8 @@ class Microsoft extends AbstractService * * Considering this scope is not officially supported: use with care */ - const SCOPE_CONTACTS_EMAILS = 'wl.contacts_emails'; + const SCOPE_CONTACTS_EMAILS = 'contacts_emails'; + public function __construct( CredentialsInterface $credentials, @@ -69,7 +75,9 @@ class Microsoft extends AbstractService */ public function getAuthorizationEndpoint() { - return new Uri('https://login.live.com/oauth20_authorize.srf'); + //return new Uri('https://login.live.com/oauth20_authorize.srf'); + //return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize'); + return new Uri('https://login.microsoftonline.com/'.$this->tenant.'/oauth2/v2.0/authorize'); } /** @@ -77,7 +85,9 @@ class Microsoft extends AbstractService */ public function getAccessTokenEndpoint() { - return new Uri('https://login.live.com/oauth20_token.srf'); + //return new Uri('https://login.live.com/oauth20_token.srf'); + //return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/token'); + return new Uri('https://login.microsoftonline.com/'.$this->tenant.'/oauth2/v2.0/token'); } /** diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 66210ef9d52..29551ac0874 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2348,4 +2348,5 @@ AllowExternalDownload=Allow external download (without login, using a shared lin DeadlineDayVATSubmission=Deadline day for vat submission on the next month MaxNumberOfAttachementOnForms=Max number of joinded files in a form IfDefinedUseAValueBeetween=If defined, use a value between %s and %s -MAIN_IMAP_USE_PHPIMAP=Use the PHP-IMAP library for IMAP instead of native PHP IMAP. This also allow the use of OAuth2 connection for IMAP. \ No newline at end of file +EMailsInGoingDesc=Incoming emails are managed by the module %s. You must enable and configure it if you need to support ingoing emails. +MAIN_IMAP_USE_PHPIMAP=Use the PHP-IMAP library for IMAP instead of native PHP IMAP. This also allow the use of OAuth2 connection for IMAP (module OAuth must also be activated). diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index a112de8ceb2..f83637c9c40 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -179,4 +179,3 @@ RecordCreatedByEmailCollector=Record created by the Email Collector %s from emai DefaultBlacklistMailingStatus=Default value for field '%s' when creating a new contact DefaultStatusEmptyMandatory=Empty but mandatory WarningLimitSendByDay=WARNING: The setup or contract of your instance limits your number of emails per day to %s. Trying to send more may result in having your instance slow down or suspended. Please contact your support if you need a higher quota. -EMailsInGoingDesc=Incoming emails are managed by the module %s. You must enable and configure it if you need to support ingoing emails. diff --git a/htdocs/langs/en_US/oauth.lang b/htdocs/langs/en_US/oauth.lang index 01bb08e38bd..e773c470b30 100644 --- a/htdocs/langs/en_US/oauth.lang +++ b/htdocs/langs/en_US/oauth.lang @@ -33,6 +33,7 @@ OAUTH_STRIPE_TEST_NAME=OAuth Stripe Test OAUTH_STRIPE_LIVE_NAME=OAuth Stripe Live OAUTH_ID=OAuth ID OAUTH_SECRET=OAuth secret +OAUTH_TENANT=OAuth tenant OAuthProviderAdded=OAuth provider added AOAuthEntryForThisProviderAndLabelAlreadyHasAKey=An OAuth entry for this provider and label already exists URLOfServiceForAuthorization=URL provided by OAuth service for authentication From d82a8dc7b137a07d93561c8bf9bb270146b0033a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Feb 2023 20:35:11 +0100 Subject: [PATCH 078/137] Trans --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 29551ac0874..46339a7bf6d 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2349,4 +2349,4 @@ DeadlineDayVATSubmission=Deadline day for vat submission on the next month MaxNumberOfAttachementOnForms=Max number of joinded files in a form IfDefinedUseAValueBeetween=If defined, use a value between %s and %s EMailsInGoingDesc=Incoming emails are managed by the module %s. You must enable and configure it if you need to support ingoing emails. -MAIN_IMAP_USE_PHPIMAP=Use the PHP-IMAP library for IMAP instead of native PHP IMAP. This also allow the use of OAuth2 connection for IMAP (module OAuth must also be activated). +MAIN_IMAP_USE_PHPIMAP=Use the PHP-IMAP library for IMAP instead of native PHP IMAP. This also allows the use of an OAuth2 connection for IMAP (module OAuth must also be activated). From eef350d1d37af2a9d531d73f292956c529d84e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 21:44:39 +0100 Subject: [PATCH 079/137] add ajax tooltip on dolresource --- .../adherents/class/adherent_type.class.php | 3 +- htdocs/core/ajax/ajaxtooltip.php | 5 +- .../class/emailcollector.class.php | 3 +- htdocs/langs/en_US/dict.lang | 1 + htdocs/resource/class/dolresource.class.php | 55 +++++++++++++++---- 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 9819110e6bc..a744ce71bdc 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -698,8 +698,9 @@ class AdherentType extends CommonObject { global $conf, $langs, $user; - $datas = []; + $langs->load('members'); + $datas = []; $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("MemberType").' '.$this->getLibStatut(4); $datas['label'] = '
'.$langs->trans("Label").': '.$this->label; if (isset($this->subscription)) { diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index 7afbc88ae17..d10b0f1a43e 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -154,6 +154,10 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'user/class'; $module = 'user'; $myobject = 'usergroup'; +} elseif ($objecttype == 'dolresource') { + $classpath = 'resource/class'; + $module = 'resource'; + $myobject = 'dolresource'; } // Generic case for $classfile and $classname @@ -189,7 +193,6 @@ if ($objecttype == 'invoice_supplier') { $classfile = 'mailing'; $classname = 'Mailing'; } elseif ($objecttype == 'adherent_type') { - $langs->load('members'); $classpath = 'adherents/class'; $classfile = 'adherent_type'; $module = 'adherent'; diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 13fcbfbef6b..f832a6ff842 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -382,11 +382,10 @@ class EmailCollector extends CommonObject // Clear fields $object->ref = "copy_of_".$object->ref; - $object->title = $langs->trans("CopyOf")." ".$object->title; + $object->label = $langs->trans("CopyOf")." ".$object->label; if (empty($object->host)) { $object->host = 'imap.example.com'; } - // ... // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { $extrafields->fetch_name_optionals_label($this->table_element); diff --git a/htdocs/langs/en_US/dict.lang b/htdocs/langs/en_US/dict.lang index 00ab5a05f24..e3b159e50de 100644 --- a/htdocs/langs/en_US/dict.lang +++ b/htdocs/langs/en_US/dict.lang @@ -247,6 +247,7 @@ CountryJE=Jersey CountryME=Montenegro CountryBL=Saint Barthelemy CountryMF=Saint Martin +CountryXK=Kosovo ##### Civilities ##### CivilityMME=Mrs. diff --git a/htdocs/resource/class/dolresource.class.php b/htdocs/resource/class/dolresource.class.php index 99cc586cbb9..5d0c0481b98 100644 --- a/htdocs/resource/class/dolresource.class.php +++ b/htdocs/resource/class/dolresource.class.php @@ -52,6 +52,9 @@ class Dolresource extends CommonObject public $type_label; + /** + * @var string description + */ public $description; public $fk_country; @@ -761,6 +764,33 @@ class Dolresource extends CommonObject } } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('resource'); + + $datas = []; + + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Resource").''; + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + /*if (isset($this->status)) { + $datas['status'] = '
' . $langs->trans("Status").": ".$this->getLibStatut(5); + }*/ + if (isset($this->type_label)) { + $datas['label'] = '
'.$langs->trans("ResourceType").": ".$this->type_label; + } + + return $datas; + } + /** * Return clicable link of object (with eventually picto) * @@ -777,15 +807,18 @@ class Dolresource extends CommonObject global $conf, $langs, $hookmanager; $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("Resource").''; - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; - /*if (isset($this->status)) { - $label.= '
' . $langs->trans("Status").": ".$this->getLibStatut(5); - }*/ - if (isset($this->type_label)) { - $label .= '
'.$langs->trans("ResourceType").": ".$this->type_label; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/resource/card.php?id='.$this->id; @@ -806,8 +839,8 @@ class Dolresource extends CommonObject $label = $langs->trans("ShowMyObject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -820,7 +853,7 @@ class Dolresource extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 39ec2331384243252bb45212c984c818ae838dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 21:52:33 +0100 Subject: [PATCH 080/137] add count extrafields in admin dolresource --- htdocs/core/lib/resource.lib.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/resource.lib.php b/htdocs/core/lib/resource.lib.php index ebfbaf224f6..1fa2aa2f2e1 100644 --- a/htdocs/core/lib/resource.lib.php +++ b/htdocs/core/lib/resource.lib.php @@ -1,7 +1,8 @@ - * Copyright (C) 2016 Gilles Poirier + * Copyright (C) 2013 Jean-François Ferry + * Copyright (C) 2016 Gilles Poirier + * Copyright (C) 2023 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,7 +27,7 @@ /** * Prepare head for tabs * - * @param Object $object Object + * @param Dolresource $object Object * @return array Array of head entries */ function resource_prepare_head($object) @@ -114,7 +115,10 @@ function resource_prepare_head($object) function resource_admin_prepare_head() { - global $langs, $conf, $user; + global $conf, $db, $langs, $user; + + $extrafields = new ExtraFields($db); + $extrafields->fetch_name_optionals_label('resource'); $h = 0; $head = array(); @@ -132,6 +136,10 @@ function resource_admin_prepare_head() $head[$h][0] = DOL_URL_ROOT.'/admin/resource_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFields"); + $nbExtrafields = $extrafields->attributes['resource']['count']; + if ($nbExtrafields > 0) { + $head[$h][1] .= ''.$nbExtrafields.''; + } $head[$h][2] = 'attributes'; $h++; From 019802ec33a75f61530dddc2fbd8adfda37585e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 7 Feb 2023 22:12:47 +0100 Subject: [PATCH 081/137] add ajax tooltip on project --- htdocs/projet/class/project.class.php | 88 ++++++++++++++++++--------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 6eb7384c11d..adc617e55c2 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1244,6 +1244,50 @@ class Project extends CommonObject return dolGetStatus($langs->transnoentitiesnoconv($this->statuts_long[$status]), $langs->transnoentitiesnoconv($this->statuts_short[$status]), '', $statusClass, $mode); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('projects'); + $option = $params['option'] ?? ''; + $moreinpopup = $params['morinpopup'] ?? ''; + + $datas = []; + if ($option != 'nolink') { + $datas['picto'] = img_picto('', $this->picto, 'class="pictofixedwidth"').' '.$langs->trans("Project").''; + } + if (isset($this->status)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['ref'] = (isset($datas['picto']) ? '
' : '').''.$langs->trans('Ref').': '.$this->ref; // The space must be after the : to not being explode when showing the title in img_picto + $datas['label'] = '
'.$langs->trans('Label').': '.$this->title; // The space must be after the : to not being explode when showing the title in img_picto + if (isset($this->public)) { + $datas['visibility'] = '
'.$langs->trans("Visibility").": "; + $datas['visibility'] .= ($this->public ? img_picto($langs->trans('SharedProject'), 'world', 'class="pictofixedwidth"').$langs->trans("SharedProject") : img_picto($langs->trans('PrivateProject'), 'private', 'class="pictofixedwidth"').$langs->trans("PrivateProject")); + } + if (!empty($this->thirdparty_name)) { + $datas['thirdparty'] = '
'.$langs->trans('ThirdParty').': '.$this->thirdparty_name; // The space must be after the : to not being explode when showing the title in img_picto + } + if (!empty($this->date_start)) { + $datas['datestart'] = '
'.$langs->trans('DateStart').': '.dol_print_date($this->date_start, 'day'); // The space must be after the : to not being explode when showing the title in img_picto + } + if (!empty($this->date_end)) { + $datas['dateend'] = '
'.$langs->trans('DateEnd').': '.dol_print_date($this->date_end, 'day'); // The space must be after the : to not being explode when showing the title in img_picto + } + if ($moreinpopup) { + $datas['moreinpopup'] = '
'.$moreinpopup; + } + + return $datas; + } + /** * Return clickable name (with picto eventually) * @@ -1269,32 +1313,20 @@ class Project extends CommonObject if (!empty($conf->global->PROJECT_OPEN_ALWAYS_ON_TAB)) { $option = $conf->global->PROJECT_OPEN_ALWAYS_ON_TAB; } - - $label = ''; - if ($option != 'nolink') { - $label = img_picto('', $this->picto, 'class="pictofixedwidth"').' '.$langs->trans("Project").''; - } - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); - } - $label .= ($label ? '
' : '').''.$langs->trans('Ref').': '.$this->ref; // The space must be after the : to not being explode when showing the title in img_picto - $label .= ($label ? '
' : '').''.$langs->trans('Label').': '.$this->title; // The space must be after the : to not being explode when showing the title in img_picto - if (isset($this->public)) { - $label .= '
'.$langs->trans("Visibility").": "; - $label .= ($this->public ? img_picto($langs->trans('SharedProject'), 'world', 'class="pictofixedwidth"').$langs->trans("SharedProject") : img_picto($langs->trans('PrivateProject'), 'private', 'class="pictofixedwidth"').$langs->trans("PrivateProject")); - } - if (!empty($this->thirdparty_name)) { - $label .= ($label ? '
' : '').''.$langs->trans('ThirdParty').': '.$this->thirdparty_name; // The space must be after the : to not being explode when showing the title in img_picto - } - if (!empty($this->date_start)) { - $label .= ($label ? '
' : '').''.$langs->trans('DateStart').': '.dol_print_date($this->date_start, 'day'); // The space must be after the : to not being explode when showing the title in img_picto - } - if (!empty($this->date_end)) { - $label .= ($label ? '
' : '').''.$langs->trans('DateEnd').': '.dol_print_date($this->date_end, 'day'); // The space must be after the : to not being explode when showing the title in img_picto - } - if ($moreinpopup) { - $label .= '
'.$moreinpopup; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'moreinpopup' => $moreinpopup, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } + $label = implode($this->getTooltipContentArray($params)); $url = ''; if ($option != 'nolink') { @@ -1325,8 +1357,8 @@ class Project extends CommonObject $label = $langs->trans("ShowProject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1342,7 +1374,7 @@ class Project extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="pictofixedwidth"' : '') : 'class="'.(($withpicto != 2) ? 'pictofixedwidth ' : '').'classfortooltip pictofixedwidth em088"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="pictofixedwidth"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'pictofixedwidth ' : '').$classfortooltip.' pictofixedwidth em088"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 411fbc1a045e877d3849e203bdd0cdf52cb69e7e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 00:13:42 +0100 Subject: [PATCH 082/137] FIX Bug in php-imap library. Fatal error if imap connet fails --- .../webklex/php-imap/src/Connection/Protocols/Protocol.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/includes/webklex/php-imap/src/Connection/Protocols/Protocol.php b/htdocs/includes/webklex/php-imap/src/Connection/Protocols/Protocol.php index ef01d46ec9b..6087ac55b75 100644 --- a/htdocs/includes/webklex/php-imap/src/Connection/Protocols/Protocol.php +++ b/htdocs/includes/webklex/php-imap/src/Connection/Protocols/Protocol.php @@ -190,7 +190,7 @@ abstract class Protocol implements ProtocolInterface { STREAM_CLIENT_CONNECT, stream_context_create($this->defaultSocketOptions($transport)) ); - stream_set_timeout($stream, $timeout); + //stream_set_timeout($stream, $timeout); // Hang id $strem empty and already done line 199 if (!$stream) { throw new ConnectionFailedException($errstr, $errno); From 310fd4e369c5c38d8d99384f2c71e4d5d3e5d6e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 01:28:14 +0100 Subject: [PATCH 083/137] Debug IMAP-PHP for MS --- htdocs/admin/emailcollector_card.php | 205 +++++++++--------- htdocs/admin/oauthlogintokens.php | 6 +- htdocs/core/class/CMailFile.class.php | 4 +- htdocs/core/lib/oauth.lib.php | 2 +- htdocs/core/lib/security.lib.php | 3 +- .../modules/oauth/google_oauthcallback.php | 2 + .../modules/oauth/microsoft_oauthcallback.php | 4 +- .../modules/printing/printgcp.modules.php | 19 +- .../class/emailcollector.class.php | 2 +- .../OAuth/Common/Storage/DoliStorage.php | 63 +++++- .../OAuth/OAuth2/Service/Microsoft.php | 21 +- htdocs/printing/admin/printing.php | 4 +- 12 files changed, 204 insertions(+), 131 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 8dfafb19b63..462839245fa 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -107,6 +107,7 @@ $permissiondellink = $user->admin; // Used by the include of actions_dellink.inc $permissiontoadd = $user->admin; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php $debuginfo = ''; +$error = 0; /* @@ -121,8 +122,6 @@ if ($reshook < 0) { } if (empty($reshook)) { - $error = 0; - $permissiontoadd = 1; $permissiontodelete = 1; if (empty($backtopage)) { @@ -397,104 +396,112 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $connectstringsource = ''; $connectstringtarget = ''; - if (function_exists('imap_open')) { - // Note: $object->host has been loaded by the fetch - $usessl = 1; + // Note: $object->host has been loaded by the fetch + $usessl = 1; - $connectstringserver = $object->getConnectStringIMAP($usessl); + $connectstringserver = $object->getConnectStringIMAP($usessl); - if ($action == 'scan') { - if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { - if ($object->acces_type == 1) { - // Mode OAUth2 with PHP-IMAP - require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array - $keyforsupportedoauth2array = $object->oauth_service; - if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { - $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); - } else { - $keyforprovider = ''; - } - $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); - $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME'; - - $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); - - require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; - //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; - //dol_syslog($debugtext); - - $storage = new DoliStorage($db, $conf); - - try { - $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); - $expire = true; - // Is token expired or will token expire in the next 30 seconds - // if (is_object($tokenobj)) { - // $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30)); - // } - // Token expired so we refresh it - if (is_object($tokenobj) && $expire) { - $credentials = new Credentials( - getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'), - getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'), - getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE') - ); - $serviceFactory = new \OAuth\ServiceFactory(); - $oauthname = explode('-', $OAUTH_SERVICENAME); - // ex service is Google-Emails we need only the first part Google - $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array()); - // We have to save the token because Google give it only once - $refreshtoken = $tokenobj->getRefreshToken(); - $tokenobj = $apiService->refreshAccessToken($tokenobj); - $tokenobj->setRefreshToken($refreshtoken); - $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj); - } - $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); - if (is_object($tokenobj)) { - $token = $tokenobj->getAccessToken(); - } else { - $object->error = "Token not found"; - return -1; - } - } catch (Exception $e) { - print $e->getMessage(); - } - - $cm = new ClientManager(); - $client = $cm->make([ - 'host' => $object->host, - 'port' => $object->port, - 'encryption' => 'ssl', - 'validate_cert' => true, - 'protocol' => 'imap', - 'username' => $object->login, - 'password' => $token, - 'authentication' => "oauth", - ]); + if ($action == 'scan') { + if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { + if ($object->acces_type == 1) { + // Mode OAUth2 with PHP-IMAP + require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array + $keyforsupportedoauth2array = $object->oauth_service; + if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { + $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); } else { - // Mode login/pass with PHP-IMAP - $cm = new ClientManager(); - $client = $cm->make([ - 'host' => $object->host, - 'port' => $object->port, - 'encryption' => 'ssl', - 'validate_cert' => true, - 'protocol' => 'imap', - 'username' => $object->login, - 'password' => $object->password, - 'authentication' => "login", - ]); + $keyforprovider = ''; } + $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); + $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME'; + + $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); + + require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; + //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; + //dol_syslog($debugtext); + + $storage = new DoliStorage($db, $conf, $keyforprovider); + + try { + $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + $expire = true; + // Is token expired or will token expire in the next 30 seconds + // if (is_object($tokenobj)) { + // $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30)); + // } + // Token expired so we refresh it + if (is_object($tokenobj) && $expire) { + $credentials = new Credentials( + getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'), + getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'), + getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE') + ); + $serviceFactory = new \OAuth\ServiceFactory(); + $oauthname = explode('-', $OAUTH_SERVICENAME); + // ex service is Google-Emails we need only the first part Google + $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array()); + // We have to save the token because Google give it only once + $refreshtoken = $tokenobj->getRefreshToken(); + $tokenobj = $apiService->refreshAccessToken($tokenobj); + $tokenobj->setRefreshToken($refreshtoken); + $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj); + } + $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + if (is_object($tokenobj)) { + $token = $tokenobj->getAccessToken(); + } else { + $error++; + $morehtml .= "Token not found"; + } + } catch (Exception $e) { + $error++; + $morehtml .= $e->getMessage(); + } + + if (empty($object->login)) { + $error++; + $morehtml .= 'Error: Login is empty. Must be email owner when using MAIN_IMAP_USE_PHPIMAP and OAuth.'; + } + + $cm = new ClientManager(); + $client = $cm->make([ + 'host' => $object->host, + 'port' => $object->port, + 'encryption' => 'ssl', + 'validate_cert' => true, + 'protocol' => 'imap', + 'username' => $object->login, + 'password' => $token, + 'authentication' => "oauth", + ]); + } else { + // Mode login/pass with PHP-IMAP + $cm = new ClientManager(); + $client = $cm->make([ + 'host' => $object->host, + 'port' => $object->port, + 'encryption' => 'ssl', + 'validate_cert' => true, + 'protocol' => 'imap', + 'username' => $object->login, + 'password' => $object->password, + 'authentication' => "login", + ]); + } + if (!$error) { try { $client->connect(); - } catch (ConnectionFailedException $e) { - print $e->getMessage(); - } - $f = $client->getFolders(false, $object->source_directory); - $nbemail = $f[0]->examine()["exists"]; - $morehtml .= $nbemail; - } else { + $f = $client->getFolders(false, $object->source_directory); + $nbemail = $f[0]->examine()["exists"]; + $morehtml .= $nbemail; + } catch (ConnectionFailedException $e) { + $morehtml .= 'ConnectionFailedException '.$e->getMessage(); + } + } + } else { + if (function_exists('imap_open')) { try { if ($sourcedir) { //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); @@ -521,7 +528,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //dol_syslog("end imap_open connection=".var_export($connection, true)); } catch (Exception $e) { - print $e->getMessage(); + $morehtml .= $e->getMessage(); } if (!$connection) { @@ -540,16 +547,16 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea dol_syslog("Imap close"); imap_close($connection); } + } else { + $morehtml .= 'IMAP functions not available on your PHP. '; } - } else { - $morehtml .= ''.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").''; } - - $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); } else { - $morehtml .= 'IMAP functions not available on your PHP. '; + $morehtml .= ''.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").''; } + $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'
'.$morehtml.'
', '', 0, '', '', 0, ''); print '
'; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index d6fcc9e0f7c..5c0ecdb007d 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -221,8 +221,11 @@ if ($mode == 'setup' && $user->admin) { $storage = new DoliStorage($db, $conf, $keyforprovider); try { // $OAUTH_SERVICENAME is for example 'Google-keyforprovider' - print $OAUTH_SERVICENAME; + print ''."\n"; $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + //print $storage->token.'
'; + //print $tokenobj->getExtraParams()['id_token'].'
'; + //print $tokenobj->getAccessToken().'
'; } catch (Exception $e) { // Return an error if token not found //print $e->getMessage(); @@ -342,7 +345,6 @@ if ($mode == 'setup' && $user->admin) { print '
'; print ''; print '\n"; - // Can edit + // Min amount print '\n"; // SHow counter of validated members publicly diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 71f01b36739..f8981df17d9 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -206,7 +206,8 @@ SubscriptionsStatistics=Contributions statistics NbOfSubscriptions=Number of contributions AmountOfSubscriptions=Amount collected from contributions TurnoverOrBudget=Turnover (for a company) or Budget (for a foundation) -DefaultAmount=Default amount of contribution +DefaultAmount=Default amount of contribution (used only if no amount is defined at member type level) +MinimumAmount=Minimum amount (used only when contribution amount is free) CanEditAmount=Subscription amount is free CanEditAmountDetail=Visitor can choose/edit amount of its contribution regardless of the member type AmountIsLowerToMinimumNotice=sur un dû total de %s diff --git a/htdocs/public/eventorganization/attendee_new.php b/htdocs/public/eventorganization/attendee_new.php index cb4ba38e628..f245b6c10f7 100644 --- a/htdocs/public/eventorganization/attendee_new.php +++ b/htdocs/public/eventorganization/attendee_new.php @@ -686,7 +686,7 @@ print load_fiche_titre($langs->trans("NewRegistration"), '', '', 0, 0, 'center') print '
'; print '
'; -print '
'; +print '
'; // Welcome message diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php index 33bbe59f118..a121f2cc5a1 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -30,7 +30,6 @@ * * Note that you can add following constant to change behaviour of page * MEMBER_NEWFORM_AMOUNT Default amount for auto-subscribe form - * MEMBER_NEWFORM_EDITAMOUNT 0 or 1 = Amount can be edited * MEMBER_MIN_AMOUNT Minimum amount * MEMBER_NEWFORM_PAYONLINE Suggest payment with paypal, paybox or stripe * MEMBER_NEWFORM_DOLIBARRTURNOVER Show field turnover (specific for dolibarr foundation) @@ -431,7 +430,7 @@ if (empty($reshook) && $action == 'add') { } if (!empty($conf->global->MEMBER_NEWFORM_PAYONLINE) && $conf->global->MEMBER_NEWFORM_PAYONLINE != '-1') { - if (empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT)) { // If edition of amount not allowed + if (empty($adht->caneditamount)) { // If edition of amount not allowed // TODO Check amount is same than the amount required for the type of member or if not defined as the defeault amount into $conf->global->MEMBER_NEWFORM_AMOUNT // It is not so important because a test is done on return of payment validation. } @@ -505,7 +504,7 @@ print load_fiche_titre($langs->trans("NewSubscription"), '', '', 0, 0, 'center') print '
'; print '
'; -print '
'; +print '
'; if (!empty($conf->global->MEMBER_NEWFORM_TEXT)) { print $langs->trans($conf->global->MEMBER_NEWFORM_TEXT)."
\n"; } else { @@ -765,7 +764,7 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW $amount = $conf->global->MEMBER_NEWFORM_AMOUNT; } - if (!empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) || $caneditamount) { + if ($caneditamount) { print ''; print ' '.$langs->trans("Currency".$conf->currency).' – '; print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)): $langs->trans("AnyAmountWithoutAdvisedAmount"); @@ -833,7 +832,7 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW $i = 0; while ($i < $num) { - $objp = $db->fetch_object($result); + $objp = $db->fetch_object($result); // Load the member type and information on it print '
'; print ''; @@ -843,7 +842,7 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW print ''; print '
'; if (is_object($tokenobj)) { - //var_dump($tokenobj); $tokentoshow = $tokenobj->getAccessToken(); print ''.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'
'; //print 'Refresh: '.$tokenobj->getRefreshToken().'
'; diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index a7a87e1ce6e..f6611669556 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -908,7 +908,7 @@ class CMailFile require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); $expire = false; @@ -1030,7 +1030,7 @@ class CMailFile require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php index 4f504196b47..2074485cd6e 100644 --- a/htdocs/core/lib/oauth.lib.php +++ b/htdocs/core/lib/oauth.lib.php @@ -35,7 +35,7 @@ $supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', ' if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard', 'returnurl'=>'/core/modules/oauth/generic_oauthcallback.php'); // See https://learn.microsoft.com/fr-fr/azure/active-directory/develop/quickstart-register-app#register-an-application - $supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); + $supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All,SMTP.Send,Mail.Read,Mail.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); } diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 51c3434a456..a097ba23e3e 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -119,6 +119,7 @@ function dolGetRandomBytes($length) function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") { global $dolibarr_main_instance_unique_id; + global $dolibarr_disable_dolcrypt_for_debug; if ($chain === '' || is_null($chain)) { return ''; @@ -136,7 +137,7 @@ function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") $newchain = $chain; - if (function_exists('openssl_encrypt')) { + if (function_exists('openssl_encrypt') && empty($dolibarr_disable_dolcrypt_for_debug)) { $ivlen = 16; if (function_exists('openssl_cipher_iv_length')) { $ivlen = openssl_cipher_iv_length($ciphering); diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index c26187e4475..bd59e513ddf 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -217,6 +217,8 @@ if (GETPOST('code')) { // We are coming from oauth provider page. //$url .= 'hd=xxx'; } + //var_dump($url);exit; + // we go on oauth provider authorization page header('Location: '.$url); exit(); diff --git a/htdocs/core/modules/oauth/microsoft_oauthcallback.php b/htdocs/core/modules/oauth/microsoft_oauthcallback.php index ed47eec06e1..4ff573725f3 100644 --- a/htdocs/core/modules/oauth/microsoft_oauthcallback.php +++ b/htdocs/core/modules/oauth/microsoft_oauthcallback.php @@ -155,10 +155,9 @@ if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provi if (GETPOST('error')) { setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors'); } else { - $apiService->tenant = getDolGlobalString($keyforparamtenant); - //$token = $apiService->requestAccessToken(GETPOST('code'), $state); $token = $apiService->requestAccessToken(GETPOST('code')); + //print $token; // Microsoft is a service that does not need state to be stored as second paramater of requestAccessToken setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token @@ -182,7 +181,6 @@ if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provi //if (!preg_match('/^forlogin/', $state)) { // $apiService->setApprouvalPrompt('auto'); //} - $apiService->tenant = getDolGlobalString($keyforparamtenant); // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index c04d3ac9ca5..c1b6ba6c86e 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -116,10 +116,12 @@ class printing_printgcp extends PrintingDriver 'type'=>'info', ); } else { + $keyforprovider = ''; // @FIXME + $this->google_id = getDolGlobalString('OAUTH_GOOGLE_ID'); $this->google_secret = getDolGlobalString('OAUTH_GOOGLE_SECRET'); // Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); //$storage->clearToken($this->OAUTH_SERVICENAME_GOOGLE); // Setup the credentials for the requests $credentials = new Credentials( @@ -254,8 +256,11 @@ class printing_printgcp extends PrintingDriver public function getlistAvailablePrinters() { $ret = array(); + + $keyforprovider = ''; // @FIXME + // Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); // Setup the credentials for the requests $credentials = new Credentials( $this->google_id, @@ -392,8 +397,11 @@ class printing_printgcp extends PrintingDriver 'content' => base64_encode($contents), // encode file content as base64 'contentType' => $contenttype, ); + + $keyforprovider = ''; // @FIXME + // Dolibarr Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); // Setup the credentials for the requests $credentials = new Credentials( $this->google_id, @@ -441,8 +449,11 @@ class printing_printgcp extends PrintingDriver $error = 0; $html = ''; + + $keyforprovider = ''; // @FIXME + // Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); // Setup the credentials for the requests $credentials = new Credentials( $this->google_id, diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 2c23f6e0475..2002adafd86 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1082,7 +1082,7 @@ class EmailCollector extends CommonObject //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; //dol_syslog($debugtext); - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); diff --git a/htdocs/includes/OAuth/Common/Storage/DoliStorage.php b/htdocs/includes/OAuth/Common/Storage/DoliStorage.php index cf280262e99..60af1f631c6 100644 --- a/htdocs/includes/OAuth/Common/Storage/DoliStorage.php +++ b/htdocs/includes/OAuth/Common/Storage/DoliStorage.php @@ -57,6 +57,8 @@ class DoliStorage implements TokenStorageInterface private $key; //private $stateKey; private $keyforprovider; + public $token; + private $tenant; public $state; public $date_creation; @@ -73,6 +75,7 @@ class DoliStorage implements TokenStorageInterface $this->db = $db; $this->conf = $conf; $this->keyforprovider = $keyforprovider; + $this->token = ''; $this->tokens = array(); $this->states = array(); //$this->key = $key; @@ -96,7 +99,7 @@ class DoliStorage implements TokenStorageInterface /** * {@inheritDoc} */ - public function storeAccessToken($service, TokenInterface $token) + public function storeAccessToken($service, TokenInterface $tokenobj) { global $conf; @@ -104,16 +107,25 @@ class DoliStorage implements TokenStorageInterface //var_dump($token); dol_syslog("storeAccessToken service=".$service); - include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; - $serializedToken = dolEncrypt(serialize($token)); + $servicepluskeyforprovider = $service; + if (!empty($this->keyforprovider)) { + // We clean the keyforprovider after the - to be sure it is not present + $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider); + // Now we add the keyforprovider + $servicepluskeyforprovider .= '-'.$this->keyforprovider; + } - $this->tokens[$service] = $token; + include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; + $serializedToken = serialize($tokenobj); if (!is_array($this->tokens)) { $this->tokens = array(); } + + $this->tokens[$service] = $tokenobj; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token"; - $sql .= " WHERE service = '".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."'"; + $sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'"; $sql .= " AND entity IN (".getEntity('oauth_token').")"; $resql = $this->db->query($sql); if (! $resql) { @@ -123,7 +135,7 @@ class DoliStorage implements TokenStorageInterface if ($obj) { // update $sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token"; - $sql.= " SET token = '".$this->db->escape($serializedToken)."'"; + $sql.= " SET token = '".$this->db->escape(dolEncrypt($serializedToken))."'"; $sql.= " WHERE rowid = ".((int) $obj['rowid']); $resql = $this->db->query($sql); if (!$resql) { @@ -132,7 +144,7 @@ class DoliStorage implements TokenStorageInterface } else { // save $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity, datec)"; - $sql .= " VALUES ('".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."', '".$this->db->escape($serializedToken)."', ".((int) $conf->entity).", "; + $sql .= " VALUES ('".$this->db->escape($servicepluskeyforprovider)."', '".$this->db->escape(dolEncrypt($serializedToken))."', ".((int) $conf->entity).", "; $sql .= " '".$this->db->idate(dol_now())."'"; $sql .= ")"; $resql = $this->db->query($sql); @@ -147,15 +159,26 @@ class DoliStorage implements TokenStorageInterface } /** - * {@inheritDoc} + * Load token and other data from a $service + * Note: Token load are cumulated into array ->tokens when other properties are erased by last loaded token. + * + * @return void */ public function hasAccessToken($service) { // get from db dol_syslog("hasAccessToken service=".$service); + $servicepluskeyforprovider = $service; + if (!empty($this->keyforprovider)) { + // We clean the keyforprovider after the - to be sure it is not present + $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider); + // Now we add the keyforprovider + $servicepluskeyforprovider .= '-'.$this->keyforprovider; + } + $sql = "SELECT token, datec, tms, state FROM ".MAIN_DB_PREFIX."oauth_token"; - $sql .= " WHERE service = '".$this->db->escape($service.(empty($this->keyforprovider) ? '' : '-'.$this->keyforprovider))."'"; + $sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'"; $sql .= " AND entity IN (".getEntity('oauth_token').")"; $resql = $this->db->query($sql); if (! $resql) { @@ -164,18 +187,20 @@ class DoliStorage implements TokenStorageInterface $result = $this->db->fetch_array($resql); if ($result) { include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; - $token = unserialize(dolDecrypt($result['token'])); + $tokenobj = unserialize(dolDecrypt($result['token'])); + $this->token = dolDecrypt($result['token']); $this->date_creation = $this->db->jdate($result['datec']); $this->date_modification = $this->db->jdate($result['tms']); $this->state = $result['state']; } else { - $token = ''; + $tokenobj = ''; + $this->token = ''; $this->date_creation = null; $this->date_modification = null; $this->state = ''; } - $this->tokens[$service] = $token; + $this->tokens[$service] = $tokenobj; return is_array($this->tokens) && isset($this->tokens[$service]) @@ -331,4 +356,18 @@ class DoliStorage implements TokenStorageInterface // allow chaining return $this; } + + /** + * Return the token + * + * @return string String for the tenant used to create the token + */ + public function getTenant() + { + // Set/Reset tenant now so it will be defined for. + // TODO We must store it into the table llx_oauth_token + $this->tenant = getDolGlobalString('OAUTH_MICROSOFT'.($this->keyforprovider ? '-'.$this->keyforprovider : '').'_TENANT'); + + return $this->tenant; + } } diff --git a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php index b1b6a042c01..e94799b81cf 100644 --- a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php +++ b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php @@ -38,9 +38,13 @@ class Microsoft extends AbstractService const SCOPE_APPLICATIONS = 'applications'; const SCOPE_APPLICATIONS_CREATE = 'applications_create'; const SCOPE_IMAP = 'imap'; - const SOCPE_IMAP_AccessAsUser_All='IMAP.AccessAsUser.All'; + const SOCPE_IMAP_ACCESSASUSERALL = 'IMAP.AccessAsUser.All'; + const SOCPE_SMTPSEND = 'SMTP.Send'; + const SOCPE_MAILREAD = 'Mail.Read'; + const SOCPE_MAILSEND = 'Mail.Send'; + + protected $storage; - public string $tenant; /** * MS uses some magical not officialy supported scope to get even moar info like full emailaddresses. @@ -65,6 +69,8 @@ class Microsoft extends AbstractService ) { parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + $this->storage = $storage; + if (null === $baseApiUri) { $this->baseApiUri = new Uri('https://apis.live.net/v5.0/'); } @@ -75,9 +81,11 @@ class Microsoft extends AbstractService */ public function getAuthorizationEndpoint() { - //return new Uri('https://login.live.com/oauth20_authorize.srf'); + $tenant = $this->storage->getTenant(); + + //return new Uri('https://login.live.com/oauth20_authorize.srf'); //return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize'); - return new Uri('https://login.microsoftonline.com/'.$this->tenant.'/oauth2/v2.0/authorize'); + return new Uri('https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/authorize'); } /** @@ -85,9 +93,11 @@ class Microsoft extends AbstractService */ public function getAccessTokenEndpoint() { + $tenant = $this->storage->getTenant(); + //return new Uri('https://login.live.com/oauth20_token.srf'); //return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/token'); - return new Uri('https://login.microsoftonline.com/'.$this->tenant.'/oauth2/v2.0/token'); + return new Uri('https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token'); } /** @@ -110,6 +120,7 @@ class Microsoft extends AbstractService } elseif (isset($data['error'])) { throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); } + //print $data['access_token'];exit; $token = new StdOAuth2Token(); $token->setAccessToken($data['access_token']); diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index fb8426abc1b..ed856024d63 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -201,13 +201,15 @@ if ($mode == 'setup' && $user->admin) { $i++; if ($key['varname'] == 'PRINTGCP_TOKEN_ACCESS') { + $keyforprovider = ''; // @BUG This must be set + // Token print '
'.$langs->trans("Token").''; $tokenobj = null; // Dolibarr storage - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME_GOOGLE); } catch (Exception $e) { From 4cf21314105bec6a9af63194d7ef0947945318e4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 01:52:28 +0100 Subject: [PATCH 084/137] Enable MS OAuth --- htdocs/core/lib/oauth.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php index 2074485cd6e..b2e59a9b87a 100644 --- a/htdocs/core/lib/oauth.lib.php +++ b/htdocs/core/lib/oauth.lib.php @@ -32,10 +32,10 @@ if (isModEnabled('stripe')) { $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'availablescopes'=>'read_write', 'returnurl'=>'/core/modules/oauth/stripelive_oauthcallback.php'); } $supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'availablescopes'=>'user,public_repo', 'returnurl'=>'/core/modules/oauth/github_oauthcallback.php'); +$supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All,SMTP.Send,Mail.Read,Mail.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard', 'returnurl'=>'/core/modules/oauth/generic_oauthcallback.php'); // See https://learn.microsoft.com/fr-fr/azure/active-directory/develop/quickstart-register-app#register-an-application - $supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All,SMTP.Send,Mail.Read,Mail.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); } From 47128f2ccc5efe5d3e4d3733c23b9866c7f44127 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 04:40:13 +0100 Subject: [PATCH 085/137] Debug v17 --- htdocs/admin/emailcollector_card.php | 16 ++++++++++++++++ htdocs/core/lib/oauth.lib.php | 2 +- .../modules/oauth/microsoft_oauthcallback.php | 7 ++++++- .../class/emailcollector.class.php | 4 +++- .../OAuth/Common/Http/Client/StreamClient.php | 1 + .../OAuth/OAuth2/Service/AbstractService.php | 2 ++ .../includes/OAuth/OAuth2/Service/Microsoft.php | 5 +++-- htdocs/includes/webklex/php-imap/src/Client.php | 1 + htdocs/langs/en_US/oauth.lang | 2 +- 9 files changed, 34 insertions(+), 6 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 462839245fa..10e7ea300f8 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -421,10 +421,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; //dol_syslog($debugtext); + $token = ''; + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + $expire = true; // Is token expired or will token expire in the next 30 seconds // if (is_object($tokenobj)) { @@ -439,11 +442,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea ); $serviceFactory = new \OAuth\ServiceFactory(); $oauthname = explode('-', $OAUTH_SERVICENAME); + // ex service is Google-Emails we need only the first part Google $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array()); + // We have to save the token because Google give it only once $refreshtoken = $tokenobj->getRefreshToken(); + //var_dump($tokenobj); $tokenobj = $apiService->refreshAccessToken($tokenobj); + $tokenobj->setRefreshToken($refreshtoken); $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj); } @@ -491,6 +498,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } if (!$error) { try { + // To emulate the command connect, you can run + // openssl s_client -crlf -connect outlook.office365.com:993 + // TAG1 AUTHENTICATE XOAUTH2 dXN... + // TO Get debug log, you can set protected $debug = true; in Protocol.php file + // + // A MS bug make this not working ! + // See https://github.com/MicrosoftDocs/office-developer-exchange-docs/issues/100 + // See github.com/MicrosoftDocs/office-developer-exchange-docs/issues/87 + // See github.com/Webklex/php-imap/issues/81 $client->connect(); $f = $client->getFolders(false, $object->source_directory); diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php index b2e59a9b87a..8a81d9a80e5 100644 --- a/htdocs/core/lib/oauth.lib.php +++ b/htdocs/core/lib/oauth.lib.php @@ -32,7 +32,7 @@ if (isModEnabled('stripe')) { $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'availablescopes'=>'read_write', 'returnurl'=>'/core/modules/oauth/stripelive_oauthcallback.php'); } $supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'availablescopes'=>'user,public_repo', 'returnurl'=>'/core/modules/oauth/github_oauthcallback.php'); -$supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All,SMTP.Send,Mail.Read,Mail.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); +$supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,User.Read,https://outlook.office365.com/IMAP.AccessAsUser.All,https://outlook.office365.com/SMTP.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard', 'returnurl'=>'/core/modules/oauth/generic_oauthcallback.php'); // See https://learn.microsoft.com/fr-fr/azure/active-directory/develop/quickstart-register-app#register-an-application diff --git a/htdocs/core/modules/oauth/microsoft_oauthcallback.php b/htdocs/core/modules/oauth/microsoft_oauthcallback.php index 4ff573725f3..bf057676cf3 100644 --- a/htdocs/core/modules/oauth/microsoft_oauthcallback.php +++ b/htdocs/core/modules/oauth/microsoft_oauthcallback.php @@ -155,11 +155,16 @@ if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provi if (GETPOST('error')) { setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors'); } else { + //print GETPOST('code');exit; + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); $token = $apiService->requestAccessToken(GETPOST('code')); - //print $token; // Microsoft is a service that does not need state to be stored as second paramater of requestAccessToken + //print $token->getAccessToken().'

'; + //print $token->getExtraParams()['id_token'].'
'; + //print $token->getRefreshToken().'
';exit; + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token } diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 2002adafd86..0168d8f86c6 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1082,10 +1082,13 @@ class EmailCollector extends CommonObject //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; //dol_syslog($debugtext); + $token = ''; + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + $expire = true; // Is token expired or will token expire in the next 30 seconds // if (is_object($tokenobj)) { @@ -1122,7 +1125,6 @@ class EmailCollector extends CommonObject return -1; } - $cm = new ClientManager(); $client = $cm->make([ 'host' => $this->host, diff --git a/htdocs/includes/OAuth/Common/Http/Client/StreamClient.php b/htdocs/includes/OAuth/Common/Http/Client/StreamClient.php index d81fee88202..9849afd4a32 100644 --- a/htdocs/includes/OAuth/Common/Http/Client/StreamClient.php +++ b/htdocs/includes/OAuth/Common/Http/Client/StreamClient.php @@ -57,6 +57,7 @@ class StreamClient extends AbstractClient } $extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody); + //var_dump($requestBody); var_dump($extraHeaders);var_dump($method);exit; $context = $this->generateStreamContext($requestBody, $extraHeaders, $method); $level = error_reporting(0); diff --git a/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php b/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php index 0de0219306a..b6f89118d83 100644 --- a/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php +++ b/htdocs/includes/OAuth/OAuth2/Service/AbstractService.php @@ -223,6 +223,8 @@ abstract class AbstractService extends BaseAbstractService implements ServiceInt $parameters, $this->getExtraOAuthHeaders() ); + //print $responseBody;exit; // We must have a result "{"token_type":"Bearer","scope... + $token = $this->parseAccessTokenResponse($responseBody); $this->storage->storeAccessToken($this->service(), $token); diff --git a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php index e94799b81cf..6c3b18b3c0f 100644 --- a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php +++ b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php @@ -38,8 +38,9 @@ class Microsoft extends AbstractService const SCOPE_APPLICATIONS = 'applications'; const SCOPE_APPLICATIONS_CREATE = 'applications_create'; const SCOPE_IMAP = 'imap'; - const SOCPE_IMAP_ACCESSASUSERALL = 'IMAP.AccessAsUser.All'; - const SOCPE_SMTPSEND = 'SMTP.Send'; + const SOCPE_IMAP_ACCESSASUSERALL = 'https://outlook.office365.com/IMAP.AccessAsUser.All'; + const SOCPE_SMTPSEND = 'https://outlook.office365.com/SMTP.Send'; + const SOCPE_USERREAD = 'User.Read'; const SOCPE_MAILREAD = 'Mail.Read'; const SOCPE_MAILSEND = 'Mail.Send'; diff --git a/htdocs/includes/webklex/php-imap/src/Client.php b/htdocs/includes/webklex/php-imap/src/Client.php index 15944e4c646..85c537f16fa 100755 --- a/htdocs/includes/webklex/php-imap/src/Client.php +++ b/htdocs/includes/webklex/php-imap/src/Client.php @@ -353,6 +353,7 @@ class Client { } catch (Exceptions\RuntimeException $e) { throw new ConnectionFailedException("connection setup failed - run exception", 0, $e); } + $this->authenticate(); return $this; diff --git a/htdocs/langs/en_US/oauth.lang b/htdocs/langs/en_US/oauth.lang index e773c470b30..9d4791a9f63 100644 --- a/htdocs/langs/en_US/oauth.lang +++ b/htdocs/langs/en_US/oauth.lang @@ -31,7 +31,7 @@ OAUTH_GITHUB_SECRET=OAuth GitHub Secret OAUTH_URL_FOR_CREDENTIAL=Go to this page to create or get your OAuth ID and Secret OAUTH_STRIPE_TEST_NAME=OAuth Stripe Test OAUTH_STRIPE_LIVE_NAME=OAuth Stripe Live -OAUTH_ID=OAuth ID +OAUTH_ID=OAuth Client ID OAUTH_SECRET=OAuth secret OAUTH_TENANT=OAuth tenant OAuthProviderAdded=OAuth provider added From b880029ac048e3b3e256fac1baf24f2451348a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= Date: Wed, 8 Feb 2023 09:58:30 +0100 Subject: [PATCH 086/137] typos in getAttchments() $arrayobject --- htdocs/emailcollector/class/emailcollector.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 53889ef9c07..5d0c92b4c32 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1951,7 +1951,7 @@ class EmailCollector extends CommonObject 'ticket' => array('table' => 'ticket', 'fields' => array('ref'), 'class' => 'ticket/class/ticket.class.php', - 'object' => ' Ticket'), + 'object' => 'Ticket'), 'knowledgemanagement' => array('table' => 'knowledgemanagement_knowledgerecord', 'fields' => array('ref'), 'class' => 'knowledgemanagement/class/knowledgemanagement.class.php', @@ -1969,7 +1969,7 @@ class EmailCollector extends CommonObject 'class' => 'compta/facture/class/facture.class.php', 'object' => 'Facture'), 'fournisseur/facture' => array('table' => 'facture_fourn', - 'fields' => array('ref', ref_client), + 'fields' => array('ref', 'ref_client'), 'class' => 'fourn/class/fournisseur.facture.class.php', 'object' => 'FactureFournisseur'), 'produit' => array('table' => 'product', From 8a0fd114d45aacda94b9cf803bf4a4649d725928 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Wed, 8 Feb 2023 10:48:46 +0100 Subject: [PATCH 087/137] FIX bug alias extra in extrafields syntax configuration --- htdocs/core/class/extrafields.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 8ac336f84f8..fbd857b0e27 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1233,7 +1233,7 @@ class ExtraFields $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]); } //We have to join on extrafield table - if (strpos($InfoFieldList[4], 'extra') !== false) { + if (strpos($InfoFieldList[4], 'extra.') !== false) { $sql .= ' as main, '.$this->db->prefix().$InfoFieldList[0].'_extrafields as extra'; $sqlwhere .= " WHERE extra.fk_object=main.".$InfoFieldList[2]." AND ".$InfoFieldList[4]; } else { From ea68c44d8f67e87ffffa33f67afa193dd1762d23 Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:00:11 +0100 Subject: [PATCH 088/137] Update ChangeLog --- ChangeLog | 53 +++++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68ce6daabcd..13b5981c8de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,20 +30,20 @@ NEW: #21000 Added columns 'alias_name' on project, supplier invoice, supplier or NEW: #21780 Add pid field to Cronjob class and store PID on job execution NEW: #21395 Added option for dark theme mode in display - color and theme NEW: #21397 added option to auto define barcode numbers for third-parties in barcode module setup -NEW: #21399 +NEW: #21399 add image for event_array NEW: #21442 Enhancement of module builder init NEW: #21654 add bank account number used on invoices for debit -NEW: #22048 Added notes to productlot module +NEW: #22048 added notes to productlot module NEW: #22298 Bank - Add salaries & vat in the tab of planned entries of a bank account -NEW: #22328 -NEW: #22424 +NEW: #22328 OAuth admin +NEW: #22424 online signature for contracts NEW: #22500 member module set up made easier NEW: #22527 projects and thirdparties can be viewed as conversation ("Message" view), like events/agenda. NEW: #22546 can now set user supervisors using mass action in htdocs/user NEW: #22594 can chose if VAT ID is unique or not for third parties NEW: #22622 all partnerships displayed on tab partnership of a thirdparty and member NEW: #22676 massaction for updating product prices -NEW: #22735 Massaction to affect users on projects +NEW: #22735 massaction to affect users on projects NEW: #25594 can chose if VAT ID is unique or not for third parties NEW: #4482 adding js to hide/show advanced option on the export data page @@ -57,27 +57,17 @@ NEW: Add max size send for "backup and link to mail" option NEW: Add method httponly_accessforbidden() NEW: Add more advices into the Setup security page NEW: Add new global variable for keeping the previous signature information on proposale (case of reopen a proposale) -NEW: Add objectLink on expedition -NEW: Add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties NEW: Add option --force on CLI cron_run_jobs.php NEW: Add option "Show price on the generated documents for receptions" -NEW: invoice export : add accounting affectation -NEW: label on products categories filter -NEW: manage no email with thirdparties (better for GDPR) NEW: Manage VAT on all lines on purchases cycle -NEW: On a bank reconciled line, we can modify the bank receipt NEW: parent company column and filter in invoice and order list -NEW: possibility to select scopes with checkbox for Oauth tokens -NEW: private and public note on user, thirdparty and contact list +NEW: private and public note columns on user, thirdparty and contact lists NEW: Public counters feature -NEW: Saved token of OAUTH module are now encrypted into llx_oauth_token NEW: Save one click to select on delivery ack, on emails. NEW: scheduled job to send unpaid invoice reminder can now use the cc and bcc from email template -NEW: experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP) NEW: can substitue project title in mail template NEW: The purge of files can purge only if older than a number of seconds NEW: Update ActionComm type_code on email message ticket -NEW: Finance - VAT - Admin - Add information on deadline day for submission of VAT declaration NEW: Add the target to select attendees of event for emailings NEW: add redirect on action confirm addconsumedline and addproduceline NEW: Add the referrer-policy to "same-origin" by default on all public pages. @@ -87,17 +77,18 @@ NEW: Can enter the unit price including the VAT NEW: Can invoice task time per different services NEW: Can set a commercial discount by entering amount including VAT NEW: Can set start and end dates and comment on button "Activate all services" -NEW: can sort and preselected best supplier price NEW: show date delivery planned on orders linked to company and product NEW: filter on reception dates (from / to) in cheque paiement card -NEW: Accountancy - Add a graphic option to enable lettering function - FPC21 -NEW: Accountancy - Add a way to clean some words when you generate thirdparty accounting account -NEW: Accountancy - Added an option during export to export or not the lettering FPC21 +NEW: Accountancy - add a graphic option to enable lettering function - FPC21 +NEW: Accountancy - add a way to clean some words when you generate thirdparty accounting account +NEW: Accountancy - added an option during export to export or not the lettering FPC21 +NEW: Accountancy - Invoice export : add accounting affectation NEW: Accountancy - Manage supplier deposit with specific account NEW: Accountancy - Model Digitaria - Add a way to clean some words when you generate thirdparty accounting account FPC22 NEW: Agenda - start a simple support of recurrent events on agenda NEW: Bank - add salaries & VAT in tab planned entries +NEW: Bank - on a bank reconciled line, we can modify the bank receipt NEW: Contracts - add a method doAutoRenewContracts that can be used as a cron task NEW: Contracts - default template of contract is not mandatory NEW: Contracts - Manage Position (Rank) on Contract Lines @@ -108,22 +99,29 @@ NEW: EMail - can send an email on scheduled job error NEW: EMail - on a form to send an email, we show all emails of all contacts of object NEW: EMail - add the SMTP header References on ticket email created by email NEW: EMail - add substitution key __SENDEREMAIL_SIGNATURE__ +NEW: EMail - experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP) NEW: EMail-Collector - add IMAP port setting NEW: EMail-Collector - add a button "Test collect" -NEW: Export - Add " as enclosure by default for CSV export. Keep removing CR/LF. NEW: Event-Organization - add date event (!= date project) and location on event organization +NEW: Expedition - add objectLink on expedition +NEW: Export - Add " as enclosure by default for CSV export. Keep removing CR/LF. NEW: Extrafields - add badge in admin extrafields setup NEW: Extrafields - can edit property css, cssview, csslist on extrafields NEW: Extrafields - default values in extrafields are not more limited to 255 char. NEW: Extrafields - field price with currency NEW: Extrafields - support IP type to store IP addresses +NEW: Finance - VAT - Admin - Add information on deadline day for submission of VAT declaration NEW: Interventions - enable online signature for interventions -NEW: Invoice - Add french mention on pdf when vat debit option is on +NEW: Invoice - add french mention on PDF when VAT debit option is on NEW: Members - default_lang for members -NEW: Members - Table of membership types +NEW: Members - table of membership types NEW: Members - add free membership amounts at the membership type level +NEW: OAuth - possibility to select scopes with checkbox for OAuth tokens +NEW: OAuth - saved token of OAUTH module are now encrypted into llx_oauth_token NEW: Orders - resize parent company column in order list -NEW: Products supplier price - autofill default supplier VAT +NEW: Products - Categories - label on products categories filter +NEW: Products - Supplier price - autofill default supplier VAT +NEW: Products - Supplier price - can sort and preselected best supplier price NEW: Projects - add author on list NEW: Projects - add thirdparty column to the time list (projet/tasks/time.php) NEW: Proposals - show delivery mode on PDF for proposals @@ -144,8 +142,10 @@ NEW: TakePOS - display currency in TakePOS menu NEW: TakePOS - Header Scroll in TakePOS NEW: TakePOS - Receipt preview in TakePOS setup NEW: TakePOS - support of Stripe Terminal with TakePOS +NEW: Thirdparty - manage no email with thirdparties (better for GDPR) NEW: Thirdparty - set thirdparty type with company modify trigger NEW: Tickets - change filter type on tickets list into a multiselect combo +NEW: Tickets - add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties NEW: Website - can delete a whole website if disabled NEW: Website - can remove a website template NEW: Website - can set header "Strict-Transport-Security" in web sites. @@ -176,11 +176,16 @@ NEW: Security: add fail2ban rules examples to limit access to /public pages Option / Const for System: NEW: FICHINTER_ALLOW_EXTERNAL_DOWNLOAD +NEW: MAIN_CHECKBOX_LEFT_COLUMN +NEW: MAIN_EMAIL_SUPPORT_ACK +NEW: MAIN_IMAP_USE_PHPIMAP NEW: MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS - const to show category customer filter +NEW: PRODUCT_ALLOW_EXTERNAL_DOWNLOAD NEW: PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT - showing warehouse on PDF NEW: PRODUIT_DESC_IN_FORM accept - desktop only or +smartphone NEW: PROPAL_BYPASS_VALIDATED_STATUS NEW: PROPAL_NEW_AS_SIGNED +NEW: PROPAL_SKIP_ACCEPT_REFUSE NEW: TIMESPENT_ALWAYS_UPDATE_THM - when it's on we always check current thm of user to update it in task time line Localisation: From 81400b1fc5667f9930ad4b05fa9cd5940b619949 Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:14:53 +0100 Subject: [PATCH 089/137] Update llx_c_availability.sql add 1-5 days --- htdocs/install/mysql/data/llx_c_availability.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/install/mysql/data/llx_c_availability.sql b/htdocs/install/mysql/data/llx_c_availability.sql index b98db76b48e..7768477c5d1 100644 --- a/htdocs/install/mysql/data/llx_c_availability.sql +++ b/htdocs/install/mysql/data/llx_c_availability.sql @@ -33,6 +33,11 @@ -- INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_NOW', 'Immediate', null, 0, 1, 10); +INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_1D', '1 day', 'd', 1, 1, 11); +INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_2D', '2 days', 'd', 2, 1, 12); +INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_3D', '3 days', 'd', 3, 1, 13); +INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_4D', '4 days', 'd', 4, 1, 14); +INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_5D', '5 days', 'd', 5, 1, 15); INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_1W', '1 week', 'w', 1, 1, 20); INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_2W', '2 weeks', 'w', 2, 1, 30); INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_3W', '3 weeks', 'w', 3, 1, 40); From 34b4cad448eae6d66fd8e90744d8c5adcc61d1e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 13:18:32 +0100 Subject: [PATCH 090/137] Complete trans --- htdocs/core/modules/modOauth.class.php | 2 +- htdocs/langs/en_US/admin.lang | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modOauth.class.php b/htdocs/core/modules/modOauth.class.php index d93a715f1e7..e7c23d30455 100644 --- a/htdocs/core/modules/modOauth.class.php +++ b/htdocs/core/modules/modOauth.class.php @@ -51,7 +51,7 @@ class modOauth extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i', '', get_class($this)); // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) - $this->description = "Enable OAuth authentication"; + $this->description = "Enable OAuth2 authentication"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 46339a7bf6d..f20065556bf 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -700,6 +700,8 @@ Module62000Name=Incoterms Module62000Desc=Add features to manage Incoterms Module63000Name=Resources Module63000Desc=Manage resources (printers, cars, rooms, ...) for allocating to events +Module66000Name=Enable OAuth2 authentication +Module66000Desc=Provide a tool to generate and manage OAuth2 tokens. The token can then be used by some other modules. Module94160Name=Receptions Permission11=Read customer invoices Permission12=Create/modify customer invoices From cdaeaae047025cf05d7e067a9111c1d100e650f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 13:32:15 +0100 Subject: [PATCH 091/137] Fix search on dolistore --- htdocs/admin/modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index dc639a4ecf0..953d8f85a68 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -1041,7 +1041,7 @@ if ($mode == 'marketplace') { print '
'; - print '
'; + print ''; ?> From 6cf792438d5bbd35d45655265b67ba462fdc89ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 13:48:17 +0100 Subject: [PATCH 092/137] Fix permission --- htdocs/core/lib/invoice.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index f4aca8ef9a7..dfe6f78092c 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -281,8 +281,8 @@ function getNumberInvoicesPieChart($mode) { global $conf, $db, $langs, $user; - if (($mode == 'customers' && isModEnabled('facture') && !empty($user->rights->facture->lire)) - || ($mode == 'suppliers' && (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && !empty($user->rights->facture->lire)) + if (($mode == 'customers' && isModEnabled('facture') && $user->hasRight('facture', 'lire')) + || ($mode == 'suppliers' && (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && $user->hasRight('fournisseur', 'facture', 'lire')) ) { include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; From 7d57cfb767f11fa9307371efccc5114c955fb47f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 14:04:50 +0100 Subject: [PATCH 093/137] Missing doc --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1b877e2b4b4..189bcd41004 100644 --- a/ChangeLog +++ b/ChangeLog @@ -210,7 +210,7 @@ Following changes may create regressions for some external modules, but were nec * Rename MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and rename MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES * Rename the substitution for "project label" instead of "project title" in substitution variables * You must use "$objectoffield" to manipulate the current object inside the formulare of computed custom extrafields instead of $obj/$object. - +* Making a global search is sending the parameter using always the name search_all (instead of sometimes sall and search_all) ***** ChangeLog for 16.0.4 compared to 16.0.3 ***** From 28c722ef598728c8b9e8c847f287f9bf544a67c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 15:19:00 +0100 Subject: [PATCH 094/137] error message may be overwritten by other error message --- htdocs/product/class/product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 60de90d819d..bb34fc2e3eb 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -14,7 +14,7 @@ * Copyright (C) 2014 Ion agorria * Copyright (C) 2016-2018 Ferran Marcet * Copyright (C) 2017 Gustavo Novaro - * Copyright (C) 2019-2022 Frédéric France + * Copyright (C) 2019-2023 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 @@ -1566,7 +1566,7 @@ class Product extends CommonObject } } elseif (isset($this->multilangs[$key])) { if (empty($this->multilangs["$key"]["label"])) { - $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")); + $this->errors[] = $key . ' : ' . $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")); return -1; } From 98bfba1f461be23fcce1451cd1f275ab82c9020e Mon Sep 17 00:00:00 2001 From: avolani <31508728+avolani@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:20:47 +0100 Subject: [PATCH 095/137] Add missing table_element This allow usage of extrafields logic (still missing table and setup pages) --- htdocs/expensereport/class/expensereport.class.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index bc7e0f36baa..04c16fc2654 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -2680,6 +2680,11 @@ class ExpenseReportLine extends CommonObjectLine * @var DoliDB Database handler. */ public $db; + + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'expensereport_det'; /** * @var string Error code (or message) From 637603731a3785eadbdd454ae96ecc79ed570b7a Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 8 Feb 2023 15:26:10 +0000 Subject: [PATCH 096/137] Fixing style errors. --- htdocs/expensereport/class/expensereport.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 04c16fc2654..6ee3c8e19e7 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -2680,11 +2680,11 @@ class ExpenseReportLine extends CommonObjectLine * @var DoliDB Database handler. */ public $db; - + /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'expensereport_det'; + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'expensereport_det'; /** * @var string Error code (or message) From f35d63cec148ae06928571e85ae9821b03b86a48 Mon Sep 17 00:00:00 2001 From: avolani <31508728+avolani@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:41:06 +0100 Subject: [PATCH 097/137] Clean placeholder of missing related project and products --- htdocs/core/class/commondocgenerator.class.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 82012400f68..05837331e16 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -538,6 +538,12 @@ abstract class CommonDocGenerator $resarray[$array_key.'_project_description'] = $object->project->description; $resarray[$array_key.'_project_date_start'] = dol_print_date($object->project->date_start, 'day'); $resarray[$array_key.'_project_date_end'] = dol_print_date($object->project->date_end, 'day'); + } else { // empty replacement + $resarray[$array_key.'_project_ref'] =''; + $resarray[$array_key.'_project_title'] = ''; + $resarray[$array_key.'_project_description'] = ''; + $resarray[$array_key.'_project_date_start'] = ''; + $resarray[$array_key.'_project_date_end'] = ''; } // Add vat by rates @@ -701,6 +707,14 @@ abstract class CommonDocGenerator foreach ($tmpproduct->array_options as $key => $label) { $resarray["line_product_".$key] = $label; } + } else { + // Set unused placeholders as blank + $extrafields->fetch_name_optionals_label("product"); + $extralabels = $extrafields->attributes["product"]['label']; + + foreach ($extralabels as $key => $label) { + $resarray['line_product_options_'.$key] = ''; + } } return $resarray; From a17c7aba7348fa1ed3cc03ee974544f7498c9a7e Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Wed, 8 Feb 2023 19:25:03 +0100 Subject: [PATCH 098/137] Fix : sall becomes search_all on top menu search also --- htdocs/main.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1dd9eb35c04..37d018a21ce 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2732,7 +2732,7 @@ function top_menu_search() $buttonList .= '
'; - $searchInput = ''; + $searchInput = ''; $dropDownHtml = ''; From 3f8aaf5cbc3f0f3532a4737e2bf9b97f9d0c674e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 21:30:55 +0100 Subject: [PATCH 099/137] clean code --- .../class/expensereport.class.php | 65 ++++++++++++++----- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 38c39d96b6f..685626ef6ff 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -3,7 +3,7 @@ * Copyright (C) 2015 Laurent Destailleur * Copyright (C) 2015 Alexandre Spangaro * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (c) 2018-2021 Frédéric France + * Copyright (c) 2018-2023 Frédéric France * Copyright (C) 2016-2020 Ferran Marcet * * This program is free software; you can redistribute it and/or modify @@ -60,8 +60,16 @@ class ExpenseReport extends CommonObject */ public $picto = 'trip'; + /** + * @var ExpenseReportLine[] array of expensereport lines + */ public $lines = array(); + /** + * @var ExpenseReportLine expensereport lines + */ + public $line; + public $date_debut; public $date_fin; @@ -93,6 +101,15 @@ class ExpenseReport extends CommonObject // Create public $date_create; + + /** + * @var int ID of user creator + */ + public $fk_user_creat; + + /** + * @var int ID of user who reclaim expense report + */ public $fk_user_author; // Note fk_user_author is not the 'author' but the guy the expense report is for. // Update @@ -107,15 +124,34 @@ class ExpenseReport extends CommonObject // Annulation public $date_cancel; public $detail_cancel; + + /** + * @var int ID of user who cancel expense report + */ public $fk_user_cancel; - public $fk_user_validator; // User that is defined to approve + /** + * @var int User that is defined to approve + */ + public $fk_user_validator; - // Validation - /* @deprecated */ + /** + * Validation date + * @var int + * @deprecated + * @see $date_valid + */ public $datevalid; - public $date_valid; // User making validation + /** + * Validation date + * @var int + */ + public $date_valid; + + /** + * @var int ID of User making validation + */ public $fk_user_valid; public $user_valid_infos; @@ -154,16 +190,15 @@ class ExpenseReport extends CommonObject */ const STATUS_APPROVED = 5; - /** - * Classified refused - */ - const STATUS_REFUSED = 99; - /** * Classified paid. */ const STATUS_CLOSED = 6; + /** + * Classified refused + */ + const STATUS_REFUSED = 99; public $fields = array( 'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), @@ -434,12 +469,12 @@ class ExpenseReport extends CommonObject $this->fk_statut = 0; // deprecated // Clear fields - $this->fk_user_creat = $user->id; - $this->fk_user_author = $fk_user_author; // Note fk_user_author is not the 'author' but the guy the expense report is for. - $this->fk_user_valid = ''; + $this->fk_user_creat = $user->id; + $this->fk_user_author = $fk_user_author; // Note fk_user_author is not the 'author' but the guy the expense report is for. + $this->fk_user_valid = ''; $this->date_create = ''; - $this->date_creation = ''; - $this->date_validation = ''; + $this->date_creation = ''; + $this->date_validation = ''; // Remove link on lines to a joined file if (is_array($this->lines) && count($this->lines) > 0) { From 9fe920b2a925fd5464e54a950c31509c7e156899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 21:45:46 +0100 Subject: [PATCH 100/137] deprecate method send_an_email --- htdocs/adherents/card.php | 6 +++--- htdocs/adherents/class/adherent.class.php | 25 +++++++++++++++++++++++ htdocs/adherents/subscription.php | 2 +- htdocs/projet/class/project.class.php | 7 ++++--- htdocs/public/members/new.php | 2 +- htdocs/public/partnership/new.php | 2 +- htdocs/public/payment/paymentok.php | 2 +- htdocs/public/project/new.php | 2 +- 8 files changed, 37 insertions(+), 11 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index f57bb2e312d..f9a43e47f0f 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -674,7 +674,7 @@ if (empty($reshook)) { $moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); if ($result < 0) { $error++; setEventMessages($object->error, $object->errors, 'errors'); @@ -745,7 +745,7 @@ if (empty($reshook)) { $moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); if ($result < 0) { $error++; setEventMessages($object->error, $object->errors, 'errors'); @@ -816,7 +816,7 @@ if (empty($reshook)) { $moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); if ($result < 0) { $error++; setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index a9db33b9980..df7737213a5 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -440,11 +440,36 @@ class Adherent extends CommonObject * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection * @param string $errors_to erros to * @param string $moreinheader Add more html headers + * @deprecated since V18 + * @see sendEmail * @return int <0 if KO, >0 if OK */ public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '') { // phpcs:enable + dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING); + return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader); + } + + /** + * Function sending an email to the current member with the text supplied in parameter. + * + * @param string $text Content of message (not html entities encoded) + * @param string $subject Subject of message + * @param array $filename_list Array of attached files + * @param array $mimetype_list Array of mime types of attached files + * @param array $mimefilename_list Array of public names of attached files + * @param string $addr_cc Email cc + * @param string $addr_bcc Email bcc + * @param int $deliveryreceipt Ask a delivery receipt + * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection + * @param string $errors_to erros to + * @param string $moreinheader Add more html headers + * @since V18 + * @return int <0 if KO, >0 if OK + */ + public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '') + { global $conf, $langs; // Detect if message is HTML diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 8c423d53029..004bd7eaf4b 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -405,7 +405,7 @@ if ($user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscripti $moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/subscription.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, '', $moreinheader); if ($result < 0) { $errmsg = $object->error; setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 51bae7ab6e9..305cfdd570b 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -2314,7 +2314,6 @@ class Project extends CommonObject $this->lines = $taskstatic->getTasksArray(0, $user, $this->id, 0, 0, '', '-1', '', 0, 0, array(), 0, array(), 0, $loadRoleMode); } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Function sending an email to the current member with the text supplied in parameter. * @@ -2329,12 +2328,14 @@ class Project extends CommonObject * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection * @param string $errors_to erros to * @param string $moreinheader Add more html headers + * @since V18 * @return int <0 if KO, >0 if OK */ - public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '') + public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '') { - // phpcs:enable global $conf, $langs; // TODO EMAIL + + return 1; } } diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php index 943280d6e2d..9ac60d8f823 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -372,7 +372,7 @@ if (empty($reshook) && $action == 'add') { if ($subjecttosend && $texttosend) { $moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); } /*if ($result < 0) { $error++; diff --git a/htdocs/public/partnership/new.php b/htdocs/public/partnership/new.php index af2583abece..d5d1dad1d81 100644 --- a/htdocs/public/partnership/new.php +++ b/htdocs/public/partnership/new.php @@ -360,7 +360,7 @@ if (empty($reshook) && $action == 'add') { if ($subjecttosend && $texttosend) { $moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); } } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 4a13de1ef7f..40898f1ff6e 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -775,7 +775,7 @@ if ($ispaymentok) { $moreinheader = 'X-Dolibarr-Info: send_an_email by public/payment/paymentok.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, "", $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, "", $moreinheader); if ($result < 0) { $errmsg = $object->error; diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index 726a318c99f..ec891fc3741 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -371,7 +371,7 @@ if (empty($reshook) && $action == 'add') { if ($subjecttosend && $texttosend) { $moreinheader = 'X-Dolibarr-Info: send_an_email by public/lead/new.php'."\r\n"; - $result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); } /*if ($result < 0) { $error++; From b22d5b3e8adde4b6c6d67b214dfada3edf1bebcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 21:47:11 +0100 Subject: [PATCH 101/137] deprecate method send_an_email --- htdocs/adherents/class/adherent.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index df7737213a5..689309f933c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -448,6 +448,7 @@ class Adherent extends CommonObject { // phpcs:enable dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING); + return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader); } From 2cdc4406558f597b25877edb71b76de8019fd01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 21:57:07 +0100 Subject: [PATCH 102/137] doc --- htdocs/reception/class/reception.class.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index e9a89691c88..018d532a363 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -11,7 +11,7 @@ * Copyright (C) 2015 Claudio Aschieri * Copyright (C) 2016-2022 Ferran Marcet * Copyright (C) 2018 Quentin Vial-Gouteyron - * Copyright (C) 2022 Frédéric France + * Copyright (C) 2022-2023 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 @@ -97,6 +97,12 @@ class Reception extends CommonObject public $date_delivery; // Date delivery planed + /** + * @var integer|string Effective delivery date + * @deprecated + * @see $date_reception + */ + public $date; /** * @var integer|string Effective delivery date @@ -396,8 +402,7 @@ class Reception extends CommonObject $this->statut = $obj->fk_statut; $this->user_author_id = $obj->fk_user_author; $this->date_creation = $this->db->jdate($obj->date_creation); - $this->date = $this->db->jdate($obj->date_reception); // TODO deprecated - $this->date_reception = $this->db->jdate($obj->date_reception); // TODO deprecated + $this->date = $this->db->jdate($obj->date_reception); // TODO deprecated $this->date_reception = $this->db->jdate($obj->date_reception); // Date real $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed $this->model_pdf = $obj->model_pdf; From 2c7a01848c9c5a70d7ebd71473e02946a9a9bb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 22:12:28 +0100 Subject: [PATCH 103/137] add ajax tooltip on partnership --- .../partnership/class/partnership.class.php | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/htdocs/partnership/class/partnership.class.php b/htdocs/partnership/class/partnership.class.php index a9645efaae2..a202bdbd284 100644 --- a/htdocs/partnership/class/partnership.class.php +++ b/htdocs/partnership/class/partnership.class.php @@ -145,6 +145,7 @@ class Partnership extends CommonObject public $last_check_backlink; public $reason_decline_or_cancel; public $fk_soc; + public $fk_member; // END MODULEBUILDER PROPERTIES @@ -938,6 +939,29 @@ class Partnership extends CommonObject return $this->setStatusCommon($user, self::STATUS_APPROVED, $notrigger, 'PARTNERSHIP_REOPEN'); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $langs; + + $langs->load('partnership'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Partnership").''; + if (isset($this->status)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + + return $datas; + } + /** * Return a link to the object card (with optionaly the picto) * @@ -957,13 +981,19 @@ class Partnership extends CommonObject } $result = ''; - - $label = img_picto('', $this->picto).' '.$langs->trans("Partnership").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + 'option' => $option, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref; + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/partnership/partnership_card.php?id='.$this->id; @@ -984,8 +1014,8 @@ class Partnership extends CommonObject $label = $langs->trans("ShowPartnership"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1006,7 +1036,7 @@ class Partnership extends CommonObject if (empty($this->showphoto_on_popup)) { if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } } else { if ($withpicto) { From dc97584f87638d8591664f21023c7b2e31933e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 22:20:46 +0100 Subject: [PATCH 104/137] add ajax tooltip on intervention --- htdocs/fichinter/class/fichinter.class.php | 52 +++++++++++++++------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 66645583216..428f0f0767b 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -770,6 +770,29 @@ class Fichinter extends CommonObject return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statuscode, $mode); } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('fichinter'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("Intervention").''; + if (isset($this->status)) { + $datas['picto'] .= ' '.$this->getLibStatut(5); + } + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + + return $datas; + } + /** * Return clicable name (with picto eventually) * @@ -784,12 +807,18 @@ class Fichinter extends CommonObject global $conf, $langs, $hookmanager; $result = ''; - - $label = img_picto('', $this->picto).' '.$langs->trans("Intervention").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); } - $label .= '
'.$langs->trans('Ref').': '.$this->ref; + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id; @@ -810,15 +839,8 @@ class Fichinter extends CommonObject $label = $langs->trans("ShowIntervention"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip"'; - - /* - $hookmanager->initHooks(array('fichinterdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.'"'; } $linkstart = 'picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From 3e7b74557a7e20b9e68603bfcf8153d4be1a4cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 22:23:40 +0100 Subject: [PATCH 105/137] add ajax tooltip on intervention --- htdocs/fichinter/class/fichinter.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 428f0f0767b..7070f94ab23 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -159,7 +159,7 @@ class Fichinter extends CommonObject public $extraparams = array(); /** - * @var array lines + * @var FichinterLigne[] lines */ public $lines = array(); From c871e844699f4874b6ad4a79cbf4a0820a9769b0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Feb 2023 22:50:27 +0100 Subject: [PATCH 106/137] Fix fatal error on constant no defined --- htdocs/core/modules/modFckeditor.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php index fa3a66c37cc..631dba395fe 100644 --- a/htdocs/core/modules/modFckeditor.class.php +++ b/htdocs/core/modules/modFckeditor.class.php @@ -63,7 +63,7 @@ class modFckeditor extends DolibarrModules $this->config_page_url = array("fckeditor.php"); // Dependencies - $this->disabled = in_array(constant('JS_CKEDITOR'), array('disabled', 'disabled/')); + $this->disabled = (defined('JS_CKEDITOR') && in_array(constant('JS_CKEDITOR'), array('disabled', 'disabled/'))); $this->depends = array(); $this->requiredby = array('modWebsites'); From eee645bb0655bba2512618b139741ef02886ff30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 23:01:04 +0100 Subject: [PATCH 107/137] add ajax tooltip on opensurvey --- htdocs/core/ajax/ajaxtooltip.php | 7 ++- .../class/opensurveysondage.class.php | 44 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/htdocs/core/ajax/ajaxtooltip.php b/htdocs/core/ajax/ajaxtooltip.php index d10b0f1a43e..60220a221ff 100644 --- a/htdocs/core/ajax/ajaxtooltip.php +++ b/htdocs/core/ajax/ajaxtooltip.php @@ -41,7 +41,8 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; top_httphead(); -$id = GETPOST('id', 'int'); +// opensurvey as aZ09 id +$id = GETPOST('id', 'aZ09'); $objecttype = GETPOST('objecttype', 'aZ09'); $html = ''; @@ -158,6 +159,10 @@ if ($objecttype == 'facture' || $objecttype == 'invoice') { $classpath = 'resource/class'; $module = 'resource'; $myobject = 'dolresource'; +} elseif ($objecttype == 'opensurvey_sondage') { + $classpath = 'opensurvey/class'; + $module = 'opensurvey'; + $myobject = 'opensurveysondage'; } // Generic case for $classfile and $classname diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index f5dadd90f2e..e928c2f3cd6 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -420,6 +420,27 @@ class Opensurveysondage extends CommonObject } } + /** + * getTooltipContentArray + * + * @param array $params ex option, infologin + * @since v18 + * @return array + */ + public function getTooltipContentArray($params) + { + global $conf, $langs; + + $langs->load('opensurvey'); + + $datas = []; + $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans("ShowSurvey").''; + $datas['ref'] = '
'.$langs->trans('Ref').': '.$this->ref; + $datas['title'] = '
'.$langs->trans('Title').': '.$this->title; + + return $datas; + } + /** * Return a link to the object card (with optionaly the picto) * @@ -440,11 +461,18 @@ class Opensurveysondage extends CommonObject } $result = ''; - - $label = img_picto('', $this->picto).' '.$langs->trans("ShowSurvey").''; - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref.'
'; - $label .= ''.$langs->trans('Title').': '.$this->title.'
'; + $params = [ + 'id' => $this->id, + 'objecttype' => $this->element, + ]; + $classfortooltip = 'classfortooltip'; + $dataparams = ''; + if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { + $classfortooltip = 'classforajaxtooltip'; + $dataparams = ' data-params='.json_encode($params); + // $label = $langs->trans('Loading'); + } + $label = implode($this->getTooltipContentArray($params)); $url = DOL_URL_ROOT.'/opensurvey/card.php?id='.$this->id; @@ -463,8 +491,8 @@ class Opensurveysondage extends CommonObject $label = $langs->trans("ShowMyObject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + $linkclose .= $dataparams.' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -475,7 +503,7 @@ class Opensurveysondage extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; From de31fb83f0df5c59268362b50213ebd8b11d1771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 8 Feb 2023 23:33:39 +0100 Subject: [PATCH 108/137] fix links --- htdocs/core/lib/hrm.lib.php | 16 ++++++++-------- htdocs/hrm/establishment/info.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/core/lib/hrm.lib.php b/htdocs/core/lib/hrm.lib.php index 5335dc1c75e..706af6bd110 100644 --- a/htdocs/core/lib/hrm.lib.php +++ b/htdocs/core/lib/hrm.lib.php @@ -52,15 +52,15 @@ function establishment_prepare_head($object) $head[$h][2] = 'info'; $h++; - $head[$h][0] = dol_buildpath("/hrm/admin/setup.php", 1); - $head[$h][1] = $langs->trans("Settings"); - $head[$h][2] = 'settings'; - $h++; + // $head[$h][0] = dol_buildpath("/hrm/admin/setup.php", 1); + // $head[$h][1] = $langs->trans("Settings"); + // $head[$h][2] = 'settings'; + // $h++; - $head[$h][0] = dol_buildpath("/hrm/admin/about.php", 1); - $head[$h][1] = $langs->trans("About"); - $head[$h][2] = 'about'; - $h++; + // $head[$h][0] = dol_buildpath("/hrm/admin/about.php", 1); + // $head[$h][1] = $langs->trans("About"); + // $head[$h][2] = 'about'; + // $h++; complete_head_from_modules($conf, $langs, null, $head, $h, 'hrm'); diff --git a/htdocs/hrm/establishment/info.php b/htdocs/hrm/establishment/info.php index 3bfbe912279..1a9ba129f10 100644 --- a/htdocs/hrm/establishment/info.php +++ b/htdocs/hrm/establishment/info.php @@ -138,7 +138,7 @@ if ($object->id > 0) { // Object card // ------------------------------------------------------------ - $linkback = '
'.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; /* From 8f2076e83e0183b95446321b3676524397c572d9 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Thu, 9 Feb 2023 11:07:30 +0100 Subject: [PATCH 109/137] fix problems in menus for modulebuilder --- htdocs/modulebuilder/index.php | 133 +++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 57 deletions(-) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 6f62e8f142c..916a91ecf61 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -896,6 +896,17 @@ if ($dirins && $action == 'confirm_removefile' && !empty($module)) { // Init an object if ($dirins && $action == 'initobject' && $module && $objectname) { + // check if module is enabled + if (isModEnabled(strtolower($module))) { + $result = unActivateModule(strtolower($module)); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + if ($result) { + setEventMessages($result, null, 'errors'); + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); + } + $objectname = ucfirst($objectname); $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; @@ -1341,43 +1352,31 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { // Regenerate left menu entry in descriptor for $objectname $stringtoadd = " \$this->menu[\$r++]=array( - // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'fk_menu'=>'fk_mainmenu=mymodule', - // This is a Left menu entry 'type'=>'left', 'titre'=>'List MyObject', 'mainmenu'=>'mymodule', 'leftmenu'=>'mymodule_myobject', 'url'=>'/mymodule/myobject_list.php', - // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'langs'=>'mymodule@mymodule', 'position'=>1100+\$r, - // Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected. 'enabled'=>'\$conf->mymodule->enabled', - // Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'perms'=>'1', 'target'=>'', - // 0=Menu for internal users, 1=external users, 2=both 'user'=>2, ); \$this->menu[\$r++]=array( - // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=mymodule_myobject', - // This is a Left menu entry 'type'=>'left', 'titre'=>'New MyObject', 'mainmenu'=>'mymodule', 'leftmenu'=>'mymodule_myobject', 'url'=>'/mymodule/myobject_card.php?action=create', - // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'langs'=>'mymodule@mymodule', 'position'=>1100+\$r, - // Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected. 'enabled'=>'\$conf->mymodule->enabled', - // Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'perms'=>'1', 'target'=>'', - // 0=Menu for internal users, 1=external users, 2=both 'user'=>2 );\n"; $stringtoadd = preg_replace('/MyObject/', $objectname, $stringtoadd); @@ -1389,8 +1388,28 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1 // TODO Avoid duplicate addition - dolReplaceInFile($moduledescriptorfile, array('END MODULEBUILDER LEFTMENU MYOBJECT */' => '*/'."\n".$stringtoadd."\n\t\t/* END MODULEBUILDER LEFTMENU MYOBJECT */")); - + // load class and check if menu exist with same object name + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; + if (class_exists($class)) { + try { + $moduleobj = new $class($db); + } catch (Exception $e) { + $error++; + dol_print_error($db, $e->getMessage()); + } + } + $menus = $moduleobj->menu; + $counter = 0 ; + foreach ($menus as $menu) { + if ($menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) { + $counter++; + } + } + if (!$counter) { + dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER LEFTMENU MYOBJECT */' => '/*LEFTMENU '.strtoupper($objectname).'*/'.$stringtoadd."\n\t\t".'/*END LEFTMENU '.strtoupper($objectname).'*/'."\n\t\t".'/* END MODULEBUILDER LEFTMENU MYOBJECT */')); + } // Add module descriptor to list of files to replace "MyObject' string with real name of object. $filetogenerate[] = 'core/modules/mod'.$module.'.class.php'; } @@ -1728,6 +1747,16 @@ if ($dirins && $action == 'confirm_deletemodule') { } if ($dirins && $action == 'confirm_deleteobject' && $objectname) { + // check if module is enabled (if it's disabled and send msg event) + if (isModEnabled(strtolower($module))) { + $result = unActivateModule(strtolower($module)); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + if ($result) { + setEventMessages($result, null, 'errors'); + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); + } if (preg_match('/[^a-z0-9_]/i', $objectname)) { $error++; setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors'); @@ -1766,53 +1795,43 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) { ); //menu for the object selected - $stringtoedit = "\$this->menu[\$r++]=array( - // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode - 'fk_menu'=>'fk_mainmenu=".strtolower($module)."', - // This is a Left menu entry - 'type'=>'left', - 'titre'=>'List ".ucfirst($objectname)."', - 'mainmenu'=>'".strtolower($module)."', - 'leftmenu'=>'".strtolower($module)."_".strtolower($objectname)."', - 'url'=>'/".strtolower($module)."/".strtolower($objectname)."_list.php', - // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'langs'=>'".strtolower($module)."@".strtolower($module)."', - 'position'=>1100+\$r, - // Define condition to show or hide menu entry. Use '\$conf->".strtolower($module)."->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected. - 'enabled'=>'\$conf->".strtolower($module)."->enabled', - // Use 'perms'=>'\$user->rights->".strtolower($module)."->level1->level2' if you want your menu with a permission rules - 'perms'=>'1', - 'target'=>'', - // 0=Menu for internal users, 1=external users, 2=both - 'user'=>2, - ); - \$this->menu[\$r++]=array( - // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode - 'fk_menu'=>'fk_mainmenu=".strtolower($module).",fk_leftmenu=".strtolower($module)."_".strtolower($objectname)."', - // This is a Left menu entry - 'type'=>'left', - 'titre'=>'New ".ucfirst($objectname)."', - 'mainmenu'=>'".strtolower($module)."', - 'leftmenu'=>'".strtolower($module)."_".strtolower($objectname)."', - 'url'=>'/".strtolower($module)."/".strtolower($objectname)."_card.php?action=create', - // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'langs'=>'".strtolower($module)."@".strtolower($module)."', - 'position'=>1100+\$r, - // Define condition to show or hide menu entry. Use '\$conf->".strtolower($module)."->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected. - 'enabled'=>'\$conf->".strtolower($module)."->enabled', - // Use 'perms'=>'\$user->rights->".strtolower($module)."->level1->level2' if you want your menu with a permission rules - 'perms'=>'1', - 'target'=>'', - // 0=Menu for internal users, 1=external users, 2=both - 'user'=>2 - );"; + // load class and check if menu exist for this object + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; + if (class_exists($class)) { + try { + $moduleobj = new $class($db); + } catch (Exception $e) { + $error++; + dol_print_error($db, $e->getMessage()); + } + } + $menus = $moduleobj->menu; $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; - $check = dolReplaceInFile($moduledescriptorfile, array($stringtoedit => '')); - if ($check > 0) { - dolReplaceInFile($moduledescriptorfile, array('/*'.strtoupper($objectname).'*/' => '')); + foreach ($menus as $menu) { + if ($menu['type'] == 'left' && $menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) { + $left="\$this->menu[\$r++]=array( + 'fk_menu'=>'".$menu['fk_menu']."', + 'type'=>'".$menu['type']."', + 'titre'=>'".$menu['titre']."', + 'mainmenu'=>'".$menu['mainmenu']."', + 'leftmenu'=>'".$menu['leftmenu']."', + 'url'=>'".$menu['url']."', + 'langs'=>'".$menu['langs']."', + 'position'=>1100+\$r, + 'enabled'=>'".$menu['enabled']."', + 'perms'=>'".$menu['perms']."', + 'target'=>'".$menu['target']."', + 'user'=>".$menu['user'].", + );"; + dolReplaceInFile($moduledescriptorfile, array($left => '')); + } } + // Remarque : "\n" not handling yet + $check = dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($objectname).'*/'."\n" => '',"\t\t".'/*END LEFTMENU '.strtoupper($objectname).'*/'."\n" => '')); // regenerate permissions and delete them $rights = " From 78c6f12a8aa676b32710609e34122487b5a4dfdd Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Thu, 9 Feb 2023 11:40:43 +0100 Subject: [PATCH 110/137] NEW functionality (delete menu manually) in modulebuilder --- htdocs/langs/en_US/modulebuilder.lang | 5 +- htdocs/langs/fr_FR/modulebuilder.lang | 5 +- htdocs/modulebuilder/index.php | 85 +++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 600dfba7227..3c442fcc84a 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -169,4 +169,7 @@ GeneratePermissions=I want to add the rights for this object GeneratePermissionsHelp=generate default rights for this object PermissionDeletedSuccesfuly=Permission has been successfully removed PermissionUpdatedSuccesfuly=Permission has been successfully updated -PermissionAddedSuccesfuly=Permission has been successfully added \ No newline at end of file +PermissionAddedSuccesfuly=Permission has been successfully added +MenuDeletedSuccessfuly=Menu has been successfully deleted +MenuAddedSuccessfuly=Menu has been successfully added +MenuUpdatedSuccessfuly=Menu has been successfully updated \ No newline at end of file diff --git a/htdocs/langs/fr_FR/modulebuilder.lang b/htdocs/langs/fr_FR/modulebuilder.lang index 3c4161941e8..c9c0b9ef1bc 100644 --- a/htdocs/langs/fr_FR/modulebuilder.lang +++ b/htdocs/langs/fr_FR/modulebuilder.lang @@ -169,4 +169,7 @@ GeneratePermissions=Je souhaite ajouter les droits pour cet objet GeneratePermissionsHelp=générer les droits par défault pour cet objet PermissionDeletedSuccesfuly=La permission a été supprimée avec succès PermissionUpdatedSuccesfuly=La permission a été mise à jour avec succès -PermissionAddedSuccesfuly= La permission a été ajoutée avec succès \ No newline at end of file +PermissionAddedSuccesfuly= La permission a été ajoutée avec succès +MenuDeletedSuccessfuly=Menu a été supprimé avec succès +MenuAddedSuccessfuly=Menu a été ajouté avec succès +MenuUpdatedSuccessfuly=Menu a été mise à jour avec succès \ No newline at end of file diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 916a91ecf61..e52985e8c50 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2360,6 +2360,91 @@ if ($action == 'reset' && $user->admin) { exit; } +// delete menu +if ($dirins && $action == 'confirm_deletemenu' && GETPOST('menukey', 'int')) { + // check if module is enabled + if (isModEnabled(strtolower($module))) { + $result = unActivateModule(strtolower($module)); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + if ($result) { + setEventMessages($result, null, 'errors'); + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); + } + // load class and check if menu exist + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; + if (class_exists($class)) { + try { + $moduleobj = new $class($db); + } catch (Exception $e) { + $error++; + dol_print_error($db, $e->getMessage()); + } + } + + $menus = $moduleobj->menu; + + $key = (int) GETPOST('menukey', 'int'); + $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + + + if ($menus[$key]['type'] == 'top') { + $menuTop = " + \$this->menu[\$r++] = array( + 'fk_menu'=>'".$menus[$key]['fk_menu']."', + 'type'=>'".$menus[$key]['type']."', + 'titre'=>'".$menus[$key]['titre']."', + 'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'), + 'mainmenu'=>'".$menus[$key]['mainmenu']."', + 'leftmenu'=> '', + 'url'=>'".$menus[$key]['url']."', + 'langs'=>'".$menus[$key]['langs']."', + 'position'=>1000 + \$r, + 'enabled'=>'isModEnabled(\"".strtolower($module)."\")', + 'perms' =>'".$menus[$key]['perms']."', + 'target'=>'".$menus[$key]['target']."', + 'user'=>".$menus[$key]['user'].", + );"; + $check = dolReplaceInFile($moduledescriptorfile, array($menuTop => '',"\t\t".'/*TOPMENU '.strtolower($menus[$key]['titre']).'*/'."\n" => '', '/*END TOPMENU '.strtolower($menus[$key]['titre']).'*/'."\n\t\t" => '')); + } + if ($menus[$key]['type'] == 'left') { + $left="\$this->menu[\$r++]=array( + 'fk_menu'=>'".$menus[$key]['fk_menu']."', + 'type'=>'".$menus[$key]['type']."', + 'titre'=>'".$menus[$key]['titre']."', + 'mainmenu'=>'".$menus[$key]['mainmenu']."', + 'leftmenu'=>'".$menus[$key]['leftmenu']."', + 'url'=>'".$menus[$key]['url']."', + 'langs'=>'".$menus[$key]['langs']."', + 'position'=>1100+\$r, + 'enabled'=>'".$menus[$key]['enabled']."', + 'perms'=>'".$menus[$key]['perms']."', + 'target'=>'".$menus[$key]['target']."', + 'user'=>".$menus[$key]['user'].", + );"; + $check = dolReplaceInFile($moduledescriptorfile, array($left => '')); + + // check if still had menu created when initial object + // if not we delete the comments from file + $menuForObj = 0; + foreach ($menus as $menu) { + if ($menu['leftmenu'] == $menus[$key]['leftmenu']) { + $menuForObj++; + } + } + if ($menuForObj == 1) { + $extractObjName = explode("_", $menus[$key]['leftmenu']); + dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($extractObjName[1]).'*/'."\n" => '','/*END LEFTMENU '.strtoupper($extractObjName[1]).'*/' => '')); + } + } + + setEventMessages($langs->trans('MenuDeletedSuccessfuly'), null); + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module); + exit; +} /* From 01e0503b0f073fa39056f168b8fe6cf049e0cd3e Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Thu, 9 Feb 2023 11:52:41 +0100 Subject: [PATCH 111/137] FIX several email sent to the same recipient when adding message from ticket --- htdocs/ticket/class/ticket.class.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index d12df619bb0..122c5ae35ab 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2576,24 +2576,24 @@ class Ticket extends CommonObject $assigned_user = new User($this->db); $assigned_user->fetch($this->fk_user_assign); if (!empty($assigned_user->email)) { - $sendto[] = $assigned_user->getFullName($langs)." <".$assigned_user->email.">"; + $sendto[$assigned_user->email] = $assigned_user->getFullName($langs)." <".$assigned_user->email.">"; } else { $assigned_user_dont_have_email = $assigned_user->getFullName($langs); } } if (empty($sendto)) { if (!empty($conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL)) { - $sendto[] = $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL; + $sendto[$conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL] = $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL; } elseif (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) { - $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; } } // Add global email address recipient if (!empty($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) && - !empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto) + !empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto) ) { - $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; } if (!empty($sendto)) { @@ -2677,7 +2677,7 @@ class Ticket extends CommonObject if ($info_sendto['email'] != '') { if (!empty($info_sendto['email'])) { - $sendto[] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">"; + $sendto[$info_sendto['email']] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">"; } //Contact type @@ -2693,9 +2693,9 @@ class Ticket extends CommonObject $message .= '
'.$langs->trans('TicketNotificationEmailBodyInfosTrackUrlinternal').' : '.$object->track_id.'
'; // Add global email address recipient - if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) { + if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) { if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) { - $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; } } @@ -2755,7 +2755,7 @@ class Ticket extends CommonObject if ($info_sendto['email'] != '' && $info_sendto['email'] != $object->origin_email) { if (!empty($info_sendto['email'])) { - $sendto[] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">"; + $sendto[$info_sendto['email']] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">"; } $recipient = dolGetFirstLastname($info_sendto['firstname'], $info_sendto['lastname'], '-1').' ('.strtolower($info_sendto['libelle']).')'; @@ -2775,21 +2775,21 @@ class Ticket extends CommonObject $message .= '
'.$message_signature; if (!empty($object->origin_email)) { - $sendto[] = $object->origin_email; + $sendto[$object->origin_email] = $object->origin_email; } - if ($object->fk_soc > 0 && !in_array($object->origin_email, $sendto)) { + if ($object->fk_soc > 0 && !array_key_exists($object->origin_email, $sendto)) { $object->socid = $object->fk_soc; $object->fetch_thirdparty(); if (!empty($object->thirdparty->email)) { - $sendto[] = $object->thirdparty->email; + $sendto[$object->thirdparty->email] = $object->thirdparty->email; } } // altairis: Add global email address reciepient - if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) { + if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) { if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) { - $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO; } } From 45900052e8c8007f88820cc8537ad84520e828cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Feb 2023 13:54:39 +0100 Subject: [PATCH 112/137] Debug v17 --- htdocs/adherents/list.php | 2 +- htdocs/public/members/new.php | 18 +++++------------- htdocs/public/project/new.php | 1 - 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index c2b81860210..64cc4fa8dc4 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -37,7 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("members", "companies")); +$langs->loadLangs(array("members", "companies", "categories")); // Get parameters diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php index 7c3e5754b23..33bbe59f118 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -34,7 +34,7 @@ * MEMBER_MIN_AMOUNT Minimum amount * MEMBER_NEWFORM_PAYONLINE Suggest payment with paypal, paybox or stripe * MEMBER_NEWFORM_DOLIBARRTURNOVER Show field turnover (specific for dolibarr foundation) - * MEMBER_URL_REDIRECT_SUBSCRIPTION Url to redirect once subscribe submitted + * MEMBER_URL_REDIRECT_SUBSCRIPTION Url to redirect once registration form has been submitted (hidden option, by default we just show a message on same page or redirect to the payment page) * MEMBER_NEWFORM_FORCETYPE Force type of member * MEMBER_NEWFORM_FORCEMORPHY Force nature of member (mor/phy) * MEMBER_NEWFORM_FORCECOUNTRYCODE Force country @@ -73,11 +73,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Init vars +$backtopage = GETPOST('backtopage', 'alpha'); +$action = GETPOST('action', 'aZ09'); + $errmsg = ''; $num = 0; $error = 0; -$backtopage = GETPOST('backtopage', 'alpha'); -$action = GETPOST('action', 'aZ09'); // Load translation files $langs->loadLangs(array("main", "members", "companies", "install", "other")); @@ -448,15 +449,6 @@ if (empty($reshook) && $action == 'add') { $urlback .= '&entity='.((int) $entity); } } - } - - if (!empty($backtopage)) { - $urlback = $backtopage; - dol_syslog("member ".$adh->ref." was created, we redirect to ".$urlback); - } elseif (!empty($conf->global->MEMBER_URL_REDIRECT_SUBSCRIPTION)) { - $urlback = $conf->global->MEMBER_URL_REDIRECT_SUBSCRIPTION; - // TODO Make replacement of __AMOUNT__, etc... - dol_syslog("member ".$adh->ref." was created, we redirect to ".$urlback); } else { $error++; $errmsg .= join('
', $adh->errors); @@ -476,7 +468,7 @@ if (empty($reshook) && $action == 'add') { } // Action called after a submitted was send and member created successfully -// If MEMBER_URL_REDIRECT_SUBSCRIPTION is set to url we never go here because a redirect was done to this url. +// If MEMBER_URL_REDIRECT_SUBSCRIPTION is set to an url, we never go here because a redirect was done to this url. Same if we ask to redirect to the payment page. // backtopage parameter with an url was set on member submit page, we never go here because a redirect was done to this url. if (empty($reshook) && $action == 'added') { diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index 778fc860e90..108f8d13771 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -416,7 +416,6 @@ if (empty($reshook) && $action == 'add') { } // Action called after a submitted was send and member created successfully -// If MEMBER_URL_REDIRECT_SUBSCRIPTION is set to url we never go here because a redirect was done to this url. // backtopage parameter with an url was set on member submit page, we never go here because a redirect was done to this url. if (empty($reshook) && $action == 'added') { llxHeaderVierge($langs->trans("NewLeadForm")); From dfda68a63c495ff54e6610418a33e58ddab53a3b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Feb 2023 14:30:48 +0100 Subject: [PATCH 113/137] Debug v17 - Online membership subscription of members --- htdocs/adherents/admin/website.php | 10 +++---- htdocs/langs/en_US/members.lang | 3 +- .../public/eventorganization/attendee_new.php | 2 +- htdocs/public/members/new.php | 11 ++++---- htdocs/public/partnership/new.php | 2 +- htdocs/public/payment/newpayment.php | 28 +++++++++---------- htdocs/public/payment/paymentok.php | 2 +- htdocs/public/project/new.php | 2 +- htdocs/public/project/suggestbooth.php | 2 +- htdocs/public/project/suggestconference.php | 2 +- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index 08e9f617750..705d7cf426f 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -58,7 +58,7 @@ if ($action == 'setMEMBER_ENABLE_PUBLIC') { if ($action == 'update') { $public = GETPOST('MEMBER_ENABLE_PUBLIC'); $amount = price2num(GETPOST('MEMBER_NEWFORM_AMOUNT'), 'MT', 2); - $editamount = GETPOST('MEMBER_NEWFORM_EDITAMOUNT'); + $minamount = GETPOST('MEMBER_MIN_AMOUNT'); $publiccounters = GETPOST('MEMBER_COUNTERS_ARE_PUBLIC'); $payonline = GETPOST('MEMBER_NEWFORM_PAYONLINE'); $forcetype = GETPOST('MEMBER_NEWFORM_FORCETYPE', 'int'); @@ -66,7 +66,7 @@ if ($action == 'update') { $res = dolibarr_set_const($db, "MEMBER_ENABLE_PUBLIC", $public, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "MEMBER_NEWFORM_AMOUNT", $amount, 'chaine', 0, '', $conf->entity); - $res = dolibarr_set_const($db, "MEMBER_NEWFORM_EDITAMOUNT", $editamount, 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "MEMBER_MIN_AMOUNT", $minamount, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "MEMBER_COUNTERS_ARE_PUBLIC", $publiccounters, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "MEMBER_NEWFORM_PAYONLINE", $payonline, 'chaine', 0, '', $conf->entity); if ($forcetype < 0) { @@ -232,11 +232,11 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) { print ''; print "
'; - print $langs->trans("CanEditAmountDetail"); + print $langs->trans("MinimumAmount"); print ''; - print $form->selectyesno("MEMBER_NEWFORM_EDITAMOUNT", (!empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) ? $conf->global->MEMBER_NEWFORM_EDITAMOUNT : 0), 1); + print ''; print "
'.dol_escape_htmltag($objp->label).''; $displayedamount = max(intval($objp->amount), intval(getDolGlobalInt("MEMBER_MIN_AMOUNT"))); - $caneditamount = !empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) || $objp->caneditamount; + $caneditamount = $objp->caneditamount; if ($objp->subscription) { if ($displayedamount > 0 || !$caneditamount) { print $displayedamount.' '.strtoupper($conf->currency); diff --git a/htdocs/public/partnership/new.php b/htdocs/public/partnership/new.php index b6444753eb7..d8e65f18c12 100644 --- a/htdocs/public/partnership/new.php +++ b/htdocs/public/partnership/new.php @@ -544,7 +544,7 @@ print load_fiche_titre($langs->trans("NewPartnershipRequest"), '', '', 0, 0, 'ce print '
'; print '
'; -print '
'; +print '
'; if (!empty($conf->global->PARTNERSHIP_NEWFORM_TEXT)) { print $langs->trans($conf->global->PARTNERSHIP_NEWFORM_TEXT)."
\n"; } else { diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 264ead82877..e3257bd659c 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -1633,7 +1633,7 @@ if ($source == 'member' || $source == 'membersubscription') { $amount = max(0, $conf->global->MEMBER_MIN_AMOUNT, $amount); } print ''.price($amount, 1, $langs, 1, -1, -1, $currency).''; // Price with currency - $caneditamount = !empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) || $adht->caneditamount; + $caneditamount = $adht->caneditamount; $minimumamount = empty($conf->global->MEMBER_MIN_AMOUNT)? $adht->amount : max($conf->global->MEMBER_MIN_AMOUNT, $adht->amount > $amount); if (!$caneditamount && $minimumamount > $amount) { print ' '. $langs->trans("AmountIsLowerToMinimumNotice", price($adht->amount, 1, $langs, 1, -1, -1, $currency)); @@ -1751,13 +1751,13 @@ if ($source == 'donation') { // Amount print '
'.$langs->trans("Amount"); if (empty($amount)) { - if (empty($conf->global->MEMBER_NEWFORM_AMOUNT)) { + if (empty($conf->global->DONATION_NEWFORM_AMOUNT)) { print ' ('.$langs->trans("ToComplete"); } - if (!empty($conf->global->MEMBER_EXT_URL_SUBSCRIPTION_INFO)) { - print ' - '.$langs->trans("SeeHere").''; + if (!empty($conf->global->DONATION_EXT_URL_SUBSCRIPTION_INFO)) { + print ' - '.$langs->trans("SeeHere").''; } - if (empty($conf->global->MEMBER_NEWFORM_AMOUNT)) { + if (empty($conf->global->DONATION_NEWFORM_AMOUNT)) { print ')'; } } @@ -1767,21 +1767,21 @@ if ($source == 'donation') { $valtoshow = price2num(GETPOST("newamount", 'alpha'), 'MT'); // force default subscription amount to value defined into constant... if (empty($valtoshow)) { - if (!empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT)) { - if (!empty($conf->global->MEMBER_NEWFORM_AMOUNT)) { - $valtoshow = $conf->global->MEMBER_NEWFORM_AMOUNT; + if (!empty($conf->global->DONATION_NEWFORM_EDITAMOUNT)) { + if (!empty($conf->global->DONATION_NEWFORM_AMOUNT)) { + $valtoshow = $conf->global->DONATION_NEWFORM_AMOUNT; } } else { - if (!empty($conf->global->MEMBER_NEWFORM_AMOUNT)) { - $amount = $conf->global->MEMBER_NEWFORM_AMOUNT; + if (!empty($conf->global->DONATION_NEWFORM_AMOUNT)) { + $amount = $conf->global->DONATION_NEWFORM_AMOUNT; } } } } if (empty($amount) || !is_numeric($amount)) { //$valtoshow=price2num(GETPOST("newamount",'alpha'),'MT'); - if (!empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) { - $valtoshow = max($conf->global->MEMBER_MIN_AMOUNT, $valtoshow); + if (!empty($conf->global->DONATION_MIN_AMOUNT) && $valtoshow) { + $valtoshow = max($conf->global->DONATION_MIN_AMOUNT, $valtoshow); } print ''; print ''; @@ -1789,8 +1789,8 @@ if ($source == 'donation') { print ' '.$langs->trans("Currency".$currency).''; } else { $valtoshow = $amount; - if (!empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) { - $valtoshow = max($conf->global->MEMBER_MIN_AMOUNT, $valtoshow); + if (!empty($conf->global->DONATION_MIN_AMOUNT) && $valtoshow) { + $valtoshow = max($conf->global->DONATION_MIN_AMOUNT, $valtoshow); $amount = $valtoshow; } print ''.price($valtoshow, 1, $langs, 1, -1, -1, $currency).''; // Price with currency diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index a82364bcce3..e596fd3d261 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -441,7 +441,7 @@ if ($ispaymentok) { // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) { // Security protection: - if (empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT)) { // If we didn't allow members to choose their membership amount (if free amount is allowed, no need to check) + if (empty($adht->caneditamount)) { // If we didn't allow members to choose their membership amount (if the amount is allowed in edit mode, no need to check) if ($object->status == $object::STATUS_DRAFT) { // If the member is not yet validated, we check that the amount is the same as expected. $typeid = $object->typeid; diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index 108f8d13771..c07062e3284 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -450,7 +450,7 @@ print load_fiche_titre($langs->trans("NewContact"), '', '', 0, 0, 'center'); print '
'; print '
'; -print '
'; +print '
'; if (!empty($conf->global->PROJECT_NEWFORM_TEXT)) { print $langs->trans($conf->global->PROJECT_NEWFORM_TEXT)."
\n"; } else { diff --git a/htdocs/public/project/suggestbooth.php b/htdocs/public/project/suggestbooth.php index 68e469b6a00..0b2e24716d5 100644 --- a/htdocs/public/project/suggestbooth.php +++ b/htdocs/public/project/suggestbooth.php @@ -564,7 +564,7 @@ print load_fiche_titre($langs->trans("NewSuggestionOfBooth"), '', '', 0, 0, 'cen print '
'; print '
'; -print '
'; +print '
'; dol_htmloutput_errors($errmsg); diff --git a/htdocs/public/project/suggestconference.php b/htdocs/public/project/suggestconference.php index 5590b0bf94c..b3418ec9e84 100644 --- a/htdocs/public/project/suggestconference.php +++ b/htdocs/public/project/suggestconference.php @@ -497,7 +497,7 @@ print load_fiche_titre($langs->trans("NewSuggestionOfConference"), '', '', 0, 0, print '
'; print '
'; -print '
'; +print '
'; dol_htmloutput_errors($errmsg, $errors); From 4985d8b350e3c01f861c4a8d30997e37fe55e3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 9 Feb 2023 14:34:13 +0100 Subject: [PATCH 114/137] missing translation --- htdocs/langs/en_US/agenda.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 2016172c381..adc9c4177ad 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -177,5 +177,6 @@ ReminderType=Callback type AddReminder=Create an automatic reminder notification for this event ErrorReminderActionCommCreation=Error creating the reminder notification for this event BrowserPush=Browser Popup Notification +Reminders=Reminders ActiveByDefault=Enabled by default Until=until From 3417b633f70255917b075dc12d2c1731497d2d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 9 Feb 2023 15:28:05 +0100 Subject: [PATCH 115/137] fix syntax --- htdocs/modulebuilder/template/admin/setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index dea2a1a596e..b9b5f262f8d 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -160,7 +160,7 @@ $item->helpText = $langs->transnoentities('AnHelpMessage'); //$item->fieldOutputOverride = false; // set this var to override field output -$setupnotempty =+ count($formSetup->items); +$setupnotempty += count($formSetup->items); $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); From 0e301988a4ed2089bdc3042e77a8b3383708df88 Mon Sep 17 00:00:00 2001 From: "Esteban L. Castro" <43482256+elcf@users.noreply.github.com> Date: Mon, 6 Feb 2023 18:29:50 -0400 Subject: [PATCH 116/137] Added key name to unique constraint --- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index d5deec862d0..fd4368b78af 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -688,7 +688,7 @@ ALTER TABLE llx_actioncomm MODIFY COLUMN note mediumtext; DELETE FROM llx_boxes WHERE box_id IN (select rowid FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year')); DELETE FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year'); -ALTER TABLE llx_takepos_floor_tables ADD UNIQUE(entity,label); +ALTER TABLE llx_takepos_floor_tables ADD UNIQUE uk_takepos_floor_tables (entity,label); ALTER TABLE llx_partnership ADD COLUMN url_to_check varchar(255); ALTER TABLE llx_c_partnership_type ADD COLUMN keyword varchar(128); From b65e3e401449c2706de1b5c2945b0838eba73d69 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Feb 2023 15:38:35 +0100 Subject: [PATCH 117/137] Fix all indexes must be named --- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 2 +- htdocs/install/mysql/tables/llx_takepos_floor_tables.key.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index fd4368b78af..ceff2a32f3c 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -688,7 +688,7 @@ ALTER TABLE llx_actioncomm MODIFY COLUMN note mediumtext; DELETE FROM llx_boxes WHERE box_id IN (select rowid FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year')); DELETE FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year'); -ALTER TABLE llx_takepos_floor_tables ADD UNIQUE uk_takepos_floor_tables (entity,label); +ALTER TABLE llx_takepos_floor_tables ADD UNIQUE INDEX uk_takepos_floor_tables (entity,label); ALTER TABLE llx_partnership ADD COLUMN url_to_check varchar(255); ALTER TABLE llx_c_partnership_type ADD COLUMN keyword varchar(128); diff --git a/htdocs/install/mysql/tables/llx_takepos_floor_tables.key.sql b/htdocs/install/mysql/tables/llx_takepos_floor_tables.key.sql index e90cd67e889..d2f699df325 100644 --- a/htdocs/install/mysql/tables/llx_takepos_floor_tables.key.sql +++ b/htdocs/install/mysql/tables/llx_takepos_floor_tables.key.sql @@ -13,4 +13,4 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see https://www.gnu.org/licenses/. -ALTER TABLE llx_takepos_floor_tables ADD UNIQUE(entity,label); \ No newline at end of file +ALTER TABLE llx_takepos_floor_tables ADD UNIQUE INDEX uk_takepos_floor_tables(entity,label); From 5ae079b0181dfbddf860f48f91161dd64230a61e Mon Sep 17 00:00:00 2001 From: Jean-Patrice Clerc <81645374+jpclerc-beep@users.noreply.github.com> Date: Mon, 6 Feb 2023 21:04:40 +0100 Subject: [PATCH 118/137] Ajout de la ligne pour enregistrer l'email du formulaire --- htdocs/public/project/new.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index c07062e3284..d4d6b4b68b5 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -224,6 +224,7 @@ if (empty($reshook) && $action == 'add') { } else { $thirdparty->name = dolGetFirstLastname(GETPOST('firstname'), GETPOST('lastname')); } + $thirdparty->email = GETPOST('email'); $thirdparty->address = GETPOST('address'); $thirdparty->zip = GETPOST('zip'); $thirdparty->town = GETPOST('town'); From 04c0272d05c03cb21e288db76c27f4ba2329efab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Feb 2023 15:58:28 +0100 Subject: [PATCH 119/137] Doc --- htdocs/includes/odtphp/odf.php | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 1a951292f94..0bba0e59345 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -24,10 +24,10 @@ class OdfException extends Exception class Odf { protected $config = array( - 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}', - 'PATH_TO_TMP' => '/tmp' + 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}', + 'PATH_TO_TMP' => '/tmp' ); protected $file; protected $contentXml; // To store content of content.xml file @@ -152,12 +152,12 @@ class Odf } /** - * Replaces html tags in odt tags and returns a compatible string + * Replaces html tags found into the $value with ODT compatible tags and return the converted compatible string * - * @param string $value Replacement value - * @param bool $encode If true, special XML characters are encoded - * @param string $charset Charset - * @return string + * @param string $value Replacement value + * @param bool $encode If true, special XML characters are encoded + * @param string $charset Charset + * @return string String in ODTsyntax format */ public function convertVarToOdf($value, $encode = true, $charset = 'ISO-8859') { @@ -203,15 +203,18 @@ class Odf } } $this->contentXml = str_replace('', $fonts . '', $this->contentXml); - } else $convertedValue = preg_replace('/(\r\n|\r|\n)/i', "", $value); + } else { + $convertedValue = preg_replace('/(\r\n|\r|\n)/i', "", $value); + } return $convertedValue; } /** * Replaces html tags in with odt tags and returns an odt string - * @param array $tags An array with html tags generated by the getDataFromHtml() function - * @param array $customStyles An array of style defenitions that should be included inside the odt file + * + * @param array $tags An array with html tags generated by the getDataFromHtml() function + * @param array $customStyles An array of style defenitions that should be included inside the odt file * @param array $fontDeclarations An array of font declarations that should be included inside the odt file * @return string */ From 6fb24bfcc78bcc125a31d0ea184fe98ae9e878aa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Feb 2023 18:00:25 +0100 Subject: [PATCH 120/137] Add missing index --- .../install/mysql/migration/17.0.0-18.0.0.sql | 11 +++++- .../tables/llx_supplier_proposal.key.sql | 34 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 htdocs/install/mysql/tables/llx_supplier_proposal.key.sql diff --git a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql index 11495748eff..328d6537ae0 100644 --- a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql +++ b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql @@ -70,4 +70,13 @@ ALTER TABLE llx_bank_account ADD COLUMN owner_zip varchar(25); ALTER TABLE llx_bank_account ADD COLUMN owner_town varchar(50); ALTER TABLE llx_bank_account ADD COLUMN owner_country_id integer DEFAULT NULL; - + +ALTER TABLE llx_supplier_proposal ADD UNIQUE INDEX uk_supplier_proposal_ref (ref, entity); + +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_soc (fk_soc); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_user_author (fk_user_author); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_user_valid (fk_user_valid); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_projet (fk_projet); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_account(fk_account); + + diff --git a/htdocs/install/mysql/tables/llx_supplier_proposal.key.sql b/htdocs/install/mysql/tables/llx_supplier_proposal.key.sql new file mode 100644 index 00000000000..350338f833d --- /dev/null +++ b/htdocs/install/mysql/tables/llx_supplier_proposal.key.sql @@ -0,0 +1,34 @@ +-- ============================================================================ +-- Copyright (C) 2023 Laurent Destailleur +-- +-- 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 +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ============================================================================ + + +ALTER TABLE llx_supplier_proposal ADD UNIQUE INDEX uk_supplier_proposal_ref (ref, entity); + +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_soc (fk_soc); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_user_author (fk_user_author); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_user_valid (fk_user_valid); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_projet (fk_projet); +ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_account(fk_account); + +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_user_signature FOREIGN KEY (fk_user_signature) REFERENCES llx_user (rowid); +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_user_cloture FOREIGN KEY (fk_user_cloture) REFERENCES llx_user (rowid); +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_projet FOREIGN KEY (fk_projet) REFERENCES llx_projet (rowid); +--ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_warehouse FOREIGN KEY (fk_warehouse) REFERENCES llx_entrepot(rowid); From 356b3af6e6c655da151c86e4890a4f668e05f932 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Feb 2023 19:44:55 +0100 Subject: [PATCH 121/137] css --- htdocs/emailcollector/class/emailcollector.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index ca5b22f3ce3..303749a16ea 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -130,7 +130,7 @@ class EmailCollector extends CommonObject 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'help'=>'Example: MyCollector1', 'csslist'=>'tdoverflowmax200'), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1, 'help'=>'Example: My Email collector', 'csslist'=>'tdoverflowmax150'), - 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1, 'csslist'=>'small'), + 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1, 'cssview'=>'small', 'csslist'=>'small tdoverflowmax200'), 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>90, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMAP server", 'help'=>'Example: imap.gmail.com', 'csslist'=>'tdoverflowmax125'), 'port' => array('type'=>'varchar(10)', 'label'=>'EMailHostPort', 'visible'=>1, 'enabled'=>1, 'position'=>91, 'notnull'=>1, 'searchall'=>0, 'comment'=>"IMAP server port", 'help'=>'Example: 993', 'csslist'=>'tdoverflowmax50', 'default'=>'993'), 'hostcharset' => array('type'=>'varchar(16)', 'label'=>'HostCharset', 'visible'=>-1, 'enabled'=>1, 'position'=>92, 'notnull'=>0, 'searchall'=>0, 'comment'=>"IMAP server charset", 'help'=>'Example: "UTF-8" (May be "US-ASCII" with some Office365)', 'default'=>'UTF-8'), @@ -143,7 +143,7 @@ class EmailCollector extends CommonObject 'maxemailpercollect' => array('type'=>'integer', 'label'=>'MaxEmailCollectPerCollect', 'visible'=>-1, 'enabled'=>1, 'position'=>111, 'default'=>100), 'datelastresult' => array('type'=>'datetime', 'label'=>'DateLastCollectResult', 'visible'=>1, 'enabled'=>'$action != "create" && $action != "edit"', 'position'=>121, 'notnull'=>-1, 'csslist'=>'nowraponall'), 'codelastresult' => array('type'=>'varchar(16)', 'label'=>'CodeLastResult', 'visible'=>1, 'enabled'=>'$action != "create" && $action != "edit"', 'position'=>122, 'notnull'=>-1,), - 'lastresult' => array('type'=>'varchar(255)', 'label'=>'LastResult', 'visible'=>1, 'enabled'=>'$action != "create" && $action != "edit"', 'position'=>123, 'notnull'=>-1, 'csslist'=>'small tdoverflowmax200'), + 'lastresult' => array('type'=>'varchar(255)', 'label'=>'LastResult', 'visible'=>1, 'enabled'=>'$action != "create" && $action != "edit"', 'position'=>123, 'notnull'=>-1, 'cssview'=>'small', 'csslist'=>'small tdoverflowmax200'), 'datelastok' => array('type'=>'datetime', 'label'=>'DateLastcollectResultOk', 'visible'=>1, 'enabled'=>'$action != "create"', 'position'=>125, 'notnull'=>-1, 'csslist'=>'nowraponall'), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'visible'=>0, 'enabled'=>1, 'position'=>61, 'notnull'=>-1,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'visible'=>0, 'enabled'=>1, 'position'=>62, 'notnull'=>-1,), From 97f0f33a4f43773c632c730aadc199c91da6595f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 9 Feb 2023 23:33:39 +0100 Subject: [PATCH 122/137] fix ajax tooltip sometimes stay open --- htdocs/core/js/lib_foot.js.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index b319185909a..963e357199a 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -89,6 +89,7 @@ if (empty($conf->dol_no_mouse_hover)) { $.ajax({ url:"' . dol_buildpath('/core/ajax/ajaxtooltip.php', 1) . '", type: "post", + async: false, data: JSON.parse(params), success: function(response){ // Setting content option From afa344393c19fbc16cd4987604c1502f50a9c282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 9 Feb 2023 23:55:42 +0100 Subject: [PATCH 123/137] add extrafields count in admin eventorganization --- htdocs/core/lib/eventorganization.lib.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/eventorganization.lib.php b/htdocs/core/lib/eventorganization.lib.php index 51ff1f2a90f..09ebc88a0b3 100644 --- a/htdocs/core/lib/eventorganization.lib.php +++ b/htdocs/core/lib/eventorganization.lib.php @@ -1,5 +1,6 @@ + * Copyright (C) 2023 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,7 +29,11 @@ */ function eventorganizationAdminPrepareHead() { - global $langs, $conf; + global $langs, $conf, $db; + + $extrafields = new ExtraFields($db); + $extrafields->fetch_name_optionals_label('actioncomm'); + $extrafields->fetch_name_optionals_label('eventorganization_conferenceorboothattendee'); $langs->load("eventorganization"); @@ -43,11 +48,19 @@ function eventorganizationAdminPrepareHead() $head[$h][0] = DOL_URL_ROOT.'/admin/eventorganization_confbooth_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFields")." (".$langs->trans("EventOrganizationConfOrBooth").")"; + $nbExtrafields = $extrafields->attributes['actioncomm']['count']; + if ($nbExtrafields > 0) { + $head[$h][1] .= ''.$nbExtrafields.''; + } $head[$h][2] = 'eventorganization_extrafields'; $h++; $head[$h][0] = DOL_URL_ROOT.'/admin/eventorganization_confboothattendee_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFields")." (".$langs->trans("Attendees").")"; + $nbExtrafields = $extrafields->attributes['eventorganization_conferenceorboothattendee']['count']; + if ($nbExtrafields > 0) { + $head[$h][1] .= ''.$nbExtrafields.''; + } $head[$h][2] = 'conferenceorboothattendee_extrafields'; $h++; From 731ddf33d87daf2644318ee62ffe63f0273bc8a5 Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Fri, 10 Feb 2023 11:52:37 +0100 Subject: [PATCH 124/137] Update ChangeLog ChangeLog for 16.0.4: #numbers sorted two lines were double --- ChangeLog | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index db82396ca76..0fe697ccb6c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -251,23 +251,24 @@ Following changes may create regressions for some external modules, but were nec FIX: Amount of localtax1 and 2 not correctly save on purchase order (the rate was saved instead) FIX: #20415 FIX: #21280 -FIX: #23008 FIX: #22271 FIX: #22524 FIX: #22837 FIX: #22964 +FIX: #23008 FIX: #23012 FIX: #23019 Impossible to add task times to an existing draft invoice FIX: #23072 +FIX: #23075 FIX: #23087 FIX: #23115 FIX: #23116 +FIX: #23117 FIX: #23281 FIX: #23420 : wrong check on $search_categ value causing FATAL ERROR FIX: Accountancy - Quadra export FIX: add border left on image product when conf activated FIX: Add missing token when deleting template inn order_supplier admin menu -FIX: Amount of localtax1 and 2 not correctly save on purchase order (the FIX: API access for deactivated users FIX: bad selection of barcode numbering module FIX: Can't see all time spent by all user @@ -278,8 +279,6 @@ FIX: Empty FormSetup emailTemplate type IF empty fieldvalue FIX: Errors Handling for CreateFrom Hooks FIX: error with dol_banner_tab, ref is needed FIX: ExpenseReport card was not reloaded after addline -FIX: #23075 -FIX: #23117 FIX: get multicurrency infos of propal when create order from propal with "WORKFLOW_PROPAL_AUTOCREATE_ORDER" conf FIX: Give predictable order to inventory lines FIX: include class multicurrency @@ -287,7 +286,6 @@ FIX: methods declaration (backport fix 67b9a7dc07d708231d12b5e58800334d4a01ef98) FIX: multicurrency_tx and not currency_tx FIX: on public ticket list, only the page 1 was accessible. Other pages were 404 error. FIX: PGSQL Integer type does not have a free lenght -FIX: PGSQL Int type does not have a free lenght FIX: Product list in setup.php in new Module FIX: propal and order stats broken on Tag+User(retricted customer list) FIX: saving of numbering module for jobs From 844ee2f9e517ba045c581abb0ca7f50c73f04776 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 10 Feb 2023 18:02:25 +0100 Subject: [PATCH 125/137] New functionality and fix som coherence in initial object & deleteObject --- htdocs/langs/en_US/errors.lang | 4 + htdocs/langs/fr_FR/errors.lang | 5 +- htdocs/modulebuilder/index.php | 436 +++++++++++++++++++++++++++------ 3 files changed, 374 insertions(+), 71 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 54a4b4fb470..5d262f54200 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -305,6 +305,10 @@ ErrorDateOfMovementLowerThanDateOfFileTransmission=The date of the bank transact ErrorTooMuchFileInForm=Too much files in form, the maximum number is %s file(s) ErrorSessionInvalidatedAfterPasswordChange=The session was been invalidated following a change of password, status or dates of validity. Please relogin. ErrorExistingPermission = Permission %s for object %s already exists +ErrorFieldExist=The value for %s already exist +ErrorEqualModule=Module invalid in %s +ErrorFieldValue=Value for %s is incorrect +ErrorCoherenceMenu=%s is required when % equal LEFT # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index cbf69ff2aa8..eddeadde288 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -305,7 +305,10 @@ ErrorDateOfMovementLowerThanDateOfFileTransmission=La date de l'opération banca ErrorTooMuchFileInForm=Trop de fichiers dans le formulaire, le nombre maximum est de %s fichier(s) ErrorExistingPermission = La permission %s pour l'objet %s est dejà existante ErrorSessionInvalidatedAfterPasswordChange=La session a été invalidée suite à un changement de mot de passe, d'état ou de dates de validité. Veuillez vous reconnecter. - +ErrorFieldExist=La valeur pour %s existe déja +ErrorEqualModule=Module invalide pour le champ %s +ErrorFieldValue=La valeur du champ %s est incorrecte +ErrorCoherenceMenu = Le champ %s est requis si le champ %s = LEFT # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Votre paramètre PHP upload_max_filesize (%s) est supérieur au paramètre PHP post_max_size (%s). Ceci n'est pas une configuration cohérente. diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index e52985e8c50..e4fe622dd1c 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1356,7 +1356,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { 'type'=>'left', 'titre'=>'List MyObject', 'mainmenu'=>'mymodule', - 'leftmenu'=>'mymodule_myobject', + 'leftmenu'=>'myobject', 'url'=>'/mymodule/myobject_list.php', 'langs'=>'mymodule@mymodule', 'position'=>1100+\$r, @@ -1366,11 +1366,11 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { 'user'=>2, ); \$this->menu[\$r++]=array( - 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=mymodule_myobject', + 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject', 'type'=>'left', 'titre'=>'New MyObject', 'mainmenu'=>'mymodule', - 'leftmenu'=>'mymodule_myobject', + 'leftmenu'=>'myobject', 'url'=>'/mymodule/myobject_card.php?action=create', 'langs'=>'mymodule@mymodule', 'position'=>1100+\$r, @@ -1403,7 +1403,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { $menus = $moduleobj->menu; $counter = 0 ; foreach ($menus as $menu) { - if ($menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) { + if ($menu['leftmenu'] == strtolower($objectname)) { $counter++; } } @@ -1812,7 +1812,7 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) { $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; foreach ($menus as $menu) { - if ($menu['type'] == 'left' && $menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) { + if ($menu['type'] == 'left' && $menu['leftmenu'] == strtolower($objectname)) { $left="\$this->menu[\$r++]=array( 'fk_menu'=>'".$menu['fk_menu']."', 'type'=>'".$menu['type']."', @@ -2436,8 +2436,7 @@ if ($dirins && $action == 'confirm_deletemenu' && GETPOST('menukey', 'int')) { } } if ($menuForObj == 1) { - $extractObjName = explode("_", $menus[$key]['leftmenu']); - dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($extractObjName[1]).'*/'."\n" => '','/*END LEFTMENU '.strtoupper($extractObjName[1]).'*/' => '')); + dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($menus[$key]['leftmenu']).'*/'."\n" => '','/*END LEFTMENU '.strtoupper($menus[$key]['leftmenu']).'*/' => '')); } } @@ -2446,6 +2445,194 @@ if ($dirins && $action == 'confirm_deletemenu' && GETPOST('menukey', 'int')) { exit; } +// Add menu in module without initial object +if ($dirins && $action == 'addmenu' && empty($cancel)) { + // check if module is enabled + if (isModEnabled(strtolower($module))) { + $result = unActivateModule(strtolower($module)); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + if ($result) { + setEventMessages($result, null, 'errors'); + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module); + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); + } + $error = 0; + $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $destdir = $dirins.'/'.strtolower($module); + $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); + $objects = array(); + foreach ($listofobject as $fileobj) { + if (preg_match('/^api_/', $fileobj['name'])) { + continue; + } + if (preg_match('/^actions_/', $fileobj['name'])) { + continue; + } + + $tmpcontent = file_get_contents($fileobj['fullname']); + $reg = array(); + if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { + $objectnameloop = $reg[1]; + $objects[] = $objectnameloop; + } + } + + // load class and check if right exist + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; + if (class_exists($class)) { + try { + $moduleobj = new $class($db); + } catch (Exception $e) { + $error++; + dol_print_error($db, $e->getMessage()); + } + } + $menus = $moduleobj->menu; + //verify fields required + if (!GETPOST('type', 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors'); + } + if (!GETPOST('titre', 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Title")), null, 'errors'); + } + if (!GETPOST('user', 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DetailUser")), null, 'errors'); + } + if (!GETPOST('url', 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Url")), null, 'errors'); + } + if (GETPOST('mainmenu') != strtolower($module)) { + $error++; + setEventMessages($langs->trans("ErrorEqualModule", $langs->transnoentities("mainmenu")), null, 'errors'); + } + if (!empty(GETPOST('target'))) { + $targets = array('_blank','_self','_parent','_top',''); + if (!in_array(GETPOST('target'), $targets)) { + $error++; + setEventMessages($langs->trans("ErrorFieldValue", $langs->transnoentities("target")), null, 'errors'); + } + } + if (!empty(GETPOST('perms'))) { + $permssion = array('read','write'); + if (GETPOST('perms') == 1 || GETPOST('perms') == '') { + $perms = 1 ; + } else { + if (!in_array(GETPOST('perms'), $permssion)) { + $error++; + setEventMessages($langs->trans("ErrorFieldValue", $langs->transnoentities("permssion")), null, 'errors'); + } + } + } + + // check if title or url already exist in menus + + foreach ($menus as $menu) { + if (!empty(GETPOST('url')) && GETPOST('url') == $menu['url']) { + $error++; + setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("url")), null, 'errors'); + break; + } + if (strtolower(GETPOST('titre')) == strtolower($menu['titre'])) { + $error++; + setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("titre")), null, 'errors'); + break; + } + } + + + if (GETPOST('type', 'alpha') == 'left' && !empty(GETPOST('lefmenu', 'alpha'))) { + if (!str_contains(GETPOST('leftmenu'), strtolower($module))) { + $error++; + setEventMessages($langs->trans("WarningFieldsMustContains", $langs->transnoentities("leftmenu")), null, 'errors'); + } + } + + if (GETPOST('type', 'alpha') == 'left') { + if (empty(GETPOST('leftmenu') && count($objects) > 0)) { + $error++; + setEventMessages($langs->trans("ErrorCoherenceMenu", $langs->transnoentities("leftmenu"), $langs->transnoentities("type")), null, 'errors'); + } + } + + if (!$error) { + $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + + $type = GETPOST('type', 'alpha'); + $fk_menu = GETPOST('fk_type', 'alpha'); + $titre = GETPOST('titre', 'alpha'); + $mainmenu = GETPOST('mainmenu', 'alpha'); + $leftmenu = GETPOST('leftmenu', 'alpha'); + $url = GETPOST('url'); + $user = GETPOST('user', 'int'); + (empty(GETPOST('perms')) && GETPOST('type') == 'top') || GETPOST('perms')==1 ? $perms=1 : $perms = 1; + $target = GETPOST('target', 'alpha'); + + + + if ($type == 'top') { + $menuTop = " + \$this->menu[\$r++] = array( + 'fk_menu'=>'".$fk_menu."', + 'type'=>'".strtolower($type)."', + 'titre'=>'".ucfirst($titre)."', + 'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'), + 'mainmenu'=>'".$mainmenu."', + 'leftmenu'=> '".$leftmenu."', + 'url'=>'".$url."', + 'langs'=>'".strtolower($module)."@".strtolower($module)."', + 'position'=>1000 + \$r, + 'enabled'=>'isModEnabled(\"".strtolower($module)."\")', + 'perms' =>'".$perms."', + 'target'=>'".$target."', + 'user'=>".$user.", + );"; + $addTopMenu = dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER TOPMENU */' => '/*TOPMENU '.strtolower($titre).'*/'.$menuTop."\n\t\t".'/*END TOPMENU '.strtolower($titre).'*/'."\n\t\t/* END MODULEBUILDER TOPMENU */")); + } + if ($type == 'left') { + $fk_menu = "fk_mainmenu=".strtolower($module).",fk_leftmenu=".strtolower($leftmenu); + $menuLeft= " + \$this->menu[\$r++]=array( + 'fk_menu'=>'".$fk_menu."', + 'type'=>'".$type."', + 'titre'=>'".ucfirst($titre)."', + 'mainmenu'=>'".strtolower($module)."', + 'leftmenu'=>'".strtolower($leftmenu)."', + 'url'=>'".$url."', + 'langs'=>'".strtolower($module)."@".strtolower($module)."', + 'position'=>1100+\$r, + 'enabled'=>'\$conf->".strtolower($module)."->enabled', + 'perms'=>'".$perms."', + 'target'=>'".$target."', + 'user'=>".$user.", + );"; + + $exist = 0; + foreach ($menus as $menu) { + if (strtolower($menu['leftmenu']) == strtolower($leftmenu)) { + $exist++; + } + } + //var_dump($exist);exit; + if ($exist) { + dolReplaceInFile($moduledescriptorfile, array('/*END LEFTMENU '.strtoupper($leftmenu).'*/' => $menuLeft."\n\t\t".'/*END LEFTMENU '.strtoupper($leftmenu).'*/')); + } else { + $addLeftMenu = dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER LEFTMENU MYOBJECT */' => '/*LEFTMENU '.strtoupper($leftmenu).'*/'."\n".$menuLeft."\n\t\t".'/*END LEFTMENU '.strtoupper($leftmenu).'*/'."\n\t\t".'/* END MODULEBUILDER LEFTMENU MYOBJECT */')); + } + } + + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module); + setEventMessages($langs->trans('MenuAddedSuccesfuly'), null); + exit; + } +} + /* * View @@ -4126,7 +4313,25 @@ if ($module == 'initmodule') { if ($tab == 'menus') { print ''."\n"; $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $destdir = $dirins.'/'.strtolower($module); + $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); + $objects = array(); + foreach ($listofobject as $fileobj) { + if (preg_match('/^api_/', $fileobj['name'])) { + continue; + } + if (preg_match('/^actions_/', $fileobj['name'])) { + continue; + } + $tmpcontent = file_get_contents($fileobj['fullname']); + $reg = array(); + if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { + $objectnameloop = $reg[1]; + $objects[] = $objectnameloop; + } + } $menus = $moduleobj->menu; if ($action != 'editfile' || empty($file)) { @@ -4155,10 +4360,10 @@ if ($module == 'initmodule') { print ''; print ''; - print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'thsticky '); + print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("LinkToParentMenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center'); print_liste_field_titre("mainmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("leftmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("URL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->transnoentitiesnoconv('DetailUrl')); @@ -4167,76 +4372,167 @@ if ($module == 'initmodule') { print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailEnabled')); print_liste_field_titre("Rights", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailRight')); print_liste_field_titre("Target", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailTarget')); - print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ', $langs->trans('DetailUser')); + print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailUser')); + print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ', $langs->trans('')); + print "\n"; + $r = count($menus)+1; + // for adding menu on module + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + print ''; if (count($menus)) { $i = 0; foreach ($menus as $menu) { $i++; - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; } else { - print $menu['user']; // should not happen - } - print ''; + print ''; + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + print ''; + } print ''; } } else { From c692d8e6bab7be9c9056882e4f88519ec6345eb2 Mon Sep 17 00:00:00 2001 From: Lamrani Abdel Date: Fri, 10 Feb 2023 18:16:18 +0100 Subject: [PATCH 126/137] New functionnality update menu on modulebuilder --- htdocs/modulebuilder/index.php | 98 ++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index e4fe622dd1c..299bae1d6ce 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2633,6 +2633,104 @@ if ($dirins && $action == 'addmenu' && empty($cancel)) { } } +// modify a menu +if ($dirins && $action == "modify_menu" && GETPOST('menukey', 'int') && empty(GETPOST('cancel'))) { + $error = 0; + $counter = 0; + // for loading class and the menu wants to modify + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; + if (class_exists($class)) { + try { + $moduleobj = new $class($db); + } catch (Exception $e) { + $error++; + dol_print_error($db, $e->getMessage()); + } + } + $menus = $moduleobj->menu; + $key = (int) GETPOST('menukey', 'int'); + $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + //get menus info + $menuTomodify = " + \$this->menu[\$r++] = array( + 'fk_menu' =>'".$menus[$key]['fk_menu']."', + 'type' =>'".$menus[$key]['type']."', + 'titre' =>'".$menus[$key]['titre']."', + 'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'), + 'mainmenu'=>'".$menus[$key]['mainmenu']."', + 'leftmenu' =>'".$menus[$key]['leftmenu']."', + 'url' =>'".$menus[$key]['url']."', + 'langs'=>'".$menus[$key]['langs']."', + 'position'=>1000 + \$r, + 'enabled'=>'isModEnabled(\"".strtolower($module)."\")', + 'perms' =>'".$menus[$key]['perms']."', + 'target'=>'".$menus[$key]['target']."', + 'user'=>".$menus[$key]['user'].", + );"; + + $fk_menu = GETPOST('fk_type', 'alpha'); + $type = GETPOST('type', 'alpha'); + $titre = GETPOST('titre', 'alpha'); + $mainmenu = GETPOST('mainmenu', 'alpha'); + $leftmenu = GETPOST('leftmenu', 'alpha'); + $url = GETPOST('url', 'alpha'); + $perms = GETPOST('perms', 'alpha'); + $target = GETPOST('target', 'alpha'); + $user = GETPOST('user', 'alpha'); + + if (!$error) { + if ($type == 'top') { + $modifiedMenu = " + \$this->menu[\$r++] = array( + 'fk_menu' =>'".$fk_menu."', + 'type' =>'".$type."', + 'titre' =>'".$titre."', + 'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'), + 'mainmenu'=>'".$menus[$key]['mainmenu']."', + 'leftmenu' =>'".$menus[$key]['leftmenu']."', + 'url' =>'".$url."', + 'langs'=>'".$menus[$key]['langs']."', + 'position'=>1000 + \$r, + 'enabled'=>'".$menus[$key]['enabled']."', + 'perms' =>'".$perms."', + 'target'=>'".$target."', + 'user'=>".$user.", + );"; + + + dolReplaceInFile($moduledescriptorfile, array($menuTomodify => '')); + if (strtolower($titre) != strtolower($menus[$key]['titre'])) { + dolReplaceInFile($moduledescriptorfile, array('/*TOPMENU '.strtolower($menus[$key]['titre']).'*/' => '/*TOPMENU '.strtolower($titre).'*/', '/*END TOPMENU '.strtolower($menus[$key]['titre']).'*/' => '/*END TOPMENU '.strtolower($titre).'*/')); + } + setEventMessages($langs->trans('MenuUpdatedSuccessfuly'), null); + } + + if ($type == 'left') { + $modifiedMenu = " + \$this->menu[\$r++] = array( + 'fk_menu' =>'".$fk_menu."', + 'type' =>'".$type."', + 'titre' =>'".$titre."', + 'mainmenu'=>'".$menus[$key]['mainmenu']."', + 'leftmenu' =>'".$menus[$key]['leftmenu']."', + 'url' =>'".$url."', + 'langs'=>'".$menus[$key]['langs']."', + 'position'=>1000 + \$r, + 'enabled'=>'isModEnabled(\"".strtolower($module)."\")', + 'perms' =>'".$perms."', + 'target'=>'".$target."', + 'user'=>'".$user."', + );"; + + dolReplaceInFile($moduledescriptorfile, array($menuTomodify => $modifiedMenu)); + setEventMessages($langs->trans('MenuUpdatedSuccessfuly'), null); + } + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module); + //exit; +} /* * View From 0115a631074bc2cb57494d1d51ecdffa241b54ec Mon Sep 17 00:00:00 2001 From: Benjamin Sonntag Date: Fri, 10 Feb 2023 19:49:51 +0100 Subject: [PATCH 127/137] Update llx_accounting_account_fr.sql If you import this by hand, a key violation occurs. the 3352 account is named 3552, which collides which the 3552 below. I propose to fix that easily ;) --- htdocs/install/mysql/data/llx_accounting_account_fr.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/data/llx_accounting_account_fr.sql b/htdocs/install/mysql/data/llx_accounting_account_fr.sql index 4520969f82b..4c24d63e5b1 100644 --- a/htdocs/install/mysql/data/llx_accounting_account_fr.sql +++ b/htdocs/install/mysql/data/llx_accounting_account_fr.sql @@ -824,7 +824,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5317,'PCG14-DEV','STOCK','3312',5315,'Produits en cours P 2','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5318,'PCG14-DEV','STOCK','335',5314,'Travaux en cours','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5319,'PCG14-DEV','STOCK','3351',5318,'Travaux en cours T 1','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5320,'PCG14-DEV','STOCK','3552',5318,'Travaux en cours T 2','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5320,'PCG14-DEV','STOCK','3352',5318,'Travaux en cours T 2','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5321,'PCG14-DEV','STOCK','34',5969,'En-cours de production de services','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5322,'PCG14-DEV','STOCK','341',5321,'Etudes en cours','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5323,'PCG14-DEV','STOCK','3411',5322,'Etudes en cours E 1','1'); From 7e277aa6ef7d7ec0e4aa4cd03a40f2c4ba6e52e5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Feb 2023 21:05:03 +0100 Subject: [PATCH 128/137] sql synta --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 98836dff8cc..67ceaf69446 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1392,8 +1392,8 @@ abstract class CommonObject } $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; $sql .= ", tc.source, tc.element, tc.code, tc.libelle"; - $sql .= " FROM ".$this->db->prefix()."c_type_contact tc"; - $sql .= ", ".$this->db->prefix()."element_contact ec"; + $sql .= " FROM ".$this->db->prefix()."c_type_contact tc,"; + $sql .= " ".$this->db->prefix()."element_contact ec"; if ($source == 'internal') { // internal contact (user) $sql .= " LEFT JOIN ".$this->db->prefix()."user t on ec.fk_socpeople = t.rowid"; } From 17ae12abfdf91ac4e5e5ea78f9cc072fb2953d93 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Feb 2023 21:09:20 +0100 Subject: [PATCH 129/137] Fix warning --- htdocs/compta/facture/class/facture.class.php | 4 ++-- htdocs/expedition/card.php | 2 +- htdocs/product/stock/class/mouvementstock.class.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 8505af85ce5..dcf43bcf0cb 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3245,7 +3245,7 @@ class Facture extends CommonInvoice $sortorder = 'ASC,ASC,ASC,ASC'; } - $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (!empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) ? null : 0), $sortfield, $sortorder); + $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER') ? null : 0), $sortfield, $sortorder); if (!is_array($resBatchList)) { $error++; $this->error = $this->db->lasterror(); @@ -3288,7 +3288,7 @@ class Facture extends CommonInvoice } if (!$error && $product_qty_remain > 0) { - if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) { + if (getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER')) { // take in the first batch $batch = $batchList[0]; $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index a9fcea34440..97e846f3054 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1268,7 +1268,7 @@ if ($action == 'create') { print ''; $stockMin = false; - if (empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) { + if (!getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER')) { $stockMin = 0; } print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1, 0, array(), 'minwidth200', '', 1, $stockMin, 'stock DESC, e.ref'); diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 2392962a500..6c491bfc6e0 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -391,7 +391,7 @@ class MouvementStock extends CommonObject // Check if stock is enough when qty is < 0 // Note that qty should be > 0 with type 0 or 3, < 0 with type 1 or 2. - if ($movestock && $qty < 0 && empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) { + if ($movestock && $qty < 0 && !getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER')) { if (isModEnabled('productbatch') && $product->hasbatch() && !$skip_batch) { $foundforbatch = 0; $qtyisnotenough = 0; From 2484df288cce572f82b8f19fc7294bb4f2efaa34 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Feb 2023 23:11:47 +0100 Subject: [PATCH 130/137] css --- htdocs/core/modules/mailings/contacts1.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 9dd6eea0e31..4063b1ef140 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -138,7 +138,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ORDER BY sp.poste"; $resql = $this->db->query($sql); - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); @@ -174,7 +174,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ORDER BY c.label"; $resql = $this->db->query($sql); - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); @@ -196,7 +196,7 @@ class mailing_contacts1 extends MailingTargets $s .= '
'; // Add prospect of a particular level - $s .= ''; $sql = "SELECT code, label"; $sql .= " FROM ".MAIN_DB_PREFIX."c_prospectlevel"; $sql .= " WHERE active > 0"; From 7b546b4140e840ea7202a2bb4ba0bd09f6dd3b3a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 00:22:24 +0100 Subject: [PATCH 131/137] Preapre type "datetimegmt" --- htdocs/core/class/commonobject.class.php | 20 +++++++++++-- htdocs/core/class/extrafields.class.php | 38 ++++++++++++++++++------ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 67ceaf69446..ab4228769e1 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2037,7 +2037,7 @@ abstract class CommonObject * @param mixed $value New value * @param string $table To force other table element or element line (should not be used) * @param int $id To force other object id (should not be used) - * @param string $format Data format ('text', 'date'). 'text' is used if not defined + * @param string $format Data format ('text', 'int', 'date'). 'text' is used if not defined * @param string $id_field To force rowid field name. 'rowid' is used if not defined * @param User|string $fuser Update the user of last update field with this user. If not provided, current user is used except if value is 'none' * @param string $trigkey Trigger key to run (in most cases something like 'XXX_MODIFY') @@ -2082,6 +2082,8 @@ abstract class CommonObject $sql .= $field." = ".((int) $value); } elseif ($format == 'date') { $sql .= $field." = ".($value ? "'".$this->db->idate($value)."'" : "null"); + } elseif ($format == 'dategmt') { + $sql .= $field." = ".($value ? "'".$this->db->idate($value, 'gmt')."'" : "null"); } if ($fk_user_field) { @@ -5340,7 +5342,7 @@ abstract class CommonObject $sql .= ", busy"; $sql .= ", mandatory"; $sql .= ") VALUES ("; - $sql .= $resource_id; + $sql .= ((int) $resource_id); $sql .= ", '".$this->db->escape($resource_type)."'"; $sql .= ", '".$this->db->escape($this->id)."'"; $sql .= ", '".$this->db->escape($this->element)."'"; @@ -6325,6 +6327,13 @@ abstract class CommonObject } $new_array_options[$key] = $this->db->idate($this->array_options[$key]); break; + case 'datetimegmt': + // If data is a string instead of a timestamp, we convert it + if (!is_numeric($this->array_options[$key]) || $this->array_options[$key] != intval($this->array_options[$key])) { + $this->array_options[$key] = strtotime($this->array_options[$key]); + } + $new_array_options[$key] = $this->db->idate($this->array_options[$key], 'gmt'); + break; case 'link': $param_list = array_keys($attributeParam['options']); // 0 : ObjectName @@ -6665,6 +6674,13 @@ abstract class CommonObject $this->array_options["options_".$key] = $this->db->idate($this->array_options["options_".$key]); } break; + case 'datetimegmt': + if (empty($this->array_options["options_".$key])) { + $this->array_options["options_".$key] = null; + } else { + $this->array_options["options_".$key] = $this->db->idate($this->array_options["options_".$key], 'gmt'); + } + break; case 'boolean': if (empty($this->array_options["options_".$key])) { $this->array_options["options_".$key] = null; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 8f8a3e54552..71d5dfdb06d 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -79,6 +79,7 @@ class ExtraFields 'double'=>'Float', 'date'=>'Date', 'datetime'=>'DateAndTime', + //'datetimegmt'=>'DateAndTimeUTC', 'boolean'=>'Boolean', 'price'=>'ExtrafieldPrice', 'pricecy'=>'ExtrafieldPriceWithCurrency', @@ -979,7 +980,7 @@ class ExtraFields // Add automatic css if ($type == 'date') { $morecss = 'minwidth100imp'; - } elseif ($type == 'datetime' || $type == 'link') { + } elseif ($type == 'datetime' || $type == 'datetimegmt' || $type == 'link') { $morecss = 'minwidth200imp'; } elseif (in_array($type, array('int', 'integer', 'double', 'price'))) { $morecss = 'maxwidth75'; @@ -1031,7 +1032,7 @@ class ExtraFields // TODO Must also support $moreparam $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1); } - } elseif (in_array($type, array('datetime'))) { + } elseif (in_array($type, array('datetime', 'datetimegmt'))) { $tmp = explode(',', $size); $newsize = $tmp[0]; $showtime = 1; @@ -1614,6 +1615,11 @@ class ExtraFields if ($value !== '') { $value = dol_print_date($value, 'dayhour', 'tzuserrel'); } + } elseif ($type == 'datetimegmt') { + $showsize = 19; + if ($value !== '') { + $value = dol_print_date($value, 'dayhour', 'gmt'); + } } elseif ($type == 'int') { $showsize = 10; } elseif ($type == 'double') { @@ -1928,7 +1934,7 @@ class ExtraFields $cssstring = ''; - if (in_array($type, array('date', 'datetime'))) { + if (in_array($type, array('date', 'datetime', 'datetimegmt'))) { $cssstring = "center"; } elseif (in_array($type, array('int', 'price', 'double'))) { $cssstring = "right"; @@ -2137,6 +2143,9 @@ class ExtraFields } elseif (in_array($key_type, array('datetime'))) { // Clean parameters $value_key = dol_mktime(GETPOST("options_".$key."hour", 'int'), GETPOST("options_".$key."min", 'int'), GETPOST("options_".$key."sec", 'int'), GETPOST("options_".$key."month", 'int'), GETPOST("options_".$key."day", 'int'), GETPOST("options_".$key."year", 'int'), 'tzuserrel'); + } elseif (in_array($key_type, array('datetimegmt'))) { + // Clean parameters + $value_key = dol_mktime(GETPOST("options_".$key."hour", 'int'), GETPOST("options_".$key."min", 'int'), GETPOST("options_".$key."sec", 'int'), GETPOST("options_".$key."month", 'int'), GETPOST("options_".$key."day", 'int'), GETPOST("options_".$key."year", 'int'), 'gmt'); } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) { $value_arr = GETPOST("options_".$key, 'array'); // check if an array if (!empty($value_arr)) { @@ -2228,7 +2237,7 @@ class ExtraFields } else { continue; // Value was not provided, we should not set it. } - } elseif (in_array($key_type, array('datetime'))) { + } elseif (in_array($key_type, array('datetime', 'datetimegmt'))) { $dateparamname_start = $keysuffix . 'options_' . $key . $keyprefix . '_start'; $dateparamname_end = $keysuffix . 'options_' . $key . $keyprefix . '_end'; if (GETPOSTISSET($dateparamname_start . 'year') && GETPOSTISSET($dateparamname_end . 'year')) { @@ -2236,13 +2245,24 @@ class ExtraFields $dateparamname_end_hour = GETPOST($dateparamname_end . 'hour', 'int') !='-1' ? GETPOST($dateparamname_end . 'hour', 'int') : '23'; $dateparamname_end_min = GETPOST($dateparamname_end . 'min', 'int') !='-1' ? GETPOST($dateparamname_end . 'min', 'int') : '59'; $dateparamname_end_sec = GETPOST($dateparamname_end . 'sec', 'int') !='-1' ? GETPOST($dateparamname_end . 'sec', 'int') : '59'; - $value_key = array( - 'start' => dol_mktime(GETPOST($dateparamname_start . 'hour', 'int'), GETPOST($dateparamname_start . 'min', 'int'), GETPOST($dateparamname_start . 'sec', 'int'), GETPOST($dateparamname_start . 'month', 'int'), GETPOST($dateparamname_start . 'day', 'int'), GETPOST($dateparamname_start . 'year', 'int'), 'tzuserrel'), - 'end' => dol_mktime($dateparamname_end_hour, $dateparamname_end_min, $dateparamname_end_sec, GETPOST($dateparamname_end . 'month', 'int'), GETPOST($dateparamname_end . 'day', 'int'), GETPOST($dateparamname_end . 'year', 'int'), 'tzuserrel') - ); + if ($key_type == 'datetimegmt') { + $value_key = array( + 'start' => dol_mktime(GETPOST($dateparamname_start . 'hour', 'int'), GETPOST($dateparamname_start . 'min', 'int'), GETPOST($dateparamname_start . 'sec', 'int'), GETPOST($dateparamname_start . 'month', 'int'), GETPOST($dateparamname_start . 'day', 'int'), GETPOST($dateparamname_start . 'year', 'int'), 'gmt'), + 'end' => dol_mktime($dateparamname_end_hour, $dateparamname_end_min, $dateparamname_end_sec, GETPOST($dateparamname_end . 'month', 'int'), GETPOST($dateparamname_end . 'day', 'int'), GETPOST($dateparamname_end . 'year', 'int'), 'gmt') + ); + } else { + $value_key = array( + 'start' => dol_mktime(GETPOST($dateparamname_start . 'hour', 'int'), GETPOST($dateparamname_start . 'min', 'int'), GETPOST($dateparamname_start . 'sec', 'int'), GETPOST($dateparamname_start . 'month', 'int'), GETPOST($dateparamname_start . 'day', 'int'), GETPOST($dateparamname_start . 'year', 'int'), 'tzuserrel'), + 'end' => dol_mktime($dateparamname_end_hour, $dateparamname_end_min, $dateparamname_end_sec, GETPOST($dateparamname_end . 'month', 'int'), GETPOST($dateparamname_end . 'day', 'int'), GETPOST($dateparamname_end . 'year', 'int'), 'tzuserrel') + ); + } } elseif (GETPOSTISSET($keysuffix."options_".$key.$keyprefix."year")) { // Clean parameters - $value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."sec", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int'), 'tzuserrel'); + if ($key_type == 'datetimegmt') { + $value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."sec", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int'), 'gmt'); + } else { + $value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."sec", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int'), 'tzuserrel'); + } } else { continue; // Value was not provided, we should not set it. } From 6f978383cd319f190306375c5d167d6f102dae25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 13:29:21 +0100 Subject: [PATCH 132/137] Doc --- dev/setup/apache/virtualhost | 55 +++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/dev/setup/apache/virtualhost b/dev/setup/apache/virtualhost index e8c5f2a8f4b..7eff1859d4f 100644 --- a/dev/setup/apache/virtualhost +++ b/dev/setup/apache/virtualhost @@ -12,6 +12,7 @@ + # The URLs of the web site ServerName myvirtualalias ServerAlias myvirtualalias @@ -23,8 +24,13 @@ AddDefaultCharset UTF-8 - DocumentRoot "/home/.../htdocs" + # Detect if we are using DoliDroid + #SetEnvIf User-Agent DoliDroid dolidroid + + + # The directory and permissions for the web site + DocumentRoot "/home/.../htdocs" AllowOverride None Options -Indexes -MultiViews +FollowSymLinks -ExecCGI @@ -40,39 +46,43 @@ # Leaving /public and /api, /dav, .well_known but also wrappers for document, viewimage and public json/img accessible to everyone AuthType None - Require all granted Satisfy any + Require all granted AuthType None - Require all granted Satisfy any + Require all granted AuthType None - Require all granted Satisfy any + Require all granted AuthType None - Require all granted Satisfy any + Require all granted AuthType None - Require all granted Satisfy any + Require all granted - + + # Log directoves ErrorLog /var/log/apache2/myvirtualalias_error_log TransferLog /var/log/apache2/myvirtualalias_access_log - # Compress returned resources of type php pages, text file export, css and javascript + + # Compress is done on resources of type php pages, text file export, css and javascript AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript - AddType text/javascript .jgz AddEncoding gzip .jgz + + + # Add cach performance directives ExpiresActive On ExpiresByType image/x-icon A2592000 ExpiresByType image/gif A2592000 @@ -83,19 +93,20 @@ ExpiresByType application/x-javascript A2592000 ExpiresByType application/javascript A2592000 - SSLEngine On - # A self-signed (snakeoil) certificate can be created by installing - # the ssl-cert package. See - # /usr/share/doc/apache2.2-common/README.Debian.gz for more info. - # If both key and certificate are stored in the same file, only the - # SSLCertificateFile directive is needed. - #SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem - #SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem - #SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem + # To enable the SSL if the certificate file exists + + SSLEngine On + + # If both key and certificate are stored in the same file, only the + # SSLCertificateFile directive is needed. + SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem + SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem + + #RewriteEngine on + #RewriteCond %{SERVER_PORT} ^80$ + #RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] + - #RewriteEngine on - #RewriteCond %{SERVER_PORT} ^80$ - #RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] - From 695ca086847b3b6a185afa93e897972c93c43d15 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 13:50:40 +0100 Subject: [PATCH 133/137] Fix #hunter7a048bb7-bfdd-4299-931e-9bc283e92bc8 --- htdocs/main.inc.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 69a9dc0808e..1ea68780746 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -173,16 +173,20 @@ function testSqlAndScriptInject($val, $type) $inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $val); $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $val); $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)\s*=/i', $val); + // More not into the previous list + $inj += preg_match('/on(repeat|begin|finish|beforeinput)\s*=/i', $val); // We refuse html into html because some hacks try to obfuscate evil strings by inserting HTML into HTML. Example: error=alert(1) to bypass test on onerror $tmpval = preg_replace('/<[^<]+>/', '', $val); // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers - $inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $val); // onmousexxx can be set on img or any html tag like + $inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like $inj += preg_match('/on(abort|afterprint|animation|auxclick|beforecopy|beforecut|beforeprint|beforeunload|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)\s*=/i', $tmpval); $inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)\s*=/i', $tmpval); $inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $tmpval); $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $tmpval); $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)\s*=/i', $tmpval); + // More not into the previous list + $inj += preg_match('/on(repeat|begin|finish|beforeinput)\s*=/i', $tmpval); //$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ... $inj += preg_match('/:|:|:/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...' From 968720bfdc2ce64cefb06f719442515f58944b68 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 14:09:00 +0100 Subject: [PATCH 134/137] Code comment --- htdocs/core/lib/website2.lib.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index c7099e8d2ed..fb4cfa1b520 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -673,10 +673,12 @@ function showWebsiteTemplates(Website $website) /** - * checkPHPCode + * Check a new string containing only php code (including " + * @param string $phpfullcodestring PHP new string. For exemple "" * @return int Error or not */ function checkPHPCode($phpfullcodestringold, $phpfullcodestring) From 81ef87cf6d8baacb094dd794fbecba146874f962 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 15:39:16 +0100 Subject: [PATCH 135/137] FIX #huntr5affff95-9a37-4004-bab2-a834b3b61ff7 --- htdocs/core/lib/website2.lib.php | 8 +++++++- test/phpunit/Website.class.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index fb4cfa1b520..768f735fe39 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -718,7 +718,12 @@ function checkPHPCode($phpfullcodestringold, $phpfullcodestring) break; } } - // Check dynamic functions $xxx( + // Deny dynamic functions '${a}(' or '$a[b](' - So we refuse '}(' and '](' + if (preg_match('/[}\]]\(/ims', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", ']('), null, 'errors'); + } + // Deny dynamic functions $xxx( if (preg_match('/\$[a-z0-9_]+\(/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors'); @@ -732,6 +737,7 @@ function checkPHPCode($phpfullcodestringold, $phpfullcodestring) if (!$error) { $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT); $allowimportsite = true; + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) { $allowimportsite = false; } diff --git a/test/phpunit/Website.class.php b/test/phpunit/Website.class.php index 50d0c16453d..364235bcc41 100644 --- a/test/phpunit/Website.class.php +++ b/test/phpunit/Website.class.php @@ -54,12 +54,17 @@ if (! defined("NOSESSION")) { require_once dirname(__FILE__).'/../../htdocs/main.inc.php'; require_once dirname(__FILE__).'/../../htdocs/core/lib/website.lib.php'; +require_once dirname(__FILE__).'/../../htdocs/core/lib/website2.lib.php'; if (empty($user->id)) { print "Load permissions for admin user nb 1\n"; $user->fetch(1); $user->getrights(); + + if (empty($user->rights->website)) { + $user->rights->website = new stdClass(); + } } $conf->global->MAIN_DISABLE_ALL_MAILS=1; @@ -175,4 +180,28 @@ class WebsiteTest extends PHPUnit\Framework\TestCase // We must found no line (so code should be KO). If we found somethiing, it means there is a SQL injection of the 1=1 $this->assertEquals($res['code'], 'KO'); } + + + /** + * testCheckPHPCode + * + * @return void + */ + public function testCheckPHPCode() + { + global $user; + + // Force permission so this is not the permission that will affect result of checkPHPCode + $user->rights->website->writephp = 1; + + $s = ''; + $result = checkPHPCode('', $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + $s = ';").($_^"/"); ?>'; + $result = checkPHPCode('', $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + } } From 954906ec4835e505806a51527a16e6648f618c0a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 16:02:51 +0100 Subject: [PATCH 136/137] Fix $dolibarr_main_restrict_os_commands applies also to antivir command --- htdocs/admin/security_file.php | 38 ++++++++++++++++++++++++---------- htdocs/admin/tools/export.php | 6 ++++-- htdocs/install/step1.php | 2 +- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index c545cc7e0dd..57100155ed3 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -32,10 +32,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page $langs->loadLangs(array('users', 'admin', 'other')); -if (!$user->admin) { - accessforbidden(); -} - $action = GETPOST('action', 'aZ09'); $sortfield = GETPOST('sortfield', 'aZ09'); $sortorder = GETPOST('sortorder', 'aZ09'); @@ -48,6 +44,12 @@ if (empty($sortorder)) { $upload_dir = $conf->admin->dir_temp; +if (!$user->admin) { + accessforbidden(); +} + +$error = 0; + /* * Actions @@ -65,12 +67,26 @@ if ($action == 'updateform') { $antivircommand = dol_string_nospecial($antivircommand, '', array("|", ";", "<", ">", "&")); // Sanitize command $antivirparam = dol_string_nospecial($antivirparam, '', array("|", ";", "<", ">", "&")); // Sanitize params - $res3 = dolibarr_set_const($db, 'MAIN_UPLOAD_DOC', GETPOST('MAIN_UPLOAD_DOC', 'alpha'), 'chaine', 0, '', $conf->entity); - $res4 = dolibarr_set_const($db, "MAIN_UMASK", GETPOST('MAIN_UMASK', 'alpha'), 'chaine', 0, '', $conf->entity); - $res5 = dolibarr_set_const($db, "MAIN_ANTIVIRUS_COMMAND", trim($antivircommand), 'chaine', 0, '', $conf->entity); - $res6 = dolibarr_set_const($db, "MAIN_ANTIVIRUS_PARAM", trim($antivirparam), 'chaine', 0, '', $conf->entity); - if ($res3 && $res4 && $res5 && $res6) { - setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); + if (!empty($dolibarr_main_restrict_os_commands)) { + $arrayofallowedcommand = explode(',', $dolibarr_main_restrict_os_commands); + $arrayofallowedcommand = array_map('trim', $arrayofallowedcommand); + dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that one of this command is inside ".$antivircommand); + $basenamecmddump = basename(str_replace('\\', '/', $antivircommand)); + if (!in_array($basenamecmddump, $arrayofallowedcommand)) { // the provided command $cmddump must be an allowed command + $errormsg = $langs->trans('CommandIsNotInsideAllowedCommands'); + setEventMessages($errormsg, null, 'errors'); + $error++; + } + } + + if (!$error) { + $res3 = dolibarr_set_const($db, 'MAIN_UPLOAD_DOC', GETPOST('MAIN_UPLOAD_DOC', 'alpha'), 'chaine', 0, '', $conf->entity); + $res4 = dolibarr_set_const($db, "MAIN_UMASK", GETPOST('MAIN_UMASK', 'alpha'), 'chaine', 0, '', $conf->entity); + $res5 = dolibarr_set_const($db, "MAIN_ANTIVIRUS_COMMAND", trim($antivircommand), 'chaine', 0, '', $conf->entity); + $res6 = dolibarr_set_const($db, "MAIN_ANTIVIRUS_PARAM", trim($antivirparam), 'chaine', 0, '', $conf->entity); + if ($res3 && $res4 && $res5 && $res6) { + setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); + } } } elseif ($action == 'deletefile') { // Delete file @@ -160,7 +176,7 @@ if (ini_get('safe_mode') && !empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) { dol_syslog("safe_mode is on, basedir is ".$basedir.", safe_mode_exec_dir is ".ini_get('safe_mode_exec_dir'), LOG_WARNING); } } -print ''; +print ''; if (defined('MAIN_ANTIVIRUS_COMMAND') && !defined('MAIN_ANTIVIRUS_BYPASS_COMMAND_AND_PARAM')) { print '
'.$langs->trans("ValueIsForcedBySystem").''; } diff --git a/htdocs/admin/tools/export.php b/htdocs/admin/tools/export.php index 7a91f8f598c..c9655afb26d 100644 --- a/htdocs/admin/tools/export.php +++ b/htdocs/admin/tools/export.php @@ -123,8 +123,9 @@ if ($what == 'mysql') { if (!empty($dolibarr_main_restrict_os_commands)) { $arrayofallowedcommand = explode(',', $dolibarr_main_restrict_os_commands); + $arrayofallowedcommand = array_map('trim', $arrayofallowedcommand); dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that one of this command is inside ".$cmddump); - $basenamecmddump = basename($cmddump); + $basenamecmddump = basename(str_replace('\\', '/', $cmddump)); if (!in_array($basenamecmddump, $arrayofallowedcommand)) { // the provided command $cmddump must be an allowed command $errormsg = $langs->trans('CommandIsNotInsideAllowedCommands'); } @@ -160,8 +161,9 @@ if ($what == 'postgresql') { if (!empty($dolibarr_main_restrict_os_commands)) { $arrayofallowedcommand=explode(',', $dolibarr_main_restrict_os_commands); + $arrayofallowedcommand = array_map('trim', $arrayofallowedcommand); dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that one of this command is inside ".$cmddump); - $basenamecmddump=basename($cmddump); + $basenamecmddump = basename(str_replace('\\', '/', $cmddump)); if (! in_array($basenamecmddump, $arrayofallowedcommand)) // the provided command $cmddump must be an allowed command { $errormsg=$langs->trans('CommandIsNotInsideAllowedCommands'); diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index 7958012b0a1..4df1370570a 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -908,7 +908,7 @@ function write_conf_file($conffile) fputs($fp, '$dolibarr_main_force_https=\''.$main_force_https.'\';'); fputs($fp, "\n"); - fputs($fp, '$dolibarr_main_restrict_os_commands=\'mysqldump, mysql, pg_dump, pgrestore\';'); + fputs($fp, '$dolibarr_main_restrict_os_commands=\'mysqldump, mysql, pg_dump, pgrestore, clamdscan, clamscan.exe\';'); fputs($fp, "\n"); fputs($fp, '$dolibarr_nocsrfcheck=\'0\';'); From ec45afb05f85913db056888b411fecb0454e4f0c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Feb 2023 16:07:39 +0100 Subject: [PATCH 137/137] Fix can clean var --- htdocs/admin/security_file.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index 57100155ed3..5538e0ad952 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -67,7 +67,7 @@ if ($action == 'updateform') { $antivircommand = dol_string_nospecial($antivircommand, '', array("|", ";", "<", ">", "&")); // Sanitize command $antivirparam = dol_string_nospecial($antivirparam, '', array("|", ";", "<", ">", "&")); // Sanitize params - if (!empty($dolibarr_main_restrict_os_commands)) { + if ($antivircommand && !empty($dolibarr_main_restrict_os_commands)) { $arrayofallowedcommand = explode(',', $dolibarr_main_restrict_os_commands); $arrayofallowedcommand = array_map('trim', $arrayofallowedcommand); dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that one of this command is inside ".$antivircommand);
'; + print ''; + print ''; + print ''; + print ''; + print '
'; - print $i; - print ''; - print dol_escape_htmltag($menu['type']); - print ''; - print dol_escape_htmltag($menu['fk_menu']); - print ''; - print dol_escape_htmltag($menu['titre']); - print ''; - print dol_escape_htmltag($menu['mainmenu']); - print ''; - print !empty($menu['leftmenu']) ? dol_escape_htmltag($menu['leftmenu']) : ''; - print ''; - print dol_escape_htmltag($menu['url']); - print ''; - print dol_escape_htmltag($menu['langs']); - print ''; - print dol_escape_htmltag($menu['position']); - print ''; - print dol_escape_htmltag($menu['enabled']); - print ''; - print dol_escape_htmltag($menu['perms']); - print ''; - print dol_escape_htmltag($menu['target']); - print ''; - if ($menu['user'] == 2) { - print $langs->trans("AllMenus"); - } elseif ($menu['user'] == 0) { - print $langs->trans('Internal'); - } elseif ($menu['user'] == 1) { - print $langs->trans('External'); + $propFk_menu = !empty($menu['fk_menu']) ? $menu['fk_menu'] : GETPOST('fk_menu'); + $propTitre = !empty($menu['titre']) ? $menu['titre'] : GETPOST('titre'); + $propLeftmenu = !empty($menu['leftmenu']) ? $menu['leftmenu'] : GETPOST('leftmenu'); + $propUrl = !empty($menu['url']) ? $menu['url'] : GETPOST('url', 'alpha'); + $propPerms = !empty($menu['perms']) ? $menu['perms'] : GETPOST('perms'); + $propUser = !empty($menu['user']) ? $menu['user'] : GETPOST('user'); + $propTarget = !empty($menu['target']) ? $menu['target'] : GETPOST('target'); + if ($action == 'editmenu' && GETPOST('menukey', 'int') == ($i-1)) { + print '
'; + print $i; + print ' + + '; + print ''; + print ''; + print '
'; + print ''; + print $i; + print ''; + print dol_escape_htmltag($menu['type']); + print ''; + print dol_escape_htmltag($menu['fk_menu']); + print ''; + print dol_escape_htmltag($menu['titre']); + print ''; + print dol_escape_htmltag($menu['mainmenu']); + print ''; + print dol_escape_htmltag($menu['leftmenu']); + print ''; + print dol_escape_htmltag($menu['url']); + print ''; + print dol_escape_htmltag($menu['langs']); + print ''; + print dol_escape_htmltag($menu['position']); + print ''; + print dol_escape_htmltag($menu['enabled']); + print ''; + print dol_escape_htmltag($menu['perms']); + print ''; + print dol_escape_htmltag($menu['target']); + print ''; + if ($menu['user'] == 2) { + print $langs->trans("AllMenus"); + } elseif ($menu['user'] == 0) { + print $langs->trans('Internal'); + } elseif ($menu['user'] == 1) { + print $langs->trans('External'); + } else { + print $menu['user']; // should not happen + } + print ''; + if ($menu['titre']!= 'Module'.$module.'Name') { + print ''.img_edit().''; + print ''.img_delete().''; + } + print '