diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index e01c3142cc0..6d461b525bc 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -54,10 +54,12 @@ if (!empty($conf->eventorganization->enabled)) { $langs->loadLangs($langsArray); +$toselect = GETPOST('toselect', 'array'); $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; $massaction = GETPOST('massaction', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation $mode = GETPOST('mode', 'aZ09'); +$optioncss = GETPOST('optioncss', 'alpha'); $id = GETPOST('id', 'int'); $rowid = GETPOST('rowid', 'alpha'); @@ -77,6 +79,7 @@ $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"') $listoffset = GETPOST('listoffset', 'alpha'); $listlimit = GETPOST('listlimit', 'alpha') > 0 ?GETPOST('listlimit', 'alpha') : 1000; +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index 038a07d5be3..772055f0809 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -1,6 +1,7 @@ * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2022 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 @@ -46,38 +47,47 @@ $action = GETPOST('action', 'aZ09'); $provider = GETPOST('provider', 'aZ09'); $label = GETPOST('label', 'aZ09'); +$error = 0; + /* * Actions */ -if ($action == 'update') { - $error = 0; - - if (GETPOST('add') && $provider && $provider != '-1') { // $provider is OAUTH_XXX +if ($action == 'add') { // $provider is OAUTH_XXX + if ($provider && $provider != '-1') { $constname = strtoupper($provider).($label ? '-'.$label : '').'_ID'; - dolibarr_set_const($db, $constname, 'ToComplete', 'chaine', 0, '', $conf->entity); - } else { - foreach ($conf->global as $key => $val) { - if (!empty($val) && preg_match('/^OAUTH_.+_ID$/', $key)) { - $constvalue = str_replace('_ID', '', $key); - if (!dolibarr_set_const($db, $constvalue.'_ID', GETPOST($constvalue.'_ID'), 'chaine', 0, '', $conf->entity)) { - $error++; - } - // If we reset this provider, we also remove the secret - if (!dolibarr_set_const($db, $constvalue.'_SECRET', GETPOST($constvalue.'_ID') ? GETPOST($constvalue.'_SECRET') : '', 'chaine', 0, '', $conf->entity)) { - $error++; - } - } - } - if (!$error) { - setEventMessages($langs->trans("SetupSaved"), null); + if (getDolGlobalString($constname)) { + setEventMessages($langs->trans("AOAuthEntryForThisProviderAndLabelAlreadyHasAKey"), null, 'errors'); + $error++; } else { - setEventMessages($langs->trans("Error"), null, 'errors'); + dolibarr_set_const($db, $constname, 'ToComplete', 'chaine', 0, '', $conf->entity); + setEventMessages($langs->trans("OAuthProviderAdded"), null); } } } +if ($action == 'update') { + foreach ($conf->global as $key => $val) { + if (!empty($val) && preg_match('/^OAUTH_.+_ID$/', $key)) { + $constvalue = str_replace('_ID', '', $key); + if (!dolibarr_set_const($db, $constvalue.'_ID', GETPOST($constvalue.'_ID'), 'chaine', 0, '', $conf->entity)) { + $error++; + } + // If we reset this provider, we also remove the secret + if (!dolibarr_set_const($db, $constvalue.'_SECRET', GETPOST($constvalue.'_ID') ? GETPOST($constvalue.'_SECRET') : '', 'chaine', 0, '', $conf->entity)) { + $error++; + } + } + } + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} + /* * View @@ -92,18 +102,18 @@ print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup'); print '
'; print ''; -print ''; +print ''; $head = oauthadmin_prepare_head(); -print dol_get_fiche_head($head, 'services', '', -1, 'technic'); +print dol_get_fiche_head($head, 'services', '', -1, ''); print ''.$langs->trans("ListOfSupportedOauthProviders").'

'; -print ''; +print ''; foreach ($list as $key) { $supported = 0; $keyforsupportedoauth2array = $key[0]; @@ -122,10 +132,16 @@ print ''; print ajax_combobox('provider'); print ' '; print ' '; +print '
'; + print '
'; print '
'; +print '
'; +print ''; +print ''; + print '
'; print ''; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index 93aac9cff15..b2830f95743 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -129,7 +129,7 @@ print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup'); $head = oauthadmin_prepare_head(); -print dol_get_fiche_head($head, 'tokengeneration', '', -1, 'technic'); +print dol_get_fiche_head($head, 'tokengeneration', '', -1, ''); if (GETPOST('error')) { setEventMessages(GETPOST('error'), null, 'errors'); diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index 4968e75989a..1e667e7abb4 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -554,7 +554,7 @@ if ($mode == 'searchkey') { break; } print ''; } else { print '"; } // Defaut print ''; // Bank Account diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 7baf2986c65..d87317e2420 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1908,14 +1908,14 @@ class BonPrelevement extends CommonObject $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; $XML_CREDITOR .= ' '.$CrLf; /* - $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.$Rum.''.$CrLf; - $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; - $XML_CREDITOR .= ' false'.$CrLf; - $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.$CrLf; - */ + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$Rum.''.$CrLf; + $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_CREDITOR .= ' false'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + */ //$XML_CREDITOR .= ' SLEV'.$CrLf; $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.$CrLf; @@ -2195,17 +2195,17 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' '.$CrLf;*/ $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV /*$XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ } } else { fputs($this->file, 'INCORRECT EMETTEUR '.$XML_SEPA_INFO.$CrLf); @@ -2343,59 +2343,59 @@ class BonPrelevement extends CommonObject } /* - if ($mode == 'direct_debit') { - $sql = "SELECT b.rowid, f.datedue as datefin"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql .= " WHERE f.entity IN (".getEntity('facture').")"; - $sql .= " AND f.total_ttc > 0"; - } else { - $sql = "SELECT b.rowid, f.datedue as datefin"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; - $sql .= " WHERE f.entity IN (".getEntity('facture_fourn').")"; - $sql .= " AND f.total_ttc > 0"; - } + if ($mode == 'direct_debit') { + $sql = "SELECT b.rowid, f.datedue as datefin"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql .= " WHERE f.entity IN (".getEntity('facture').")"; + $sql .= " AND f.total_ttc > 0"; + } else { + $sql = "SELECT b.rowid, f.datedue as datefin"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; + $sql .= " WHERE f.entity IN (".getEntity('facture_fourn').")"; + $sql .= " AND f.total_ttc > 0"; + } - $resql = $this->db->query($sql); - if ($resql) { - $langs->load("banks"); - $now = dol_now(); + $resql = $this->db->query($sql); + if ($resql) { + $langs->load("banks"); + $now = dol_now(); - $response = new WorkboardResponse(); - if ($mode == 'direct_debit') { - $response->warning_delay = $conf->prelevement->warning_delay / 60 / 60 / 24; - $response->label = $langs->trans("PendingDirectDebitToComplete"); - $response->labelShort = $langs->trans("PendingDirectDebitToCompleteShort"); - $response->url = DOL_URL_ROOT.'/compta/prelevement/index.php?leftmenu=checks&mainmenu=bank'; - } else { - $response->warning_delay = $conf->paymentbybanktransfer->warning_delay / 60 / 60 / 24; - $response->label = $langs->trans("PendingCreditTransferToComplete"); - $response->labelShort = $langs->trans("PendingCreditTransferToCompleteShort"); - $response->url = DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php?leftmenu=checks&mainmenu=bank'; - } - $response->img = img_object('', "payment"); + $response = new WorkboardResponse(); + if ($mode == 'direct_debit') { + $response->warning_delay = $conf->prelevement->warning_delay / 60 / 60 / 24; + $response->label = $langs->trans("PendingDirectDebitToComplete"); + $response->labelShort = $langs->trans("PendingDirectDebitToCompleteShort"); + $response->url = DOL_URL_ROOT.'/compta/prelevement/index.php?leftmenu=checks&mainmenu=bank'; + } else { + $response->warning_delay = $conf->paymentbybanktransfer->warning_delay / 60 / 60 / 24; + $response->label = $langs->trans("PendingCreditTransferToComplete"); + $response->labelShort = $langs->trans("PendingCreditTransferToCompleteShort"); + $response->url = DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php?leftmenu=checks&mainmenu=bank'; + } + $response->img = img_object('', "payment"); - while ($obj = $this->db->fetch_object($resql)) { - $response->nbtodo++; + while ($obj = $this->db->fetch_object($resql)) { + $response->nbtodo++; - if ($this->db->jdate($obj->datefin) < ($now - $conf->withdraw->warning_delay)) { - $response->nbtodolate++; - } - } + if ($this->db->jdate($obj->datefin) < ($now - $conf->withdraw->warning_delay)) { + $response->nbtodolate++; + } + } - $response->nbtodo = 0; - $response->nbtodolate = 0; - // Return workboard only if quantity is not 0 - if ($response->nbtodo) { - return $response; - } else { - return 0; - } - } else { - dol_print_error($this->db); - $this->error = $this->db->error(); - return -1; - } - */ + $response->nbtodo = 0; + $response->nbtodolate = 0; + // Return workboard only if quantity is not 0 + if ($response->nbtodo) { + return $response; + } else { + return 0; + } + } else { + dol_print_error($this->db); + $this->error = $this->db->error(); + return -1; + } + */ return 0; } } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 0f61ecada43..75689f509ea 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1285,9 +1285,8 @@ if ($action == 'create') { // Print form confirm print $formconfirm; - /* - * Contrat - */ + + // Contract if (!empty($object->brouillon) && $user->rights->contrat->creer) { print ''; print ''; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 2a5ddcf5a34..42442f47fd0 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7399,8 +7399,10 @@ abstract class CommonObject } // Format output value differently according to properties of field - if ($key == 'ref' && method_exists($this, 'getNomUrl')) { - $value = $this->getNomUrl(1, '', 0, '', 1); + if (in_array($key, array('rowid', 'ref')) && method_exists($this, 'getNomUrl')) { + if ($key != 'rowid' || empty($this->fields['ref'])) { // If we want ref field or if we want ID and there is no ref field, we show the link. + $value = $this->getNomUrl(1, '', 0, '', 1); + } } elseif ($key == 'status' && method_exists($this, 'getLibStatut')) { $value = $this->getLibStatut(3); } elseif ($type == 'date') { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 2a109fb0f5c..d30eb562feb 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1257,9 +1257,10 @@ class Form * @param array $ajaxoptions Options for ajax_autocompleter * @param bool $multiple add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter) * @param array $excludeids Exclude IDs from the select combo + * @param int $showcode Show code * @return string HTML string with select box for thirdparty. */ - public function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false, $excludeids = array()) + public function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false, $excludeids = array(), $showcode = 0) { // phpcs:enable global $conf, $user, $langs; @@ -1284,7 +1285,7 @@ class Form } // mode 1 - $urloption = 'htmlname='.urlencode(str_replace('.', '_', $htmlname)).'&outjson=1&filter='.urlencode($filter).(empty($excludeids) ? '' : '&excludeids='.join(',', $excludeids)).($showtype ? '&showtype='.urlencode($showtype) : ''); + $urloption = 'htmlname='.urlencode(str_replace('.', '_', $htmlname)).'&outjson=1&filter='.urlencode($filter).(empty($excludeids) ? '' : '&excludeids='.join(',', $excludeids)).($showtype ? '&showtype='.urlencode($showtype) : '').($showcode ? '&showcode='.urlencode($showcode) : ''); $out .= ''; if (empty($hidelabel)) { @@ -1303,7 +1304,7 @@ class Form $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); } else { // Immediate load of all database - $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple, $excludeids); + $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple, $excludeids, $showcode); } return $out; @@ -1328,9 +1329,10 @@ class Form * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param bool $multiple add [] in the name of element and add 'multiple' attribut * @param array $excludeids Exclude IDs from the select combo + * @param int $showcode Show code in list * @return string HTML string with */ - public function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false, $excludeids = array()) + public function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false, $excludeids = array(), $showcode = 0) { // phpcs:enable global $conf, $user, $langs; @@ -1442,13 +1444,15 @@ class Form $out .= ''."\n"; } + $companytemp = new Societe($this->db); + $num = $this->db->num_rows($resql); $i = 0; if ($num) { while ($i < $num) { $obj = $this->db->fetch_object($resql); $label = ''; - if ($conf->global->SOCIETE_ADD_REF_IN_LIST) { + if ($showcode || !empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) { if (($obj->client) && (!empty($obj->code_client))) { $label = $obj->code_client.' - '; } @@ -1468,7 +1472,17 @@ class Form $label .= ' - '.$obj->tva_intra.''; } + $labelhtml = $label; + if ($showtype) { + $companytemp->id = $obj->rowid; + $companytemp->client = $obj->client; + $companytemp->fournisseur = $obj->fournisseur; + $tmptype = $companytemp->getTypeUrl(1, '', 0, 'span'); + if ($tmptype) { + $labelhtml .= ' '.$tmptype; + } + if ($obj->client || $obj->fournisseur) { $label .= ' ('; } @@ -1487,20 +1501,22 @@ class Form } if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) { - $label .= ($obj->address ? ' - '.$obj->address : '').($obj->zip ? ' - '.$obj->zip : '').($obj->town ? ' '.$obj->town : ''); + $s = ($obj->address ? ' - '.$obj->address : '').($obj->zip ? ' - '.$obj->zip : '').($obj->town ? ' '.$obj->town : ''); if (!empty($obj->country_code)) { - $label .= ', '.$langs->trans('Country'.$obj->country_code); + $s .= ', '.$langs->trans('Country'.$obj->country_code); } + $label .= $s; + $labelhtml .= $s; } if (empty($outputmode)) { if (in_array($obj->rowid, $selected)) { - $out .= ''; + $out .= ''; } else { - $out .= ''; + $out .= ''; } } else { - array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label)); + array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label, 'labelhtml'=>$labelhtml)); } $i++; @@ -6286,24 +6302,24 @@ class Form * - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location) * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1) * - * @param integer $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). - * @param string $prefix Prefix for fields name - * @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty - * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty - * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only - * @param string $form_name Not used - * @param int $d 1=Show days, month, years - * @param int $addnowlink Add a link "Now", 1 with server time, 2 with local computer time - * @param int $disabled Disable input fields - * @param int $fullday When a checkbox with id #fullday is checked, hours are set with 00:00 (if value if 'fulldaystart') or 23:59 (if value is 'fulldayend') - * @param string $addplusone Add a link "+1 hour". Value must be name of another selectDate field. - * @param datetime $adddateof Add a link "Date of ..." using the following date. See also $labeladddateof for the label used. - * @param string $openinghours Specify hour start and hour end for the select ex 8,20 - * @param int $stepminutes Specify step for minutes between 1 and 30 - * @param string $labeladddateof Label to use for the $adddateof parameter. - * @param string $placeholder Placeholder - * @param mixed $gm 'auto' (for backward compatibility, avoid this), 'gmt' or 'tzserver' or 'tzuserrel' - * @return string Html for selectDate + * @param integer|string $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). + * @param string $prefix Prefix for fields name + * @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty + * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty + * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only + * @param string $form_name Not used + * @param int $d 1=Show days, month, years + * @param int $addnowlink Add a link "Now", 1 with server time, 2 with local computer time + * @param int $disabled Disable input fields + * @param int $fullday When a checkbox with id #fullday is checked, hours are set with 00:00 (if value if 'fulldaystart') or 23:59 (if value is 'fulldayend') + * @param string $addplusone Add a link "+1 hour". Value must be name of another selectDate field. + * @param datetime $adddateof Add a link "Date of ..." using the following date. See also $labeladddateof for the label used. + * @param string $openinghours Specify hour start and hour end for the select ex 8,20 + * @param int $stepminutes Specify step for minutes between 1 and 30 + * @param string $labeladddateof Label to use for the $adddateof parameter. + * @param string $placeholder Placeholder + * @param mixed $gm 'auto' (for backward compatibility, avoid this), 'gmt' or 'tzserver' or 'tzuserrel' + * @return string Html for selectDate * @see form_date(), select_month(), select_year(), select_dayofweek() */ public function selectDate($set_time = '', $prefix = 're', $h = 0, $m = 0, $empty = 0, $form_name = "", $d = 1, $addnowlink = 0, $disabled = 0, $fullday = '', $addplusone = '', $adddateof = '', $openinghours = '', $stepminutes = 1, $labeladddateof = '', $placeholder = '', $gm = 'auto') diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index dbaaacc2d18..1f5a48a517d 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -581,6 +581,15 @@ class SMTPs // The error here just means the ID/password combo doesn't work. $_retVal = $this->socket_send_str(base64_encode("\0".$this->_smtpsID."\0".$this->_smtpsPW), '235'); break; + case 'XOAUTH2': + // "user=$email\1auth=Bearer $token\1\1" + $token = 'xxx'; + $xxxx = "user=".$this->_smtpsID."\1auth=Bearer ".$token."\1\1"; + $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($xxxx), '235'); + if (!$_retVal) { + $this->_setErr(130, 'Error when asking for AUTH XOAUTH2'); + } + break; case 'LOGIN': // most common case default: $_retVal = $this->socket_send_str('AUTH LOGIN', '334'); @@ -590,7 +599,7 @@ class SMTPs // User name will not return any error, server will take anything we give it. $this->socket_send_str(base64_encode($this->_smtpsID), '334'); // The error here just means the ID/password combo doesn't work. - // There is not a method to determine which is the problem, ID or password + // There is no method to determine which is the problem, ID or password $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235'); } break; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 482831191d6..223095609d3 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2977,6 +2977,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping for import module $accessallowed = $user->rights->import->run; $original_file = $conf->import->dir_temp.'/'.$original_file; + } elseif ($modulepart == 'recruitment' && !empty($conf->recruitment->dir_temp)) { + // Wrapping for recruitment module + $accessallowed = $user->rights->$modulepart->recruitmentjobposition->read; + $original_file = $conf->recruitment->dir_output .'/'. $original_file; } elseif ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output)) { // Wrapping for wysiwyg editor $accessallowed = 1; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 80ed0b345ba..627a13a7844 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -1452,8 +1452,9 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it // Search if cron entry already present $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob"; - $sql .= " WHERE module_name = '".$this->db->escape(empty($this->rights_class) ?strtolower($this->name) : $this->rights_class)."'"; - if ($class) { + //$sql .= " WHERE module_name = '".$this->db->escape(empty($this->rights_class) ?strtolower($this->name) : $this->rights_class)."'"; + $sql .= " WHERE label = '".$this->db->escape($label)."'"; + /*if ($class) { $sql .= " AND classesname = '".$this->db->escape($class)."'"; } if ($objectname) { @@ -1467,7 +1468,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it } if ($parameters) { $sql .= " AND params = '".$this->db->escape($parameters)."'"; - } + }*/ $sql .= " AND entity = ".((int) $entity); // Must be exact entity $now = dol_now(); @@ -1516,7 +1517,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $sql .= "'".$this->db->escape($priority)."', "; } if (is_int($status)) { - $sql .= "'".$this->db->escape($status)."', "; + $sql .= ((int) $status).", "; } $sql .= $entity.","; $sql .= "'".$this->db->escape($test)."'"; diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 8c3e5bfeab9..32284a2cbd1 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -470,9 +470,9 @@ class ImportCsv extends ModeleImports $newval = $classinstance->id; } else { if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) { - $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); + $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', num2Alpha($key - 1), $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); } elseif (!empty($objimport->array_import_convertvalue[0][$val]['element'])) { - $this->errors[$error]['lib'] = $langs->trans('ErrorFieldRefNotIn', $key, $newval, $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['element'])); + $this->errors[$error]['lib'] = $langs->trans('ErrorFieldRefNotIn', num2Alpha($key - 1), $newval, $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['element'])); } else { $this->errors[$error]['lib'] = 'ErrorBadDefinitionOfImportProfile'; } @@ -512,7 +512,7 @@ class ImportCsv extends ModeleImports $newval = $classinstance->id; } else { if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) { - $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); + $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', num2Alpha($key - 1), $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); } else { $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; } @@ -549,7 +549,7 @@ class ImportCsv extends ModeleImports $newval = $scaleorid ? $scaleorid : 0; } else { if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) { - $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); + $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', num2Alpha($key - 1), $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); } else { $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; } @@ -697,7 +697,7 @@ class ImportCsv extends ModeleImports if (!empty($filter)) { $tableforerror .= ':'.$filter; } - $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorFieldValueNotIn', $key, $newval, $field, $tableforerror); + $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorFieldValueNotIn', num2Alpha($key - 1), $newval, $field, $tableforerror); $this->errors[$error]['type'] = 'FOREIGNKEY'; $errorforthistable++; $error++; @@ -705,13 +705,22 @@ class ImportCsv extends ModeleImports } elseif (!preg_match('/'.$objimport->array_import_regex[0][$val].'/i', $newval)) { // If test is just a static regex //if ($key == 19) print "xxx".$newval."zzz".$objimport->array_import_regex[0][$val]."
"; - $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorWrongValueForField', $key, $newval, $objimport->array_import_regex[0][$val]); + $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorWrongValueForField', num2Alpha($key - 1), $newval, $objimport->array_import_regex[0][$val]); $this->errors[$error]['type'] = 'REGEX'; $errorforthistable++; $error++; } } + // Check HTML injection + $inj = testSqlAndScriptInject($newval, 0); + if ($inj) { + $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorHtmlInjectionForField', num2Alpha($key - 1), dol_trunc($newval, 100)); + $this->errors[$error]['type'] = 'HTMLINJECTION'; + $errorforthistable++; + $error++; + } + // Other tests // ... } diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 4740f7d3390..d8a9d77a98e 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -756,6 +756,15 @@ class ImportXlsx extends ModeleImports } } + // Check HTML injection + $inj = testSqlAndScriptInject($newval, 0); + if ($inj) { + $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorHtmlInjectionForField', $key, dol_trunc($newval, 100)); + $this->errors[$error]['type'] = 'HTMLINJECTION'; + $errorforthistable++; + $error++; + } + // Other tests // ... } diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index 0d4a85e00ae..215e7dd3c64 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -286,8 +286,8 @@ class modAdherent extends DolibarrModules $this->export_label[$r] = 'MembersAndSubscriptions'; $this->export_permission[$r] = array(array("adherent", "export")); $this->export_fields_array[$r] = array( - 'a.rowid'=>'Id', 'a.civility'=>"UserTitle", 'a.lastname'=>"Lastname", 'a.firstname'=>"Firstname", 'a.login'=>"Login", 'a.gender'=>"Gender", 'a.morphy'=>'MemberNature', - 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", 'd.nom'=>"State", 'co.code'=>"CountryCode", 'co.label'=>"Country", + 'a.rowid'=>'MemberId', 'a.ref'=>'MemberRef', 'a.civility'=>"UserTitle", 'a.lastname'=>"Lastname", 'a.firstname'=>"Firstname", 'a.login'=>"Login", 'a.gender'=>"Gender", 'a.morphy'=>'MemberNature', + 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", 'd.code_departement'=>'StateCode', 'd.nom'=>"State", 'co.code'=>"CountryCode", 'co.label'=>"Country", 'a.phone'=>"PhonePro", 'a.phone_perso'=>"PhonePerso", 'a.phone_mobile'=>"PhoneMobile", 'a.email'=>"Email", 'a.birth'=>"Birthday", 'a.statut'=>"Status", 'a.photo'=>"Photo", 'a.note_public'=>"NotePublic", 'a.note_private'=>"NotePrivate", 'a.datec'=>'DateCreation', 'a.datevalid'=>'DateValidation', 'a.tms'=>'DateLastModification', 'a.datefin'=>'DateEndSubscription', 'ta.rowid'=>'MemberTypeId', 'ta.libelle'=>'MemberTypeLabel', @@ -301,7 +301,7 @@ class modAdherent extends DolibarrModules 'c.rowid'=>'Numeric', 'c.dateadh'=>'Date', 'c.datef'=>'Date', 'c.subscription'=>'Numeric' ); $this->export_entities_array[$r] = array( - 'a.rowid'=>'member', 'a.civility'=>"member", 'a.lastname'=>"member", 'a.firstname'=>"member", 'a.login'=>"member", 'a.gender'=>'member', 'a.morphy'=>'member', + 'a.rowid'=>'member', 'a.ref'=>'member', 'a.civility'=>"member", 'a.lastname'=>"member", 'a.firstname'=>"member", 'a.login'=>"member", 'a.gender'=>'member', 'a.morphy'=>'member', 'a.societe'=>'member', 'a.address'=>"member", 'a.zip'=>"member", 'a.town'=>"member", 'd.nom'=>"member", 'co.code'=>"member", 'co.label'=>"member", 'a.phone'=>"member", 'a.phone_perso'=>"member", 'a.phone_mobile'=>"member", 'a.email'=>"member", 'a.birth'=>"member", 'a.statut'=>"member", 'a.photo'=>"member", 'a.note_public'=>"member", 'a.note_private'=>"member", 'a.datec'=>'member', 'a.datevalid'=>'member', 'a.tms'=>'member', @@ -338,10 +338,10 @@ class modAdherent extends DolibarrModules $this->import_tables_array[$r] = array('a'=>MAIN_DB_PREFIX.'adherent', 'extra'=>MAIN_DB_PREFIX.'adherent_extrafields'); $this->import_tables_creator_array[$r] = array('a'=>'fk_user_author'); // Fields to store import user id $this->import_fields_array[$r] = array( - 'a.ref' => 'Member Ref*', + 'a.ref' => 'MemberRef*', 'a.civility'=>"UserTitle", 'a.lastname'=>"Lastname*", 'a.firstname'=>"Firstname", 'a.gender'=>"Gender", 'a.login'=>"Login*", "a.pass"=>"Password", - "a.fk_adherent_type"=>"MemberType*", 'a.morphy'=>'MemberNature*', 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", - 'a.state_id'=>'StateId', 'a.country'=>"CountryId", 'a.phone'=>"PhonePro", 'a.phone_perso'=>"PhonePerso", 'a.phone_mobile'=>"PhoneMobile", + "a.fk_adherent_type"=>"MemberTypeId*", 'a.morphy'=>'MemberNature*', 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", + 'a.state_id'=>'StateId|StateCode', 'a.country'=>"CountryId|CountryCode", 'a.phone'=>"PhonePro", 'a.phone_perso'=>"PhonePerso", 'a.phone_mobile'=>"PhoneMobile", 'a.email'=>"Email", 'a.birth'=>"Birthday", 'a.statut'=>"Status*", 'a.photo'=>"Photo", 'a.note_public'=>"NotePublic", 'a.note_private'=>"NotePrivate", 'a.datec'=>'DateCreation', 'a.datefin'=>'DateEndSubscription' ); @@ -397,7 +397,7 @@ class modAdherent extends DolibarrModules if (!empty($conf->societe->enabled)) { $this->import_examplevalues_array[$r]['a.fk_soc'] = "rowid or name"; } - $this->import_updatekeys_array[$r] = array('a.ref'=>'Member Ref', 'a.login'=>'Login'); + $this->import_updatekeys_array[$r] = array('a.ref'=>'MemberRef', 'a.login'=>'Login'); // Cronjobs $arraydate = dol_getdate(dol_now()); diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index bdd670814c2..6fd71669d9c 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -389,7 +389,7 @@ if (($action == "create") || ($action == "edit")) { print '
"; print ""; print ""; print ""; print ""; print "\n"; - print ''; print ''; +print ''; print ''; print ''; -print ''; -print ''; +//print ''; +//print ''; print ''; print ''; print ''; @@ -453,13 +451,14 @@ print ''; print ''; print ''; -print_liste_field_titre("ID", $_SERVER["PHP_SELF"], "t.rowid", "", $param, '', $sortfield, $sortorder); +print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "t.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("CronLabel", $_SERVER["PHP_SELF"], "t.label", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Prority", $_SERVER["PHP_SELF"], "t.priority", "", $param, '', $sortfield, $sortorder); -print_liste_field_titre("CronTask", '', '', "", $param, '', $sortfield, $sortorder); +print_liste_field_titre("CronModule", $_SERVER["PHP_SELF"], "t.module_name", "", $param, '', $sortfield, $sortorder); +print_liste_field_titre("CronType", '', '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("CronFrequency", '', "", "", $param, '', $sortfield, $sortorder); -print_liste_field_titre("CronDtStart", $_SERVER["PHP_SELF"], "t.datestart", "", $param, 'align="center"', $sortfield, $sortorder); -print_liste_field_titre("CronDtEnd", $_SERVER["PHP_SELF"], "t.dateend", "", $param, 'align="center"', $sortfield, $sortorder); +//print_liste_field_titre("CronDtStart", $_SERVER["PHP_SELF"], "t.datestart", "", $param, 'align="center"', $sortfield, $sortorder); +//print_liste_field_titre("CronDtEnd", $_SERVER["PHP_SELF"], "t.dateend", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre("CronNbRun", $_SERVER["PHP_SELF"], "t.nbrun", "", $param, 'align="right"', $sortfield, $sortorder); print_liste_field_titre("CronDtLastLaunch", $_SERVER["PHP_SELF"], "t.datelastrun", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre("Duration", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); @@ -497,6 +496,9 @@ if ($num > 0) { $object->priority = $obj->priority; $object->processing = $obj->processing; $object->lastresult = $obj->lastresult; + $object->datestart = $db->jdate($obj->datestart); + $object->dateend = $db->jdate($obj->dateend); + $object->module_name = $obj->module_name; $datelastrun = $db->jdate($obj->datelastrun); $datelastresult = $db->jdate($obj->datelastresult); @@ -521,9 +523,15 @@ if ($num > 0) { // Priority print ''; + // Module + print ''; + + // Class/Method print ''; + /* print ''; + */ print ''; @@ -598,24 +608,27 @@ if ($num > 0) { print ''; // Return code of last run - print ''; // Output of last run - print ''; - print '
'.$langcode.''.$key.''; - $titleforvalue = $langs->trans("Translation").' en_US for key '.$key.':
'.($langsenfileonly->tab_translate[$key] ? $langsenfileonly->trans($key) : ''.$langs->trans("None").''); + $titleforvalue = $langs->trans("Translation").' en_US for key '.$key.':
'.(!empty($langsenfileonly->tab_translate[$key]) ? $langsenfileonly->trans($key) : ''.$langs->trans("None").''); print ''; print dol_escape_htmltag($val); print ''; diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 53de8fe2502..6f1012d1af4 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -35,9 +35,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'members', 'users')); -if (!$user->admin) { - accessforbidden(); -} $extrafields = new ExtraFields($db); @@ -51,6 +48,10 @@ $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'user'; +if (empty($user->admin)) { + accessforbidden(); +} + /* * Action @@ -58,6 +59,8 @@ $type = 'user'; include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +$reg = array(); + if ($action == 'set_default') { $ret = addDocumentModel($value, $type, $label, $scandir); $res = true; @@ -83,6 +86,9 @@ if ($action == 'set_default') { $ret = addDocumentModel($value, $type, $label, $scandir); } $res = true; +} elseif ($action == 'unsetdoc') { + // We disable the template + dolibarr_del_const($db, "USER_ADDON_PDF_ODT", $conf->entity); } elseif (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) { $code = $reg[1]; if (dolibarr_set_const($db, $code, 1, 'chaine', 0, '', $conf->entity) > 0) { @@ -118,6 +124,9 @@ if ($action == 'set_default') { $form = new Form($db); +dol_mkdir(DOL_DATA_ROOT.'/doctemplates/users'); +dol_mkdir(DOL_DATA_ROOT.'/doctemplates/usergroups'); + $help_url = 'EN:Module_Users|FR:Module_Utilisateurs|ES:Módulo_Usuarios'; llxHeader('', $langs->trans("UsersSetup"), $help_url); @@ -264,14 +273,17 @@ foreach ($dirmodels as $reldir) { print '
'."\n"; - print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print 'scandir).'&label='.urlencode($module->name).'">'; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; print "'; if (getDolGlobalString('USER_ADDON_PDF_ODT') == $name) { - print img_picto($langs->trans("Default"), 'on'); + //print img_picto($langs->trans("Default"), 'on'); + print 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Default"), 'on').''; } else { print 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index f4c4127a0a4..b8b46a0c8d9 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1718,7 +1718,7 @@ if ($action == 'create') { // Mode of payment print '
'.$langs->trans('PaymentMode').''; print img_picto('', 'bank', 'class="pictofixedwidth"'); - $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') ? GETPOST('mode_reglement_id', 'int') : $soc->mode_reglement_id), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); + $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && GETPOST('mode_reglement_id') != 0) ? GETPOST('mode_reglement_id', 'int') : $soc->mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); print '
'; print $langs->trans('CronArgs').""; - print "params."\" /> "; + print ' '; print ""; print $form->textwithpicto('', $langs->trans("CronArgsHelp"), 1, 'help'); @@ -398,7 +398,7 @@ if (($action == "create") || ($action == "edit")) { print '
'; print $langs->trans('CronCommand').""; - print "command."\" /> "; + print ' '; print ""; print $form->textwithpicto('', $langs->trans("CronCommandHelp"), 1, 'help'); @@ -471,7 +471,7 @@ if (($action == "create") || ($action == "edit")) { if (!empty($object->datestart)) { print $form->selectDate($object->datestart, 'datestart', 1, 1, '', "cronform"); } else { - print $form->selectDate('', 'datestart', 1, 1, '', "cronform"); + print $form->selectDate(-1, 'datestart', 1, 1, '', "cronform"); } print ""; @@ -483,7 +483,7 @@ if (($action == "create") || ($action == "edit")) { if (!empty($object->dateend)) { print $form->selectDate($object->dateend, 'dateend', 1, 1, '', "cronform"); } else { - print $form->selectDate(-1, 'dateend', 1, 1, 1, "cronform"); + print $form->selectDate(-1, 'dateend', 1, 1, '', "cronform"); } print ""; @@ -514,7 +514,7 @@ if (($action == "create") || ($action == "edit")) { print "
'; + print '
'; print $langs->trans('CronDtNextLaunch'); print ' ('.$langs->trans('CronFrom').')'; print ""; @@ -768,7 +768,7 @@ if (($action == "create") || ($action == "edit")) { if (!$user->rights->cron->create) { print ''.$langs->trans("CronStatusActiveBtn").'/'.$langs->trans("CronStatusInactiveBtn").''; } else { - print ''.$langs->trans("Clone").''; + print ''.$langs->trans("ToClone").''; if (empty($object->status)) { print ''.$langs->trans("CronStatusActiveBtn").''; diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 9d246b58eea..744ac1834aa 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -262,8 +262,8 @@ class Cronjob extends CommonObject // Check parameters // Put here code to add a control on parameters values - if (dol_strlen($this->datestart) == 0) { - $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronDtStart')); + if (dol_strlen($this->datenextrun) == 0) { + $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronDtNextLaunch')); $error++; } if (empty($this->label)) { @@ -377,10 +377,6 @@ class Cronjob extends CommonObject // Commit or rollback if ($error) { - foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); - } $this->db->rollback(); return -1 * $error; } else { @@ -717,8 +713,8 @@ class Cronjob extends CommonObject // Check parameters // Put here code to add a control on parameters values - if (dol_strlen($this->datestart) == 0) { - $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronDtStart')); + if (dol_strlen($this->datenextrun) == 0) { + $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronDtNextLaunch')); $error++; } if ((dol_strlen($this->datestart) != 0) && (dol_strlen($this->dateend) != 0) && ($this->dateend < $this->datestart)) { @@ -873,7 +869,7 @@ class Cronjob extends CommonObject // Clear fields $object->status = self::STATUS_DISABLED; - $object->label = $langs->trans("CopyOf").' '.$object->label; + $object->label = $langs->trans("CopyOf").' '.$langs->trans($object->label); // Create clone $object->context['createfromclone'] = 'createfromclone'; @@ -968,7 +964,16 @@ class Cronjob extends CommonObject $label .= ' '.$this->getLibStatut(5); } $label .= '
'.$langs->trans('Ref').': '.$this->ref; - $label .= '
'.$langs->trans('Title').': '.$this->label; + $label .= '
'.$langs->trans('Title').': '.$langs->trans($this->label); + if ($this->label != $langs->trans($this->label)) { + $label .= ' ('.$this->label.')'; + } + if (!empty($this->datestart)) { + $label .= '
'.$langs->trans('CronDtStart').': '.dol_print_date($this->datestart, 'dayhour', 'tzuserrel'); + } + if (!empty($this->dateend)) { + $label .= '
'.$langs->trans('CronDtEnd').': '.dol_print_date($this->dateend, 'dayhour', 'tzuserrel'); + } $url = DOL_URL_ROOT.'/cron/card.php?id='.$this->id; diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index c8cb251ea46..40fe27d3404 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -33,10 +33,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Load translation files required by the page $langs->loadLangs(array("admin", "cron", "bills", "members")); -if (!$user->rights->cron->read) { - accessforbidden(); -} - $action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) $confirm = GETPOST('confirm', 'alpha'); @@ -87,6 +83,15 @@ $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); +// Security +if (!$user->rights->cron->read) { + accessforbidden(); +} + +$permissiontoread = $user->rights->cron->read; +$permissiontoadd = $user->rights->cron->create ? $user->rights->cron->create : $user->rights->cron->write; +$permissiontodelete = $user->rights->cron->delete; +$permissiontoexecute = $user->rights->cron->execute; /* @@ -129,7 +134,7 @@ if (empty($reshook)) { } // Delete jobs - if ($action == 'confirm_delete' && $confirm == "yes" && $user->rights->cron->delete) { + if ($action == 'confirm_delete' && $confirm == "yes" && $permissiontodelete) { //Delete cron task $object = new Cronjob($db); $object->id = $id; @@ -141,7 +146,7 @@ if (empty($reshook)) { } // Execute jobs - if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->execute) { + if ($action == 'confirm_execute' && $confirm == "yes" && $permissiontoexecute) { if (!empty($conf->global->CRON_KEY) && $conf->global->CRON_KEY != $securitykey) { setEventMessages('Security key '.$securitykey.' is wrong', null, 'errors'); $action = ''; @@ -196,9 +201,6 @@ if (empty($reshook)) { // Mass actions $objectclass = 'CronJob'; $objectlabel = 'CronJob'; - $permissiontoread = $user->rights->cron->read; - $permissiontoadd = $user->rights->cron->create ? $user->rights->cron->create : $user->rights->cron->write; - $permissiontodelete = $user->rights->cron->delete; $uploaddir = $conf->cron->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; if ($massaction && $permissiontoadd) { @@ -281,12 +283,8 @@ if (is_array($filter) && count($filter) > 0) { $sql .= " AND ".$key." LIKE '%".$db->escape($value)."%'"; } } -$sqlwhere = array(); if (!empty($search_module_name)) { - $sqlwhere[] = "(t.module_name = '".$db->escape($search_module_name)."')"; -} -if (count($sqlwhere) > 0) { - $sql .= " WHERE ".implode(' AND ', $sqlwhere); + $sql .= natural_search("t.module_name", $search_module_name); } // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -353,7 +351,7 @@ if ($action == 'execute') { print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$id.'&securitykey='.$securitykey.$param, $langs->trans("CronExecute"), $langs->trans("CronConfirmExecute"), "confirm_execute", '', '', 1); } -if ($action == 'delete') { +if ($action == 'delete' && empty($toselect)) { // Used when we make a delete on 1 line (not used for mass delete) print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$id.$param, $langs->trans("CronDelete"), $langs->trans("CronConfirmDelete"), "confirm_delete", '', '', 1); } @@ -386,7 +384,6 @@ if ($optioncss != '') { } print ''; print ''; -print ''; print ''; print ''; print ''; @@ -434,10 +431,11 @@ print '
'; print ''; print '          
'; - print $object->priority; + print dol_escape_htmltag($object->priority); print ''; + print dol_escape_htmltag($object->module_name); + print ''; if ($obj->jobtype == 'method') { $text = $langs->trans("CronClass"); @@ -557,6 +565,7 @@ if ($num > 0) { } print ''; if (!empty($obj->datestart)) { print dol_print_date($db->jdate($obj->datestart), 'dayhour', 'tzserver'); @@ -568,15 +577,16 @@ if ($num > 0) { print dol_print_date($db->jdate($obj->dateend), 'dayhour', 'tzserver'); } print ''; if (!empty($obj->nbrun)) { - print $obj->nbrun; + print dol_escape_htmltag($obj->nbrun); } else { print '0'; } if (!empty($obj->maxrun)) { - print ' / '.$obj->maxrun.''; + print ' / '.dol_escape_htmltag($obj->maxrun).''; } print ''; + print ''; if ($obj->lastresult != '') { if (empty($obj->lastresult)) { - print $obj->lastresult; + print $obj->lastresult; // Print '0' } else { - print ''.dol_trunc($obj->lastresult).''; + print ''.dol_escape_htmltag(dol_trunc($obj->lastresult)).''; } } print ''; + print ''; if (!empty($obj->lastoutput)) { - print dol_trunc(nl2br($obj->lastoutput), 50); + print '
'; + print dol_trunc(dolGetFirstLineOfText($obj->lastoutput, 2), 100); + print '
'; } print '
'; + // Next run + print ''; if (!empty($obj->datenextrun)) { $datenextrun = $db->jdate($obj->datenextrun); if (empty($obj->status)) { diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index a877b659141..47eefb01be9 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -138,7 +138,7 @@ $candelete = 0; if (!empty($user->rights->expensereport->supprimer)) { $candelete = 1; } -if ($object->statut == ExpenseReport::STATUS_DRAFT && !empty($user->rights->expensereport->write) && in_array($object->fk_user_author, $childids)) { +if ($object->statut == ExpenseReport::STATUS_DRAFT && $user->hasRight('expensereport', 'write') && in_array($object->fk_user_author, $childids)) { $candelete = 1; } diff --git a/htdocs/hrm/skill_tab.php b/htdocs/hrm/skill_tab.php index 11dcf9a5172..b2ac9e6bce1 100644 --- a/htdocs/hrm/skill_tab.php +++ b/htdocs/hrm/skill_tab.php @@ -317,6 +317,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; print ''; + print ''; print '
'; print ''; print ''; @@ -336,6 +337,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; print ''; + print ''; print ''; } print '
'; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 38a540ca042..51a50c6376c 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -876,9 +876,9 @@ if ($step == 4 && $datatoimport) { $isrequired = preg_match('/\*$/', $label); if (!empty($isrequired)) { $newlabel = substr($label, 0, -1); - $fieldstarget_tmp[$key] = array("label"=>$newlabel,"required"=>true); + $fieldstarget_tmp[$key] = array("label"=>$newlabel, "required"=>true); } else { - $fieldstarget_tmp[$key] = array("label"=>$label,"required"=>false); + $fieldstarget_tmp[$key] = array("label"=>$label, "required"=>false); } if (!empty($array_match_database_to_file[$key])) { $fieldstarget_tmp[$key]["imported"] = true; @@ -1089,9 +1089,14 @@ if ($step == 4 && $datatoimport) { $optionsall = array(); foreach ($fieldstarget as $code => $line) { //var_dump($line); - $labeltoshow = $langs->transnoentities($line["label"]); - $optionsall[$code] = array('labelkey'=>$line['label'], 'label'=>$labeltoshow, 'required'=>(empty($line["required"]) ? 0 : 1), 'position'=>!empty($line['position']) ? $line['position'] : 0); - // TODO Get type from an new array into module descriptor. + + $tmparray = explode('|', $line["label"]); // If label of field is several translation keys separated with | + $labeltoshow = ''; + foreach ($tmparray as $tmpkey => $tmpval) { + $labeltoshow .= ($labeltoshow ? ' '.$langs->trans('or').' ' : '').$langs->transnoentities($tmpval); + } + $optionsall[$code] = array('labelkey'=>$line['label'], 'labelkeyarray'=>$tmparray, 'label'=>$labeltoshow, 'required'=>(empty($line["required"]) ? 0 : 1), 'position'=>!empty($line['position']) ? $line['position'] : 0); + // TODO Get type from a new array into module descriptor. //$picto = 'email'; $picto = ''; if ($picto) { @@ -1129,9 +1134,6 @@ if ($step == 4 && $datatoimport) { print '
'; $entity = (!empty($objimport->array_import_entities[0][$code]) ? $objimport->array_import_entities[0][$code] : $objimport->array_import_icon[0]); - $tablealias = preg_replace('/(\..*)$/i', '', $code); - $tablename = !empty($objimport->array_import_tables[0][$tablealias]) ? $objimport->array_import_tables[0][$tablealias] : ""; - $entityicon = !empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity; // $entityicon must string name of picto of the field like 'project', 'company', 'contact', 'modulename', ... $entitylang = $entitytolang[$entity] ? $entitytolang[$entity] : $objimport->array_import_label[0]; // $entitylang must be a translation key to describe object the field is related to, like 'Company', 'Contact', 'MyModyle', ... @@ -1161,6 +1163,48 @@ if ($step == 4 && $datatoimport) { $label .= $tmpval['label']; $label .= $tmpval['required'] ? '*' : ''; + $tablealias = preg_replace('/(\..*)$/i', '', $tmpcode); + $tablename = !empty($objimport->array_import_tables[0][$tablealias]) ? $objimport->array_import_tables[0][$tablealias] : ""; + + $htmltext = ''; + + $filecolumn = ($i + 1); + // Source field info + if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need convertion + $filecolumntoshow = num2Alpha($i); + } else { + if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') { + $htmltext .= $langs->trans("DataComeFromIdFoundFromRef", $filecolumn, $langs->transnoentitiesnoconv($entitylang)).'
'; + } + if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') { + $htmltext .= $langs->trans("DataComeFromIdFoundFromCodeId", $filecolumn, $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$code]['dict'])).'
'; + } + } + // Source required + $example = !empty($objimport->array_import_examplevalues[0][$tmpcode])?$objimport->array_import_examplevalues[0][$tmpcode]:""; + // Example + if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need convertion + if ($example) { + $htmltext .= $langs->trans("SourceExample").': '.str_replace('"', '', $example).'
'; + } + } else { + if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') { + $htmltext .= $langs->trans("SourceExample").': '.$langs->transnoentitiesnoconv("ExampleAnyRefFoundIntoElement", $entitylang).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.$example.')' : '').'
'; + } elseif ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') { + $htmltext .= $langs->trans("SourceExample").': '.$langs->trans("ExampleAnyCodeOrIdFoundIntoDictionary", $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$code]['dict'])).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.$example.')' : '').'
'; + } elseif ($example) { + $htmltext .= $langs->trans("SourceExample").': '.str_replace('"', '', $example).'
'; + } + } + // Format control rule + if (!empty($objimport->array_import_regex[0][$tmpcode])) { + $htmltext .= $langs->trans("FormatControlRule").': '.str_replace('"', '', $objimport->array_import_regex[0][$tmpcode]).'
'; + } + + $htmltext .= $langs->trans("Table")."->".$langs->trans("Field").':   '.$tablename."->".preg_replace('/^.*\./', '', $tmpcode).""; + + $labelhtml = $label.' '.$form->textwithpicto('', $htmltext, 1, 'help', '', 1); + $selectforline .= ''; print ''; $i++; } @@ -1926,9 +1931,9 @@ if ($step == 5 && $datatoimport) { print $langs->trans("TooMuchErrors", (count($arrayoferrors) - $nboferrors))."
"; break; } - print '* '.$langs->trans("Line").' '.$key.'
'; + print '* '.$langs->trans("Line").' '.dol_escape_htmltag($key).'
'; foreach ($val as $i => $err) { - print '     > '.$err['lib'].'
'; + print '     > '.dol_escape_htmltag($err['lib']).'
'; } } print '
' . $langs->trans('AddSkill') . '
'; - $filecolumn = ($i + 1); + // Source field info $htmltext = ''.$langs->trans("FieldSource").'
'; - if ($filecolumn > count($fieldssource)) { - $htmltext .= $langs->trans("DataComeFromNoWhere").'
'; - } else { - if (empty($objimport->array_import_convertvalue[0][$code])) { // If source file does not need convertion - $filecolumntoshow = num2Alpha($i); - $htmltext .= $langs->trans("DataComeFromFileFieldNb", $filecolumntoshow).'
'; - } else { - if ($objimport->array_import_convertvalue[0][$code]['rule'] == 'fetchidfromref') { - $htmltext .= $langs->trans("DataComeFromIdFoundFromRef", $filecolumn, $langs->transnoentitiesnoconv($entitylang)).'
'; - } - if ($objimport->array_import_convertvalue[0][$code]['rule'] == 'fetchidfromcodeid') { - $htmltext .= $langs->trans("DataComeFromIdFoundFromCodeId", $filecolumn, $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$code]['dict'])).'
'; - } - } - } - // Source required - $example = !empty($objimport->array_import_examplevalues[0][$code])?$objimport->array_import_examplevalues[0][$code]:""; - // Example - if (empty($objimport->array_import_convertvalue[0][$code])) { // If source file does not need convertion - if ($example) { - $htmltext .= $langs->trans("SourceExample").': '.$example.'
'; - } - } else { - if ($objimport->array_import_convertvalue[0][$code]['rule'] == 'fetchidfromref') { - $htmltext .= $langs->trans("SourceExample").': '.$langs->transnoentitiesnoconv("ExampleAnyRefFoundIntoElement", $entitylang).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.$example.')' : '').'
'; - } elseif ($objimport->array_import_convertvalue[0][$code]['rule'] == 'fetchidfromcodeid') { - $htmltext .= $langs->trans("SourceExample").': '.$langs->trans("ExampleAnyCodeOrIdFoundIntoDictionary", $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$code]['dict'])).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.$example.')' : '').'
'; - } elseif ($example) { - $htmltext .= $langs->trans("SourceExample").': '.$example.'
'; - } - } - // Format control rule - if (!empty($objimport->array_import_regex[0][$code])) { - $htmltext .= $langs->trans("FormatControlRule").': '.$objimport->array_import_regex[0][$code].'
'; - } - $htmltext .= '
'; - // Target field info - $htmltext .= ''.$langs->trans("FieldTarget").'
'; - //$htmltext .= $langs->trans("SourceRequired").': '.yn($line["label"]).'
'; - if (empty($objimport->array_import_convertvalue[0][$code])) { // If source file does not need convertion - $htmltext .= $langs->trans("DataIsInsertedInto").'
'; - } else { - if ($objimport->array_import_convertvalue[0][$code]['rule'] == 'fetchidfromref') { - $htmltext .= $langs->trans("DataIDSourceIsInsertedInto").'
'; - } - if ($objimport->array_import_convertvalue[0][$code]['rule'] == 'fetchidfromcodeid') { - $htmltext .= $langs->trans("DataCodeIDSourceIsInsertedInto").'
'; - } - } - $htmltext .= $langs->trans("FieldTitle").": ".$langs->trans($fieldstarget[$arraykeysfieldtarget[$code-1]]["label"])."
"; - $htmltext .= $langs->trans("Table")." -> ".$langs->trans("Field").': '.$tablename." -> ".preg_replace('/^.*\./', '', $code)."
"; - print $form->textwithpicto($more, $htmltext); + $filecolumntoshow = num2Alpha($i); + $htmltext .= $langs->trans("DataComeFromFileFieldNb", $filecolumntoshow).'
'; + + print $form->textwithpicto('', $htmltext); + + print '
'; @@ -1946,9 +1951,9 @@ if ($step == 5 && $datatoimport) { print $langs->trans("TooMuchWarnings", (count($arrayofwarnings) - $nbofwarnings))."
"; break; } - print ' * '.$langs->trans("Line").' '.$key.'
'; + print ' * '.$langs->trans("Line").' '.dol_escape_htmltag($key).'
'; foreach ($val as $i => $err) { - print '     > '.$err['lib'].'
'; + print '     > '.dol_escape_htmltag($err['lib']).'
'; } } print '
'; 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 382001722e5..1d9c0141ca2 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 @@ -51,7 +51,8 @@ -- VPGSQL8.2 ALTER TABLE llx_c_payment_term ALTER COLUMN rowid SET DEFAULT nextval('llx_c_payment_term_rowid_seq'); -- VPGSQL8.2 SELECT setval('llx_c_payment_term_rowid_seq', MAX(rowid)) FROM llx_c_payment_term; - +ALTER TABLE llx_entrepot ADD COLUMN barcode varchar(180) DEFAULT NULL; +ALTER TABLE llx_entrepot ADD COLUMN fk_barcode_type integer DEFAULT NULL; ALTER TABLE llx_c_transport_mode ADD UNIQUE INDEX uk_c_transport_mode (code, entity); @@ -650,5 +651,10 @@ ALTER TABLE llx_prelevement_facture_demande MODIFY COLUMN ext_payment_id varchar INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES (140, 'PCN2020-LUXEMBURG', 'Plan comptable normalisé 2020 Luxembourgeois', 1); --- Allow users to make subscriptions of any amount during membership subscription -ALTER TABLE llx_adherent_type ADD COLUMN caneditamount varchar(3) DEFAULT 0 AFTER amount; +ALTER TABLE llx_cronjob MODIFY COLUMN label varchar(255) NOT NULL; + +-- We need to keep only the PurgeDeleteTemporaryFilesShort with params = 'tempfilsold+logfiles' +DELETE FROM llx_cronjob WHERE label = 'PurgeDeleteTemporaryFilesShort' AND params = 'tempfilesold'; + +ALTER TABLE llx_cronjob DROP INDEX uk_cronjob; +ALTER TABLE llx_cronjob ADD UNIQUE INDEX uk_cronjob (label, entity); diff --git a/htdocs/install/mysql/tables/llx_cronjob.key.sql b/htdocs/install/mysql/tables/llx_cronjob.key.sql index d0fac214ba0..a1d7587e217 100644 --- a/htdocs/install/mysql/tables/llx_cronjob.key.sql +++ b/htdocs/install/mysql/tables/llx_cronjob.key.sql @@ -21,3 +21,5 @@ ALTER TABLE llx_cronjob ADD INDEX idx_cronjob_datelastrun (datelastrun); ALTER TABLE llx_cronjob ADD INDEX idx_cronjob_datenextrun (datenextrun); ALTER TABLE llx_cronjob ADD INDEX idx_cronjob_datestart (datestart); ALTER TABLE llx_cronjob ADD INDEX idx_cronjob_dateend (dateend); + +ALTER TABLE llx_cronjob ADD UNIQUE INDEX uk_cronjob (label, entity); diff --git a/htdocs/install/mysql/tables/llx_cronjob.sql b/htdocs/install/mysql/tables/llx_cronjob.sql index 69d30d924e8..27e8a31cc9a 100644 --- a/htdocs/install/mysql/tables/llx_cronjob.sql +++ b/htdocs/install/mysql/tables/llx_cronjob.sql @@ -24,7 +24,7 @@ CREATE TABLE llx_cronjob tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, datec datetime, jobtype varchar(10) NOT NULL, -- 'method', 'function' or 'command' - label text NOT NULL, + label varchar(255) NOT NULL, command varchar(255), classesname varchar(255), -- when jobtype is 'method', name of the class file containing the method. objectname varchar(255), diff --git a/htdocs/install/mysql/tables/llx_entrepot.sql b/htdocs/install/mysql/tables/llx_entrepot.sql index b2e814c15c6..4b93106e0d4 100644 --- a/htdocs/install/mysql/tables/llx_entrepot.sql +++ b/htdocs/install/mysql/tables/llx_entrepot.sql @@ -35,6 +35,8 @@ create table llx_entrepot fk_pays integer DEFAULT 0, phone varchar(20), -- phone number fax varchar(20), -- fax number + barcode varchar(180) DEFAULT NULL, -- barcode + fk_barcode_type integer DEFAULT NULL, -- barcode type warehouse_usage integer DEFAULT 1, -- 1=internal, 2=external (virtual warehouse or stock out of company) statut tinyint DEFAULT 1, -- 1 open, 0 close fk_user_author integer, diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index c4a964b6b62..71b16f24506 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -60,13 +60,14 @@ NatureOfThirdParty=Nature of Third party NatureOfContact=Nature of Contact Address=Address State=State/Province +StateId=State ID StateCode=State/Province code StateShort=State Region=Region Region-State=Region - State Country=Country CountryCode=Country code -CountryId=Country id +CountryId=Country ID Phone=Phone PhoneShort=Phone Skype=Skype diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 2857d7a3f54..c50ccc810cf 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -92,6 +92,7 @@ ErrorModuleRequireJavascript=Javascript must not be disabled to have this featur ErrorPasswordsMustMatch=Both typed passwords must match each other ErrorContactEMail=A technical error occured. Please, contact administrator to following email %s and provide the error code %s in your message, or add a screen copy of this page. ErrorWrongValueForField=Field %s: '%s' does not match regex rule %s +ErrorHtmlInjectionForField=Field %s: The value '%s' contains a malicious data not allowed ErrorFieldValueNotIn=Field %s: '%s' is not a value found in field %s of %s ErrorFieldRefNotIn=Field %s: '%s' is not a %s existing ref ErrorsOnXLines=%s errors found diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 972be559eec..e4ca610c44f 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -35,7 +35,8 @@ DateEndSubscription=End date of membership EndSubscription=End of membership SubscriptionId=Contribution ID WithoutSubscription=Without contribution -MemberId=Member id +MemberId=Member Id +MemberRef=Member Ref NewMember=New member MemberType=Member type MemberTypeId=Member type id diff --git a/htdocs/langs/en_US/oauth.lang b/htdocs/langs/en_US/oauth.lang index f41c1632cac..08f7956f455 100644 --- a/htdocs/langs/en_US/oauth.lang +++ b/htdocs/langs/en_US/oauth.lang @@ -12,9 +12,10 @@ TokenDeleted=Token deleted RequestAccess=Click here to request/renew access and receive a new token DeleteAccess=Click here to delete token UseTheFollowingUrlAsRedirectURI=Use the following URL as the Redirect URI when creating your credentials with your OAuth provider: -ListOfSupportedOauthProviders=Enter the credentials provided by your OAuth2 provider. Only supported OAuth2 providers are listedd here. These services may be used by other modules that need OAuth2 authentication. +ListOfSupportedOauthProviders=Add your OAuth2 token providers. Then, go on your OAuth provider admin page to create/get an OAuth ID and Secret and save them here. Once done, switch on the other tab to generate your token. OAuthSetupForLogin=Page to manage (generate/delete) OAuth tokens SeePreviousTab=See previous tab +OAuthProvider=OAuth provider OAuthIDSecret=OAuth ID and Secret TOKEN_REFRESH=Token Refresh Present TOKEN_EXPIRED=Token expired @@ -23,13 +24,13 @@ TOKEN_DELETE=Delete saved token OAUTH_GOOGLE_NAME=OAuth Google service OAUTH_GOOGLE_ID=OAuth Google Id OAUTH_GOOGLE_SECRET=OAuth Google Secret -OAUTH_GOOGLE_DESC=Go to this page then "Credentials" to create OAuth credentials OAUTH_GITHUB_NAME=OAuth GitHub service OAUTH_GITHUB_ID=OAuth GitHub Id OAUTH_GITHUB_SECRET=OAuth GitHub Secret -OAUTH_GITHUB_DESC=Go to this page then "Register a new application" to create OAuth credentials -OAUTH_URL_FOR_CREDENTIAL=Go to this page to create or get your OAuth ID and 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_SECRET=OAuth secret \ No newline at end of file +OAUTH_SECRET=OAuth secret +OAuthProviderAdded=OAuth provider added +AOAuthEntryForThisProviderAndLabelAlreadyHasAKey=An OAuth entry for this provider and label already exists \ No newline at end of file diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index de14cae280b..5697e93407d 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -131,7 +131,7 @@ function testSqlAndScriptInject($val, $type) $inj += preg_match('/user\s*\(/i', $val); // avoid to use function user() or mysql_user() that return current database login $inj += preg_match('/information_schema/i', $val); // avoid to use request that read information_schema database $inj += preg_match('/'; + print '
'; + print $langs->trans("Picto"); + print ''; + print $moduleobj->picto; + print '   '.img_picto('', $moduleobj->picto, 'class="valignmiddle pictomodule paddingrightonly"'); + print '
'; + print '
'; print $langs->trans("Description"); print ''; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index d9898338960..eedb4de0b13 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -59,9 +59,9 @@ class MyObject extends CommonObject public $isextrafieldmanaged = 1; /** - * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png + * @var string String with name of icon for myobject. Must be a 'fa-xxx' fontawesome code (or 'fa-xxx_fa_color_size') or 'myobject@mymodule' if picto is file 'img/object_myobject.png'. */ - public $picto = 'myobject@mymodule'; + public $picto = 'fa-file'; const STATUS_DRAFT = 0; @@ -240,7 +240,7 @@ class MyObject extends CommonObject $this->db = $db; - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid']) && !empty($this->fields['ref'])) { $this->fields['rowid']['visible'] = 0; } if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) { diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 7702aa6699b..ec818206705 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -92,7 +92,7 @@ $lineid = GETPOST('lineid', 'int'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'aZ09'); -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'myobjectcard'; // To manage different context of search +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', __FILE__); // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); $dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09'); diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 14fd3a52171..aaf93d1e229 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -97,7 +97,7 @@ $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'myobjectlist'; // To manage different context of search +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', __FILE__); // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $mode = GETPOST('mode', 'aZ'); @@ -570,7 +570,7 @@ foreach ($object->fields as $key => $val) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'rowid' && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { @@ -632,7 +632,7 @@ foreach ($object->fields as $key => $val) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'rowid' && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label diff --git a/htdocs/partnership/class/partnership.class.php b/htdocs/partnership/class/partnership.class.php index 28fcc2fd68e..85787075f28 100644 --- a/htdocs/partnership/class/partnership.class.php +++ b/htdocs/partnership/class/partnership.class.php @@ -205,7 +205,7 @@ class Partnership extends CommonObject $this->fields['fk_soc'] = array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'company', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150'); } - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid']) && !empty($this->fields['ref'])) { $this->fields['rowid']['visible'] = 0; } // if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) { diff --git a/htdocs/partnership/partnership_list.php b/htdocs/partnership/partnership_list.php index 014d576f5d6..a237a359b25 100644 --- a/htdocs/partnership/partnership_list.php +++ b/htdocs/partnership/partnership_list.php @@ -43,9 +43,10 @@ $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'partnershiplist'; // To manage different context of search +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', __FILE__); // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$mode = GETPOST('mode', 'aZ'); $id = GETPOST('id', 'int'); @@ -55,8 +56,9 @@ $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters $page = 0; -} // If $page is not defined, or '' or -1 or if we click on clear filters +} $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -88,7 +90,7 @@ if (!$sortorder) { } // Initialize array of search criterias -$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); +$search_all = GETPOST('search_all', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { @@ -118,11 +120,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1, 1, '1'); + $visible = (int) dol_eval($val['visible'], 1); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), + 'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); @@ -150,14 +152,13 @@ if ($user->socid > 0) { // Protection if external user //$result = restrictedArea($user, 'partnership'); //if (!$permissiontoread) accessforbidden(); +$error = 0; /* * Actions */ -$error = 0; - if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; @@ -187,7 +188,6 @@ if (empty($reshook)) { } $toselect = array(); $search_array_options = array(); - $search_filter = ""; } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) { @@ -285,7 +285,7 @@ $now = dol_now(); //$help_url="EN:Module_Partnership|FR:Module_Partnership_FR|ES:Módulo_Partnership"; $help_url = ''; -$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("Partnerships")); +$title = $langs->trans("Partnerships"); $morejs = array(); $morecss = array(); @@ -341,17 +341,17 @@ foreach ($search as $key => $val) { $mode_search = 2; } if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } } else { if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { if (preg_match('/_dtstart$/', $key)) { - $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; + $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'"; } if (preg_match('/_dtend$/', $key)) { - $sql .= " AND t.".$columnName." <= '".$db->idate($search[$key])."'"; + $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'"; } } } @@ -382,11 +382,13 @@ $sql .= $hookmanager->resPrint; /* If a group by is required $sql.= " GROUP BY "; foreach($object->fields as $key => $val) { - $sql .= "t.".$key.", "; + $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.', ' : ''); + 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(); @@ -395,35 +397,41 @@ $sql.=$hookmanager->resPrint; $sql=preg_replace('/,\s*$/','', $sql); */ -$sql .= $db->order($sortfield, $sortorder); - // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } -// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. -if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) { - $num = $nbtotalofrecords; -} else { - if ($limit) { - $sql .= $db->plimit($limit + 1, $offset); - } - $resql = $db->query($sql); - if (!$resql) { - dol_print_error($db); - exit; - } - - $num = $db->num_rows($resql); +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); } +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + + // Direct jump if only one record found if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { $obj = $db->fetch_object($resql); @@ -451,9 +459,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) { foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { foreach ($search[$key] as $skey) { - $param .= '&search_'.$key.'[]='.urlencode($skey); + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } } - } else { + } elseif ($search[$key] != '') { $param .= '&search_'.$key.'='.urlencode($search[$key]); } } @@ -496,9 +506,12 @@ print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'; + print ''."\n"; + print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'."\n"; } $moreforfilter = ''; @@ -536,7 +552,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table @@ -551,25 +567,31 @@ if ($managedfor == 'member') { // Fields title search // -------------------------------------------------------------------- print ''; +// Action column +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; +} foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $searchkey = empty($search[$key]) ? '' : $search[$key]; + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'rowid' && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { - print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth125', 1); - } elseif (!preg_match('/^(date|timestamp|datetime)/', $val['type'])) { - print ''; + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1); } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { print '
'; print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); @@ -577,6 +599,12 @@ foreach ($object->fields as $key => $val) { print '
'; print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); print '
'; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; } print ''; } @@ -596,16 +624,23 @@ $parameters = array('arrayfields'=>$arrayfields); $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print ''; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print ''; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print ''; +} print ''."\n"; +$totalarray = array(); +$totalarray['nbfield'] = 0; // Fields title label // -------------------------------------------------------------------- print ''; +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} foreach ($object->fields as $key => $val) { $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { @@ -614,11 +649,13 @@ foreach ($object->fields as $key => $val) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'rowid' && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } + $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label if (!empty($arrayfields['t.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; + $totalarray['nbfield']++; } } // End of subscription date @@ -630,11 +667,14 @@ if ($managedfor == 'member') { // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields -$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} +$totalarray['nbfield']++; print ''."\n"; @@ -652,8 +692,11 @@ if (isset($extrafields->attributes[$object->table_element]['computed']) && is_ar // Loop on record // -------------------------------------------------------------------- $i = 0; +$savnbfield = $totalarray['nbfield']; $totalarray = array(); -while ($i < ($limit ? min($num, $limit) : $num)) { +$totalarray['nbfield'] = 0; +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); if (empty($obj)) { break; // Should not happen @@ -662,98 +705,132 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // Store properties in $object $object->setVarsFromFetchObj($obj); - // Show here line of result - print ''; - foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); - if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif ($key == 'status') { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; + if ($mode == 'kanban') { + if ($i == 0) { + print ''; + print '
'; } - - if (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif ($key == 'ref') { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + // Output Kanban + print $object->getKanbanView(''); + if ($i == ($imaxinloop - 1)) { + print '
'; + print ''; } - - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'right'; - } - //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; - - if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; - if ($key == 'status') { - print $object->getLibStatut(5); - } else { - print $object->showOutputField($val, $key, $object->$key, ''); + } else { + // Show here line of result + $j = 0; + print ''; + // Action column + if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; } print ''; - if (!$i) { - $totalarray['nbfield']++; + } + foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; } - if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + + if (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif ($key == 'ref') { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } + + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; + + if (!empty($arrayfields['t.'.$key]['checked'])) { + print ''; + if ($key == 'status') { + print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); + } else { + print $object->showOutputField($val, $key, $object->$key, ''); + } + print ''; if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + $totalarray['nbfield']++; } - if (!isset($totalarray['val'])) { - $totalarray['val'] = array(); + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + } + if (!isset($totalarray['val'])) { + $totalarray['val'] = array(); + } + if (!isset($totalarray['val']['t.'.$key])) { + $totalarray['val']['t.'.$key] = 0; + } + $totalarray['val']['t.'.$key] += $object->$key; } - if (!isset($totalarray['val']['t.'.$key])) { - $totalarray['val']['t.'.$key] = 0; - } - $totalarray['val']['t.'.$key] += $object->$key; } } - } - // End of subscription date - if ($managedfor == 'member') { - print ''; - $result = $adherent->fetch($object->fk_member); - if ($result) { - $datefin = $adherent->datefin; - if ($datefin) { - print dol_print_date($datefin, 'day'); - if ($adherent->hasDelay()) { - $textlate .= ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; - print " ".img_warning($langs->trans("SubscriptionLate").$textlate); - } - } else { - if ($adherent->subscription == 'yes') { - print $langs->trans("SubscriptionNotReceived"); - if ($adherent->statut > 0) { - print " ".img_warning(); + // End of subscription date + if ($managedfor == 'member') { + print ''; + $result = $adherent->fetch($object->fk_member); + if ($result) { + $datefin = $adherent->datefin; + if ($datefin) { + print dol_print_date($datefin, 'day'); + if ($adherent->hasDelay()) { + $textlate .= ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; + print " ".img_warning($langs->trans("SubscriptionLate").$textlate); } } else { - print ' '; + if ($adherent->subscription == 'yes') { + print $langs->trans("SubscriptionNotReceived"); + if ($adherent->statut > 0) { + print " ".img_warning(); + } + } else { + print ' '; + } } } + print ''; } - print ''; - } - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Action column - print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($object->id, $arrayofselected)) { - $selected = 1; + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print ''; + } + if (!$i) { + $totalarray['nbfield']++; } - print ''; - } - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - print ''."\n"; + print ''."\n"; + } $i++; } @@ -771,14 +848,14 @@ if ($num == 0) { } } if ($managedfor != 'member') $colspan++; // End of subscription date - print ''.$langs->trans("NoRecordFound").''; + print ''.$langs->trans("NoRecordFound").''; } $db->free($resql); $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); -$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print ''."\n"; diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index 5c02afe85dc..f845c161ab2 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -50,7 +50,8 @@ $outjson = (GETPOST('outjson', 'int') ? GETPOST('outjson', 'int') : 0); $action = GETPOST('action', 'aZ09'); $id = GETPOST('id', 'int'); $excludeids = GETPOST('excludeids', 'intcomma'); -$showtype = GETPOST('showtype', 'int'); +$showtype = GETPOSTINT('showtype'); +$showcode = GETPOSTINT('showcode'); $object = new Societe($db); if ($id > 0) { @@ -123,7 +124,7 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) { $excludeids = array(); } - $arrayresult = $form->select_thirdparty_list(0, $htmlname, $filter, 1, $showtype, 0, null, $searchkey, $outjson, 0, 'minwidth100', '', false, $excludeids); + $arrayresult = $form->select_thirdparty_list(0, $htmlname, $filter, 1, $showtype, 0, null, $searchkey, $outjson, 0, 'minwidth100', '', false, $excludeids, $showcode); $db->close(); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 0946201b100..d13893ca7dd 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2784,29 +2784,30 @@ class Societe extends CommonObject /** * Return link(s) on type of thirdparty (with picto) * - * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only) - * @param string $option ''=All - * @param int $notooltip 1=Disable tooltip - * @return string String with URL + * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only) + * @param string $option ''=All + * @param int $notooltip 1=Disable tooltip + * @param string $tag Tag 'a' or 'span' + * @return string String with URL */ - public function getTypeUrl($withpicto = 0, $option = '', $notooltip = 0) + public function getTypeUrl($withpicto = 0, $option = '', $notooltip = 0, $tag = 'a') { global $conf, $langs; $s = ''; if (empty($option) || preg_match('/prospect/', $option)) { if (($this->client == 2 || $this->client == 3) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { - $s .= ''.dol_substr($langs->trans("Prospect"), 0, 1).''; + $s .= '<'.$tag.' class="customer-back opacitymedium" title="'.$langs->trans("Prospect").'" href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id.'">'.dol_substr($langs->trans("Prospect"), 0, 1).''; } } if (empty($option) || preg_match('/customer/', $option)) { if (($this->client == 1 || $this->client == 3) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { - $s .= ''.dol_substr($langs->trans("Customer"), 0, 1).''; + $s .= '<'.$tag.' class="customer-back" title="'.$langs->trans("Customer").'" href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id.'">'.dol_substr($langs->trans("Customer"), 0, 1).''; } } if (empty($option) || preg_match('/supplier/', $option)) { if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && $this->fournisseur) { - $s .= ''.dol_substr($langs->trans("Supplier"), 0, 1).''; + $s .= '<'.$tag.' class="vendor-back" title="'.$langs->trans("Supplier").'" href="'.DOL_URL_ROOT.'/fourn/card.php?socid='.$this->id.'">'.dol_substr($langs->trans("Supplier"), 0, 1).''; } } return $s; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index a57b498490b..255152744f7 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -1583,7 +1583,7 @@ while ($i < min($num, $limit)) { } } if (!empty($arrayfields['s.email']['checked'])) { - print ''.dol_print_email($obj->email, $obj->rowid, $obj->socid, 'AC_EMAIL', 0, 0, 1)."\n"; + print ''.dol_print_email($obj->email, $obj->rowid, $obj->rowid, 'AC_EMAIL', 0, 0, 1)."\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 4c22ede0b59..70b5285fb2c 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2739,6 +2739,7 @@ li.tmenu:hover .tmenuimage:not(.menuhider), li.tmenu:hover .tmenuimage:not(.menu print "div.mainmenu.".$val." {\n"; print " background-image: url(".$url.");\n"; print " background-position-y: 3px;\n"; + print " filter: saturate(0);\n"; print "}\n"; } } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 8b288cdf307..90607fd31be 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2702,7 +2702,7 @@ div.mainmenu.menu { print "/* A mainmenu entry was found but img file ".$val.".png not found (check /".$val."/img/".$val.".png), so we use a generic one */\n"; print 'div.mainmenu.'.$val.'::before { content: "\f249"; - }'; + }'."\n"; } else { print "/* A mainmenu entry was found but img file ".$val.".png not found (check /".$val."/img/".$val.".png), so we use a generic one. */\n"; print "/* Overwrite this definition in your own css with a different content to use your own font awesome icon. */\n"; @@ -2715,6 +2715,7 @@ div.mainmenu.menu { } else { print "div.mainmenu.".$val." {\n"; print " background-image: url(".$url.");\n"; + print " filter: saturate(0);\n"; print "}\n"; } } diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index cf7536799a1..4f7a78790f1 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -217,9 +217,17 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=testSqlAndScriptInject($test, 1); $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL1b. Should find an attack on GET param and did not.'); + $test = '... update ... set ... ='; + $result=testSqlAndScriptInject($test, 1); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2a. Should find an attack on GET param and did not.'); + + $test = 'action=update& ... set ... ='; + $result=testSqlAndScriptInject($test, 1); + $this->assertEquals(0, $result, 'Error on testSqlAndScriptInject for SQL2b. Should not find an attack on GET param and did.'); + $test = '... union ... selection '; $result=testSqlAndScriptInject($test, 1); - $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2. Should find an attack on GET param and did not.'); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2c. Should find an attack on GET param and did not.'); $test = 'javascript:'; $result=testSqlAndScriptInject($test, 0);