Dynamic Menu with Auto Delete of Menu Items

Hi,

I created a dynamic menu based on my database pursuant to the Scriptcase tutorial. Here’s my working code located in AppInit and OnLoad events:


//======================Preparation

sc_reset_menu_disable();

sc_reset_menu_delete();

sc_appmenu_reset(‘main_menu’);

//======================Dynamic Menu Creation

sc_appmenu_create(‘main_menu’);

sc_lookup(dsmenu,"
SELECT
id,
parent_item,
label,
application,
parameters,
icon,
hint,
target
FROM
main_menu
ORDER BY
parent_item ASC,
node_order ASC,
label ASC");

foreach({dsmenu} as $arr_menu)
{

$item_id = $arr_menu[0];

$menu_item_id = 'item_'.$arr_menu[0];

if($arr_menu[1] == 0) 
{
	$parent_item = "";
}
else 
{
	$parent_item = 'item_'.$arr_menu[1];
}	

sc_appmenu_add_item(‘main_menu’,
$menu_item_id,
$parent_item,
$arr_menu[2],
$arr_menu[3],
“”,
$arr_menu[5],
$arr_menu[6],
$arr_menu[7]);
}

//====================== Delete menu items not accessible to the user_group

sc_select(rs, "
SELECT id
FROM main_menu
WHERE id != ‘0’ AND id != 1 AND application IN (SELECT app_name FROM groups_apps WHERE group_id = ‘".[glo_group_id]."’ AND priv_access IS NULL) AND id NOT IN (SELECT parent_item FROM main_menu WHERE parent_item != ‘’)
");

while(!$rs->EOF)
{
	$del_item = 'item_'.$rs->fields[0];
	sc_appmenu_remove_item ('main_menu', $del_item);
	
	$rs->MoveNext();
}
$rs->Close();

I need to have it automatically delete/remove menu items that fall under the following criteria:

  1. Auto delete menu items that the user group has no access in the linked applications per Scriptcase Security Module generated tables (do not forget to enable security module in “My Scriptcase” option);
  2. Auto delete menu items (node) that has no active/existing submenu items – when all submenu items were already automatically deleted per criteria #1;
  3. Auto delete menu items (which are not node) that has no linked application.

Any help would be greatly appreciated. I’ve been trying to solve this for weeks now and it’s badly needed. Thanks in advance!

–Mister Grey

PS. I only studied programming via online tutorials so please bear with me.

Does this piece of code not address your first question?

Hi,

Thanks for replying to this thread.

Yes, that code you quoted addressed my first criteria…

I was able to achieve what I needed by changing my approach… Instead of deleting unnecessary menu items, do not create or add them in the first place. Just create the menu items needed… I did this this way:

  1. Create menu items with linked applications in accordance with the authorization table created by the security module.
  2. Then create nodes (could be an empty menu item which is a parent of the menu item that is linked to an application)…
  3. And create parent nodes… Continue creating parent nodes if you have multi level menu…
  4. Run the code in the appinit event and have a menu item (preferably HOME) that will call the menu application if you want to immediately update the menu.

That’s it! A totally and literally dynamic menu!

Would you mind sharing your code mistergrey? That’s exactly what I’m tyring to do. I have the dynamic menu working - but it shows ALL items on the menu whether the user has access or not - and the user gets a bunch of ‘not authorized’ messsages. I just want to show the user only those items they have access to. So I did what you suggest in Step 1 - create the items with linked applications in accordance with authorizations. I am stuck there. How to create nodes & parent nodes & loop through that?

Hi betty,

Apologies for a very late response.

This is what i did.

  1. Create table for the menu

CREATE TABLE tbl_menu (
id int(11) NOT NULL AUTO_INCREMENT,
label varchar(255) DEFAULT NULL,
app_name varchar(255) DEFAULT NULL,
parent_id int(11) DEFAULT NULL,
parameters text,
icon blob,
hint text,
target varchar(16) DEFAULT ‘_self’,
node_order smallint(4) NOT NULL DEFAULT ‘9000’,
PRIMARY KEY (id)
)

  1. Create a menu application named my_menu_app or any name of your preference
  2. Under programming, create a PHP method/function with name and variables: get_Parent_Menu($sql, $child_item_id, $menu_table)
  3. Use this code inside get_Parent_Menu method/function

get_parent_menu($menu_app_name, $sql, $child_item_id, $menu_table_name)
{
sc_lookup(rs_item, $sql . " WHERE id IN (SELECT parent_id FROM $menu_table_name WHERE id = $child_item_id)");

if (isset({rs_item[0][0]})) // Row found
{
foreach({rs_item} as $item)
{
$item_id = ‘item_’ . $item[0];
$child_item_id = $item[0];

if($item[1] == 0)
{
$parent_id = “”;
}
else
{
$parent_id = ‘item_’ . $item[1];
}

sc_appmenu_add_item(
$menu_app_name,
$item_id,
$parent_id,
$item[2],
$item[3],
var_param=$item[4],
$item[5],
$item[6],
$item[7]);

if ($parent_id != “”) {
get_parent_menu($menu_app_name, $sql, $child_item_id, $menu_table_name);
}
}
}
}

  1. Go to event onApplicationInit and type this code

//code by mistergrey.zeroten@gmail.com

$menu_app_name = ‘my_menu_app’;

$menu_table_name = ‘tbl_menu’;

//-------------------------------------------------------------------------
sc_appmenu_reset($menu_app_name);
sc_appmenu_create($menu_app_name);
//-------------------------------------------------------------------------

$sql = "
SELECT
id,
parent_id,
label,
app_name,
parameters,
icon,
hint,
target
FROM $menu_table_name ";

//just modify the sql select query and add the WHERE clause to relate your menu to your authorization table. use the app_name as the reference or link

//================================================== ===================
//Create Menu Items
sc_lookup(rs_item, $sql . $sql_where);

foreach({rs_item} as $item)
{
$item_id = ‘item_’ . $item[0];
$child_item_id = $item[0];

if($item[1] == 0)
{
$parent_id = “”;
}
else
{
$parent_id = ‘item_’ . $item[1];
}

sc_appmenu_add_item(
$menu_app_name,
$item_id,
$parent_id,
$item[2],
$item[3],
var_param=$item[4],
$item[5],
$item[6],
$item[7]);

get_parent_menu($menu_app_name, $sql, $child_item_id, $menu_table_name);
}
//================================================== ===================

//================================================== ===================
//Rearrange Menu Items
sc_lookup(rs_item, $sql . “ORDER BY node_order ASC, name”);

foreach({rs_item} as $item)
{
$item_id = ‘item_’ . $item[0];
$child_item_id = $item[0];

if($item[1] == 0)
{
$parent_id = “”;
}
else
{
$parent_id = ‘item_’ . $item[1];
}

if(sc_appmenu_exist_item($menu_app_name, $item_id))
{
sc_appmenu_remove_item($menu_app_name, $item_id);

sc_appmenu_add_item(
$menu_app_name,
$item_id,
$parent_id,
$item[2],
$item[3],
var_param=$item[4],
$item[5],
$item[6],
$item[7]);
}
}

That’s it! You may now run and enjoy your fully dynamic menu based on your database table.

PS. var_param will receive the parameters from each menu item. optional.

1 Like

Revisiting this again. Thank you for sharing.

This is where I struggle … cannot get the where clause to work in the menu app.

This query works (in mysql, a control app, and SQL Builder - but not the menu app (in either your code or mine)
select id, parent_id, label from sec_menu where app_name IN (select app_name from sec_permissions where priv_access = ‘Y’ AND group_id = ‘1’)

This is what I have in the menu app:
$sql_where = “WHERE app_name IN (SELECT app_name FROM sec_permissions WHERE group_id = ‘[usr_group_id]’ and priv_access = ‘Y’)” ;

I must be overlooking something.

try this…

$sql_where = " WHERE app_name IN (SELECT app_name FROM sec_permissions WHERE group_id = ‘[usr_group_id]’ and priv_access = ‘Y’) " ;

or check the variables in your php method

That’s what I had. Took a different approach and have things working. Thanks for your help!