From e0d713bbef3f34f31d797f8d4ff18007a559f5f9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Mar 2020 12:56:21 +0200 Subject: [PATCH 01/12] Update demo --- dev/initdemo/updatedemo.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/initdemo/updatedemo.php b/dev/initdemo/updatedemo.php index aceaeb88456..0cc43a18a9d 100755 --- a/dev/initdemo/updatedemo.php +++ b/dev/initdemo/updatedemo.php @@ -71,7 +71,9 @@ $tables=array( 'paiement'=>array(0=>'datep'), 'bank'=>array(0=>'datev', 1=>'dateo'), 'commande_fournisseur'=>array(0=>'date_commande', 1=>'date_valid', 3=>'date_creation', 4=>'date_approve', 5=>'date_approve2', 6=>'date_livraison'), - 'supplier_proposal'=>array(0=>'datec', 1=>'date_valid', 2=>'date_cloture') + 'supplier_proposal'=>array(0=>'datec', 1=>'date_valid', 2=>'date_cloture'), + 'expense_report'=>array(0=>'date_debut', 1=>'date_fin', 2=>'date_create', 3=>'date_valid', 4=>'date_approve', 5=>'date_refuse', 6=>'date_cancel'), + 'leave'=>array(0=>'date_debut', 1=>'date_fin', 2=>'date_create', 3=>'date_valid', 5=>'date_refuse', 6=>'date_cancel') ); $year=2010; From 0b486ea5adbc20de948b4e7a0e3be46ef8d48f25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Mar 2020 13:28:19 +0200 Subject: [PATCH 02/12] CSS --- htdocs/theme/eldy/global.inc.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index efe17c67e03..c9d58be7da3 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -175,11 +175,15 @@ input, select { margin-bottom:1px; margin-top:1px; } -#mainbody input.button { +#mainbody input.button:not(.buttongen) { background: var(--butactionbg); border-collapse: collapse; border: none; } +#mainbody input.buttongen { + padding: 4px 4px; +} + input.button:focus { border-bottom: 0; } From e75e49426f0ad7905627aa33f5ca354d8d34b2f6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Mar 2020 13:52:02 +0200 Subject: [PATCH 03/12] Look and feel v12 --- htdocs/core/class/html.formfile.class.php | 6 +++--- htdocs/core/lib/files.lib.php | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index e84feb90601..20c723ba8a2 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1387,7 +1387,7 @@ class FormFile if ($permtoeditline) { $paramsectiondir = (in_array($modulepart, array('medias', 'ecm')) ? '§ion_dir='.urlencode($relativepath) : ''); - print ''.img_edit('default', 0, 'class="paddingrightonly"').''; + print ''.img_edit('default', 0, 'class="paddingrightonly"').''; } } if ($permonobject) @@ -1879,9 +1879,9 @@ class FormFile print ''.dol_print_date($link->datea, "dayhour", "tzuser").''; print ''; print ''; - print ''.img_edit().''; // id= is included into $param + print ''.img_edit().''; // id= is included into $param if ($permissiontodelete) { - print '   '.img_delete().''; // id= is included into $param + print '   '.img_delete().''; // id= is included into $param } else { print ' '; } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 1cd80af55ed..7dafb316a18 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1545,11 +1545,13 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess // Define $destfull (path to file including filename) and $destfile (only filename) $destfull = $upload_dir."/".$TFile['name'][$i]; $destfile = $TFile['name'][$i]; + $destfilewithoutext = preg_replace('/\.[^\.]+$/', '', $destfile); - if ($savingdocmask) + if ($savingdocmask && strpos($savingdocmask, $destfilewithoutext) !== 0) { $destfull = $upload_dir."/".preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); $destfile = preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); + } // dol_sanitizeFileName the file name and lowercase extension From f09321a4971e96eba8bcfe432d8ffb02bc2ac599 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Mar 2020 13:57:19 +0200 Subject: [PATCH 04/12] css --- htdocs/theme/eldy/btn.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index 4831bb40c4a..4e5cde2c4e2 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -7,7 +7,7 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> --btncolorbg: #fbfbfb; --btncolorborderhover: none; --btncolorborder: #FFF; - --butactionbg:rgb(225, 231, 225); + --butactionbg:rgb(225, 235, 225); --butactiondeletebg: rgb(234,228,225); } From 766f480741125d05b9e84a548fa4e026944645eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Mar 2020 16:24:33 +0200 Subject: [PATCH 05/12] css --- htdocs/theme/eldy/global.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index c9d58be7da3..35a9234cecc 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -175,7 +175,7 @@ input, select { margin-bottom:1px; margin-top:1px; } -#mainbody input.button:not(.buttongen) { +#mainbody input.button:not(.buttongen):not(.bordertransp) { background: var(--butactionbg); border-collapse: collapse; border: none; From b407797ca3d119fb70f361522006ad93741bebe3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Mar 2020 17:45:45 +0200 Subject: [PATCH 06/12] Fix css --- htdocs/bom/tpl/objectline_view.tpl.php | 4 ++-- htdocs/cashdesk/index.php | 2 +- htdocs/core/tpl/objectline_view.tpl.php | 4 ++-- htdocs/expedition/card.php | 2 +- htdocs/reception/card.php | 6 +++--- htdocs/theme/eldy/global.inc.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index ad2c2d3e4c6..1419136a2e8 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -113,7 +113,7 @@ if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines' ) $coldisplay++; if (($line->info_bits & 2) == 2 || ! empty($disableedit)) { } else { - print 'id.'#line_'.$line->id.'">'.img_edit().''; + print 'id.'#line_'.$line->id.'">'.img_edit().''; } print ''; @@ -121,7 +121,7 @@ if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines' ) $coldisplay++; if (($line->fk_prev_id == null) && empty($disableremove)) { //La suppression n'est autorisée que si il n'y a pas de ligne dans une précédente situation - print 'id.'">'; + print 'id.'">'; print img_delete(); print ''; } diff --git a/htdocs/cashdesk/index.php b/htdocs/cashdesk/index.php index fcfe9905bae..2d7d169395a 100644 --- a/htdocs/cashdesk/index.php +++ b/htdocs/cashdesk/index.php @@ -191,7 +191,7 @@ print "\n";
-
+
diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index ee1d85e3b54..d61810c5178 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -311,7 +311,7 @@ if ($this->statut == 0 && ($object_rights->creer) && $action != 'selectlines') { $coldisplay++; if (($line->info_bits & 2) == 2 || !empty($disableedit)) { } else { ?> - id.'#line_'.$line->id; ?>"> + id.'#line_'.$line->id; ?>"> '; } print ''; @@ -319,7 +319,7 @@ if ($this->statut == 0 && ($object_rights->creer) && $action != 'selectlines') { print ''; $coldisplay++; if (($line->fk_prev_id == null) && empty($disableremove)) { //La suppression n'est autorisée que si il n'y a pas de ligne dans une précédente situation - print 'id.'">'; + print 'id.'">'; print img_delete(); print ''; } diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 3c739f7dbd7..3632cbfd52e 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2436,7 +2436,7 @@ elseif ($id || $ref) { // edit-delete buttons print ''; - print 'id . '">' . img_edit() . ''; + print 'id . '">' . img_edit() . ''; print ''; print ''; print 'id . '">' . img_delete() . ''; diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 03dc37db114..0bc3839a23d 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1962,14 +1962,14 @@ elseif ($id || $ref) print '
'; print '
'; } - elseif ($object->statut == 0) + elseif ($object->statut == Reception::STATUS_DRAFT) { // edit-delete buttons print ''; - print 'id.'">'.img_edit().''; + print 'id.'">'.img_edit().''; print ''; print ''; - print 'id.'">'.img_delete().''; + print 'id.'">'.img_delete().''; print ''; // Display lines extrafields diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 35a9234cecc..b0644ad3ff1 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -405,7 +405,7 @@ div#moretabsList, div#moretabsListaction { hr { border: 0; border-top: 1px solid #ccc; } .tabBar hr { margin-top: 20px; margin-bottom: 17px; } -.button, .buttonDelete, input[name="sbmtConnexion"] { +.button:not(.bordertransp), .buttonDelete:not(.bordertransp) { margin-bottom: 0; margin-top: 0; margin-left: 5px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 8f03e70f460..7b3216e9cf5 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -530,7 +530,7 @@ div#moretabsList, div#moretabsListaction { hr { border: 0; border-top: 1px solid #ccc; } -.button, .buttonDelete, input[name="sbmtConnexion"] { +.button:not(.bordertransp), .buttonDelete:not(.bordertransp) { border-color: #c5c5c5; border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); display: inline-block; From 33d2b61c191ba94c691871cc502bb57c1a11c579 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Apr 2020 16:21:03 +0200 Subject: [PATCH 07/12] Work on extralanguages --- htdocs/core/class/commonobject.class.php | 159 ++++++++++++++++++++++- htdocs/core/class/html.form.class.php | 4 +- htdocs/societe/card.php | 13 +- htdocs/societe/class/societe.class.php | 9 ++ 4 files changed, 174 insertions(+), 11 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e3e072f34a8..7553594bb82 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5054,8 +5054,9 @@ abstract class CommonObject * This method is NOT called by method fetch of objects but must be called separately. * * @return int <0 if error, 0 if no values of alternative languages to find nor found, 1 if a value was found and loaded + * @see fetch_optionnals() */ - public function fetchValueForAlternateLanguages() + public function fetchValuesForExtraLanguages() { // To avoid SQL errors. Probably not the better solution though if (!$this->element) { @@ -5126,7 +5127,7 @@ abstract class CommonObject * @param string $onlykey Only the following key is filled. When we make update of only one language field ($action = 'update_languages'), calling page must set this to avoid to have other languages being reset. * @return int 1 if array_options set, 0 if no value, -1 if error (field required missing for example) */ - public function setValuesForAlternateLanguages($onlykey = '') + public function setValuesForExtraLanguages($onlykey = '') { global $_POST, $langs; @@ -5214,6 +5215,7 @@ abstract class CommonObject * @param int $rowid Id of line. Use the id of object if not defined. Deprecated. Function must be called without parameters. * @param array $optionsArray Array resulting of call of extrafields->fetch_name_optionals_label(). Deprecated. Function must be called without parameters. * @return int <0 if error, 0 if no values of extrafield to find nor found, 1 if an attribute is found and value loaded + * @see fetchValuesForExtraLanguages() */ public function fetch_optionals($rowid = null, $optionsArray = null) { @@ -5357,7 +5359,7 @@ abstract class CommonObject * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) * @param User $userused Object user * @return int -1=error, O=did nothing, 1=OK - * @see updateExtraField(), setValueFrom() + * @see insertExtraLanguages(), updateExtraField(), setValueFrom() */ public function insertExtraFields($trigger = '', $userused = null) { @@ -5635,6 +5637,130 @@ abstract class CommonObject else return 0; } + /** + * Add/Update all extra fields values for the current object. + * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) + * This function delete record with all extrafields and insert them again from the array $this->array_options. + * + * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) + * @param User $userused Object user + * @return int -1=error, O=did nothing, 1=OK + * @see insertExtraFields(), updateExtraField(), setValueFrom() + */ + public function insertExtraLanguages($trigger = '', $userused = null) + { + global $conf, $langs, $user; + + if (empty($userused)) $userused = $user; + + $error = 0; + + if (!empty($conf->global->MAIN_EXTRALANGUAGES_DISABLED)) return 0; // For avoid conflicts if trigger used + + if (is_array($this->array_languages)) + { + $new_array_languages = $this->array_languages; + + foreach ($new_array_languages as $key => $value) + { + $attributeKey = $key; + $attributeType = $this->fields[$attributeKey]['type']; + $attributeLabel = $this->fields[$attributeKey]['label']; + + //dol_syslog("attributeLabel=".$attributeLabel, LOG_DEBUG); + //dol_syslog("attributeType=".$attributeType, LOG_DEBUG); + + switch ($attributeType) + { + case 'int': + if (!is_numeric($value) && $value != '') + { + $this->errors[] = $langs->trans("ExtraLanguageHasWrongValue", $attributeLabel); + return -1; + } + elseif ($value == '') + { + $new_array_languages[$key] = null; + } + break; + case 'double': + $value = price2num($value); + if (!is_numeric($value) && $value != '') + { + dol_syslog($langs->trans("ExtraLanguageHasWrongValue")." sur ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); + $this->errors[] = $langs->trans("ExtraLanguageHasWrongValue", $attributeLabel); + return -1; + } + elseif ($value == '') + { + $new_array_languages[$key] = null; + } + //dol_syslog("double value"." sur ".$attributeLabel."(".$value." is '".$attributeType."')", LOG_DEBUG); + $new_array_languages[$key] = $value; + break; + /*case 'select': // Not required, we chosed value='0' for undefined values + if ($value=='-1') + { + $this->array_options[$key] = null; + } + break;*/ + } + } + + $this->db->begin(); + + $table_element = $this->table_element; + if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility + + dol_syslog(get_class($this)."::insertExtraLanguages delete then insert", LOG_DEBUG); + + foreach($new_array_languages as $key => $langcodearray) { // $key = 'name', 'town', ... + foreach($langcodearray as $langcode => $value) { + + $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."object_lang"; + $sql_del .= " WHERE fk_object = ".$this->id." AND property = '".$this->db->escape($key)."' AND type_object = '".$this->db->escape($table_element)."'"; + $sql_del .= " AND lang = '".$this->db->escape($langcode)."'"; + $this->db->query($sql_del); + + if ($value !== '') { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."object_lang (fk_object, property, type_object, lang, value"; + $sql .= ") VALUES (".$this->id.", '".$this->db->escape($key)."', '".$this->db->escape($table_element)."', '".$this->db->escape($langcode)."', '".$this->db->escape($value)."'"; + $sql .= ")"; + + $resql = $this->db->query($sql); + if (!$resql) + { + $this->error = $this->db->lasterror(); + $error++; + break; + } + } + } + } + + if (!$error && $trigger) + { + // Call trigger + $this->context = array('extralanguagesaddupdate'=>1); + $result = $this->call_trigger($trigger, $userused); + if ($result < 0) $error++; + // End call trigger + } + + if ($error) + { + $this->db->rollback(); + return -1; + } + else + { + $this->db->commit(); + return 1; + } + } + else return 0; + } + /** * Update an extra field value for the current object. * Data to describe values to update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) @@ -5643,7 +5769,7 @@ abstract class CommonObject * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) * @param User $userused Object user * @return int -1=error, O=did nothing, 1=OK - * @see setValueFrom(), insertExtraFields() + * @see updateExtraLanguages(), setValueFrom(), insertExtraFields() */ public function updateExtraField($key, $trigger = null, $userused = null) { @@ -5661,7 +5787,7 @@ abstract class CommonObject $langs->load('admin'); require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); - $target_extrafields = $extrafields->fetch_name_optionals_label($this->table_element); + $extrafields->fetch_name_optionals_label($this->table_element); $value = $this->array_options["options_".$key]; @@ -5765,6 +5891,29 @@ abstract class CommonObject else return 0; } + /** + * Update an extra language value for the current object. + * Data to describe values to update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) + * + * @param string $key Key of the extrafield (without starting 'options_') + * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) + * @param User $userused Object user + * @return int -1=error, O=did nothing, 1=OK + * @see updateExtraFields(), insertExtraLanguages() + */ + public function updateExtraLanguages($key, $trigger = null, $userused = null) + { + global $conf, $langs, $user; + + if (empty($userused)) $userused = $user; + + $error = 0; + + if (!empty($conf->global->MAIN_EXTRALANGUAGES_DISABLED)) return 0; // For avoid conflicts if trigger used + + return 0; + } + /** * Return HTML string to put an input field into a page diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9f8e02e4948..696d1a9aa7d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -345,12 +345,12 @@ class Form $valuetoshow = GETPOSTISSET('field-'.$object->element."-".$fieldname."-".$langcode) ? GETPOST('field-'.$object->element.'-'.$fieldname."-".$langcode, $check) : ''; if (empty($valuetoshow)) { - $object->fetchValueForAlternateLanguages(); + $object->fetchValuesForExtraLanguages(); //var_dump($object->array_languages); $valuetoshow = $object->array_languages[$fieldname][$langcode]; } - $s=picto_from_langcode($conf->global->PDF_USE_ALSO_LANGUAGE_CODE, 'class="pictoforlang"'); + $s=picto_from_langcode($conf->global->PDF_USE_ALSO_LANGUAGE_CODE, 'class="pictoforlang paddingright"'); $result .= $s; if ($typeofdata == 'textarea') { $result .= ''; + print ''; + print $form->widgetForTranslation("address", $object, $permissiontoadd, 'textarea', 'alphanohtml', 'quatrevingtpercent'); + print ''; // Zip / Town print ''.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).''; print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth50onsmartphone'); print ''.$form->editfieldkey('Town', 'town', '', $object, 0).''; print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); + print $form->widgetForTranslation("town", $object, $permissiontoadd, 'string', 'alphanohtml', 'maxwidth100 quatrevingtpercent'); print ''; // Country print ''.$form->editfieldkey('Country', 'selectcounty_id', '', $object, 0).''; - print $form->select_country((GETPOST('country_id') != '' ?GETPOST('country_id') : $object->country_id), 'country_id'); + print $form->select_country((GETPOSTISSET('country_id') ? GETPOST('country_id') : $object->country_id), 'country_id'); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index e6e9e42aa75..b6193d12b6e 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1403,6 +1403,15 @@ class Societe extends CommonObject $error++; } } + // Actions on extra languages + if (!$error && empty($conf->global->MAIN_EXTRALANGUAGES_DISABLED)) // For avoid conflicts if trigger used + { + $result = $this->insertExtraLanguages(); + if ($result < 0) + { + $error++; + } + } if (!$error && $call_trigger) { From 4727800206ffd169adaf9a80622ab46476b3d512 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Apr 2020 16:51:45 +0200 Subject: [PATCH 08/12] Can show technical ID of any object in banner. --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1b16f2a2ca5..2b1d2695ed4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1660,7 +1660,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi $morehtmlref .= ''; } } - if (!empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && in_array($object->element, array('societe', 'contact', 'member', 'product'))) + if (!empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && ($conf->global->MAIN_SHOW_TECHNICAL_ID == '1' || preg_match('/'.preg_quote($object->element, '/').'/i', $conf->global->MAIN_SHOW_TECHNICAL_ID)) && ! empty($object->id)) { $morehtmlref .= '
'; $morehtmlref .= $langs->trans("TechnicalID").': '.$object->id; From d2de6a22ebf126e9600b5d49fea87308295af242 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Apr 2020 18:11:28 +0200 Subject: [PATCH 09/12] WIP Can set values in extra languages --- htdocs/core/class/commonobject.class.php | 28 +++++++++++-- htdocs/core/class/html.form.class.php | 17 ++++++++ htdocs/core/lib/functions.lib.php | 53 +++++++++++++----------- htdocs/societe/card.php | 2 +- 4 files changed, 71 insertions(+), 29 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 7553594bb82..1d5ebbc4fa6 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -593,9 +593,10 @@ abstract class CommonObject * @param int $withcountry 1=Add country into address string * @param string $sep Separator to use to build string * @param int $withregion 1=Add region into address string + * @param string $extralangcode User extralanguages as value * @return string Full address string */ - public function getFullAddress($withcountry = 0, $sep = "\n", $withregion = 0) + public function getFullAddress($withcountry = 0, $sep = "\n", $withregion = 0, $extralangcode = '') { if ($withcountry && $this->country_id && (empty($this->country_code) || empty($this->country))) { @@ -615,7 +616,7 @@ abstract class CommonObject $this->region = $tmparray['region']; } - return dol_format_address($this, $withcountry, $sep); + return dol_format_address($this, $withcountry, $sep, '', 0, $extralangcode); } @@ -628,7 +629,7 @@ abstract class CommonObject */ public function getBannerAddress($htmlkey, $object) { - global $conf, $langs; + global $conf, $langs, $form; $countriesusingstate = array('AU', 'US', 'IN', 'GB', 'ES', 'UK', 'TR'); // See also option MAIN_FORCE_STATE_INTO_ADDRESS @@ -657,6 +658,7 @@ abstract class CommonObject { if (!empty($conf->use_javascript_ajax)) { + // Add picto with tooltip on map $namecoords = ''; if ($this->element == 'contact' && !empty($conf->global->MAIN_SHOW_COMPANY_NAME_IN_BANNER_ADDRESS)) { @@ -670,6 +672,26 @@ abstract class CommonObject } $out .= dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', '); $outdone++; $outdone++; + + $useextralanguages = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; + if ($useextralanguages) { + $this->fetchValuesForExtraLanguages(); + $extralanguages = array(); + if (isset($this->array_languages['address'])) $extralanguages[] = reset(array_keys($this->array_languages['address'])); + if (isset($this->array_languages['town'])) $extralanguages[] = reset(array_keys($this->array_languages['town'])); + + if (is_array($extralanguages) && count($extralanguages)) { + if (! is_object($form)) $form = new Form($this->db); + $htmltext = ''; + // If there is extra languages + foreach($extralanguages as $key => $extralangcode) { + $s=picto_from_langcode($extralangcode, 'class="pictoforlang paddingright"'); + $coords = $this->getFullAddress(1, ', ', $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT, $extralangcode); + $htmltext .= $s.dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', '); + } + $out .= $form->textwithpicto('', $htmltext, -1, 'language', 'opacitymedium paddingleft'); + } + } } if (!in_array($this->country_code, $countriesusingstate) && empty($conf->global->MAIN_FORCE_STATE_INTO_ADDRESS) // If MAIN_FORCE_STATE_INTO_ADDRESS is on, state is already returned previously with getFullAddress diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 696d1a9aa7d..7404b3c6945 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7359,6 +7359,23 @@ class Form if ($object->element == 'societe') { $ret .= dol_htmlentities($object->name); + + $useextralanguages = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; + if ($useextralanguages) { + $object->fetchValuesForExtraLanguages(); + $extralanguages = array(); + if (isset($object->array_languages['name'])) $extralanguages[] = reset(array_keys($object->array_languages['name'])); + + if (is_array($extralanguages) && count($extralanguages)) { + $htmltext = ''; + // If there is extra languages + foreach($extralanguages as $extralangcode) { + $s=picto_from_langcode($extralangcode, 'class="pictoforlang paddingright"'); + $htmltext .= $s.$object->array_languages['name'][$extralangcode]; + } + $ret .= $this->textwithpicto('', $htmltext, -1, 'language', 'opacitymedium paddingleft'); + } + } } elseif ($object->element == 'member') { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 2b1d2695ed4..751e3ebb0a6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1646,12 +1646,12 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi if (!empty($object->name_alias)) $morehtmlref .= '
'.$object->name_alias.'
'; // Add label - if ($object->element == 'product' || $object->element == 'bank_account' || $object->element == 'project_task') + if (in_array($object->element, array('product', 'bank_account', 'project_task'))) { if (!empty($object->label)) $morehtmlref .= '
'.$object->label.'
'; } - if (method_exists($object, 'getBannerAddress') && $object->element != 'product' && $object->element != 'bookmark' && $object->element != 'ecm_directories' && $object->element != 'ecm_files') + if (method_exists($object, 'getBannerAddress') && !in_array($object->element, array('product', 'bookmark', 'ecm_directories', 'ecm_files'))) { $moreaddress = $object->getBannerAddress('refaddress', $object); if ($moreaddress) { @@ -1718,10 +1718,11 @@ function dol_bc($var, $moreclass = '') * @param string $sep Separator to use to build string * @param Translate $outputlangs Object lang that contains language for text translation. * @param int $mode 0=Standard output, 1=Remove address + * @param string $extralangcode User extralanguage $langcode as values for address, town * @return string Formated string * @see dol_print_address() */ -function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs = '', $mode = 0) +function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs = '', $mode = 0, $extralangcode = '') { global $conf, $langs; @@ -1729,15 +1730,15 @@ function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs $countriesusingstate = array('AU', 'CA', 'US', 'IN', 'GB', 'ES', 'UK', 'TR'); // See also MAIN_FORCE_STATE_INTO_ADDRESS // See format of addresses on https://en.wikipedia.org/wiki/Address - // Address if (empty($mode)) { - $ret .= $object->address; + $ret .= ($extralangcode ? $object->array_languages['address'][$extralangcode] : $object->address); } // Zip/Town/State if (in_array($object->country_code, array('AU', 'CA', 'US')) || !empty($conf->global->MAIN_FORCE_STATE_INTO_ADDRESS)) // US: title firstname name \n address lines \n town, state, zip \n country { - $ret .= ($ret ? $sep : '').$object->town; + $town = ($extralangcode ? $object->array_languages['town'][$extralangcode] : $object->town); + $ret .= ($ret ? $sep : '').$town; if ($object->state) { $ret .= ($ret ? ", " : '').$object->state; @@ -1746,7 +1747,8 @@ function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs } elseif (in_array($object->country_code, array('GB', 'UK'))) // UK: title firstname name \n address lines \n town state \n zip \n country { - $ret .= ($ret ? $sep : '').$object->town; + $town = ($extralangcode ? $object->array_languages['town'][$extralangcode] : $object->town); + $ret .= ($ret ? $sep : '').$town; if ($object->state) { $ret .= ($ret ? ", " : '').$object->state; @@ -1756,7 +1758,8 @@ function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs elseif (in_array($object->country_code, array('ES', 'TR'))) // ES: title firstname name \n address lines \n zip town \n state \n country { $ret .= ($ret ? $sep : '').$object->zip; - $ret .= ($object->town ? (($object->zip ? ' ' : '').$object->town) : ''); + $town = ($extralangcode ? $object->array_languages['town'][$extralangcode] : $object->town); + $ret .= ($town ? (($object->zip ? ' ' : '').$town) : ''); if ($object->state) { $ret .= "\n".$object->state; @@ -1765,13 +1768,15 @@ function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs elseif (in_array($object->country_code, array('IT'))) // IT: tile firstname name\n address lines \n zip (Code Departement) \n country { $ret .= ($ret ? $sep : '').$object->zip; - $ret .= ($object->town ? (($object->zip ? ' ' : '').$object->town) : ''); + $town = ($extralangcode ? $object->array_languages['town'][$extralangcode] : $object->town); + $ret .= ($town ? (($object->zip ? ' ' : '').$town) : ''); $ret .= ($object->state_code ? (' '.($object->state_code)) : ''); } else // Other: title firstname name \n address lines \n zip town \n country { + $town = ($extralangcode ? $object->array_languages['town'][$extralangcode] : $object->town); $ret .= $object->zip ? (($ret ? $sep : '').$object->zip) : ''; - $ret .= ($object->town ? (($object->zip ? ' ' : ($ret ? $sep : '')).$object->town) : ''); + $ret .= ($town ? (($object->zip ? ' ' : ($ret ? $sep : '')).$town) : ''); if ($object->state && in_array($object->country_code, $countriesusingstate)) { $ret .= ($ret ? ", " : '').$object->state; @@ -2853,16 +2858,16 @@ function dol_user_country() /** * Format address string * - * @param string $address Address + * @param string $address Address string, already formatted with dol_format_address() * @param int $htmlid Html ID (for example 'gmap') - * @param int $mode thirdparty|contact|member|other + * @param int $element 'thirdparty'|'contact'|'member'|'other' * @param int $id Id of object * @param int $noprint No output. Result is the function return * @param string $charfornl Char to use instead of nl2br. '' means we use a standad nl2br. * @return string|void Nothing if noprint is 0, formatted address if noprint is 1 * @see dol_format_address() */ -function dol_print_address($address, $htmlid, $mode, $id, $noprint = 0, $charfornl = '') +function dol_print_address($address, $htmlid, $element, $id, $noprint = 0, $charfornl = '') { global $conf, $user, $langs, $hookmanager; @@ -2871,7 +2876,7 @@ function dol_print_address($address, $htmlid, $mode, $id, $noprint = 0, $charfor if ($address) { if ($hookmanager) { - $parameters = array('element' => $mode, 'id' => $id); + $parameters = array('element' => $element, 'id' => $id); $reshook = $hookmanager->executeHooks('printAddress', $parameters, $address); $out .= $hookmanager->resPrint; } @@ -2880,24 +2885,22 @@ function dol_print_address($address, $htmlid, $mode, $id, $noprint = 0, $charfor if (empty($charfornl)) $out .= nl2br($address); else $out .= preg_replace('/[\r\n]+/', $charfornl, $address); + // TODO Remove this block, we can add this using the hook now $showgmap = $showomap = 0; - - // TODO Add a hook here - if (($mode == 'thirdparty' || $mode == 'societe') && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS)) $showgmap = 1; - if ($mode == 'contact' && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS_CONTACTS)) $showgmap = 1; - if ($mode == 'member' && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS_MEMBERS)) $showgmap = 1; - if (($mode == 'thirdparty' || $mode == 'societe') && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS)) $showomap = 1; - if ($mode == 'contact' && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_CONTACTS)) $showomap = 1; - if ($mode == 'member' && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_MEMBERS)) $showomap = 1; - + if (($element == 'thirdparty' || $element == 'societe') && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS)) $showgmap = 1; + if ($element == 'contact' && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS_CONTACTS)) $showgmap = 1; + if ($element == 'member' && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS_MEMBERS)) $showgmap = 1; + if (($element == 'thirdparty' || $element == 'societe') && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS)) $showomap = 1; + if ($element == 'contact' && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_CONTACTS)) $showomap = 1; + if ($element == 'member' && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_MEMBERS)) $showomap = 1; if ($showgmap) { - $url = dol_buildpath('/google/gmaps.php?mode='.$mode.'&id='.$id, 1); + $url = dol_buildpath('/google/gmaps.php?mode='.$element.'&id='.$id, 1); $out .= ' '; } if ($showomap) { - $url = dol_buildpath('/openstreetmap/maps.php?mode='.$mode.'&id='.$id, 1); + $url = dol_buildpath('/openstreetmap/maps.php?mode='.$element.'&id='.$id, 1); $out .= ' '; } } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index be97aff6377..0186d3d9807 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -931,7 +931,7 @@ else * Creation */ $private = GETPOST("private", "int"); - if (!empty($conf->global->THIRDPARTY_DEFAULT_CREATE_CONTACT) && !isset($_GET['private']) && !isset($_POST['private'])) $private = 1; + if (!empty($conf->global->THIRDPARTY_DEFAULT_CREATE_CONTACT) && ! GETPOSTISSET('private')) $private = 1; if (empty($private)) $private = 0; // Load object modCodeTiers From 184d50171dc9bcaab3254527e8723613d5f31226 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Apr 2020 22:01:05 +0200 Subject: [PATCH 10/12] Update example for clamav - prefer clamav daemon --- htdocs/langs/en_US/admin.lang | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 51ff5f4e2f7..738f07a2c0a 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -98,10 +98,10 @@ MustBeLowerThanPHPLimit=Note: your PHP configuration currently limits the NoMaxSizeByPHPLimit=Note: No limit is set in your PHP configuration MaxSizeForUploadedFiles=Maximum size for uploaded files (0 to disallow any upload) UseCaptchaCode=Use graphical code (CAPTCHA) on login page -AntiVirusCommand= Full path to antivirus command -AntiVirusCommandExample= Example for ClamWin: c:\\Progra~1\\ClamWin\\bin\\clamscan.exe
Example for ClamAv: /usr/bin/clamscan +AntiVirusCommand=Full path to antivirus command +AntiVirusCommandExample=Example for ClamAv Daemon (require clamav-daemon): /usr/bin/clamdscan
Example for ClamWin (very very slow): c:\\Progra~1\\ClamWin\\bin\\clamscan.exe AntiVirusParam= More parameters on command line -AntiVirusParamExample= Example for ClamWin: --database="C:\\Program Files (x86)\\ClamWin\\lib" +AntiVirusParamExample=Example for ClamAv Daemon: --fdpass
Example for ClamWin: --database="C:\\Program Files (x86)\\ClamWin\\lib" ComptaSetup=Accounting module setup UserSetup=User management setup MultiCurrencySetup=Multi-currency setup From 6aea67a5b96fca933027b33fde892efda9a3c64a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Apr 2020 23:15:53 +0200 Subject: [PATCH 11/12] Work on extralanguages --- htdocs/core/class/commonobject.class.php | 24 +- htdocs/core/class/extrafields.class.php | 26 +- htdocs/core/class/extralanguages.class.php | 1333 ++++++++++++++++++++ htdocs/core/class/html.form.class.php | 76 +- 4 files changed, 1400 insertions(+), 59 deletions(-) create mode 100644 htdocs/core/class/extralanguages.class.php diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 1d5ebbc4fa6..bc1fd5e75b7 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -629,7 +629,7 @@ abstract class CommonObject */ public function getBannerAddress($htmlkey, $object) { - global $conf, $langs, $form; + global $conf, $langs, $form, $extralanguages; $countriesusingstate = array('AU', 'US', 'IN', 'GB', 'ES', 'UK', 'TR'); // See also option MAIN_FORCE_STATE_INTO_ADDRESS @@ -673,18 +673,24 @@ abstract class CommonObject $out .= dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', '); $outdone++; $outdone++; - $useextralanguages = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; - if ($useextralanguages) { - $this->fetchValuesForExtraLanguages(); - $extralanguages = array(); - if (isset($this->array_languages['address'])) $extralanguages[] = reset(array_keys($this->array_languages['address'])); - if (isset($this->array_languages['town'])) $extralanguages[] = reset(array_keys($this->array_languages['town'])); + // List of extra languages + $arrayoflangcode = array(); + if (! empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE)) $arrayoflangcode[] = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; - if (is_array($extralanguages) && count($extralanguages)) { + if (is_array($arrayoflangcode) && count($arrayoflangcode)) { + if (! is_object($extralanguages)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/extralanguages.class.php'; + $extralanguages = new ExtraLanguages($this->db); + } + $extralanguages->fetch_name_extralanguages('societe'); + + if (! empty($extralanguages->attributes['societe']['address']) || ! empty($extralanguages->attributes['societe']['town'])) + { + $this->fetchValuesForExtraLanguages(); if (! is_object($form)) $form = new Form($this->db); $htmltext = ''; // If there is extra languages - foreach($extralanguages as $key => $extralangcode) { + foreach($arrayoflangcode as $extralangcode) { $s=picto_from_langcode($extralangcode, 'class="pictoforlang paddingright"'); $coords = $this->getFullAddress(1, ', ', $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT, $extralangcode); $htmltext .= $s.dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', '); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 7a9373d59db..f044943272b 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -842,7 +842,7 @@ class ExtraFields /** * Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ... * - * @param string $elementtype Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). + * @param string $elementtype Type of element ('' = all, 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). * @param boolean $forceload Force load of extra fields whatever is status of cache. * @return array Array of attributes keys+label for all extra fields. */ @@ -859,30 +859,6 @@ class ExtraFields $array_name_label = array(); - // To avoid conflicts with external modules. TODO Remove this. - if (empty($forceload) && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label; - - // If already loaded - // TODO Enable this cache test - // if (empty($forceload) && ! empty($this->attributes[$tab->elementtype]['loaded'])) return $array_name_label; - - // Set array of label of entity - // Remove completely loading of label. This should be done by presentation. - /* - $labelmulticompany=array(); - if (!empty($conf->multicompany->enabled)) - { - $sql_entity_name='SELECT rowid, label FROM '.MAIN_DB_PREFIX.'entity WHERE rowid in (0,'.$conf->entity.')'; - $resql_entity_name=$this->db->query($sql_entity_name); - if ($resql_entity_name) - { - while ($obj = $this->db->fetch_object($resql_entity_name)) - { - $labelmulticompany[$obj->rowid]=$obj->label; - } - } - }*/ - // We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,printable,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; $sql .= " FROM ".MAIN_DB_PREFIX."extrafields"; diff --git a/htdocs/core/class/extralanguages.class.php b/htdocs/core/class/extralanguages.class.php new file mode 100644 index 00000000000..768169cd3eb --- /dev/null +++ b/htdocs/core/class/extralanguages.class.php @@ -0,0 +1,1333 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/extralanguages.class.php + * \ingroup core + * \brief File of class to manage extra fields + */ + + +/** + * Class to manage standard extra languages + */ +class ExtraLanguages +{ + /** + * @var DoliDB Database handler. + */ + public $db; + + /** + * @var array New array to store extralanguages definition + */ + public $attributes; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string[] Array of Error code (or message) + */ + public $errors = array(); + + /** + * @var string DB Error number + */ + public $errno; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + $this->db = $db; + $this->error = ''; + $this->errors = array(); + $this->attributes = array(); + } + + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Load array this->attributes + * + * @param string $elementtype Type of element ('' = all, 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). + * @param boolean $forceload Force load of extra fields whatever is status of cache. + * @return array Array of attributes keys+label for all extra fields. + */ + public function fetch_name_extralanguages($elementtype, $forceload = false) + { + // phpcs:enable + global $conf; + + if (empty($elementtype)) return array(); + + if ($elementtype == 'thirdparty') $elementtype = 'societe'; + if ($elementtype == 'contact') $elementtype = 'socpeople'; + if ($elementtype == 'order_supplier') $elementtype = 'commande_fournisseur'; + + $array_name_label = array( + 'societe' => array('name'=>'Name'), + 'contact' => array('firstname' => 'Firstname', 'lastname' => 'Lastname') + ); + + $this->attributes = $array_name_label; + + return $array_name_label; + } + + + /** + * Return HTML string to put an input field into a page + * Code very similar with showInputField of common object + * + * @param string $key Key of attribute + * @param string $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value) + * @param string $moreparam To add more parametes on html input tag + * @param string $keysuffix Prefix string to add after name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Suffix string to add before name and id of field (can be used to avoid duplicate names) + * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) + * @param int $objectid Current object id + * @param string $extrafieldsobjectkey If defined (for example $object->table_element), use the new method to get extrafields data + * @param string $mode 1=Used for search filters + * @return string + */ + public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $objectid = 0, $extrafieldsobjectkey = '', $mode = 0) + { + global $conf, $langs, $form; + + if (!is_object($form)) + { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $form = new Form($this->db); + } + + $out = ''; + + if (!preg_match('/options_$/', $keyprefix)) // Because we work on extrafields, we add 'options_' to prefix if not already added + { + $keyprefix = $keyprefix.'options_'; + } + + if (!empty($extrafieldsobjectkey)) + { + $label = $this->attributes[$extrafieldsobjectkey]['label'][$key]; + $type = $this->attributes[$extrafieldsobjectkey]['type'][$key]; + $size = $this->attributes[$extrafieldsobjectkey]['size'][$key]; + $default = $this->attributes[$extrafieldsobjectkey]['default'][$key]; + $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key]; + $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key]; + $required = $this->attributes[$extrafieldsobjectkey]['required'][$key]; + $param = $this->attributes[$extrafieldsobjectkey]['param'][$key]; + $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1); + $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key]; + $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1); + $totalizable = $this->attributes[$extrafieldsobjectkey]['totalizable'][$key]; + $help = $this->attributes[$extrafieldsobjectkey]['help'][$key]; + $hidden = (empty($list) ? 1 : 0); // If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) + } + else // Old usage + { + $label = $this->attribute_label[$key]; + $type = $this->attribute_type[$key]; + $size = $this->attribute_size[$key]; + $elementtype = $this->attribute_elementtype[$key]; // Seems not used + $default = $this->attribute_default[$key]; + $computed = $this->attribute_computed[$key]; + $unique = $this->attribute_unique[$key]; + $required = $this->attribute_required[$key]; + $param = $this->attribute_param[$key]; + $langfile = $this->attribute_langfile[$key]; + $list = $this->attribute_list[$key]; + $totalizable = $this->attribute_totalizable[$key]; + $hidden = (empty($list) ? 1 : 0); // If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) + } + + if ($computed) + { + if (!preg_match('/^search_/', $keyprefix)) return ''.$langs->trans("AutomaticallyCalculated").''; + else return ''; + } + + if (empty($morecss)) + { + if ($type == 'date') + { + $morecss = 'minwidth100imp'; + } + elseif ($type == 'datetime' || $type == 'link') + { + $morecss = 'minwidth200imp'; + } + elseif (in_array($type, array('int', 'integer', 'double', 'price'))) + { + $morecss = 'maxwidth75'; + } + elseif ($type == 'password') + { + $morecss = 'maxwidth100'; + } + elseif ($type == 'url') + { + $morecss = 'minwidth400'; + } + elseif ($type == 'boolean') + { + $morecss = ''; + } + else + { + if (round($size) < 12) + { + $morecss = 'minwidth100'; + } + elseif (round($size) <= 48) + { + $morecss = 'minwidth200'; + } + else + { + $morecss = 'minwidth400'; + } + } + } + + if (in_array($type, array('date', 'datetime'))) + { + $tmp = explode(',', $size); + $newsize = $tmp[0]; + + $showtime = in_array($type, array('datetime')) ? 1 : 0; + + // Do not show current date when field not required (see selectDate() method) + if (!$required && $value == '') $value = '-1'; + + // TODO Must also support $moreparam + $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1); + } + elseif (in_array($type, array('int', 'integer'))) + { + $tmp = explode(',', $size); + $newsize = $tmp[0]; + $out = ''; + } + elseif (preg_match('/varchar/', $type)) + { + $out = ''; + } + elseif (in_array($type, array('mail', 'phone', 'url'))) + { + $out = ''; + } + elseif ($type == 'text') + { + if (!preg_match('/search_/', $keyprefix)) // If keyprefix is search_ or search_options_, we must just use a simple text field + { + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, false, ROWS_5, '90%'); + $out = $doleditor->Create(1); + } + else + { + $out = ''; + } + } + elseif ($type == 'html') + { + if (!preg_match('/search_/', $keyprefix)) // If keyprefix is search_ or search_options_, we must just use a simple text field + { + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, !empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, '90%'); + $out = $doleditor->Create(1); + } + else + { + $out = ''; + } + } + elseif ($type == 'boolean') + { + if (empty($mode)) + { + $checked = ''; + if (!empty($value)) { + $checked = ' checked value="1" '; + } else { + $checked = ' value="1" '; + } + $out = ''; + } + else + { + $out .= $form->selectyesno($keyprefix.$key.$keysuffix, $value, 1, false, 1); + } + } + elseif ($type == 'price') + { + if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format. + $value = price($value); + } + $out = ' '.$langs->getCurrencySymbol($conf->currency); + } + elseif ($type == 'double') + { + if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format. + $value = price($value); + } + $out = ' '; + } + elseif ($type == 'select') + { + $out = ''; + if (!empty($conf->use_javascript_ajax) && !empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2)) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + $out .= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0); + } + + $out .= ''; + } + elseif ($type == 'sellist') + { + $out = ''; + if (!empty($conf->use_javascript_ajax) && !empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2)) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + $out .= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0); + } + + $out .= ''; + } + elseif ($type == 'checkbox') + { + $value_arr = explode(',', $value); + $out = $form->multiselectarray($keyprefix.$key.$keysuffix, (empty($param['options']) ?null:$param['options']), $value_arr, '', 0, '', 0, '100%'); + } + elseif ($type == 'radio') + { + $out = ''; + foreach ($param['options'] as $keyopt => $val) + { + $out .= ''.$val.'
'; + } + } + elseif ($type == 'chkbxlst') + { + if (is_array($value)) { + $value_arr = $value; + } + else { + $value_arr = explode(',', $value); + } + + if (is_array($param['options'])) { + $param_list = array_keys($param['options']); + $InfoFieldList = explode(":", $param_list[0]); + $parentName = ''; + $parentField = ''; + // 0 : tableName + // 1 : label field name + // 2 : key fields name (if differ of rowid) + // 3 : key field parent (for dependent lists) + // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value + // 5 : id category type + // 6 : ids categories list separated by comma for category root + $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid'); + + if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { + list ($parentName, $parentField) = explode('|', $InfoFieldList[3]); + $keyList .= ', '.$parentField; + } + if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) { + if (strpos($InfoFieldList[4], 'extra.') !== false) { + $keyList = 'main.'.$InfoFieldList[2].' as rowid'; + } else { + $keyList = $InfoFieldList[2].' as rowid'; + } + } + + $filter_categorie = false; + if (count($InfoFieldList) > 5) { + if ($InfoFieldList[0] == 'categorie') { + $filter_categorie = true; + } + } + + if ($filter_categorie === false) { + $fields_label = explode('|', $InfoFieldList[1]); + if (is_array($fields_label)) { + $keyList .= ', '; + $keyList .= implode(', ', $fields_label); + } + + $sqlwhere = ''; + $sql = 'SELECT '.$keyList; + $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0]; + if (!empty($InfoFieldList[4])) { + // can use SELECT request + if (strpos($InfoFieldList[4], '$SEL$') !== false) { + $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]); + } + + // current object id can be use into filter + if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) { + $InfoFieldList[4] = str_replace('$ID$', $objectid, $InfoFieldList[4]); + } elseif (preg_match("#^.*list.php$#", $_SERVER["PHP_SELF"])) { + // Pattern for word=$ID$ + $word = '\b[a-zA-Z0-9-\.-_]+\b=\$ID\$'; + + // Removing space arount =, ( and ) + $InfoFieldList[4] = preg_replace('# *(=|\(|\)) *#', '$1', $InfoFieldList[4]); + + $nbPreg = 1; + // While we have parenthesis + while ($nbPreg != 0) { + // Init des compteurs + $nbPregRepl = $nbPregSel = 0; + // On retire toutes les parenthèses sans = avant + $InfoFieldList[4] = preg_replace('#([^=])(\([^)^(]*('.$word.')[^)^(]*\))#', '$1 $3 ', $InfoFieldList[4], -1, $nbPregRepl); + // On retire les espaces autour des = et parenthèses + $InfoFieldList[4] = preg_replace('# *(=|\(|\)) *#', '$1', $InfoFieldList[4]); + // On retire toutes les parenthèses avec = avant + $InfoFieldList[4] = preg_replace('#\b[a-zA-Z0-9-\.-_]+\b=\([^)^(]*('.$word.')[^)^(]*\)#', '$1 ', $InfoFieldList[4], -1, $nbPregSel); + // On retire les espaces autour des = et parenthèses + $InfoFieldList[4] = preg_replace('# *(=|\(|\)) *#', '$1', $InfoFieldList[4]); + + // Calcul du compteur général pour la boucle + $nbPreg = $nbPregRepl + $nbPregSel; + } + + // Si l'on a un AND ou un OR, avant ou après + preg_match('#(AND|OR|) *('.$word.') *(AND|OR|)#', $InfoFieldList[4], $matchCondition); + while (!empty($matchCondition[0])) { + // If the two sides differ but are not empty + if (!empty($matchCondition[1]) && !empty($matchCondition[3]) && $matchCondition[1] != $matchCondition[3]) { + // Nobody sain would do that without parentheses + $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]); + } else { + if (!empty($matchCondition[1])) { + $boolCond = (($matchCondition[1] == "AND") ? ' AND TRUE ' : ' OR FALSE '); + $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond.$matchCondition[3], $InfoFieldList[4]); + } elseif (!empty($matchCondition[3])) { + $boolCond = (($matchCondition[3] == "AND") ? ' TRUE AND ' : ' FALSE OR'); + $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond, $InfoFieldList[4]); + } else { + $InfoFieldList[4] = " TRUE "; + } + } + + // Si l'on a un AND ou un OR, avant ou après + preg_match('#(AND|OR|) *('.$word.') *(AND|OR|)#', $InfoFieldList[4], $matchCondition); + } + } else { + $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]); + } + + // We have to join on extrafield table + if (strpos($InfoFieldList[4], 'extra.') !== false) { + $sql .= ' as main, '.MAIN_DB_PREFIX.$InfoFieldList[0].'_extrafields as extra'; + $sqlwhere .= ' WHERE extra.fk_object=main.'.$InfoFieldList[2].' AND '.$InfoFieldList[4]; + } else { + $sqlwhere .= ' WHERE '.$InfoFieldList[4]; + } + } else { + $sqlwhere .= ' WHERE 1=1'; + } + // Some tables may have field, some other not. For the moment we disable it. + if (in_array($InfoFieldList[0], array('tablewithentity'))) { + $sqlwhere .= ' AND entity = '.$conf->entity; + } + // $sql.=preg_replace('/^ AND /','',$sqlwhere); + // print $sql; + + $sql .= $sqlwhere; + dol_syslog(get_class($this).'::showInputField type=chkbxlst', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + + $data = array(); + + while ($i < $num) { + $labeltoshow = ''; + $obj = $this->db->fetch_object($resql); + + $notrans = false; + // Several field into label (eq table:code|libelle:rowid) + $fields_label = explode('|', $InfoFieldList[1]); + if (is_array($fields_label)) { + $notrans = true; + foreach ($fields_label as $field_toshow) { + $labeltoshow .= $obj->$field_toshow.' '; + } + } else { + $labeltoshow = $obj->{$InfoFieldList[1]}; + } + $labeltoshow = dol_trunc($labeltoshow, 45); + + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { + foreach ($fields_label as $field_toshow) { + $translabel = $langs->trans($obj->$field_toshow); + if ($translabel != $obj->$field_toshow) { + $labeltoshow = dol_trunc($translabel, 18).' '; + } else { + $labeltoshow = dol_trunc($obj->$field_toshow, 18).' '; + } + } + + $data[$obj->rowid] = $labeltoshow; + } else { + if (!$notrans) { + $translabel = $langs->trans($obj->{$InfoFieldList[1]}); + if ($translabel != $obj->{$InfoFieldList[1]}) { + $labeltoshow = dol_trunc($translabel, 18); + } else { + $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18); + } + } + if (empty($labeltoshow)) + $labeltoshow = '(not defined)'; + + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { + $data[$obj->rowid] = $labeltoshow; + } + + if (!empty($InfoFieldList[3]) && $parentField) { + $parent = $parentName.':'.$obj->{$parentField}; + } + + $data[$obj->rowid] = $labeltoshow; + } + + $i++; + } + $this->db->free($resql); + + $out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%'); + } else { + print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.
'; + } + } else { + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1); + $out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%'); + } + } + } + elseif ($type == 'link') + { + $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath' + $showempty=(($required && $default != '')?0:1); + $out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss); + } + elseif ($type == 'password') + { + // If prefix is 'search_', field is used as a filter, we use a common text field. + $out=''; // Hidden field to reduce impact of evil Google Chrome autopopulate bug. + $out.=''; + } + if (!empty($hidden)) { + $out=''; + } + /* Add comments + if ($type == 'date') $out.=' (YYYY-MM-DD)'; + elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; + */ + /*if (! empty($help) && $keyprefix != 'search_options_') { + $out .= $form->textwithpicto('', $help, 1, 'help', '', 0, 3); + }*/ + return $out; + } + + + /** + * Return HTML string to put an output field into a page + * + * @param string $key Key of attribute + * @param string $value Value to show + * @param string $moreparam To add more parameters on html input tag (only checkbox use html input for output rendering) + * @param string $extrafieldsobjectkey If defined (for example $object->table_element), function uses the new method to get extrafields data + * @return string Formated value + */ + public function showOutputField($key, $value, $moreparam = '', $extrafieldsobjectkey = '') + { + global $conf, $langs; + + if (!empty($extrafieldsobjectkey)) + { + $label = $this->attributes[$extrafieldsobjectkey]['label'][$key]; + $type = $this->attributes[$extrafieldsobjectkey]['type'][$key]; + $size = $this->attributes[$extrafieldsobjectkey]['size'][$key]; + $default = $this->attributes[$extrafieldsobjectkey]['default'][$key]; + $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key]; + $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key]; + $required = $this->attributes[$extrafieldsobjectkey]['required'][$key]; + $param = $this->attributes[$extrafieldsobjectkey]['param'][$key]; + $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1); + $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key]; + $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1); + $help = $this->attributes[$extrafieldsobjectkey]['help'][$key]; + $hidden = (empty($list) ? 1 : 0); // If $list empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) + } + else // Old usage + { + //dol_syslog("Warning: parameter 'extrafieldsobjectkey' is missing", LOG_WARNING); + $label = $this->attribute_label[$key]; + $type = $this->attribute_type[$key]; + $size = $this->attribute_size[$key]; + $default = $this->attribute_default[$key]; + $computed = $this->attribute_computed[$key]; + $unique = $this->attribute_unique[$key]; + $required = $this->attribute_required[$key]; + $param = $this->attribute_param[$key]; + $perms = dol_eval($this->attribute_perms[$key], 1); + $langfile = $this->attribute_langfile[$key]; + $list = dol_eval($this->attribute_list[$key], 1); + $help = ''; // Not supported with old syntax + $hidden = (empty($list) ? 1 : 0); // If $list empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) + } + + if ($hidden) return ''; // This is a protection. If field is hidden, we should just not call this method. + + //if ($computed) $value = // $value is already calculated into $value before calling this method + + $showsize = 0; + if ($type == 'date') + { + $showsize = 10; + $value = dol_print_date($value, 'day'); + } + elseif ($type == 'datetime') + { + $showsize = 19; + $value = dol_print_date($value, 'dayhour'); + } + elseif ($type == 'int') + { + $showsize = 10; + } + elseif ($type == 'double') + { + if (!empty($value)) { + //$value=price($value); + $sizeparts = explode(",", $size); + $number_decimals = $sizeparts[1]; + $value = price($value, 0, $langs, 0, 0, $number_decimals, ''); + } + } + elseif ($type == 'boolean') + { + $checked = ''; + if (!empty($value)) { + $checked = ' checked '; + } + $value = ''; + } + elseif ($type == 'mail') + { + $value = dol_print_email($value, 0, 0, 0, 64, 1, 1); + } + elseif ($type == 'url') + { + $value = dol_print_url($value, '_blank', 32, 1); + } + elseif ($type == 'phone') + { + $value = dol_print_phone($value, '', 0, 0, '', ' ', 'phone'); + } + elseif ($type == 'price') + { + $value = price($value, 0, $langs, 0, 0, -1, $conf->currency); + } + elseif ($type == 'select') + { + if ($langfile && $param['options'][$value]) $value = $langs->trans($param['options'][$value]); + else $value = $param['options'][$value]; + } + elseif ($type == 'sellist') + { + $param_list = array_keys($param['options']); + $InfoFieldList = explode(":", $param_list[0]); + + $selectkey = "rowid"; + $keyList = 'rowid'; + + if (count($InfoFieldList) >= 3) + { + $selectkey = $InfoFieldList[2]; + $keyList = $InfoFieldList[2].' as rowid'; + } + + $fields_label = explode('|', $InfoFieldList[1]); + if (is_array($fields_label)) { + $keyList .= ', '; + $keyList .= implode(', ', $fields_label); + } + + $sql = 'SELECT '.$keyList; + $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0]; + if (strpos($InfoFieldList[4], 'extra') !== false) + { + $sql .= ' as main'; + } + if ($selectkey == 'rowid' && empty($value)) { + $sql .= " WHERE ".$selectkey."=0"; + } elseif ($selectkey == 'rowid') { + $sql .= " WHERE ".$selectkey."=".$this->db->escape($value); + } else { + $sql .= " WHERE ".$selectkey."='".$this->db->escape($value)."'"; + } + + //$sql.= ' AND entity = '.$conf->entity; + + dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $value = ''; // value was used, so now we reste it to use it to build final output + + $obj = $this->db->fetch_object($resql); + + // Several field into label (eq table:code|libelle:rowid) + $fields_label = explode('|', $InfoFieldList[1]); + + if (is_array($fields_label) && count($fields_label) > 1) + { + foreach ($fields_label as $field_toshow) + { + $translabel = ''; + if (!empty($obj->$field_toshow)) { + $translabel = $langs->trans($obj->$field_toshow); + } + if ($translabel != $field_toshow) { + $value .= dol_trunc($translabel, 18).' '; + } else { + $value .= $obj->$field_toshow.' '; + } + } + } + else + { + $translabel = ''; + if (!empty($obj->{$InfoFieldList[1]})) { + $translabel = $langs->trans($obj->{$InfoFieldList[1]}); + } + if ($translabel != $obj->{$InfoFieldList[1]}) { + $value = dol_trunc($translabel, 18); + } else { + $value = $obj->{$InfoFieldList[1]}; + } + } + } + else dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING); + } + elseif ($type == 'radio') + { + $value = $param['options'][$value]; + } + elseif ($type == 'checkbox') + { + $value_arr = explode(',', $value); + $value = ''; + $toprint = array(); + if (is_array($value_arr)) + { + foreach ($value_arr as $keyval=>$valueval) { + $toprint[] = '
  • '.$param['options'][$valueval].'
  • '; + } + } + $value = '
      '.implode(' ', $toprint).'
    '; + } + elseif ($type == 'chkbxlst') + { + $value_arr = explode(',', $value); + + $param_list = array_keys($param['options']); + $InfoFieldList = explode(":", $param_list[0]); + + $selectkey = "rowid"; + $keyList = 'rowid'; + + if (count($InfoFieldList) >= 3) { + $selectkey = $InfoFieldList[2]; + $keyList = $InfoFieldList[2].' as rowid'; + } + + $fields_label = explode('|', $InfoFieldList[1]); + if (is_array($fields_label)) { + $keyList .= ', '; + $keyList .= implode(', ', $fields_label); + } + + $sql = 'SELECT '.$keyList; + $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0]; + if (strpos($InfoFieldList[4], 'extra') !== false) { + $sql .= ' as main'; + } + // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'"; + // $sql.= ' AND entity = '.$conf->entity; + + dol_syslog(get_class($this).':showOutputField:$type=chkbxlst', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $value = ''; // value was used, so now we reste it to use it to build final output + $toprint = array(); + while ($obj = $this->db->fetch_object($resql)) { + // Several field into label (eq table:code|libelle:rowid) + $fields_label = explode('|', $InfoFieldList[1]); + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { + if (is_array($fields_label) && count($fields_label) > 1) { + foreach ($fields_label as $field_toshow) { + $translabel = ''; + if (!empty($obj->$field_toshow)) { + $translabel = $langs->trans($obj->$field_toshow); + } + if ($translabel != $field_toshow) { + $toprint[] = '
  • '.dol_trunc($translabel, 18).'
  • '; + } else { + $toprint[] = '
  • '.$obj->$field_toshow.'
  • '; + } + } + } else { + $translabel = ''; + if (!empty($obj->{$InfoFieldList[1]})) { + $translabel = $langs->trans($obj->{$InfoFieldList[1]}); + } + if ($translabel != $obj->{$InfoFieldList[1]}) { + $toprint[] = '
  • '.dol_trunc($translabel, 18).'
  • '; + } else { + $toprint[] = '
  • '.$obj->{$InfoFieldList[1]}.'
  • '; + } + } + } + } + $value = '
      '.implode(' ', $toprint).'
    '; + } else { + dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING); + } + } + elseif ($type == 'link') + { + $out = ''; + + // Only if something to display (perf) + if ($value) // If we have -1 here, pb is into insert, not into ouptut (fix insert instead of changing code here to compensate) + { + $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' + + $InfoFieldList = explode(":", $param_list[0]); + $classname = $InfoFieldList[0]; + $classpath = $InfoFieldList[1]; + if (!empty($classpath)) + { + dol_include_once($InfoFieldList[1]); + if ($classname && class_exists($classname)) + { + $object = new $classname($this->db); + $object->fetch($value); + $value = $object->getNomUrl(3); + } + } + else + { + dol_syslog('Error bad setup of extrafield', LOG_WARNING); + return 'Error bad setup of extrafield'; + } + } + } + elseif ($type == 'text') + { + $value = dol_htmlentitiesbr($value); + } + elseif ($type == 'html') + { + $value = dol_htmlentitiesbr($value); + } + elseif ($type == 'password') + { + $value = dol_trunc(preg_replace('/./i', '*', $value), 8, 'right', 'UTF-8', 1); + } + else + { + $showsize = round($size); + if ($showsize > 48) $showsize = 48; + } + + //print $type.'-'.$size; + $out = $value; + + return $out; + } + + /** + * Return tag to describe alignement to use for this extrafield + * + * @param string $key Key of attribute + * @param string $extrafieldsobjectkey If defined, use the new method to get extrafields data + * @return string Formated value + */ + public function getAlignFlag($key, $extrafieldsobjectkey = '') + { + global $conf, $langs; + + if (!empty($extrafieldsobjectkey)) $type = $this->attributes[$extrafieldsobjectkey]['type'][$key]; + else $type = $this->attribute_type[$key]; + + $align = ''; + + if ($type == 'date') + { + $align = "center"; + } + elseif ($type == 'datetime') + { + $align = "center"; + } + elseif ($type == 'int') + { + $align = "right"; + } + elseif ($type == 'price') + { + $align="right"; + } + elseif ($type == 'double') + { + $align = "right"; + } + elseif ($type == 'boolean') + { + $align = "center"; + } + elseif ($type == 'radio') + { + $align = "center"; + } + elseif ($type == 'checkbox') + { + $align = "center"; + } + elseif ($type == 'price') + { + $align = "right"; + } + + return $align; + } + + /** + * Return HTML string to print separator extrafield + * + * @param string $key Key of attribute + * @param string $object Object + * @param int $colspan Value of colspan to use (it must includes the first column with title) + * @return string HTML code with line for separator + */ + public function showSeparator($key, $object, $colspan = 2) + { + global $langs; + + $out = ''; + $out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]); + $out .= ''; + + $extrafield_param = $this->attributes[$object->table_element]['param'][$key]; + if (!empty($extrafield_param) && is_array($extrafield_param)) { + $extrafield_param_list = array_keys($extrafield_param['options']); + + if (count($extrafield_param_list) > 0) { + $extrafield_collapse_display_value = intval($extrafield_param_list[0]); + if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { + // Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup. + $collapse_display = ((isset($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key]) || GETPOST('ignorecollapsesetup', 'int')) ? ($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key] ? true : false) : ($extrafield_collapse_display_value == 2 ? false : true)); + $extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key]; + + $out .= ''; + $out .= ''; + } + } + } + + return $out; + } + + /** + * Fill array_options property of object by extrafields value (using for data sent by forms) + * + * @param array $extralabels Deprecated (old $array of extrafields, now set this to null) + * @param object $object Object + * @param string $onlykey Only the following key is filled. When we make update of only one extrafield ($action = 'update_extras'), calling page must set this to avoid to have other extrafields being reset. + * @return int 1 if array_options set, 0 if no value, -1 if error (field required missing for example) + */ + public function setOptionalsFromPost($extralabels, &$object, $onlykey = '') + { + global $_POST, $langs; + + $nofillrequired = 0; // For error when required field left blank + $error_field_required = array(); + + if (is_array($this->attributes[$object->table_element]['label'])) $extralabels = $this->attributes[$object->table_element]['label']; + + if (is_array($extralabels)) + { + // Get extra fields + foreach ($extralabels as $key => $value) + { + if (!empty($onlykey) && $key != $onlykey) continue; + + $key_type = $this->attributes[$object->table_element]['type'][$key]; + if ($key_type == 'separate') continue; + + $enabled = 1; + if (isset($this->attributes[$object->table_element]['list'][$key])) + { + $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); + } + $perms = 1; + if (isset($this->attributes[$object->table_element]['perms'][$key])) + { + $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); + } + if (empty($enabled)) continue; + if (empty($perms)) continue; + + if ($this->attributes[$object->table_element]['required'][$key]) // Value is required + { + // Check if empty without using GETPOST, value can be alpha, int, array, etc... + if ((!is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] != 'select' && $_POST["options_".$key] != '0') + || (!is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] == 'select') + || (is_array($_POST["options_".$key]) && empty($_POST["options_".$key]))) + { + //print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key]; + $nofillrequired++; + $error_field_required[] = $langs->transnoentitiesnoconv($value); + } + } + + if (in_array($key_type, array('date'))) + { + // Clean parameters + // TODO GMT date in memory must be GMT so we should add gm=true in parameters + $value_key = dol_mktime(0, 0, 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); + } + elseif (in_array($key_type, array('datetime'))) + { + // Clean parameters + // TODO GMT date in memory must be GMT so we should add gm=true in parameters + $value_key = dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); + } + elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) + { + $value_arr = GETPOST("options_".$key, 'array'); // check if an array + if (!empty($value_arr)) { + $value_key = implode($value_arr, ','); + } else { + $value_key = ''; + } + } + elseif (in_array($key_type, array('price', 'double'))) + { + $value_arr = GETPOST("options_".$key, 'alpha'); + $value_key = price2num($value_arr); + } + else + { + $value_key = GETPOST("options_".$key); + if (in_array($key_type, array('link')) && $value_key == '-1') $value_key = ''; + } + + $object->array_options["options_".$key] = $value_key; + } + + if ($nofillrequired) { + $langs->load('errors'); + setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ', $error_field_required), null, 'errors'); + return -1; + } + else { + return 1; + } + } + else { + return 0; + } + } + + /** + * return array_options array of data of extrafields value of object sent by a search form + * + * @param array|string $extrafieldsobjectkey array of extrafields (old usage) or value of object->table_element (new usage) + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return array|int array_options set or 0 if no value + */ + public function getOptionalsFromPost($extrafieldsobjectkey, $keyprefix = '', $keysuffix = '') + { + global $_POST; + + if (is_string($extrafieldsobjectkey) && is_array($this->attributes[$extrafieldsobjectkey]['label'])) + { + $extralabels = $this->attributes[$extrafieldsobjectkey]['label']; + } + else + { + $extralabels = $extrafieldsobjectkey; + } + + if (is_array($extralabels)) + { + $array_options = array(); + + // Get extra fields + foreach ($extralabels as $key => $value) + { + $key_type = ''; + if (is_string($extrafieldsobjectkey)) + { + $key_type = $this->attributes[$extrafieldsobjectkey]['type'][$key]; + } + + if (in_array($key_type, array('date', 'datetime'))) + { + if (!GETPOSTISSET($keysuffix."options_".$key.$keyprefix."year")) continue; // Value was not provided, we should not set it. + // Clean parameters + $value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), 0, GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int')); + } + elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) + { + if (!GETPOSTISSET($keysuffix."options_".$key.$keyprefix)) continue; // Value was not provided, we should not set it. + $value_arr = GETPOST($keysuffix."options_".$key.$keyprefix); + // Make sure we get an array even if there's only one checkbox + $value_arr = (array) $value_arr; + $value_key = implode(',', $value_arr); + } + elseif (in_array($key_type, array('price', 'double', 'int'))) + { + if (!GETPOSTISSET($keysuffix."options_".$key.$keyprefix)) continue; // Value was not provided, we should not set it. + $value_arr = GETPOST($keysuffix."options_".$key.$keyprefix); + $value_key = price2num($value_arr); + } + else + { + if (!GETPOSTISSET($keysuffix."options_".$key.$keyprefix)) continue; // Value was not provided, we should not set it. + $value_key = GETPOST($keysuffix."options_".$key.$keyprefix); + } + + $array_options[$keysuffix."options_".$key] = $value_key; // No keyprefix here. keyprefix is used only for read. + } + + return $array_options; + } + + return 0; + } +} diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 7404b3c6945..0b8185b3854 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -329,12 +329,24 @@ class Form */ public function widgetForTranslation($fieldname, $object, $perm, $typeofdata = 'string', $check = '', $morecss = '') { - global $conf, $langs; + global $conf, $langs, $extralanguages; $result = ''; - if (! empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE)) { - $langcode = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; + // List of extra languages + $arrayoflangcode = array(); + if (! empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE)) $arrayoflangcode[] = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; + + if (is_array($arrayoflangcode) && count($arrayoflangcode)) { + if (! is_object($extralanguages)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/extralanguages.class.php'; + $extralanguages = new ExtraLanguages($this->db); + } + $extralanguages->fetch_name_extralanguages('societe'); + + if (! is_array($extralanguages->attributes[$object->element]) || empty($extralanguages->attributes[$object->element][$fieldname])) { + return ''; // No extralang field to show + } $result .='
    '; $s=img_picto($langs->trans("ShowOtherLanguages"), 'language', '', false, 0, 0, '', 'fa-15 editfieldlang'); @@ -343,22 +355,28 @@ class Form $result .=''; $result .= ''; } @@ -7260,7 +7278,7 @@ class Form */ public function showrefnav($object, $paramid, $morehtml = '', $shownav = 1, $fieldid = 'rowid', $fieldref = 'ref', $morehtmlref = '', $moreparam = '', $nodbprefix = 0, $morehtmlleft = '', $morehtmlstatus = '', $morehtmlright = '') { - global $langs, $conf, $hookmanager; + global $langs, $conf, $hookmanager, $extralanguages; $ret = ''; if (empty($fieldid)) $fieldid = 'rowid'; @@ -7360,16 +7378,24 @@ class Form { $ret .= dol_htmlentities($object->name); - $useextralanguages = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; - if ($useextralanguages) { - $object->fetchValuesForExtraLanguages(); - $extralanguages = array(); - if (isset($object->array_languages['name'])) $extralanguages[] = reset(array_keys($object->array_languages['name'])); + // List of extra languages + $arrayoflangcode = array(); + if (! empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE)) $arrayoflangcode[] = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE; + + if (is_array($arrayoflangcode) && count($arrayoflangcode)) { + if (! is_object($extralanguages)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/extralanguages.class.php'; + $extralanguages = new ExtraLanguages($this->db); + } + $extralanguages->fetch_name_extralanguages('societe'); + + if (! empty($extralanguages->attributes['societe']['name'])) + { + $object->fetchValuesForExtraLanguages(); - if (is_array($extralanguages) && count($extralanguages)) { $htmltext = ''; // If there is extra languages - foreach($extralanguages as $extralangcode) { + foreach($arrayoflangcode as $extralangcode) { $s=picto_from_langcode($extralangcode, 'class="pictoforlang paddingright"'); $htmltext .= $s.$object->array_languages['name'][$extralangcode]; } From f6b216eafc73b3fe6814f08f90ebfdb010a652db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Apr 2020 23:32:44 +0200 Subject: [PATCH 12/12] Fix travis --- htdocs/core/class/commonobject.class.php | 1 - htdocs/core/lib/files.lib.php | 1 - 2 files changed, 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index bc1fd5e75b7..2352450e770 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5744,7 +5744,6 @@ abstract class CommonObject foreach($new_array_languages as $key => $langcodearray) { // $key = 'name', 'town', ... foreach($langcodearray as $langcode => $value) { - $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."object_lang"; $sql_del .= " WHERE fk_object = ".$this->id." AND property = '".$this->db->escape($key)."' AND type_object = '".$this->db->escape($table_element)."'"; $sql_del .= " AND lang = '".$this->db->escape($langcode)."'"; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 7dafb316a18..a39e48e3a60 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1551,7 +1551,6 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess { $destfull = $upload_dir."/".preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); $destfile = preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); - } // dol_sanitizeFileName the file name and lowercase extension