diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 5f9c4ac77c8..8a86752b31b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1594,6 +1594,21 @@ function dol_escape_json($stringtoescape) return str_replace('"', '\"', $stringtoescape); } +/** + * Returns text escaped for inclusion into a php string, build with double quotes " + * + * @param string $stringtoescape String to escape + * @return string Escaped string for json content. + */ +function dol_escape_php($stringtoescape) +{ + if (is_null($stringtoescape)) { + return ''; + } + + return str_replace('"', "'", $stringtoescape); +} + /** * Return a string label ready to be output on HTML content * To use text inside an attribute, use can use only dol_escape_htmltag() diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index ac4dcfc04da..4497ee4e957 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -126,10 +126,10 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = if (!empty($val['picto'])) { $texttoinsert .= " 'picto'=>'".$val['picto']."',"; } - $texttoinsert .= " 'enabled'=>'".($val['enabled'] !== '' ? $val['enabled'] : 1)."',"; + $texttoinsert .= ' "enabled"=>"'.($val['enabled'] !== '' ? dol_escape_php($val['enabled']) : 1).'",'; $texttoinsert .= " 'position'=>".($val['position'] !== '' ? $val['position'] : 50).","; $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : $val['notnull']).","; - $texttoinsert .= " 'visible'=>".($val['visible'] !== '' ? $val['visible'] : -1).","; + $texttoinsert .= ' "visible"=>"'.($val['visible'] !== '' ? dol_escape_js($val['visible']) : -1).'",'; if (!empty($val['noteditable'])) { $texttoinsert .= " 'noteditable'=>'".$val['noteditable']."',"; } diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 4ae7d6c4968..59e8baef5b5 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -149,7 +149,7 @@ CSSListClass=CSS for list NotEditable=Not editable ForeignKey=Foreign key ForeignKeyDesc=If the value of this field must be guaranted to exists into another table. Enter here a value matching syntax: tablename.parentfieldtocheck -TypeOfFieldsHelp=Example:
varchar(99), double(24,8), real, text, html, datetime, timestamp, integer, integer:ClassName:relativepath/to/classfile.class.php[:1[:filter]]
'1' means we add a + button after the combo to create the record
'filter' is a sql condition, example: 'status=1 AND fk_user=__USER_ID__ AND entity IN (__SHARED_ENTITIES__)' +TypeOfFieldsHelp=Example:
varchar(99), double(24,8), real, text, html, datetime, timestamp, integer, integer:ClassName:relativepath/to/classfile.class.php[:1[:filter]]

'1' means we add a + button after the combo to create the record
'filter' is an Universal Filter syntax condition, example: '((status:=:1) AND (fk_user:=:__USER_ID__) AND (entity:IN:(__SHARED_ENTITIES__))' TypeOfFieldsHelpIntro=This is the type of the field/attribute. AsciiToHtmlConverter=Ascii to HTML converter AsciiToPdfConverter=Ascii to PDF converter diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 1b7b6349f3f..ecdb3f06b1a 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1681,10 +1681,10 @@ if ($dirins && ($action == 'droptable' || $action == 'droptableextrafields') && } } -if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && !empty(GETPOST('obj')) && $tabobj == "createproperty") { +if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && (!empty($tabobj) || !empty(GETPOST('obj')))) { $error = 0; - $objectname = GETPOST('obj'); + $objectname = (GETPOST('obj') ? GETPOST('obj') : $tabobj); $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; $moduletype = $listofmodules[strtolower($module)]['moduletype']; @@ -1713,14 +1713,14 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors'); } - if (!$error && !GETPOST('regenerateclasssql')&& !GETPOST('regeneratemissing')) { + if (!$error && !GETPOST('regenerateclasssql') && !GETPOST('regeneratemissing')) { $addfieldentry = array( 'name'=>GETPOST('propname', 'aZ09'), 'label'=>GETPOST('proplabel', 'alpha'), 'type'=>strtolower(GETPOST('proptype', 'alpha')), 'arrayofkeyval'=>GETPOST('proparrayofkeyval', 'restricthtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' - 'visible'=>GETPOST('propvisible', 'int'), - 'enabled'=>GETPOST('propenabled', 'int'), + 'visible'=>GETPOST('propvisible', 'alphanohtml'), + 'enabled'=>GETPOST('propenabled', 'alphanohtml'), 'position'=>GETPOST('propposition', 'int'), 'notnull'=>GETPOST('propnotnull', 'int'), 'index'=>GETPOST('propindex', 'int'), @@ -1733,7 +1733,7 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && 'csslist'=>GETPOST('propcsslist', 'alpha'), 'default'=>GETPOST('propdefault', 'restricthtml'), 'noteditable'=>intval(GETPOST('propnoteditable', 'int')), - 'alwayseditable'=>intval(GETPOST('propalwayseditable', 'int')), + //'alwayseditable'=>intval(GETPOST('propalwayseditable', 'int')), 'validate' => GETPOST('propvalidate', 'int') ); if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) { @@ -1743,7 +1743,7 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && } else { $addfieldentry = array(); } - + var_dump($addfieldentry); /*if (GETPOST('regeneratemissing')) { setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings'); @@ -3838,8 +3838,8 @@ if ($module == 'initmodule') { print ''; } elseif ($tabobj == 'createproperty') { $attributesUnique = array ( - 'propname' => $form->textwithpicto($langs->trans("Code"), $langs->trans("PropertyDesc"), 1, 'help', 'extracss', 0, 3, 'propertyhelp'), 'proplabel' => $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")), + 'propname' => $form->textwithpicto($langs->trans("Code"), $langs->trans("PropertyDesc"), 1, 'help', 'extracss', 0, 3, 'propertyhelp'), 'proptype' => $form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'

'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp'), 'proparrayofkeyval' => $form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")), 'propnotnull' => $form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")), @@ -3850,7 +3850,7 @@ if ($module == 'initmodule') { 'propenabled' => $form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp'), 'propvisible' => $form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'

'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp'), 'propnoteditable' => $langs->trans("NotEditable"), - 'propalwayseditable' => $langs->trans("AlwaysEditable"), + //'propalwayseditable' => $langs->trans("AlwaysEditable"), 'propsearchall' => $form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")), 'propisameasure' => $form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")), 'propcss' => $langs->trans("CSSClass"), @@ -3858,7 +3858,7 @@ if ($module == 'initmodule') { 'propcsslist' => $langs->trans("CSSListClass"), 'prophelp' => $langs->trans("KeyForTooltip"), 'propshowoncombobox' => $langs->trans("ShowOnCombobox"), - 'propvalidate' => $form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")), + //'propvalidate' => $form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")), 'propcomment' => $langs->trans("Comment"), ); print '
'; @@ -3878,10 +3878,16 @@ if ($module == 'initmodule') { print ''.$attribute.''; } elseif ($key == 'proptype') { print ''.$attribute.'
'; - } elseif ($key == 'propvalidate') { - print ''.$attribute.''; + //} elseif ($key == 'propvalidate') { + // print ''.$attribute.''; + } elseif ($key == 'propvisible') { + print ''.$attribute.''; + } elseif ($key == 'propenabled') { + print ''.$attribute.''; + } elseif ($key == 'proparrayofkeyval') { + print ''.$attribute.''; } else { - print ''.$attribute.''; + print ''.$attribute.''; } $counter++; if ($counter % 2 === 0) { @@ -3933,35 +3939,62 @@ if ($module == 'initmodule') { } else { suggestionsDiv.show(); } - } + } - $("#proptype").on("input", showSuggestions); + $("#proptype").on("input", showSuggestions); - $("#suggestions").on("click", "div", function() { + $("#suggestions").on("click", "div", function() { var selectedValue = $(this).text(); $("#proptype").val(selectedValue); $("#suggestions").hide(); - }); + }); // when we click outside the input - $(document).on("click", function(event) { + $(document).on("click", function(event) { if (!$(event.target).closest("#proptype, #suggestions").length) { $("#suggestions").hide(); } - }); - // when we delete the content input - $("#proptype").on("keyup", function() { + }); + // when we delete the content input + $("#proptype").on("keyup", function() { if ($(this).val() === "") { $("#suggestions").hide(); } - }); + }); + + $("#proplabel").on("keyup", function() { + console.log("key up on label"); + s = cleanString($("#proplabel").val()); + $("#propname").val(s); + }); + // when hover in suggestion $("#suggestions").on("mouseenter", "div", function() { + console.log("enter suggestion"); $(this).css("background-color", "#e0e0e0"); - }); + }); - $("#suggestions").on("mouseleave", "div", function() { + $("#suggestions").on("mouseleave", "div", function() { + console.log("leave suggestion"); $(this).css("background-color", "#fff"); - }); + }); + + function cleanString( stringtoclean ) + { + // allow "a-z", "A-Z", "0-9" and "_" + stringtoclean = stringtoclean.replace(/[^a-z0-9_]+/ig, ""); + stringtoclean = stringtoclean.toLowerCase(); + if (!isNaN(stringtoclean)) { + return "" + } + while ( stringtoclean.length > 1 && !isNaN( stringtoclean.charAt(0)) ){ + stringtoclean = stringtoclean.substr(1) + } + if (stringtoclean.length > 28) { + stringtoclean = stringtoclean.substring(0, 27); + } + return stringtoclean + } + });'; print ''; } elseif ($tabobj == 'deleteobject') { @@ -4294,7 +4327,7 @@ if ($module == 'initmodule') { print ''.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp').''; print ''.$form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'

'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp').''; print ''.$langs->trans("NotEditable").''; - print ''.$langs->trans("AlwaysEditable").''; + //print ''.$langs->trans("AlwaysEditable").''; print ''.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).''; print ''.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).''; print ''.$langs->trans("CSSClass").''; @@ -4341,7 +4374,7 @@ if ($module == 'initmodule') { $propenabled = $propval['enabled']; $propvisible = $propval['visible']; $propnoteditable = !empty($propval['noteditable'])?$propval['noteditable']:0; - $propalwayseditable = !empty($propval['alwayseditable'])?$propval['alwayseditable']:0; + //$propalwayseditable = !empty($propval['alwayseditable'])?$propval['alwayseditable']:0; $propsearchall = !empty($propval['searchall'])?$propval['searchall']:0; $propisameasure = !empty($propval['isameasure'])?$propval['isameasure']:0; $propcss = !empty($propval['css'])?$propval['css']:''; @@ -4353,6 +4386,7 @@ if ($module == 'initmodule') { $propvalidate = !empty($propval['validate'])?$propval['validate']:0; $propcomment = !empty($propval['comment'])?$propval['comment']:''; + print ''."\n"; print ''; print ''; @@ -4368,14 +4402,13 @@ if ($module == 'initmodule') { print ''; print ''; print ''; - print ''; if (isset($proparrayofkeyval)) { if (is_array($proparrayofkeyval) || $proparrayofkeyval != '') { print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE)); } } - print '">'; - print ''; + print ''; print ''; print ''; print ''; @@ -4393,22 +4426,22 @@ if ($module == 'initmodule') { print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; - print ''; + print ''; print ''; - print ''; + /*print ''; print ''; + print '';*/ + print ''; + print ''; print ''; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; print ''; print ''; print ''; @@ -4485,9 +4518,9 @@ if ($module == 'initmodule') { print ''; print $propnoteditable ? dol_escape_htmltag($propnoteditable) : ''; print ''; - print ''; + /*print ''; print $propalwayseditable ? dol_escape_htmltag($propalwayseditable) : ''; - print ''; + print '';*/ print ''; print $propsearchall ? '1' : ''; print ''; @@ -5188,7 +5221,7 @@ if ($module == 'initmodule') { print ''; // Enabled print ''; - print ''; + print ''; $htmltext = ''.$langs->trans("Examples").':
'; $htmltext .= '1 (always enabled)
'; $htmltext .= '0 (always disabled)
';