¿Cómo eliminar páginas del menú de administración insertadas por plugins?
Tengo el siguiente código, que limpia muchos elementos que no se van a utilizar dentro del área de administración:
add_action( 'admin_menu', 'my_remove_menu_pages' );
function my_remove_menu_pages() {
remove_menu_page( 'edit.php' ); //Entradas
remove_menu_page( 'upload.php' ); //Medios
remove_menu_page( 'edit-comments.php' ); //Comentarios
remove_menu_page( 'themes.php' ); //Apariencia
remove_menu_page( 'users.php' ); //Usuarios
remove_menu_page( 'tools.php' ); //Herramientas
remove_menu_page( 'options-general.php' ); //Ajustes
};
Sin embargo, hay dos elementos del menú que han sido insertados por plugins.
Cuando paso el cursor sobre cada elemento del menú, dice que los enlaces son:
/wp-admin/edit.php?post_type=acf
/wp-admin/admin.php?page=wpcf7
¿Hay alguna manera de ocultar también estas páginas del menú?

Necesitas utilizar los hooks correctos (que no siempre son los mismos que las URLs/slugs), y no está de más usar un hook que se ejecute más tarde (por ejemplo, admin_init
):
add_action( 'admin_init', 'wpse_136058_remove_menu_pages' );
function wpse_136058_remove_menu_pages() {
remove_menu_page( 'edit.php?post_type=acf' );
remove_menu_page( 'wpcf7' );
}
Puedes usar lo siguiente para depurar:
add_action( 'admin_init', 'wpse_136058_debug_admin_menu' );
function wpse_136058_debug_admin_menu() {
echo '<pre>' . print_r( $GLOBALS[ 'menu' ], TRUE) . '</pre>';
}
Esto devuelve (en mi configuración) lo siguiente para el menú del plugin Contact Form 7:
[27] => Array
(
[0] => Formulario
[1] => wpcf7_read_contact_forms
[2] => wpcf7
[3] => Contact Form 7
[4] => menu-top menu-icon-generic toplevel_page_wpcf7 menu-top-last
[5] => toplevel_page_wpcf7
[6] => none
)
El elemento del array con la clave 2
es lo que estás buscando: wpcf7
.

Mostrar cómo listar el menú y encontrar qué usar para remove_menu_page()
fue de gran ayuda — ¡me enseñó a pescar en lugar de sólo darme el pescado!

Para ACF hay un mejor enfoque, revisa la documentación

// PLUGINS QUE AÑADEN SUBMENÚS AL ESCRITORIO
// SI ESTA ES LA URL DE ABAJO - LA VARIABLE PAGE ES LO QUE NECESITO ( LO QUE VENGA DESPUÉS DE PAGE= )
// http://example.com/wp-admin/index.php?page=iconize-plugin-update-notifier
remove_submenu_page( 'index.php', 'iconize-plugin-update-notifier' );
// O POR EJEMPLO SUBMENÚS DE WOOCOMMERCE EN EL ESCRITORIO
remove_submenu_page( 'index.php', 'wc-about' ); //WOO
remove_submenu_page( 'index.php', 'wc-credits' ); //WOO
remove_submenu_page( 'index.php', 'wc-translators' ); //WOO
// TIPOS DE POST PERSONALIZADOS EN NIVEL SUPERIOR
remove_menu_page( 'edit.php?post_type={$POST_TYPE}' ); //BUSCA LO QUE VIENE DESPUÉS DE POST TYPE EN LA URL
remove_menu_page( 'edit.php?post_type=testimonials-widget' ); //TESTIMONIALS WIDGET
remove_menu_page( 'edit.php?post_type=product' ); //WOOCOMMERCE
// SUBMENÚS DE TIPOS DE POST PERSONALIZADOS
remove_submenu_page( 'edit.php?post_type={$POST_TYPE}', '{$SUBMENU_URL_VARIABLE}' ); //EJEMPLO DE FORMATO
// ASÍ QUE SI LA URL ES LA SIGUIENTE
// http://example.com/wp-admin/edit.php?post_type=testimonials-widget&page=testimonialswidget_settings
// NECESITAS VER QUÉ VIENE DESPUÉS DE PAGE
remove_submenu_page( 'edit.php?post_type=testimonials-widget', 'testimonialswidget_settings' ); //TESTIMONIALS WIDGET
// OTROS EJEMPLOS
remove_menu_page( 'revslider' ); // REVSLIDER
remove_menu_page( 'woocommerce' ); // WOOCOMMERCE
remove_menu_page( 'order-post-types-shop_order' ); // WOOCOMMERCE
remove_menu_page( 'order-post-types-shop_coupons' ); // WOOCOMMERCE
remove_menu_page( 'shortcodes-ultimate' ); // SHORTCODES ULTIMATE
remove_menu_page( 'wp-admin-microblog/wp-admin-microblog.php' ); // ADMIN MICROBLOG
remove_menu_page( 'snippets' ); //CODE SNIPPETS
remove_menu_page( 'gf_edit_forms' ); // GRAVITY FORMS
remove_submenu_page( 'gf_edit_forms', 'gf_settings' ); // GRAVITY FORMS
remove_submenu_page( 'gf_edit_forms', 'gf_export' ); // GRAVITY FORMS
remove_submenu_page( 'gf_edit_forms', 'gf_update' ); // GRAVITY FORMS
remove_submenu_page( 'gf_edit_forms', 'gf_addons' ); // GRAVITY FORMS
remove_submenu_page( 'gf_edit_forms', 'gf_help' ); // GRAVITY FORMS
remove_submenu_page( 'cleverness-to-do-list', 'cleverness-to-do-list-settings' ); //Cleverness TODO
PUEDES DEPURAR TODO ESTO CON LO SIGUIENTE PARA OBTENER TODA LA INFORMACIÓN QUE NECESITAS:
if (!function_exists('debug_admin_menus')):
function debug_admin_menus() {
if ( !is_admin())
return;
global $submenu, $menu, $pagenow;
if ( current_user_can('manage_options') ) { // SOLO HACER ESTO PARA ADMIN
if( $pagenow == 'index.php' ) { // SE IMPRIME EN EL ESCRITORIO
echo '<pre>'; print_r( $menu ); echo '</pre>'; // MENÚS DE NIVEL SUPERIOR
echo '<pre>'; print_r( $submenu ); echo '</pre>'; // SUBMENÚS
}
}
}
add_action( 'admin_notices', 'debug_admin_menus' );
endif;
Las claves te darán los valores de array que te permiten hacer todo esto con variables globales de WordPress (aunque no se recomienda)
function remove_submenus_all_please() {
if ( !is_admin())
return;
global $submenu;
unset($submenu['index.php'][10]); // Elimina Actualizaciones
//Menú de entradas
// unset($submenu['edit.php'][5]); // Lleva al listado de entradas disponibles para editar
// unset($submenu['edit.php'][10]); // Añadir nueva entrada
// unset($submenu['edit.php'][15]); // Eliminar categorías
// unset($submenu['edit.php'][16]); // Elimina etiquetas de entradas
}
add_action('admin_menu', 'remove_submenus_all_please', 999);
Y para eliminar para ciertos usuarios simplemente haz lo mismo pero añadiendo capacidades:
function remove_by_caps_admin_menu() {
if ( !is_admin())
return;
if ( !current_user_can('manage_options') ) {
remove_menu_page( 'revslider' ); // REVSLIDER
} elseif ( !current_user_can('edit_posts') ) {
remove_menu_page( 'woocommerce' ); // WOO
} else {
}
}
add_action('admin_menu', 'remove_by_caps_admin_menu', 999);
Y PARA UNIRLO TODO, ¿POR QUÉ NO ACORTAR NUESTRO CÓDIGO? PUEDES USAR ARRAYS PARA EVITAR ESCRIBIR remove_submenu_page 50 VECES. Esto también funciona con los nodos de la barra de herramientas:
if ( !function_exists( 'remove_admin_menupages_in_array' ) ) {
function remove_admin_menupages_in_array() {
if ( !is_admin())
return;
$admin_menus = array(
'revslider',
'woocommerce',
'shortcodes-ultimate',
);
foreach ( $admin_menus as $menu_page ) {
if ( !current_user_can('manage_options') ) {
remove_menu_page( $menu_page );
}
} // foreach
} // function
add_action('admin_menu', 'remove_admin_menupages_in_array', 9999);
} // exists

Probablemente necesites establecer la prioridad (priority) del add_action a un número más alto y apuntar específicamente a esos dos nuevos enlaces de esta manera:
add_action( 'admin_menu', 'my_remove_menu_pages', 999 );
function my_remove_menu_pages() {
remove_menu_page( 'edit.php' ); //Entradas
remove_menu_page( 'upload.php' ); //Medios
remove_menu_page( 'edit-comments.php' ); //Comentarios
remove_menu_page( 'themes.php' ); //Apariencia
remove_menu_page( 'users.php' ); //Usuarios
remove_menu_page( 'tools.php' ); //Herramientas
remove_menu_page( 'options-general.php' ); //Ajustes
remove_menu_page( 'edit.php?post_type=acf' );
remove_menu_page( 'wpcf7' );
};
Advanced Custom Fields también proporciona un documento de ayuda sobre cómo hacer esto para su menú aquí:
http://www.advancedcustomfields.com/resources/how-to/how-to-hide-acf-menu-from-clients/
Contact Form 7 también tiene su propia forma de restringir la visibilidad del menú:
http://contactform7.com/restricting-access-to-the-administration-panel/

Actualización
Creé un fragmento de código con una función más robusta que maneja tanto los menús principales como los elementos de submenú.
Respuesta original
En lugar de especificar los menús que quieres eliminar, especifica los menús que deseas conservar :)
add_action('admin_init', 'nwcm_admin_init');
function nwcm_admin_init()
{
// Eliminar menús innecesarios
$menus_to_stay = array(
// Gestor de clientes
'nwcm',
// Escritorio
'index.php',
// Usuarios
'users.php'
);
foreach ($GLOBALS['menu'] as $key => $value) {
if (!in_array($value[2], $menus_to_stay)) remove_menu_page($value[2]);
}
}
De esta manera no tienes que buscar nombres de plugins y modificar el código cuando añades nuevos plugins..

Por supuesto que puedes especificar solo los elementos que quieres eliminar. Echa un vistazo al código a continuación:
/wordpress/wp-content/plugins/your_plugin/your_plugin.php :
add_action('admin_init', 'nwcm_admin_init');
function nwcm_admin_init()
{
// Eliminar menús innecesarios
$menus_to_remove = array(
// elementos del menú que deseas eliminar
'menu_item_1',
'menu_item_2',
.
.
'menu_item_n'
);
// Para evitar mensajes de advertencia, verifica si 'menu' está definido Y es un array
if(isset($GLOBALS['menu']) && is_array($GLOBALS['menu'])) {
foreach ($GLOBALS['menu'] as $key => $value) {
//Elimina el '!' en la condición 'if'.
if (in_array($value[2], $menus_to_remove)) remove_menu_page($value[2]);
}
}
}
Esto es justo lo contrario al método de numediaweb. Gracias @numediaweb. Funciona perfectamente.
P.D.: 'menu_item_1/n' -> coloca el ratón sobre el elemento del menú y obtén la página exacta de ese elemento mostrada en el enlace.
