Browse Source

Merge pull request #23875 from lamrani002/UpdateMenuOnMD

New functionality for moduleBuilder "Update menu"
Laurent Destailleur 2 years ago
parent
commit
4d417760c9
3 changed files with 460 additions and 59 deletions
  1. 4 0
      htdocs/langs/en_US/errors.lang
  2. 4 1
      htdocs/langs/fr_FR/errors.lang
  3. 452 58
      htdocs/modulebuilder/index.php

+ 4 - 0
htdocs/langs/en_US/errors.lang

@@ -305,6 +305,10 @@ ErrorDateOfMovementLowerThanDateOfFileTransmission=The date of the bank transact
 ErrorTooMuchFileInForm=Too much files in form, the maximum number is %s file(s)
 ErrorSessionInvalidatedAfterPasswordChange=The session was been invalidated following a change of password, status or dates of validity. Please relogin.
 ErrorExistingPermission = Permission <b>%s</b> for object <b>%s</b> already exists
+ErrorFieldExist=The value for <b>%s</b> already exist 
+ErrorEqualModule=Module invalid in <b>%s</b>
+ErrorFieldValue=Value for <b>%s</b> is incorrect
+ErrorCoherenceMenu=<b>%s</b> is required when <b>%</b> equal LEFT
 
 # Warnings
 WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.

+ 4 - 1
htdocs/langs/fr_FR/errors.lang

@@ -305,7 +305,10 @@ ErrorDateOfMovementLowerThanDateOfFileTransmission=La date de l'opération banca
 ErrorTooMuchFileInForm=Trop de fichiers dans le formulaire, le nombre maximum est de %s fichier(s)
 ErrorExistingPermission = La permission <b>%s</b> pour l'objet <b>%s</b> est dejà existante
 ErrorSessionInvalidatedAfterPasswordChange=La session a été invalidée suite à un changement de mot de passe, d'état ou de dates de validité. Veuillez vous reconnecter.
-
+ErrorFieldExist=La valeur pour <b>%s</b> existe déja 
+ErrorEqualModule=Module invalide pour le champ <b>%s</b>
+ErrorFieldValue=La valeur du champ <b>%s</b> est incorrecte
+ErrorCoherenceMenu = Le champ <b>%s</b> est requis si le champ <b>%s</b> = LEFT
 
 # Warnings
 WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Votre paramètre PHP upload_max_filesize (%s) est supérieur au paramètre PHP post_max_size (%s). Ceci n'est pas une configuration cohérente.

+ 452 - 58
htdocs/modulebuilder/index.php

@@ -1356,7 +1356,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) {
             'type'=>'left',
             'titre'=>'List MyObject',
             'mainmenu'=>'mymodule',
-            'leftmenu'=>'mymodule_myobject',
+            'leftmenu'=>'myobject',
             'url'=>'/mymodule/myobject_list.php',
             'langs'=>'mymodule@mymodule',
             'position'=>1100+\$r,
@@ -1366,11 +1366,11 @@ if ($dirins && $action == 'initobject' && $module && $objectname) {
             'user'=>2,
         );
         \$this->menu[\$r++]=array(
-            'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=mymodule_myobject',
+            'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject',
             'type'=>'left',
             'titre'=>'New MyObject',
             'mainmenu'=>'mymodule',
-            'leftmenu'=>'mymodule_myobject',
+            'leftmenu'=>'myobject',
             'url'=>'/mymodule/myobject_card.php?action=create',
             'langs'=>'mymodule@mymodule',
             'position'=>1100+\$r,
@@ -1403,7 +1403,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) {
 			$menus = $moduleobj->menu;
 			$counter = 0 ;
 		foreach ($menus as $menu) {
-			if ($menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) {
+			if ($menu['leftmenu'] == strtolower($objectname)) {
 				$counter++;
 			}
 		}
@@ -1812,7 +1812,7 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) {
 		$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
 
 		foreach ($menus as $menu) {
-			if ($menu['type'] == 'left' && $menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) {
+			if ($menu['type'] == 'left' && $menu['leftmenu'] == strtolower($objectname)) {
 				$left="\$this->menu[\$r++]=array(
 			'fk_menu'=>'".$menu['fk_menu']."',
 			'type'=>'".$menu['type']."',
@@ -2436,8 +2436,7 @@ if ($dirins && $action == 'confirm_deletemenu' && GETPOST('menukey', 'int')) {
 			}
 		}
 		if ($menuForObj == 1) {
-			$extractObjName = explode("_", $menus[$key]['leftmenu']);
-			dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($extractObjName[1]).'*/'."\n" => '','/*END LEFTMENU '.strtoupper($extractObjName[1]).'*/' => ''));
+			dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($menus[$key]['leftmenu']).'*/'."\n" => '','/*END LEFTMENU '.strtoupper($menus[$key]['leftmenu']).'*/' => ''));
 		}
 	}
 
@@ -2446,6 +2445,292 @@ if ($dirins && $action == 'confirm_deletemenu' && GETPOST('menukey', 'int')) {
 		exit;
 }
 
+// Add menu in module without initial object
+if ($dirins && $action == 'addmenu' && empty($cancel)) {
+	// check if module is enabled
+	if (isModEnabled(strtolower($module))) {
+		$result = unActivateModule(strtolower($module));
+		dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
+		if ($result) {
+			setEventMessages($result, null, 'errors');
+		}
+		header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
+		setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings');
+	}
+	$error = 0;
+	$dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
+	$destdir = $dirins.'/'.strtolower($module);
+	$listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
+	$objects = array();
+	foreach ($listofobject as $fileobj) {
+		if (preg_match('/^api_/', $fileobj['name'])) {
+			continue;
+		}
+		if (preg_match('/^actions_/', $fileobj['name'])) {
+			continue;
+		}
+
+		$tmpcontent = file_get_contents($fileobj['fullname']);
+		$reg = array();
+		if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
+			$objectnameloop = $reg[1];
+			$objects[] = $objectnameloop;
+		}
+	}
+
+	// load class and check if right exist
+	$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
+	dol_include_once($pathtofile);
+		$class = 'mod'.$module;
+	if (class_exists($class)) {
+		try {
+			$moduleobj = new $class($db);
+		} catch (Exception $e) {
+			$error++;
+			dol_print_error($db, $e->getMessage());
+		}
+	}
+	$menus = $moduleobj->menu;
+	//verify fields required
+	if (!GETPOST('type', 'alpha')) {
+		$error++;
+		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors');
+	}
+	if (!GETPOST('titre', 'alpha')) {
+		$error++;
+		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Title")), null, 'errors');
+	}
+	if (!GETPOST('user', 'alpha')) {
+		$error++;
+		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DetailUser")), null, 'errors');
+	}
+	if (!GETPOST('url', 'alpha')) {
+		$error++;
+		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Url")), null, 'errors');
+	}
+	if (GETPOST('mainmenu') != strtolower($module)) {
+		$error++;
+		setEventMessages($langs->trans("ErrorEqualModule", $langs->transnoentities("mainmenu")), null, 'errors');
+	}
+	if (!empty(GETPOST('target'))) {
+		$targets = array('_blank','_self','_parent','_top','');
+		if (!in_array(GETPOST('target'), $targets)) {
+			$error++;
+			setEventMessages($langs->trans("ErrorFieldValue", $langs->transnoentities("target")), null, 'errors');
+		}
+	}
+	if (!empty(GETPOST('perms'))) {
+		$permssion = array('read','write');
+		if (GETPOST('perms') == 1 || GETPOST('perms') == '') {
+			$perms = 1 ;
+		} else {
+			if (!in_array(GETPOST('perms'), $permssion)) {
+				$error++;
+				setEventMessages($langs->trans("ErrorFieldValue", $langs->transnoentities("permssion")), null, 'errors');
+			}
+		}
+	}
+
+	// check if title or url already exist in menus
+
+	foreach ($menus as $menu) {
+		if (!empty(GETPOST('url')) && GETPOST('url') == $menu['url']) {
+			$error++;
+			setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("url")), null, 'errors');
+			break;
+		}
+		if (strtolower(GETPOST('titre')) == strtolower($menu['titre'])) {
+			$error++;
+			setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("titre")), null, 'errors');
+			break;
+		}
+	}
+
+
+	if (GETPOST('type', 'alpha') == 'left' && !empty(GETPOST('lefmenu', 'alpha'))) {
+		if (!str_contains(GETPOST('leftmenu'), strtolower($module))) {
+			$error++;
+			setEventMessages($langs->trans("WarningFieldsMustContains", $langs->transnoentities("leftmenu")), null, 'errors');
+		}
+	}
+
+	if (GETPOST('type', 'alpha') == 'left') {
+		if (empty(GETPOST('leftmenu') && count($objects) > 0)) {
+			$error++;
+			setEventMessages($langs->trans("ErrorCoherenceMenu", $langs->transnoentities("leftmenu"), $langs->transnoentities("type")), null, 'errors');
+		}
+	}
+
+	if (!$error) {
+		$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
+
+		$type = GETPOST('type', 'alpha');
+		$fk_menu = GETPOST('fk_type', 'alpha');
+		$titre = GETPOST('titre', 'alpha');
+		$mainmenu = GETPOST('mainmenu', 'alpha');
+		$leftmenu = GETPOST('leftmenu', 'alpha');
+		$url = GETPOST('url');
+		$user = GETPOST('user', 'int');
+		(empty(GETPOST('perms')) && GETPOST('type') == 'top') || GETPOST('perms')==1 ? $perms=1 : $perms = 1;
+		$target = GETPOST('target', 'alpha');
+
+
+
+		if ($type == 'top') {
+			$menuTop = "
+		\$this->menu[\$r++] = array(
+			'fk_menu'=>'".$fk_menu."', 
+			'type'=>'".strtolower($type)."', 
+			'titre'=>'".ucfirst($titre)."',
+			'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'),
+			'mainmenu'=>'".$mainmenu."',
+			'leftmenu'=> '".$leftmenu."',
+			'url'=>'".$url."',
+			'langs'=>'".strtolower($module)."@".strtolower($module)."', 
+			'position'=>1000 + \$r,
+			'enabled'=>'isModEnabled(\"".strtolower($module)."\")', 
+			'perms' =>'".$perms."',
+			'target'=>'".$target."',
+			'user'=>".$user.", 
+		);";
+			$addTopMenu = dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER TOPMENU */' => '/*TOPMENU '.strtolower($titre).'*/'.$menuTop."\n\t\t".'/*END TOPMENU '.strtolower($titre).'*/'."\n\t\t/* END MODULEBUILDER TOPMENU */"));
+		}
+		if ($type == 'left') {
+			$fk_menu = "fk_mainmenu=".strtolower($module).",fk_leftmenu=".strtolower($leftmenu);
+			$menuLeft= "
+		\$this->menu[\$r++]=array(
+			'fk_menu'=>'".$fk_menu."',
+			'type'=>'".$type."',
+			'titre'=>'".ucfirst($titre)."',
+			'mainmenu'=>'".strtolower($module)."',
+			'leftmenu'=>'".strtolower($leftmenu)."',
+			'url'=>'".$url."',
+			'langs'=>'".strtolower($module)."@".strtolower($module)."', 
+			'position'=>1100+\$r,
+			'enabled'=>'\$conf->".strtolower($module)."->enabled',
+			'perms'=>'".$perms."',
+			'target'=>'".$target."',
+			'user'=>".$user.",
+		);";
+
+			$exist = 0;
+			foreach ($menus as $menu) {
+				if (strtolower($menu['leftmenu']) == strtolower($leftmenu)) {
+					$exist++;
+				}
+			}
+			//var_dump($exist);exit;
+			if ($exist) {
+				dolReplaceInFile($moduledescriptorfile, array('/*END LEFTMENU '.strtoupper($leftmenu).'*/' => $menuLeft."\n\t\t".'/*END LEFTMENU '.strtoupper($leftmenu).'*/'));
+			} else {
+				$addLeftMenu = dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER LEFTMENU MYOBJECT */' => '/*LEFTMENU '.strtoupper($leftmenu).'*/'."\n".$menuLeft."\n\t\t".'/*END LEFTMENU '.strtoupper($leftmenu).'*/'."\n\t\t".'/* END MODULEBUILDER LEFTMENU MYOBJECT */'));
+			}
+		}
+
+			header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
+			setEventMessages($langs->trans('MenuAddedSuccesfuly'), null);
+			exit;
+	}
+}
+
+// modify a menu
+if ($dirins && $action == "modify_menu" && GETPOST('menukey', 'int') && empty(GETPOST('cancel'))) {
+	$error = 0;
+	$counter = 0;
+	// for loading class and the menu wants to modify
+	$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
+	dol_include_once($pathtofile);
+	$class = 'mod'.$module;
+	if (class_exists($class)) {
+		try {
+			$moduleobj = new $class($db);
+		} catch (Exception $e) {
+			$error++;
+			dol_print_error($db, $e->getMessage());
+		}
+	}
+	$menus = $moduleobj->menu;
+	$key = (int) GETPOST('menukey', 'int');
+	$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
+		//get menus info
+		$menuTomodify = "
+		\$this->menu[\$r++] = array(
+			'fk_menu' =>'".$menus[$key]['fk_menu']."',
+			'type' =>'".$menus[$key]['type']."',
+			'titre' =>'".$menus[$key]['titre']."',
+			'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'),
+			'mainmenu'=>'".$menus[$key]['mainmenu']."',
+			'leftmenu' =>'".$menus[$key]['leftmenu']."',
+			'url' =>'".$menus[$key]['url']."',
+			'langs'=>'".$menus[$key]['langs']."', 
+			'position'=>1000 + \$r,
+			'enabled'=>'isModEnabled(\"".strtolower($module)."\")', 
+			'perms' =>'".$menus[$key]['perms']."',
+			'target'=>'".$menus[$key]['target']."',
+			'user'=>".$menus[$key]['user'].", 
+		);";
+
+		$fk_menu = GETPOST('fk_type', 'alpha');
+		$type = GETPOST('type', 'alpha');
+		$titre = GETPOST('titre', 'alpha');
+		$mainmenu = GETPOST('mainmenu', 'alpha');
+		$leftmenu = GETPOST('leftmenu', 'alpha');
+		$url = GETPOST('url', 'alpha');
+		$perms = GETPOST('perms', 'alpha');
+		$target = GETPOST('target', 'alpha');
+		$user = GETPOST('user', 'alpha');
+
+	if (!$error) {
+		if ($type == 'top') {
+			$modifiedMenu = "
+		\$this->menu[\$r++] = array(
+			'fk_menu' =>'".$fk_menu."',
+			'type' =>'".$type."',
+			'titre' =>'".$titre."',
+			'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'),
+			'mainmenu'=>'".$menus[$key]['mainmenu']."',
+			'leftmenu' =>'".$menus[$key]['leftmenu']."',
+			'url' =>'".$url."',
+			'langs'=>'".$menus[$key]['langs']."', 
+			'position'=>1000 + \$r,
+			'enabled'=>'".$menus[$key]['enabled']."', 
+			'perms' =>'".$perms."',
+			'target'=>'".$target."',
+			'user'=>".$user.", 
+		);";
+
+
+			dolReplaceInFile($moduledescriptorfile, array($menuTomodify => ''));
+			if (strtolower($titre) != strtolower($menus[$key]['titre'])) {
+				dolReplaceInFile($moduledescriptorfile, array('/*TOPMENU '.strtolower($menus[$key]['titre']).'*/' => '/*TOPMENU '.strtolower($titre).'*/', '/*END TOPMENU '.strtolower($menus[$key]['titre']).'*/' => '/*END TOPMENU '.strtolower($titre).'*/'));
+			}
+			setEventMessages($langs->trans('MenuUpdatedSuccessfuly'), null);
+		}
+
+		if ($type == 'left') {
+			$modifiedMenu = "
+		\$this->menu[\$r++] = array(
+			'fk_menu' =>'".$fk_menu."',
+			'type' =>'".$type."',
+			'titre' =>'".$titre."',
+			'mainmenu'=>'".$menus[$key]['mainmenu']."',
+			'leftmenu' =>'".$menus[$key]['leftmenu']."',
+			'url' =>'".$url."',
+			'langs'=>'".$menus[$key]['langs']."', 
+			'position'=>1000 + \$r,
+			'enabled'=>'isModEnabled(\"".strtolower($module)."\")', 
+			'perms' =>'".$perms."',
+			'target'=>'".$target."',
+			'user'=>'".$user."', 
+		);";
+
+			dolReplaceInFile($moduledescriptorfile, array($menuTomodify => $modifiedMenu));
+			setEventMessages($langs->trans('MenuUpdatedSuccessfuly'), null);
+		}
+	}
+	header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
+	//exit;
+}
 
 /*
  * View
@@ -4126,7 +4411,25 @@ if ($module == 'initmodule') {
 		if ($tab == 'menus') {
 			print '<!-- tab=menus -->'."\n";
 			$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
+			$dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
+			$destdir = $dirins.'/'.strtolower($module);
+			$listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
+			$objects = array();
+			foreach ($listofobject as $fileobj) {
+				if (preg_match('/^api_/', $fileobj['name'])) {
+					continue;
+				}
+				if (preg_match('/^actions_/', $fileobj['name'])) {
+					continue;
+				}
 
+				$tmpcontent = file_get_contents($fileobj['fullname']);
+				$reg = array();
+				if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
+					$objectnameloop = $reg[1];
+					$objects[] = $objectnameloop;
+				}
+			}
 			$menus = $moduleobj->menu;
 
 			if ($action != 'editfile' || empty($file)) {
@@ -4155,10 +4458,10 @@ if ($module == 'initmodule') {
 				print '<table class="noborder small">';
 
 				print '<tr class="liste_titre">';
-				print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'thsticky ');
+				print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ');
 				print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
 				print_liste_field_titre("LinkToParentMenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-				print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
+				print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center');
 				print_liste_field_titre("mainmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
 				print_liste_field_titre("leftmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
 				print_liste_field_titre("URL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->transnoentitiesnoconv('DetailUrl'));
@@ -4167,76 +4470,167 @@ if ($module == 'initmodule') {
 				print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailEnabled'));
 				print_liste_field_titre("Rights", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailRight'));
 				print_liste_field_titre("Target", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailTarget'));
-				print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ', $langs->trans('DetailUser'));
+				print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailUser'));
+				print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ', $langs->trans(''));
+
 				print "</tr>\n";
+				$r = count($menus)+1;
+				// for adding menu on module
+				print '<tr>';
+				print '<td class="center"><input type="hidden" readonly class="center maxwidth50" name="propenabled" value="#"></td>';
+				print '<td class="center">';
+				print '<select class="center maxwidth50" name="type">';
+				print '<option value="">'.$langs->trans("........").'</option><option value="'.dol_escape_htmltag("left").'">left</option><option value="'.dol_escape_htmltag("top").'">top</option>';
+				print '</select></td>';
+				print '<td class="center"><input type="text" class="center maxwidth10" readonly name="fk_menu" value="'.dol_escape_htmltag(GETPOST('fk_menu', 'alpha')).'"></td>';
+				print '<td class="center"><input type="text" class="center maxwidth100" name="titre" value="'.dol_escape_htmltag(GETPOST('titre', 'alpha')).'"></td>';
+				print '<td class="center"><input type="text" class="center maxwidth50" name="mainmenu" value="'.strtolower($module).'"></td>';
+				print '<td class="center">';
+				print '<select name="leftmenu">';
+				print '<option value="">'.$langs->trans("........").'</option>';
+				foreach ($objects as $obj) {
+					print "<option value=".strtolower($obj).">".$obj."</option>";
+				}
+				print '</select>';
+				print '</td>';
+				print '<td class="center"><input type="text" class="left maxwidth30" name="url" value="'.dol_escape_htmltag(GETPOST('url', 'alpha')).'"></td>';
+				print '<td class="center"><input type="text" class="left maxwidth50" name="langs" value="'.strtolower($module).'@'.strtolower($module).'"></td>';
+				print '<td class="center"><input type="hidden" class="center maxwidth50 tdstickygray" name="position" value="'.$r.'" readonly></td>';
+				print '<td class="center"><input type="text" class="center maxwidth1000" name="enabled" value="'.dol_escape_htmltag('isModEnabled("'.strtolower($module).'")').'"></td>';
+				print '<td class="center"><input type="text" class="center maxwidth50" name="perms" value="'.dol_escape_htmltag(GETPOST('perms', 'int')).'"></td>';
+				print '<td class="center"><input type="text" class="center maxwidth50" name="target" value="'.dol_escape_htmltag(GETPOST('target', 'alpha')).'"></td>';
+				print '<td class="center"><select class="center maxwidth10" name="user"><option value="2">'.$langs->trans("AllMenus").'</option><option value="0">'.$langs->trans("Internal").'</option><option value="1">'.$langs->trans("External").'</option></select></td>';
+
+				print '<td class="center tdstickyright tdstickyghostwhite">';
+				print '<input type="submit" class="button" name="add" value="'.$langs->trans("Add").'">';
+				print '</td>';
+				print '</tr>';
 
 				if (count($menus)) {
 					$i = 0;
 					foreach ($menus as $menu) {
 						$i++;
 
-						print '<tr class="oddeven">';
+						$propFk_menu = !empty($menu['fk_menu']) ? $menu['fk_menu'] : GETPOST('fk_menu');
+						$propTitre = !empty($menu['titre']) ? $menu['titre'] : GETPOST('titre');
+						$propLeftmenu = !empty($menu['leftmenu']) ? $menu['leftmenu'] : GETPOST('leftmenu');
+						$propUrl = !empty($menu['url']) ? $menu['url'] : GETPOST('url', 'alpha');
+						$propPerms = !empty($menu['perms']) ? $menu['perms'] : GETPOST('perms');
+						$propUser = !empty($menu['user']) ? $menu['user'] : GETPOST('user');
+						$propTarget = !empty($menu['target']) ? $menu['target'] : GETPOST('target');
+						if ($action == 'editmenu' && GETPOST('menukey', 'int') == ($i-1)) {
+							print '<tr class="oddeven">';
+							print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
+							print '<input type="hidden" name="token" value="'.newToken().'">';
+							print '<input type="hidden" name="action" value="modify_menu">';
+							print '<input type="hidden" name="tab" value="menus">';
+							print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
+							print '<input type="hidden" name="tabobject" value="'.dol_escape_htmltag($tabobject).'">';
+							print '<input type="hidden" name="menukey" value="'.($i-1).'"/>';
+							print '<td class="tdsticky tdstickygray">';
+							print $i;
+							print '</td>';
+							print '<td class="center">
+									<select class="center maxwidth50" name="type">
+										<option value="'.dol_escape_htmltag($menu['type']).'">
+										'.dol_escape_htmltag($menu['type']).'
+										</option>';
+										print '<option value="'.($menu['type'] == 'left' ? 'top' : 'left').'">';
+							if ($menu['type'] == 'left') {
+								print 'top';
+							} else {
+								print 'left';
+							}
+								print '</option>
+									</select>
+									</td>';
+							print '<td class="center"><input type="text" class="center maxwidth10" readonly name="fk_menu" value="'.dol_escape_htmltag($propFk_menu).'"></td>';
+							print '<td class="center"><input type="text" class="center maxwidth100" name="titre" value="'.dol_escape_htmltag($propTitre).'"></td>';
+							print '<td class="center"><input type="text" class="center maxwidth50" name="mainmenu" value="'.strtolower($module).'"></td>';
+							print '<td class="center"><input type="text" class="center maxwidth50"  name="leftmenu" value="'. dol_escape_htmltag($propLeftMenu).'"></td>';
+							print '<td class="center"><input type="text" class="left maxwidth30" name="url" value="'.dol_escape_htmltag($propUrl).'"></td>';
+							print '<td class="center"><input type="text" class="left maxwidth50" name="langs" value="'.strtolower($module).'@'.strtolower($module).'"></td>';
+							print '<td class="center"><input type="text" class="center maxwidth50 tdstickygray" name="position" value="'.(1000+$r-1).'" readonly></td>';
+							print '<td class="center"><input type="text" class="center maxwidth1000" name="enabled" value="'.dol_escape_htmltag('isModEnabled("'.strtolower($module).'")').'"></td>';
+							print '<td class="center"><input type="text" class="center maxwidth50" name="perms" value="'.dol_escape_htmltag($propPerms).'"></td>';
+							print '<td class="center"><input type="text" class="center maxwidth50" name="target" value="'.dol_escape_htmltag($propTarget).'"></td>';
+							print '<td class="center"><select class="center maxwidth10" name="user"><option value="2">'.$langs->trans("AllMenus").'</option><option value="0">'.$langs->trans("Internal").'</option><option value="1">'.$langs->trans("External").'</option></select></td>';
+							print '<td class="center tdstickyright tdstickyghostwhite">';
+							print '<input class="reposition button smallpaddingimp" type="submit" name="edit" value="'.$langs->trans("Modify").'">';
+							print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
+							print '</td>';
+							print '</form>';
+							print '</tr>';
+						} else {
+							print '<tr class="oddeven">';
 
-						print '<td class="tdsticky tdstickygray">';
-						print $i;
-						print '</td>';
+							print '<td class="tdsticky tdstickygray">';
+							print '<input type="hidden" name="menukey" value="'.($i-1).'"/>';
+							print $i;
+							print '</td>';
 
-						print '<td>';
-						print dol_escape_htmltag($menu['type']);
-						print '</td>';
+							print '<td>';
+							print dol_escape_htmltag($menu['type']);
+							print '</td>';
 
-						print '<td>';
-						print dol_escape_htmltag($menu['fk_menu']);
-						print '</td>';
+							print '<td>';
+							print dol_escape_htmltag($menu['fk_menu']);
+							print '</td>';
 
-						print '<td>';
-						print dol_escape_htmltag($menu['titre']);
-						print '</td>';
+							print '<td>';
+							print dol_escape_htmltag($menu['titre']);
+							print '</td>';
 
-						print '<td>';
-						print dol_escape_htmltag($menu['mainmenu']);
-						print '</td>';
+							print '<td>';
+							print dol_escape_htmltag($menu['mainmenu']);
+							print '</td>';
 
-						print '<td>';
-						print !empty($menu['leftmenu']) ? dol_escape_htmltag($menu['leftmenu']) : '';
-						print '</td>';
+							print '<td>';
+							print dol_escape_htmltag($menu['leftmenu']);
+							print '</td>';
 
-						print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($menu['url']).'">';
-						print dol_escape_htmltag($menu['url']);
-						print '</td>';
+							print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($menu['url']).'">';
+							print dol_escape_htmltag($menu['url']);
+							print '</td>';
 
-						print '<td>';
-						print dol_escape_htmltag($menu['langs']);
-						print '</td>';
+							print '<td>';
+							print dol_escape_htmltag($menu['langs']);
+							print '</td>';
 
-						print '<td class="right">';
-						print dol_escape_htmltag($menu['position']);
-						print '</td>';
+							print '<td class="center">';
+							print dol_escape_htmltag($menu['position']);
+							print '</td>';
 
-						print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['enabled']).'">';
-						print dol_escape_htmltag($menu['enabled']);
-						print '</td>';
+							print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['enabled']).'">';
+							print dol_escape_htmltag($menu['enabled']);
+							print '</td>';
 
-						print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['perms']).'">';
-						print dol_escape_htmltag($menu['perms']);
-						print '</td>';
+							print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['perms']).'">';
+							print dol_escape_htmltag($menu['perms']);
+							print '</td>';
 
-						print '<td>';
-						print dol_escape_htmltag($menu['target']);
-						print '</td>';
+							print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['target']).'">';
+							print dol_escape_htmltag($menu['target']);
+							print '</td>';
 
-						print '<td class="right">';
-						if ($menu['user'] == 2) {
-							print $langs->trans("AllMenus");
-						} elseif ($menu['user'] == 0) {
-							print $langs->trans('Internal');
-						} elseif ($menu['user'] == 1) {
-							print $langs->trans('External');
-						} else {
-							print $menu['user']; // should not happen
+							print '<td class="center">';
+							if ($menu['user'] == 2) {
+								print $langs->trans("AllMenus");
+							} elseif ($menu['user'] == 0) {
+								print $langs->trans('Internal');
+							} elseif ($menu['user'] == 1) {
+								print $langs->trans('External');
+							} else {
+								print $menu['user']; // should not happen
+							}
+							print '</td>';
+							print '<td class="center tdstickyright tdstickyghostwhite">';
+							if ($menu['titre']!= 'Module'.$module.'Name') {
+								print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=editmenu&token='.newToken().'&menukey='.urlencode($i-1).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_edit().'</a>';
+								print '<a class="marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=deletemenu&token='.newToken().'&menukey='.urlencode($i-1).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_delete().'</a>';
+							}
+							print '</td>';
 						}
-						print '</td>';
-
 						print '</tr>';
 					}
 				} else {