WordPress как на ладони

admin_menuхук-событиеWP 1.5.0

Позволяет изменить элементы админ-меню.

Этот хук используется для добавления дополнительных подменю и пунктов меню в структуру меню панели администратора функциями add_menu_page(), add_submenu_page() и их производными.

Этот хук нельзя вызывать на хуке admin_init, поскольку admin_init вызывается после admin_menu.

Хук выполняется после создания базовой структуры меню панели администратора.

После этого хука все данные находящиеся в глобальных переменных $menu и $submenu дополнительно обрабатываются:

  • Проверяется право пользователя на доступ к пункту меню (см. current_user_can()). Если доступа нет, то пункт меню будет удален из списка. Название проверяемого права находится в элементе меню под индексом 1 - $data[1].

  • Сортировка меню. Для того чтобы сортировка работала, нужно её включить - делается это через хук add_filter( 'custom_menu_order', '__return_true' );. Затем на хуке add_filter( 'menu_order', 'my_menu_order' ) нужно указать какой именно порядок элементов нам нужен. Пример смотрите здесь.

  • Добавляются CSS классы для элементов меню.

  • Проверка доступа к странице адмники. В конце создания меню происходит проверка доступа - см. user_can_access_admin_page(). На основе текущих данных меню, текущая страница админки проверяется на наличие доступа к ней, если доступа нет, то WP прерывает свою работу с сообщением об ошибке:
    wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );

Использование

add_action( 'admin_menu', 'wp_kama_admin_menu_action' );

/**
 * Function for `admin_menu` action-hook.
 * 
 * @param string $context Empty context.
 *
 * @return void
 */
function wp_kama_admin_menu_action( $context ){

	// action...
}
$context(строка)
Пустая строка.

Примеры

2

#1 Структура глобальных переменных $menu и $submenu

global $menu:

/*
$menu = Array (
	[2] => Array (
		[0] => Dashboard
		[1] => read
		[2] => index.php
		[3] =>
		[4] => menu-top menu-top-first menu-icon-dashboard
		[5] => menu-dashboard
		[6] => dashicons-dashboard
	)

	[4] => Array (
		[0] =>
		[1] => read
		[2] => separator1
		[3] =>
		[4] => wp-menu-separator
	)

	[10] => Array (
		[0] => Media
		[1] => upload_files
		[2] => upload.php
		[3] =>
		[4] => menu-top menu-icon-media
		[5] => menu-media
		[6] => dashicons-admin-media
	)

	[25] => Array (
		[0] => Comments <span class="awaiting-mod count-0"><span class="pending-count" aria-hidden="true">0</span><span class="comments-in-moderation-text screen-reader-text">0 Comments in moderation</span></span>
		[1] => edit_posts
		[2] => edit-comments.php
		[3] =>
		[4] => menu-top menu-icon-comments
		[5] => menu-comments
		[6] => dashicons-admin-comments
	)

	[5] => Array (
		[0] => Posts
		[1] => edit_posts
		[2] => edit.php
		[3] =>
		[4] => menu-top menu-icon-post open-if-no-js
		[5] => menu-posts
		[6] => dashicons-admin-post
	)

	[20] => Array (
		[0] => Pages
		[1] => edit_pages
		[2] => edit.php?post_type=page
		[3] =>
		[4] => menu-top menu-icon-page
		[5] => menu-pages
		[6] => dashicons-admin-page
	)

	[59] => Array (
		[0] =>
		[1] => read
		[2] => separator2
		[3] =>
		[4] => wp-menu-separator
	)

	[60] => Array (
		[0] => Appearance
		[1] => switch_themes
		[2] => themes.php
		[3] =>
		[4] => menu-top menu-icon-appearance
		[5] => menu-appearance
		[6] => dashicons-admin-appearance
	)

	[65] => Array (
		[0] => Plugins
		[1] => activate_plugins
		[2] => plugins.php
		[3] =>
		[4] => menu-top menu-icon-plugins
		[5] => menu-plugins
		[6] => dashicons-admin-plugins
	)

	[70] => Array (
		[0] => Users
		[1] => list_users
		[2] => users.php
		[3] =>
		[4] => menu-top menu-icon-users
		[5] => menu-users
		[6] => dashicons-admin-users
	)

	[75] => Array (
		[0] => Tools
		[1] => edit_posts
		[2] => tools.php
		[3] =>
		[4] => menu-top menu-icon-tools
		[5] => menu-tools
		[6] => dashicons-admin-tools
	)

	[80] => Array (
		[0] => Settings
		[1] => manage_options
		[2] => options-general.php
		[3] =>
		[4] => menu-top menu-icon-settings
		[5] => menu-settings
		[6] => dashicons-admin-settings
	)

	[99] => Array (
		[0] =>
		[1] => read
		[2] => separator-last
		[3] =>
		[4] => wp-menu-separator
	)

	[99.31337] => Array (
		[0] => SEO <span class="update-plugins count-0"><span class="plugin-count" aria-hidden="true">0</span><span class="screen-reader-text">0 notifications</span></span>
		[1] => wpseo_manage_options
		[2] => wpseo_dashboard
		[3] => Yoast SEO: Dashboard
		[4] => menu-top toplevel_page_wpseo_dashboard
		[5] => toplevel_page_wpseo_dashboard
		[6] => data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgc3R5bGU9ImZpbGw6IzgyODc4YyIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHJvbGU9ImltZyIgYXJpYS1oaWRkZW49InRydWUiIGZvY3VzYWJsZT0iZmFsc2UiPjxnPjxnPjxnPjxnPjxwYXRoIGQ9Ik0yMDMuNiwzOTVjNi44LTE3LjQsNi44LTM2LjYsMC01NGwtNzkuNC0yMDRoNzAuOWw0Ny43LDE0OS40bDc0LjgtMjA3LjZIMTE2LjRjLTQxLjgsMC03NiwzNC4yLTc2LDc2VjM1N2MwLDQxLjgsMzQuMiw3Niw3Niw3NkgxNzNDMTg5LDQyNC4xLDE5Ny42LDQxMC4zLDIwMy42LDM5NXoiLz48L2c+PGc+PHBhdGggZD0iTTQ3MS42LDE1NC44YzAtNDEuOC0zNC4yLTc2LTc2LTc2aC0zTDI4NS43LDM2NWMtOS42LDI2LjctMTkuNCw0OS4zLTMwLjMsNjhoMjE2LjJWMTU0Ljh6Ii8+PC9nPjwvZz48cGF0aCBzdHJva2Utd2lkdGg9IjIuOTc0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik0zMzgsMS4zbC05My4zLDI1OS4xbC00Mi4xLTEzMS45aC04OS4xbDgzLjgsMjE1LjJjNiwxNS41LDYsMzIuNSwwLDQ4Yy03LjQsMTktMTksMzcuMy01Myw0MS45bC03LjIsMXY3Nmg4LjNjODEuNywwLDExOC45LTU3LjIsMTQ5LjYtMTQyLjlMNDMxLjYsMS4zSDMzOHogTTI3OS40LDM2MmMtMzIuOSw5Mi02Ny42LDEyOC43LTEyNS43LDEzMS44di00NWMzNy41LTcuNSw1MS4zLTMxLDU5LjEtNTEuMWM3LjUtMTkuMyw3LjUtNDAuNywwLTYwbC03NS0xOTIuN2g1Mi44bDUzLjMsMTY2LjhsMTA1LjktMjk0aDU4LjFMMjc5LjQsMzYyeiIvPjwvZz48L2c+PC9zdmc+
	)
)
*/

global $submenu:

/*
$submenu = Array (
	[upload.php] => Array (
		[5] => Array (
				[0] => Library
				[1] => upload_files
				[2] => upload.php
			)

		[10] => Array (
				[0] => Add New
				[1] => upload_files
				[2] => media-new.php
			)
	)

	[edit-comments.php] => Array (
		[0] => Array (
				[0] => All Comments
				[1] => edit_posts
				[2] => edit-comments.php
			)
	)

	[edit.php] => Array (
		[5] => Array (
				[0] => All Posts
				[1] => edit_posts
				[2] => edit.php
			)

		[10] => Array (
				[0] => Add New
				[1] => edit_posts
				[2] => post-new.php
			)

		[15] => Array (
				[0] => Categories
				[1] => manage_categories
				[2] => edit-tags.php?taxonomy=category
			)

		[16] => Array (
				[0] => Tags
				[1] => manage_post_tags
				[2] => edit-tags.php?taxonomy=post_tag
			)
	)

	[edit.php?post_type=page] => Array (
		[5] => Array (
				[0] => All Pages
				[1] => edit_pages
				[2] => edit.php?post_type=page
			)

		[10] => Array (
				[0] => Add New
				[1] => edit_pages
				[2] => post-new.php?post_type=page
			)
	)

	[themes.php] => Array (
		[5] => Array (
				[0] => Themes
				[1] => switch_themes
				[2] => themes.php
			)

		[6] => Array (
				[0] => Customize
				[1] => customize
				[2] => customize.php?return=%2Fwp-admin%2Fpost.php%3Fpost%3D5710%26action%3Dedit
				[3] =>
				[4] => hide-if-no-customize
			)

		[7] => Array (
				[0] => Widgets
				[1] => edit_theme_options
				[2] => widgets.php
			)

		[10] => Array (
				[0] => Menus
				[1] => edit_theme_options
				[2] => nav-menus.php
			)
	)

	[plugins.php] => Array (
		[5] => Array (
				[0] => Installed Plugins
				[1] => activate_plugins
				[2] => plugins.php
			)
	)

	[users.php] => Array (
		[5] => Array (
				[0] => All Users
				[1] => list_users
				[2] => users.php
			)

		[10] => Array (
				[0] => Add New
				[1] => create_users
				[2] => user-new.php
			)

		[15] => Array (
				[0] => Profile
				[1] => read
				[2] => profile.php
			)
	)

	[tools.php] => Array (
		[5] => Array (
				[0] => Available Tools
				[1] => edit_posts
				[2] => tools.php
			)

		[10] => Array (
				[0] => Import
				[1] => import
				[2] => import.php
			)

		[15] => Array (
				[0] => Export
				[1] => export
				[2] => export.php
			)

		[20] => Array (
				[0] => Site Health
				[1] => view_site_health_checks
				[2] => site-health.php
			)
	)

	[options-general.php] => Array (
		[10] => Array (
				[0] => General
				[1] => manage_options
				[2] => options-general.php
			)

		[15] => Array (
				[0] => Writing
				[1] => manage_options
				[2] => options-writing.php
			)

		[20] => Array (
				[0] => Reading
				[1] => manage_options
				[2] => options-reading.php
			)

		[25] => Array (
				[0] => Discussion
				[1] => manage_options
				[2] => options-discussion.php
			)

		[30] => Array (
				[0] => Media
				[1] => manage_options
				[2] => options-media.php
			)

		[40] => Array (
				[0] => Permalinks
				[1] => manage_options
				[2] => options-permalink.php
			)

		[45] => Array (
				[0] => Privacy
				[1] => manage_privacy_options
				[2] => options-privacy.php
			)
	)

	[wpseo_dashboard] => Array (
		[0] => Array (
				[0] => General
				[1] => wpseo_manage_options
				[2] => wpseo_dashboard
				[3] => General - Yoast SEO
			)

		[1] => Array (
				[0] => Search Appearance
				[1] => wpseo_manage_options
				[2] => wpseo_titles
				[3] => Search Appearance - Yoast SEO
			)

		[2] => Array (
				[0] => Social
				[1] => wpseo_manage_options
				[2] => wpseo_social
				[3] => Social - Yoast SEO
			)

		[3] => Array (
				[0] => Tools
				[1] => wpseo_manage_options
				[2] => wpseo_tools
				[3] => Tools - Yoast SEO
			)

		[4] => Array (
				[0] => Premium
				[1] => wpseo_manage_options
				[2] => wpseo_licenses
				[3] => Premium - Yoast SEO
			)

		[5] => Array (
				[0] => Workouts
				[1] => edit_others_posts
				[2] => wpseo_workouts
				[3] => Workouts - Yoast SEO
			)
	)
)
*/
0

#2 Изменение названий пунктов меню и добавление разделителей

Допустим, по каким-то причинам, мы хотим изменить дефолтные названия пунктов меню в админке. Например, нам нужно добавить разделители между некоторыми пунктами и переименовать Внешний вид в Темы, а Плагины в Плагины Сайта.

Для этого создаем файл (класс) и кладем туда следующий код:

<?php

final class Change_Admin_Menu {

	public static function init(): void {
		add_action( 'admin_menu', [ __CLASS__, 'change' ] );
	}

	public static function change() {
		global $menu;

		self::add_separator( 9 );
		self::add_separator( 70 );

		foreach( $menu as & $item ){
			// переименуем 'Внешний вид' в 'Тема'
			if( 'themes.php' === $item[2] ){
				$item[0] = __( 'Тема', 'km' );
			}

			// переименуем Плагины
			if( 'plugins.php' === $item[2] ){
				$item[0] = __( 'Плагины Сайта', 'km' );
			}
		}
		unset( $item );
	}

	/**
	 * Добавляет разделитель в меню админки.
	 * Проверяет наличие указанного индекса, если он есть увеличивает указанный индекс на 1.
	 * Нужно это, чтобы не затереть существующие элементы меню, если указан одинаковый индекс.
	 *
	 * @param int $position Индекс, в какое место добавлять разделитель
	 *
	 * @author kama
	 * @ver 1.0
	 */
	protected static function add_separator( int $position ): void {
		global $menu;

		static $index;
		$index || ( $index = 1 );

		foreach( $menu as $mindex => $section ){

			if( $mindex >= $position ){

				while( isset( $menu[ $position ] ) ){
					++$position;
				}

				$menu[ $position ] = [
					'',
					'read',
					"separator-my{$index}",
					'',
					'wp-menu-separator'
				];

				$index++;

				break;
			}
		}

		ksort( $menu );
	}
}

Подключаем созданный файл в файле functions.php и инициализируем класс:

require_once __DIR__ . '/rel/path/to/Change_Admin_Menu.php';
Change_Admin_Menu::init();

Список изменений

С версии 1.5.0 Введена.

Где вызывается хук

В файле: /wp-admin/includes/menu.php
admin_menu
wp-admin/includes/menu.php 161
do_action( 'admin_menu', '' );

Где используется хук в WordPress

wp-admin/includes/class-custom-background.php 55
add_action( 'admin_menu', array( $this, 'init' ) );
wp-admin/includes/class-custom-image-header.php 62
add_action( 'admin_menu', array( $this, 'init' ) );
wp-admin/menu.php 251
add_action( 'admin_menu', '_add_themes_utility_last', 101 );
wp-admin/menu.php 313
add_action( 'admin_menu', '_add_plugin_file_editor_to_tools', 101 );
wp-includes/default-filters.php 547
add_action( 'admin_menu', '_add_post_type_submenus' );
wp-includes/theme.php 3116
remove_action( 'admin_menu', array( $GLOBALS['custom_image_header'], 'init' ) );
wp-includes/theme.php 3129
remove_action( 'admin_menu', array( $GLOBALS['custom_background'], 'init' ) );
5 комментариев
    Войти