Как удалить пункты меню администратора, добавленные плагинами?
У меня есть следующий код, который очищает множество неиспользуемых элементов в области администрирования:
add_action( 'admin_menu', 'my_remove_menu_pages' );
function my_remove_menu_pages() {
remove_menu_page( 'edit.php' ); //Записи
remove_menu_page( 'upload.php' ); //Медиафайлы
remove_menu_page( 'edit-comments.php' ); //Комментарии
remove_menu_page( 'themes.php' ); //Внешний вид
remove_menu_page( 'users.php' ); //Пользователи
remove_menu_page( 'tools.php' ); //Инструменты
remove_menu_page( 'options-general.php' ); //Настройки
};
Однако есть два пункта меню, которые были добавлены плагинами.
Когда я навожу курсор на каждый пункт меню, ссылки выглядят так:
/wp-admin/edit.php?post_type=acf
/wp-admin/admin.php?page=wpcf7
Есть ли способ скрыть и эти страницы меню тоже?

Вам нужно использовать правильные хуки (которые не всегда совпадают с URL-адресами/слагами), и не помешает использовать хук, который срабатывает позже (например, 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' );
}
Для отладки можно использовать следующий код:
add_action( 'admin_init', 'wpse_136058_debug_admin_menu' );
function wpse_136058_debug_admin_menu() {
echo '<pre>' . print_r( $GLOBALS[ 'menu' ], TRUE) . '</pre>';
}
В моем случае для меню плагина Contact Form 7 это выводит следующее:
[27] => Array
(
[0] => Форма
[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
)
Элемент массива с ключом 2
— это то, что вам нужно: wpcf7
.

Показать, как выгрузить меню и найти, что использовать для remove_menu_page()
, было огромной помощью — научил меня ловить рыбу, а не просто дал рыбу!

Для ACF есть лучший подход, см. документацию

// ПЛАГИНЫ, КОТОРЫЕ ДОБАВЛЯЮТСЯ КАК ПОДМЕНЮ В ПАНЕЛИ УПРАВЛЕНИЯ
// ЕСЛИ URL ВЫГЛЯДИТ ТАК, КАК НИЖЕ - НАМ НУЖНА ПЕРЕМЕННАЯ PAGE (ТО, ЧТО ИДЕТ ПОСЛЕ PAGE=)
// http://example.com/wp-admin/index.php?page=iconize-plugin-update-notifier
remove_submenu_page( 'index.php', 'iconize-plugin-update-notifier' );
// ИЛИ НАПРИМЕР ПОДМЕНЮ WOOCOMMERCE В ПАНЕЛИ УПРАВЛЕНИЯ
remove_submenu_page( 'index.php', 'wc-about' ); //WOO
remove_submenu_page( 'index.php', 'wc-credits' ); //WOO
remove_submenu_page( 'index.php', 'wc-translators' ); //WOO
// ПОЛЬЗОВАТЕЛЬСКИЕ ТИПЫ ЗАПИСЕЙ В ВЕРХНЕМ МЕНЮ
remove_menu_page( 'edit.php?post_type={$POST_TYPE}' ); //СМОТРИМ, ЧТО ИДЕТ ПОСЛЕ POST_TYPE В URL
remove_menu_page( 'edit.php?post_type=testimonials-widget' ); //WIDGET ТЕСТИМОНИАЛОВ
remove_menu_page( 'edit.php?post_type=product' ); //WOOCOMMERCE
// ПОДМЕНЮ ПОЛЬЗОВАТЕЛЬСКИХ ТИПОВ ЗАПИСЕЙ
remove_submenu_page( 'edit.php?post_type={$POST_TYPE}', '{$SUBMENU_URL_VARIABLE}' ); //ПРИМЕР ФОРМАТА
// ЕСЛИ URL ВЫГЛЯДИТ ТАК:
// http://example.com/wp-admin/edit.php?post_type=testimonials-widget&page=testimonialswidget_settings
// НАМ НУЖНО ПОСМОТРЕТЬ, ЧТО ИДЕТ ПОСЛЕ PAGE
remove_submenu_page( 'edit.php?post_type=testimonials-widget', 'testimonialswidget_settings' ); //WIDGET ТЕСТИМОНИАЛОВ
// ДРУГИЕ ПРИМЕРЫ
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
ВЫ МОЖЕТЕ ОТЛАДЫВАТЬ ВСЕ ЭТО С ПОМОЩЬЮ СЛЕДУЮЩЕГО КОДА, ЧТОБЫ ПОЛУЧИТЬ ВСЮ НЕОБХОДИМУЮ ИНФОРМАЦИЮ:
if (!function_exists('debug_admin_menus')):
function debug_admin_menus() {
if ( !is_admin())
return;
global $submenu, $menu, $pagenow;
if ( current_user_can('manage_options') ) { // ТОЛЬКО ДЛЯ АДМИНИСТРАТОРА
if( $pagenow == 'index.php' ) { // ВЫВОДИТСЯ НА ПАНЕЛИ УПРАВЛЕНИЯ
echo '<pre>'; print_r( $menu ); echo '</pre>'; // МЕНЮ ВЕРХНЕГО УРОВНЯ
echo '<pre>'; print_r( $submenu ); echo '</pre>'; // ПОДМЕНЮ
}
}
}
add_action( 'admin_notices', 'debug_admin_menus' );
endif;
Ключи дадут вам значения массива, которые позволяют делать все это с глобальными переменными WordPress (хотя это и не рекомендуется)
function remove_submenus_all_please() {
if ( !is_admin())
return;
global $submenu;
unset($submenu['index.php'][10]); // Удаляет "Обновления"
//Меню записей
// unset($submenu['edit.php'][5]); // Ведущий к списку доступных записей для редактирования
// unset($submenu['edit.php'][10]); // Добавить новую запись
// unset($submenu['edit.php'][15]); // Удаляет категории
// unset($submenu['edit.php'][16]); // Удаляет метки записей
}
add_action('admin_menu', 'remove_submenus_all_please', 999);
А чтобы удалить для определенных пользователей, просто делаем то же самое, но с добавлением проверки прав:
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);
И ЧТОБЫ ОБЪЕДИНИТЬ ВСЕ ВМЕСТЕ, ПОЧЕМУ БЫ НЕ СОКРАТИТЬ НАШ КОД? МОЖНО ИСПОЛЬЗОВАТЬ МАССИВЫ, ЧТОБЫ НЕ ПИСАТЬ remove_submenu_page 50 РАЗ. Это также работает с узлами панели инструментов:
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

Вероятно, вам нужно установить приоритет add_action на более высокое число и конкретно указать эти две новые ссылки, как показано ниже:
add_action( 'admin_menu', 'my_remove_menu_pages', 999 );
function my_remove_menu_pages() {
remove_menu_page( 'edit.php' ); //Записи
remove_menu_page( 'upload.php' ); //Медиафайлы
remove_menu_page( 'edit-comments.php' ); //Комментарии
remove_menu_page( 'themes.php' ); //Внешний вид
remove_menu_page( 'users.php' ); //Пользователи
remove_menu_page( 'tools.php' ); //Инструменты
remove_menu_page( 'options-general.php' ); //Настройки
remove_menu_page( 'edit.php?post_type=acf' );
remove_menu_page( 'wpcf7' );
};
Advanced Custom Fields также предоставляет справочный документ о том, как это сделать для их меню:
http://www.advancedcustomfields.com/resources/how-to/how-to-hide-acf-menu-from-clients/
Contact Form 7 также имеет собственный способ ограничения видимости меню:
http://contactform7.com/restricting-access-to-the-administration-panel/

Обновление
Я создал сниппет кода с более надежной функцией, которая работает как с основными меню, так и с подменю.
Оригинальный ответ
Вместо того чтобы указывать меню, которые нужно удалить, укажите меню, которые нужно оставить :)
add_action('admin_init', 'nwcm_admin_init');
function nwcm_admin_init()
{
// Удаляем ненужные меню
$menus_to_stay = array(
// Менеджер клиентов
'nwcm',
// Консоль
'index.php',
// Пользователи
'users.php'
);
foreach ($GLOBALS['menu'] as $key => $value) {
if (!in_array($value[2], $menus_to_stay)) remove_menu_page($value[2]);
}
}
Таким образом вам не нужно искать названия плагинов и изменять код при добавлении новых плагинов..

Конечно, вы можете указать только те элементы, которые хотите удалить. Взгляните на код ниже:
/wordpress/wp-content/plugins/your_plugin/your_plugin.php :
add_action('admin_init', 'nwcm_admin_init');
function nwcm_admin_init()
{
// Удаление ненужных меню
$menus_to_remove = array(
// элементы меню, которые вы хотите удалить
'menu_item_1',
'menu_item_2',
.
.
'menu_item_n'
);
// Чтобы избежать предупреждения, проверя, установлен ли 'menu' И является ли он массивом
if(isset($GLOBALS['menu']) && is_array($GLOBALS['menu'])) {
foreach ($GLOBALS['menu'] as $key => $value) {
//Удалите '!' в условии 'if'.
if (in_array($value[2], $menus_to_remove)) remove_menu_page($value[2]);
}
}
}
Это просто обратный метод numediaweb. Спасибо @numediaweb. Работает отлично.
P.S.: 'menu_item_1/n' -> наведите указатель мыши на элемент меню и получите точную страницу этого элемента меню, отображаемую в ссылке.
