Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Function to hide submenu WordPress

  • SOLVED

I have created a user account "testuser" and am using a custom functions.php file to remove some of the back end dashboard <em>stuff</em> that might overwhelm my client (or that I don't want them to have access to). This is the function that is currently working well:

function remove_admin_menu_items()
{
global $menu;
global $submenu;
global $current_user;
get_currentuserinfo();

if($current_user->user_login == 'testuser')
{
unset($menu[10]); // media

unset($submenu['options-general.php'][10]); // settings - general
}
}
add_action( '_admin_menu', 'remove_admin_menu_items' );


I have to double check the admin menu.php core file to make sure I have the menu # correct, but with this I can pretty much hide anything from "testuser". The problem, however, comes with certain sub menu items that don't actually have their own menu link. More specifically, I am using the [[LINK href="http://planetozh.com/blog/my-projects/wordpress-admin-menu-drop-down-css/"]]Ozh admin drop down menu plugin[[/LINK]]. I can't seem to find the correct $submenu variable. The link itself is options-general.php?page=ozh_admin_menu. I contacted Ozh and he's suggested I write a function using a filter from the plugin itself, but the problem is that is a little beyond me. For instance:
function myplugin_remove_items( $menu ) {
// do something with $menu
// var_dump( $menu ) for instance to see what it's like before hacking
// ...

return $menu; // a filter must return a value
}
add_filter( 'post_ozh_adminmenu_ozh_menu', 'myplugin_remove_items' );

I'm not sure how to find the correct filter, or how to create the function to work properly. Can anyone help me with the correct function? Either to append to the one above that works, or to write a completely separate new one specifically for the Ozh settings link.

Answers (2)

2010-12-08

rilwis answers:

Here's the code:

function remove_admin_menu_items() {
global $menu;
global $submenu;
global $current_user;

get_currentuserinfo();
if($current_user->user_login == 'testuser') {
unset($menu[10]); // media
unset($submenu['options-general.php'][10]); // settings - general

foreach ($submenu['options-general.php'] as $key => $item) {
if (in_array('ozh_admin_menu', $item)) { // ozh sub menu
unset($submenu['options-general.php'][$key]);
}
}
}
}
add_action( 'admin_menu', 'remove_admin_menu_items' );


The "_admin_menu" (with underscore) hook happens right after core menu items are defined. But the "admin_menu" (without underscore) hook happens after user-defined menu items are added.

I changed the hook and add some check for menu item to hide it. You can customize it to fit your needs.

2010-12-08

Rashad Aliyev answers:

Hello,


I make a solution for you. Define your testuser as subscriber.
Then remove all of menu and only show user's profile. You can improve this code also.

best regards


function agent_remove_menus () {
global $menu, $submenu;

// current user is an Editor, do nothing/ return //
if (current_user_can('level_5'))
return;

// define main menus & sub-menus allowed //
// <strong>No we dont want him seeing the Dashboard either</strong> //
$allowed_menu = array('edit.php', 'profile.php');
$allowed_smenu = array('post-new.php', 'profile.php');

end ($menu);
while (prev($menu)){
if(!in_array($menu[key($menu)][2], $allowed_menu)) {
unset($menu[key($menu)]);
}
}

end ($menu);
while (prev($menu)){
$menu_item = $menu[key($menu)];
$submenu_item = $submenu[$menu_item[2]];

if($submenu_item != NULL && !empty($submenu_item)){

if(is_array($submenu_item)){
foreach($submenu_item as $id => $smenu){
if(!in_array($smenu[2] , $allowed_smenu))
unset($submenu[$menu_item[2]][$id]);
}
}
else
{
if(!in_array($submenu_item , $allowed_smenu))
unset($submenu[$menu_item[2]]);
}
}
}

// see if the requested page is allowed or not. //
$page_ok = false;
foreach($allowed_smenu as $smenu)
{
$result = stripos($_SERVER['REQUEST_URI'], '/'.$smenu);
if ($result!==false)
$page_ok = true;
}

// if not, send him to the profile page //
if($page_ok == false)
wp_redirect(get_option('siteurl') . '/wp-admin/profile.php');
}
add_action('admin_menu' , 'agent_remove_menus');




Rashad Aliyev comments:

Other solution: You can define it manually from this. (which code below) $restricted = array(__('Dashboard'), __('Posts'), __('Media'), __('Links'), __('Pages'), __('Appearance'), __('Tools'), __('Users'), __('Settings'), __('Comments'), __('Plugins'));


function remove_submenu() {
global $submenu;
//remove Theme editor
unset($submenu['themes.php'][10]);
}

function remove_menu() {
global $menu;
//remove post top level menu
unset($menu[5]);
}
add_action('admin_head', 'remove_menu');
add_action('admin_head', 'remove_submenu');
//We can remove a set of admin menu by doing this.

function remove_menus () {
global $menu;
$restricted = array(__('Dashboard'), __('Posts'), __('Media'), __('Links'), __('Pages'), __('Appearance'), __('Tools'), __('Users'), __('Settings'), __('Comments'), __('Plugins'));
end ($menu);
while (prev($menu)){
$value = explode(' ',$menu[key($menu)][0]);
if(in_array($value[0] != NULL?$value[0]:"" , $restricted)){unset($menu[key($menu)]);}
}
}
add_action('admin_menu', 'remove_menus');



Ramsey comments:

Thanks but I didn't want to use the $restricted array, or to have to use userlevels to restrict things.