wp/wp-admin/includes/plugin.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
    52  * @param bool   $translate   Optional. If the returned data should be translated. Default true.
    52  * @param bool   $translate   Optional. If the returned data should be translated. Default true.
    53  * @return array {
    53  * @return array {
    54  *     Plugin data. Values will be empty if not supplied by the plugin.
    54  *     Plugin data. Values will be empty if not supplied by the plugin.
    55  *
    55  *
    56  *     @type string $Name        Name of the plugin. Should be unique.
    56  *     @type string $Name        Name of the plugin. Should be unique.
    57  *     @type string $Title       Title of the plugin and link to the plugin's site (if set).
    57  *     @type string $PluginURI   Plugin URI.
       
    58  *     @type string $Version     Plugin version.
    58  *     @type string $Description Plugin description.
    59  *     @type string $Description Plugin description.
    59  *     @type string $Author      Author's name.
    60  *     @type string $Author      Plugin author's name.
    60  *     @type string $AuthorURI   Author's website address (if set).
    61  *     @type string $AuthorURI   Plugin author's website address (if set).
    61  *     @type string $Version     Plugin version.
       
    62  *     @type string $TextDomain  Plugin textdomain.
    62  *     @type string $TextDomain  Plugin textdomain.
    63  *     @type string $DomainPath  Plugins relative directory path to .mo files.
    63  *     @type string $DomainPath  Plugin's relative directory path to .mo files.
    64  *     @type bool   $Network     Whether the plugin can only be activated network-wide.
    64  *     @type bool   $Network     Whether the plugin can only be activated network-wide.
    65  *     @type string $RequiresWP  Minimum required version of WordPress.
    65  *     @type string $RequiresWP  Minimum required version of WordPress.
    66  *     @type string $RequiresPHP Minimum required version of PHP.
    66  *     @type string $RequiresPHP Minimum required version of PHP.
    67  *     @type string $UpdateURI   ID of the plugin for update purposes, should be a URI.
    67  *     @type string $UpdateURI   ID of the plugin for update purposes, should be a URI.
       
    68  *     @type string $Title       Title of the plugin and link to the plugin's site (if set).
       
    69  *     @type string $AuthorName  Plugin author's name.
    68  * }
    70  * }
    69  */
    71  */
    70 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
    72 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
    71 
    73 
    72 	$default_headers = array(
    74 	$default_headers = array(
   127  * @param string $plugin_file Path to the main plugin file.
   129  * @param string $plugin_file Path to the main plugin file.
   128  * @param array  $plugin_data An array of plugin data. See `get_plugin_data()`.
   130  * @param array  $plugin_data An array of plugin data. See `get_plugin_data()`.
   129  * @param bool   $markup      Optional. If the returned data should have HTML markup applied.
   131  * @param bool   $markup      Optional. If the returned data should have HTML markup applied.
   130  *                            Default true.
   132  *                            Default true.
   131  * @param bool   $translate   Optional. If the returned data should be translated. Default true.
   133  * @param bool   $translate   Optional. If the returned data should be translated. Default true.
   132  * @return array {
   134  * @return array Plugin data. Values will be empty if not supplied by the plugin.
   133  *     Plugin data. Values will be empty if not supplied by the plugin.
   135  *               See get_plugin_data() for the list of possible values.
   134  *
       
   135  *     @type string $Name        Name of the plugin. Should be unique.
       
   136  *     @type string $Title       Title of the plugin and link to the plugin's site (if set).
       
   137  *     @type string $Description Plugin description.
       
   138  *     @type string $Author      Author's name.
       
   139  *     @type string $AuthorURI   Author's website address (if set).
       
   140  *     @type string $Version     Plugin version.
       
   141  *     @type string $TextDomain  Plugin textdomain.
       
   142  *     @type string $DomainPath  Plugins relative directory path to .mo files.
       
   143  *     @type bool   $Network     Whether the plugin can only be activated network-wide.
       
   144  * }
       
   145  */
   136  */
   146 function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup = true, $translate = true ) {
   137 function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup = true, $translate = true ) {
   147 
   138 
   148 	// Sanitize the plugin filename to a WP_PLUGIN_DIR relative path.
   139 	// Sanitize the plugin filename to a WP_PLUGIN_DIR relative path.
   149 	$plugin_file = plugin_basename( $plugin_file );
   140 	$plugin_file = plugin_basename( $plugin_file );
   162 		} elseif ( 'hello.php' === basename( $plugin_file ) ) {
   153 		} elseif ( 'hello.php' === basename( $plugin_file ) ) {
   163 			$textdomain = 'default';
   154 			$textdomain = 'default';
   164 		}
   155 		}
   165 		if ( $textdomain ) {
   156 		if ( $textdomain ) {
   166 			foreach ( array( 'Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version' ) as $field ) {
   157 			foreach ( array( 'Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version' ) as $field ) {
   167 				// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain
   158 				if ( ! empty( $plugin_data[ $field ] ) ) {
   168 				$plugin_data[ $field ] = translate( $plugin_data[ $field ], $textdomain );
   159 					// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain
       
   160 					$plugin_data[ $field ] = translate( $plugin_data[ $field ], $textdomain );
       
   161 				}
   169 			}
   162 			}
   170 		}
   163 		}
   171 	}
   164 	}
   172 
   165 
   173 	// Sanitize fields.
   166 	// Sanitize fields.
   222 
   215 
   223 	return $plugin_data;
   216 	return $plugin_data;
   224 }
   217 }
   225 
   218 
   226 /**
   219 /**
   227  * Get a list of a plugin's files.
   220  * Gets a list of a plugin's files.
   228  *
   221  *
   229  * @since 2.8.0
   222  * @since 2.8.0
   230  *
   223  *
   231  * @param string $plugin Path to the plugin file relative to the plugins directory.
   224  * @param string $plugin Path to the plugin file relative to the plugins directory.
   232  * @return string[] Array of file names relative to the plugin root.
   225  * @return string[] Array of file names relative to the plugin root.
   257 
   250 
   258 	return $plugin_files;
   251 	return $plugin_files;
   259 }
   252 }
   260 
   253 
   261 /**
   254 /**
   262  * Check the plugins directory and retrieve all plugin files with plugin data.
   255  * Checks the plugins directory and retrieve all plugin files with plugin data.
   263  *
   256  *
   264  * WordPress only supports plugin files in the base plugins directory
   257  * WordPress only supports plugin files in the base plugins directory
   265  * (wp-content/plugins) and in one directory above the plugins directory
   258  * (wp-content/plugins) and in one directory above the plugins directory
   266  * (wp-content/plugins/my-plugin). The file it looks for has the plugin data
   259  * (wp-content/plugins/my-plugin). The file it looks for has the plugin data
   267  * and must be found in those two locations. It is recommended to keep your
   260  * and must be found in those two locations. It is recommended to keep your
   357 
   350 
   358 	return $wp_plugins;
   351 	return $wp_plugins;
   359 }
   352 }
   360 
   353 
   361 /**
   354 /**
   362  * Check the mu-plugins directory and retrieve all mu-plugin files with any plugin data.
   355  * Checks the mu-plugins directory and retrieve all mu-plugin files with any plugin data.
   363  *
   356  *
   364  * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins).
   357  * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins).
   365  *
   358  *
   366  * @since 3.0.0
   359  * @since 3.0.0
   367  * @return array[] Array of arrays of mu-plugin data, keyed by plugin file name. See `get_plugin_data()`.
   360  * @return array[] Array of arrays of mu-plugin data, keyed by plugin file name. See `get_plugin_data()`.
   416 
   409 
   417 	return $wp_plugins;
   410 	return $wp_plugins;
   418 }
   411 }
   419 
   412 
   420 /**
   413 /**
   421  * Callback to sort array by a 'Name' key.
   414  * Declares a callback to sort array by a 'Name' key.
   422  *
   415  *
   423  * @since 3.1.0
   416  * @since 3.1.0
   424  *
   417  *
   425  * @access private
   418  * @access private
   426  *
   419  *
   431 function _sort_uname_callback( $a, $b ) {
   424 function _sort_uname_callback( $a, $b ) {
   432 	return strnatcasecmp( $a['Name'], $b['Name'] );
   425 	return strnatcasecmp( $a['Name'], $b['Name'] );
   433 }
   426 }
   434 
   427 
   435 /**
   428 /**
   436  * Check the wp-content directory and retrieve all drop-ins with any plugin data.
   429  * Checks the wp-content directory and retrieve all drop-ins with any plugin data.
   437  *
   430  *
   438  * @since 3.0.0
   431  * @since 3.0.0
   439  * @return array[] Array of arrays of dropin plugin data, keyed by plugin file name. See `get_plugin_data()`.
   432  * @return array[] Array of arrays of dropin plugin data, keyed by plugin file name. See `get_plugin_data()`.
   440  */
   433  */
   441 function get_dropins() {
   434 function get_dropins() {
   735 
   728 
   736 	return null;
   729 	return null;
   737 }
   730 }
   738 
   731 
   739 /**
   732 /**
   740  * Deactivate a single plugin or multiple plugins.
   733  * Deactivates a single plugin or multiple plugins.
   741  *
   734  *
   742  * The deactivation hook is disabled by the plugin upgrader by using the $silent
   735  * The deactivation hook is disabled by the plugin upgrader by using the $silent
   743  * parameter.
   736  * parameter.
   744  *
   737  *
   745  * @since 2.5.0
   738  * @since 2.5.0
   843 		update_site_option( 'active_sitewide_plugins', $network_current );
   836 		update_site_option( 'active_sitewide_plugins', $network_current );
   844 	}
   837 	}
   845 }
   838 }
   846 
   839 
   847 /**
   840 /**
   848  * Activate multiple plugins.
   841  * Activates multiple plugins.
   849  *
   842  *
   850  * When WP_Error is returned, it does not mean that one of the plugins had
   843  * When WP_Error is returned, it does not mean that one of the plugins had
   851  * errors. It means that one or more of the plugin file paths were invalid.
   844  * errors. It means that one or more of the plugin file paths were invalid.
   852  *
   845  *
   853  * The execution will be halted as soon as one of the plugins has an error.
   846  * The execution will be halted as soon as one of the plugins has an error.
   883 
   876 
   884 	return true;
   877 	return true;
   885 }
   878 }
   886 
   879 
   887 /**
   880 /**
   888  * Remove directory and files of a plugin for a list of plugins.
   881  * Removes directory and files of a plugin for a list of plugins.
   889  *
   882  *
   890  * @since 2.6.0
   883  * @since 2.6.0
   891  *
   884  *
   892  * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
   885  * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
   893  *
   886  *
  1048 
  1041 
  1049 	return true;
  1042 	return true;
  1050 }
  1043 }
  1051 
  1044 
  1052 /**
  1045 /**
  1053  * Validate active plugins
  1046  * Validates active plugins.
  1054  *
  1047  *
  1055  * Validate all active plugins, deactivates invalid and
  1048  * Validate all active plugins, deactivates invalid and
  1056  * returns an array of deactivated ones.
  1049  * returns an array of deactivated ones.
  1057  *
  1050  *
  1058  * @since 2.5.0
  1051  * @since 2.5.0
  1087 	}
  1080 	}
  1088 	return $invalid;
  1081 	return $invalid;
  1089 }
  1082 }
  1090 
  1083 
  1091 /**
  1084 /**
  1092  * Validate the plugin path.
  1085  * Validates the plugin path.
  1093  *
  1086  *
  1094  * Checks that the main plugin file exists and is a valid plugin. See validate_file().
  1087  * Checks that the main plugin file exists and is a valid plugin. See validate_file().
  1095  *
  1088  *
  1096  * @since 2.5.0
  1089  * @since 2.5.0
  1097  *
  1090  *
  1189 
  1182 
  1190 	return true;
  1183 	return true;
  1191 }
  1184 }
  1192 
  1185 
  1193 /**
  1186 /**
  1194  * Whether the plugin can be uninstalled.
  1187  * Determines whether the plugin can be uninstalled.
  1195  *
  1188  *
  1196  * @since 2.7.0
  1189  * @since 2.7.0
  1197  *
  1190  *
  1198  * @param string $plugin Path to the plugin file relative to the plugins directory.
  1191  * @param string $plugin Path to the plugin file relative to the plugins directory.
  1199  * @return bool Whether plugin can be uninstalled.
  1192  * @return bool Whether plugin can be uninstalled.
  1208 
  1201 
  1209 	return false;
  1202 	return false;
  1210 }
  1203 }
  1211 
  1204 
  1212 /**
  1205 /**
  1213  * Uninstall a single plugin.
  1206  * Uninstalls a single plugin.
  1214  *
  1207  *
  1215  * Calls the uninstall hook, if it is available.
  1208  * Calls the uninstall hook, if it is available.
  1216  *
  1209  *
  1217  * @since 2.7.0
  1210  * @since 2.7.0
  1218  *
  1211  *
  1276 //
  1269 //
  1277 // Menu.
  1270 // Menu.
  1278 //
  1271 //
  1279 
  1272 
  1280 /**
  1273 /**
  1281  * Add a top-level menu page.
  1274  * Adds a top-level menu page.
  1282  *
  1275  *
  1283  * This function takes a capability which will be used to determine whether
  1276  * This function takes a capability which will be used to determine whether
  1284  * or not a page is included in the menu.
  1277  * or not a page is included in the menu.
  1285  *
  1278  *
  1286  * The function which is hooked in to handle the output of the page must check
  1279  * The function which is hooked in to handle the output of the page must check
  1291  * @global array $menu
  1284  * @global array $menu
  1292  * @global array $admin_page_hooks
  1285  * @global array $admin_page_hooks
  1293  * @global array $_registered_pages
  1286  * @global array $_registered_pages
  1294  * @global array $_parent_pages
  1287  * @global array $_parent_pages
  1295  *
  1288  *
  1296  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1289  * @param string    $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1297  * @param string   $menu_title The text to be used for the menu.
  1290  * @param string    $menu_title The text to be used for the menu.
  1298  * @param string   $capability The capability required for this menu to be displayed to the user.
  1291  * @param string    $capability The capability required for this menu to be displayed to the user.
  1299  * @param string   $menu_slug  The slug name to refer to this menu by. Should be unique for this menu page and only
  1292  * @param string    $menu_slug  The slug name to refer to this menu by. Should be unique for this menu page and only
  1300  *                             include lowercase alphanumeric, dashes, and underscores characters to be compatible
  1293  *                              include lowercase alphanumeric, dashes, and underscores characters to be compatible
  1301  *                             with sanitize_key().
  1294  *                              with sanitize_key().
  1302  * @param callable $function   The function to be called to output the content for this page.
  1295  * @param callable  $callback   Optional. The function to be called to output the content for this page.
  1303  * @param string   $icon_url   The URL to the icon to be used for this menu.
  1296  * @param string    $icon_url   Optional. The URL to the icon to be used for this menu.
  1304  *                             * Pass a base64-encoded SVG using a data URI, which will be colored to match
  1297  *                              * Pass a base64-encoded SVG using a data URI, which will be colored to match
  1305  *                               the color scheme. This should begin with 'data:image/svg+xml;base64,'.
  1298  *                                the color scheme. This should begin with 'data:image/svg+xml;base64,'.
  1306  *                             * Pass the name of a Dashicons helper class to use a font icon,
  1299  *                              * Pass the name of a Dashicons helper class to use a font icon,
  1307  *                               e.g. 'dashicons-chart-pie'.
  1300  *                                e.g. 'dashicons-chart-pie'.
  1308  *                             * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS.
  1301  *                              * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS.
  1309  * @param int      $position   The position in the menu order this item should appear.
  1302  * @param int|float $position   Optional. The position in the menu order this item should appear.
  1310  * @return string The resulting page's hook_suffix.
  1303  * @return string The resulting page's hook_suffix.
  1311  */
  1304  */
  1312 function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = null ) {
  1305 function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $icon_url = '', $position = null ) {
  1313 	global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages;
  1306 	global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages;
  1314 
  1307 
  1315 	$menu_slug = plugin_basename( $menu_slug );
  1308 	$menu_slug = plugin_basename( $menu_slug );
  1316 
  1309 
  1317 	$admin_page_hooks[ $menu_slug ] = sanitize_title( $menu_title );
  1310 	$admin_page_hooks[ $menu_slug ] = sanitize_title( $menu_title );
  1318 
  1311 
  1319 	$hookname = get_plugin_page_hookname( $menu_slug, '' );
  1312 	$hookname = get_plugin_page_hookname( $menu_slug, '' );
  1320 
  1313 
  1321 	if ( ! empty( $function ) && ! empty( $hookname ) && current_user_can( $capability ) ) {
  1314 	if ( ! empty( $callback ) && ! empty( $hookname ) && current_user_can( $capability ) ) {
  1322 		add_action( $hookname, $function );
  1315 		add_action( $hookname, $callback );
  1323 	}
  1316 	}
  1324 
  1317 
  1325 	if ( empty( $icon_url ) ) {
  1318 	if ( empty( $icon_url ) ) {
  1326 		$icon_url   = 'dashicons-admin-generic';
  1319 		$icon_url   = 'dashicons-admin-generic';
  1327 		$icon_class = 'menu-icon-generic ';
  1320 		$icon_class = 'menu-icon-generic ';
  1330 		$icon_class = '';
  1323 		$icon_class = '';
  1331 	}
  1324 	}
  1332 
  1325 
  1333 	$new_menu = array( $menu_title, $capability, $menu_slug, $page_title, 'menu-top ' . $icon_class . $hookname, $hookname, $icon_url );
  1326 	$new_menu = array( $menu_title, $capability, $menu_slug, $page_title, 'menu-top ' . $icon_class . $hookname, $hookname, $icon_url );
  1334 
  1327 
  1335 	if ( null === $position ) {
  1328 	if ( null !== $position && ! is_numeric( $position ) ) {
       
  1329 		_doing_it_wrong(
       
  1330 			__FUNCTION__,
       
  1331 			sprintf(
       
  1332 				/* translators: %s: add_menu_page() */
       
  1333 				__( 'The seventh parameter passed to %s should be numeric representing menu position.' ),
       
  1334 				'<code>add_menu_page()</code>'
       
  1335 			),
       
  1336 			'6.0.0'
       
  1337 		);
       
  1338 		$position = null;
       
  1339 	}
       
  1340 
       
  1341 	if ( null === $position || ! is_numeric( $position ) ) {
  1336 		$menu[] = $new_menu;
  1342 		$menu[] = $new_menu;
  1337 	} elseif ( isset( $menu[ "$position" ] ) ) {
  1343 	} elseif ( isset( $menu[ (string) $position ] ) ) {
  1338 		$position            = $position + substr( base_convert( md5( $menu_slug . $menu_title ), 16, 10 ), -5 ) * 0.00001;
  1344 		$collision_avoider = base_convert( substr( md5( $menu_slug . $menu_title ), -4 ), 16, 10 ) * 0.00001;
  1339 		$menu[ "$position" ] = $new_menu;
  1345 		$position          = (string) ( $position + $collision_avoider );
       
  1346 		$menu[ $position ] = $new_menu;
  1340 	} else {
  1347 	} else {
       
  1348 		/*
       
  1349 		 * Cast menu position to a string.
       
  1350 		 *
       
  1351 		 * This allows for floats to be passed as the position. PHP will normally cast a float to an
       
  1352 		 * integer value, this ensures the float retains its mantissa (positive fractional part).
       
  1353 		 *
       
  1354 		 * A string containing an integer value, eg "10", is treated as a numeric index.
       
  1355 		 */
       
  1356 		$position          = (string) $position;
  1341 		$menu[ $position ] = $new_menu;
  1357 		$menu[ $position ] = $new_menu;
  1342 	}
  1358 	}
  1343 
  1359 
  1344 	$_registered_pages[ $hookname ] = true;
  1360 	$_registered_pages[ $hookname ] = true;
  1345 
  1361 
  1348 
  1364 
  1349 	return $hookname;
  1365 	return $hookname;
  1350 }
  1366 }
  1351 
  1367 
  1352 /**
  1368 /**
  1353  * Add a submenu page.
  1369  * Adds a submenu page.
  1354  *
  1370  *
  1355  * This function takes a capability which will be used to determine whether
  1371  * This function takes a capability which will be used to determine whether
  1356  * or not a page is included in the menu.
  1372  * or not a page is included in the menu.
  1357  *
  1373  *
  1358  * The function which is hooked in to handle the output of the page must check
  1374  * The function which is hooked in to handle the output of the page must check
  1366  * @global array $_wp_real_parent_file
  1382  * @global array $_wp_real_parent_file
  1367  * @global bool  $_wp_submenu_nopriv
  1383  * @global bool  $_wp_submenu_nopriv
  1368  * @global array $_registered_pages
  1384  * @global array $_registered_pages
  1369  * @global array $_parent_pages
  1385  * @global array $_parent_pages
  1370  *
  1386  *
  1371  * @param string   $parent_slug The slug name for the parent menu (or the file name of a standard
  1387  * @param string    $parent_slug The slug name for the parent menu (or the file name of a standard
  1372  *                              WordPress admin page).
  1388  *                               WordPress admin page).
  1373  * @param string   $page_title  The text to be displayed in the title tags of the page when the menu
  1389  * @param string    $page_title  The text to be displayed in the title tags of the page when the menu
  1374  *                              is selected.
  1390  *                               is selected.
  1375  * @param string   $menu_title  The text to be used for the menu.
  1391  * @param string    $menu_title  The text to be used for the menu.
  1376  * @param string   $capability  The capability required for this menu to be displayed to the user.
  1392  * @param string    $capability  The capability required for this menu to be displayed to the user.
  1377  * @param string   $menu_slug   The slug name to refer to this menu by. Should be unique for this menu
  1393  * @param string    $menu_slug   The slug name to refer to this menu by. Should be unique for this menu
  1378  *                              and only include lowercase alphanumeric, dashes, and underscores characters
  1394  *                               and only include lowercase alphanumeric, dashes, and underscores characters
  1379  *                              to be compatible with sanitize_key().
  1395  *                               to be compatible with sanitize_key().
  1380  * @param callable $function    The function to be called to output the content for this page.
  1396  * @param callable  $callback    Optional. The function to be called to output the content for this page.
  1381  * @param int      $position    The position in the menu order this item should appear.
  1397  * @param int|float $position    Optional. The position in the menu order this item should appear.
  1382  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1398  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1383  */
  1399  */
  1384 function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1400 function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1385 	global $submenu, $menu, $_wp_real_parent_file, $_wp_submenu_nopriv,
  1401 	global $submenu, $menu, $_wp_real_parent_file, $_wp_submenu_nopriv,
  1386 		$_registered_pages, $_parent_pages;
  1402 		$_registered_pages, $_parent_pages;
  1387 
  1403 
  1388 	$menu_slug   = plugin_basename( $menu_slug );
  1404 	$menu_slug   = plugin_basename( $menu_slug );
  1389 	$parent_slug = plugin_basename( $parent_slug );
  1405 	$parent_slug = plugin_basename( $parent_slug );
  1410 			}
  1426 			}
  1411 		}
  1427 		}
  1412 	}
  1428 	}
  1413 
  1429 
  1414 	$new_sub_menu = array( $menu_title, $capability, $menu_slug, $page_title );
  1430 	$new_sub_menu = array( $menu_title, $capability, $menu_slug, $page_title );
  1415 	if ( ! is_int( $position ) ) {
  1431 
  1416 		if ( null !== $position ) {
  1432 	if ( null !== $position && ! is_numeric( $position ) ) {
  1417 			_doing_it_wrong(
  1433 		_doing_it_wrong(
  1418 				__FUNCTION__,
  1434 			__FUNCTION__,
  1419 				sprintf(
  1435 			sprintf(
  1420 					/* translators: %s: add_submenu_page() */
  1436 				/* translators: %s: add_submenu_page() */
  1421 					__( 'The seventh parameter passed to %s should be an integer representing menu position.' ),
  1437 				__( 'The seventh parameter passed to %s should be numeric representing menu position.' ),
  1422 					'<code>add_submenu_page()</code>'
  1438 				'<code>add_submenu_page()</code>'
  1423 				),
  1439 			),
  1424 				'5.3.0'
  1440 			'5.3.0'
  1425 			);
  1441 		);
  1426 		}
  1442 		$position = null;
  1427 
  1443 	}
       
  1444 
       
  1445 	if (
       
  1446 		null === $position ||
       
  1447 		( ! isset( $submenu[ $parent_slug ] ) || $position >= count( $submenu[ $parent_slug ] ) )
       
  1448 	) {
  1428 		$submenu[ $parent_slug ][] = $new_sub_menu;
  1449 		$submenu[ $parent_slug ][] = $new_sub_menu;
  1429 	} else {
  1450 	} else {
  1430 		// Append the submenu if the parent item is not present in the submenu,
  1451 		// Test for a negative position.
  1431 		// or if position is equal or higher than the number of items in the array.
  1452 		$position = max( $position, 0 );
  1432 		if ( ! isset( $submenu[ $parent_slug ] ) || $position >= count( $submenu[ $parent_slug ] ) ) {
  1453 		if ( 0 === $position ) {
  1433 			$submenu[ $parent_slug ][] = $new_sub_menu;
  1454 			// For negative or `0` positions, prepend the submenu.
       
  1455 			array_unshift( $submenu[ $parent_slug ], $new_sub_menu );
  1434 		} else {
  1456 		} else {
  1435 			// Test for a negative position.
  1457 			// Grab all of the items before the insertion point.
  1436 			$position = max( $position, 0 );
  1458 			$before_items = array_slice( $submenu[ $parent_slug ], 0, $position, true );
  1437 			if ( 0 === $position ) {
  1459 			// Grab all of the items after the insertion point.
  1438 				// For negative or `0` positions, prepend the submenu.
  1460 			$after_items = array_slice( $submenu[ $parent_slug ], $position, null, true );
  1439 				array_unshift( $submenu[ $parent_slug ], $new_sub_menu );
  1461 			// Add the new item.
  1440 			} else {
  1462 			$before_items[] = $new_sub_menu;
  1441 				// Grab all of the items before the insertion point.
  1463 			// Merge the items.
  1442 				$before_items = array_slice( $submenu[ $parent_slug ], 0, $position, true );
  1464 			$submenu[ $parent_slug ] = array_merge( $before_items, $after_items );
  1443 				// Grab all of the items after the insertion point.
  1465 		}
  1444 				$after_items = array_slice( $submenu[ $parent_slug ], $position, null, true );
  1466 	}
  1445 				// Add the new item.
  1467 
  1446 				$before_items[] = $new_sub_menu;
       
  1447 				// Merge the items.
       
  1448 				$submenu[ $parent_slug ] = array_merge( $before_items, $after_items );
       
  1449 			}
       
  1450 		}
       
  1451 	}
       
  1452 	// Sort the parent array.
  1468 	// Sort the parent array.
  1453 	ksort( $submenu[ $parent_slug ] );
  1469 	ksort( $submenu[ $parent_slug ] );
  1454 
  1470 
  1455 	$hookname = get_plugin_page_hookname( $menu_slug, $parent_slug );
  1471 	$hookname = get_plugin_page_hookname( $menu_slug, $parent_slug );
  1456 	if ( ! empty( $function ) && ! empty( $hookname ) ) {
  1472 	if ( ! empty( $callback ) && ! empty( $hookname ) ) {
  1457 		add_action( $hookname, $function );
  1473 		add_action( $hookname, $callback );
  1458 	}
  1474 	}
  1459 
  1475 
  1460 	$_registered_pages[ $hookname ] = true;
  1476 	$_registered_pages[ $hookname ] = true;
  1461 
  1477 
  1462 	/*
  1478 	/*
  1472 
  1488 
  1473 	return $hookname;
  1489 	return $hookname;
  1474 }
  1490 }
  1475 
  1491 
  1476 /**
  1492 /**
  1477  * Add submenu page to the Tools main menu.
  1493  * Adds a submenu page to the Tools main menu.
  1478  *
  1494  *
  1479  * This function takes a capability which will be used to determine whether
  1495  * This function takes a capability which will be used to determine whether
  1480  * or not a page is included in the menu.
  1496  * or not a page is included in the menu.
  1481  *
  1497  *
  1482  * The function which is hooked in to handle the output of the page must check
  1498  * The function which is hooked in to handle the output of the page must check
  1487  *
  1503  *
  1488  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1504  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1489  * @param string   $menu_title The text to be used for the menu.
  1505  * @param string   $menu_title The text to be used for the menu.
  1490  * @param string   $capability The capability required for this menu to be displayed to the user.
  1506  * @param string   $capability The capability required for this menu to be displayed to the user.
  1491  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1507  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1492  * @param callable $function   The function to be called to output the content for this page.
  1508  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1493  * @param int      $position   The position in the menu order this item should appear.
  1509  * @param int      $position   Optional. The position in the menu order this item should appear.
  1494  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1510  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1495  */
  1511  */
  1496 function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1512 function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1497 	return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1513 	return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1498 }
  1514 }
  1499 
  1515 
  1500 /**
  1516 /**
  1501  * Add submenu page to the Settings main menu.
  1517  * Adds a submenu page to the Settings main menu.
  1502  *
  1518  *
  1503  * This function takes a capability which will be used to determine whether
  1519  * This function takes a capability which will be used to determine whether
  1504  * or not a page is included in the menu.
  1520  * or not a page is included in the menu.
  1505  *
  1521  *
  1506  * The function which is hooked in to handle the output of the page must check
  1522  * The function which is hooked in to handle the output of the page must check
  1511  *
  1527  *
  1512  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1528  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1513  * @param string   $menu_title The text to be used for the menu.
  1529  * @param string   $menu_title The text to be used for the menu.
  1514  * @param string   $capability The capability required for this menu to be displayed to the user.
  1530  * @param string   $capability The capability required for this menu to be displayed to the user.
  1515  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1531  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1516  * @param callable $function   The function to be called to output the content for this page.
  1532  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1517  * @param int      $position   The position in the menu order this item should appear.
  1533  * @param int      $position   Optional. The position in the menu order this item should appear.
  1518  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1534  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1519  */
  1535  */
  1520 function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1536 function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1521 	return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1537 	return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1522 }
  1538 }
  1523 
  1539 
  1524 /**
  1540 /**
  1525  * Add submenu page to the Appearance main menu.
  1541  * Adds a submenu page to the Appearance main menu.
  1526  *
  1542  *
  1527  * This function takes a capability which will be used to determine whether
  1543  * This function takes a capability which will be used to determine whether
  1528  * or not a page is included in the menu.
  1544  * or not a page is included in the menu.
  1529  *
  1545  *
  1530  * The function which is hooked in to handle the output of the page must check
  1546  * The function which is hooked in to handle the output of the page must check
  1535  *
  1551  *
  1536  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1552  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1537  * @param string   $menu_title The text to be used for the menu.
  1553  * @param string   $menu_title The text to be used for the menu.
  1538  * @param string   $capability The capability required for this menu to be displayed to the user.
  1554  * @param string   $capability The capability required for this menu to be displayed to the user.
  1539  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1555  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1540  * @param callable $function   The function to be called to output the content for this page.
  1556  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1541  * @param int      $position   The position in the menu order this item should appear.
  1557  * @param int      $position   Optional. The position in the menu order this item should appear.
  1542  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1558  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1543  */
  1559  */
  1544 function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1560 function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1545 	return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1561 	return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1546 }
  1562 }
  1547 
  1563 
  1548 /**
  1564 /**
  1549  * Add submenu page to the Plugins main menu.
  1565  * Adds a submenu page to the Plugins main menu.
  1550  *
  1566  *
  1551  * This function takes a capability which will be used to determine whether
  1567  * This function takes a capability which will be used to determine whether
  1552  * or not a page is included in the menu.
  1568  * or not a page is included in the menu.
  1553  *
  1569  *
  1554  * The function which is hooked in to handle the output of the page must check
  1570  * The function which is hooked in to handle the output of the page must check
  1559  *
  1575  *
  1560  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1576  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1561  * @param string   $menu_title The text to be used for the menu.
  1577  * @param string   $menu_title The text to be used for the menu.
  1562  * @param string   $capability The capability required for this menu to be displayed to the user.
  1578  * @param string   $capability The capability required for this menu to be displayed to the user.
  1563  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1579  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1564  * @param callable $function   The function to be called to output the content for this page.
  1580  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1565  * @param int      $position   The position in the menu order this item should appear.
  1581  * @param int      $position   Optional. The position in the menu order this item should appear.
  1566  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1582  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1567  */
  1583  */
  1568 function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1584 function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1569 	return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1585 	return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1570 }
  1586 }
  1571 
  1587 
  1572 /**
  1588 /**
  1573  * Add submenu page to the Users/Profile main menu.
  1589  * Adds a submenu page to the Users/Profile main menu.
  1574  *
  1590  *
  1575  * This function takes a capability which will be used to determine whether
  1591  * This function takes a capability which will be used to determine whether
  1576  * or not a page is included in the menu.
  1592  * or not a page is included in the menu.
  1577  *
  1593  *
  1578  * The function which is hooked in to handle the output of the page must check
  1594  * The function which is hooked in to handle the output of the page must check
  1583  *
  1599  *
  1584  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1600  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1585  * @param string   $menu_title The text to be used for the menu.
  1601  * @param string   $menu_title The text to be used for the menu.
  1586  * @param string   $capability The capability required for this menu to be displayed to the user.
  1602  * @param string   $capability The capability required for this menu to be displayed to the user.
  1587  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1603  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1588  * @param callable $function   The function to be called to output the content for this page.
  1604  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1589  * @param int      $position   The position in the menu order this item should appear.
  1605  * @param int      $position   Optional. The position in the menu order this item should appear.
  1590  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1606  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1591  */
  1607  */
  1592 function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1608 function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1593 	if ( current_user_can( 'edit_users' ) ) {
  1609 	if ( current_user_can( 'edit_users' ) ) {
  1594 		$parent = 'users.php';
  1610 		$parent = 'users.php';
  1595 	} else {
  1611 	} else {
  1596 		$parent = 'profile.php';
  1612 		$parent = 'profile.php';
  1597 	}
  1613 	}
  1598 	return add_submenu_page( $parent, $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1614 	return add_submenu_page( $parent, $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1599 }
  1615 }
  1600 
  1616 
  1601 /**
  1617 /**
  1602  * Add submenu page to the Dashboard main menu.
  1618  * Adds a submenu page to the Dashboard main menu.
  1603  *
  1619  *
  1604  * This function takes a capability which will be used to determine whether
  1620  * This function takes a capability which will be used to determine whether
  1605  * or not a page is included in the menu.
  1621  * or not a page is included in the menu.
  1606  *
  1622  *
  1607  * The function which is hooked in to handle the output of the page must check
  1623  * The function which is hooked in to handle the output of the page must check
  1612  *
  1628  *
  1613  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1629  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1614  * @param string   $menu_title The text to be used for the menu.
  1630  * @param string   $menu_title The text to be used for the menu.
  1615  * @param string   $capability The capability required for this menu to be displayed to the user.
  1631  * @param string   $capability The capability required for this menu to be displayed to the user.
  1616  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1632  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1617  * @param callable $function   The function to be called to output the content for this page.
  1633  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1618  * @param int      $position   The position in the menu order this item should appear.
  1634  * @param int      $position   Optional. The position in the menu order this item should appear.
  1619  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1635  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1620  */
  1636  */
  1621 function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1637 function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1622 	return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1638 	return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1623 }
  1639 }
  1624 
  1640 
  1625 /**
  1641 /**
  1626  * Add submenu page to the Posts main menu.
  1642  * Adds a submenu page to the Posts main menu.
  1627  *
  1643  *
  1628  * This function takes a capability which will be used to determine whether
  1644  * This function takes a capability which will be used to determine whether
  1629  * or not a page is included in the menu.
  1645  * or not a page is included in the menu.
  1630  *
  1646  *
  1631  * The function which is hooked in to handle the output of the page must check
  1647  * The function which is hooked in to handle the output of the page must check
  1636  *
  1652  *
  1637  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1653  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1638  * @param string   $menu_title The text to be used for the menu.
  1654  * @param string   $menu_title The text to be used for the menu.
  1639  * @param string   $capability The capability required for this menu to be displayed to the user.
  1655  * @param string   $capability The capability required for this menu to be displayed to the user.
  1640  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1656  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1641  * @param callable $function   The function to be called to output the content for this page.
  1657  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1642  * @param int      $position   The position in the menu order this item should appear.
  1658  * @param int      $position   Optional. The position in the menu order this item should appear.
  1643  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1659  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1644  */
  1660  */
  1645 function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1661 function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1646 	return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1662 	return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1647 }
  1663 }
  1648 
  1664 
  1649 /**
  1665 /**
  1650  * Add submenu page to the Media main menu.
  1666  * Adds a submenu page to the Media main menu.
  1651  *
  1667  *
  1652  * This function takes a capability which will be used to determine whether
  1668  * This function takes a capability which will be used to determine whether
  1653  * or not a page is included in the menu.
  1669  * or not a page is included in the menu.
  1654  *
  1670  *
  1655  * The function which is hooked in to handle the output of the page must check
  1671  * The function which is hooked in to handle the output of the page must check
  1660  *
  1676  *
  1661  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1677  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1662  * @param string   $menu_title The text to be used for the menu.
  1678  * @param string   $menu_title The text to be used for the menu.
  1663  * @param string   $capability The capability required for this menu to be displayed to the user.
  1679  * @param string   $capability The capability required for this menu to be displayed to the user.
  1664  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1680  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1665  * @param callable $function   The function to be called to output the content for this page.
  1681  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1666  * @param int      $position   The position in the menu order this item should appear.
  1682  * @param int      $position   Optional. The position in the menu order this item should appear.
  1667  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1683  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1668  */
  1684  */
  1669 function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1685 function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1670 	return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1686 	return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1671 }
  1687 }
  1672 
  1688 
  1673 /**
  1689 /**
  1674  * Add submenu page to the Links main menu.
  1690  * Adds a submenu page to the Links main menu.
  1675  *
  1691  *
  1676  * This function takes a capability which will be used to determine whether
  1692  * This function takes a capability which will be used to determine whether
  1677  * or not a page is included in the menu.
  1693  * or not a page is included in the menu.
  1678  *
  1694  *
  1679  * The function which is hooked in to handle the output of the page must check
  1695  * The function which is hooked in to handle the output of the page must check
  1684  *
  1700  *
  1685  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1701  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1686  * @param string   $menu_title The text to be used for the menu.
  1702  * @param string   $menu_title The text to be used for the menu.
  1687  * @param string   $capability The capability required for this menu to be displayed to the user.
  1703  * @param string   $capability The capability required for this menu to be displayed to the user.
  1688  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1704  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1689  * @param callable $function   The function to be called to output the content for this page.
  1705  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1690  * @param int      $position   The position in the menu order this item should appear.
  1706  * @param int      $position   Optional. The position in the menu order this item should appear.
  1691  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1707  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1692  */
  1708  */
  1693 function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1709 function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1694 	return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1710 	return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1695 }
  1711 }
  1696 
  1712 
  1697 /**
  1713 /**
  1698  * Add submenu page to the Pages main menu.
  1714  * Adds a submenu page to the Pages main menu.
  1699  *
  1715  *
  1700  * This function takes a capability which will be used to determine whether
  1716  * This function takes a capability which will be used to determine whether
  1701  * or not a page is included in the menu.
  1717  * or not a page is included in the menu.
  1702  *
  1718  *
  1703  * The function which is hooked in to handle the output of the page must check
  1719  * The function which is hooked in to handle the output of the page must check
  1708  *
  1724  *
  1709  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1725  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1710  * @param string   $menu_title The text to be used for the menu.
  1726  * @param string   $menu_title The text to be used for the menu.
  1711  * @param string   $capability The capability required for this menu to be displayed to the user.
  1727  * @param string   $capability The capability required for this menu to be displayed to the user.
  1712  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1728  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1713  * @param callable $function   The function to be called to output the content for this page.
  1729  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1714  * @param int      $position   The position in the menu order this item should appear.
  1730  * @param int      $position   Optional. The position in the menu order this item should appear.
  1715  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1731  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1716  */
  1732  */
  1717 function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1733 function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1718 	return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1734 	return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1719 }
  1735 }
  1720 
  1736 
  1721 /**
  1737 /**
  1722  * Add submenu page to the Comments main menu.
  1738  * Adds a submenu page to the Comments main menu.
  1723  *
  1739  *
  1724  * This function takes a capability which will be used to determine whether
  1740  * This function takes a capability which will be used to determine whether
  1725  * or not a page is included in the menu.
  1741  * or not a page is included in the menu.
  1726  *
  1742  *
  1727  * The function which is hooked in to handle the output of the page must check
  1743  * The function which is hooked in to handle the output of the page must check
  1732  *
  1748  *
  1733  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1749  * @param string   $page_title The text to be displayed in the title tags of the page when the menu is selected.
  1734  * @param string   $menu_title The text to be used for the menu.
  1750  * @param string   $menu_title The text to be used for the menu.
  1735  * @param string   $capability The capability required for this menu to be displayed to the user.
  1751  * @param string   $capability The capability required for this menu to be displayed to the user.
  1736  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1752  * @param string   $menu_slug  The slug name to refer to this menu by (should be unique for this menu).
  1737  * @param callable $function   The function to be called to output the content for this page.
  1753  * @param callable $callback   Optional. The function to be called to output the content for this page.
  1738  * @param int      $position   The position in the menu order this item should appear.
  1754  * @param int      $position   Optional. The position in the menu order this item should appear.
  1739  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1755  * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required.
  1740  */
  1756  */
  1741 function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) {
  1757 function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $callback = '', $position = null ) {
  1742 	return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position );
  1758 	return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $callback, $position );
  1743 }
  1759 }
  1744 
  1760 
  1745 /**
  1761 /**
  1746  * Remove a top-level admin menu.
  1762  * Removes a top-level admin menu.
       
  1763  *
       
  1764  * Example usage:
       
  1765  *
       
  1766  *  - `remove_menu_page( 'tools.php' )`
       
  1767  *  - `remove_menu_page( 'plugin_menu_slug' )`
  1747  *
  1768  *
  1748  * @since 3.1.0
  1769  * @since 3.1.0
  1749  *
  1770  *
  1750  * @global array $menu
  1771  * @global array $menu
  1751  *
  1772  *
  1764 
  1785 
  1765 	return false;
  1786 	return false;
  1766 }
  1787 }
  1767 
  1788 
  1768 /**
  1789 /**
  1769  * Remove an admin submenu.
  1790  * Removes an admin submenu.
       
  1791  *
       
  1792  * Example usage:
       
  1793  *
       
  1794  *  - `remove_submenu_page( 'themes.php', 'nav-menus.php' )`
       
  1795  *  - `remove_submenu_page( 'tools.php', 'plugin_submenu_slug' )`
       
  1796  *  - `remove_submenu_page( 'plugin_menu_slug', 'plugin_submenu_slug' )`
  1770  *
  1797  *
  1771  * @since 3.1.0
  1798  * @since 3.1.0
  1772  *
  1799  *
  1773  * @global array $submenu
  1800  * @global array $submenu
  1774  *
  1801  *
  1792 
  1819 
  1793 	return false;
  1820 	return false;
  1794 }
  1821 }
  1795 
  1822 
  1796 /**
  1823 /**
  1797  * Get the URL to access a particular menu page based on the slug it was registered with.
  1824  * Gets the URL to access a particular menu page based on the slug it was registered with.
  1798  *
  1825  *
  1799  * If the slug hasn't been registered properly, no URL will be returned.
  1826  * If the slug hasn't been registered properly, no URL will be returned.
  1800  *
  1827  *
  1801  * @since 3.0.0
  1828  * @since 3.0.0
  1802  *
  1829  *
  1803  * @global array $_parent_pages
  1830  * @global array $_parent_pages
  1804  *
  1831  *
  1805  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
  1832  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
  1806  * @param bool   $echo      Whether or not to echo the URL. Default true.
  1833  * @param bool   $display   Optional. Whether or not to display the URL. Default true.
  1807  * @return string The menu page URL.
  1834  * @return string The menu page URL.
  1808  */
  1835  */
  1809 function menu_page_url( $menu_slug, $echo = true ) {
  1836 function menu_page_url( $menu_slug, $display = true ) {
  1810 	global $_parent_pages;
  1837 	global $_parent_pages;
  1811 
  1838 
  1812 	if ( isset( $_parent_pages[ $menu_slug ] ) ) {
  1839 	if ( isset( $_parent_pages[ $menu_slug ] ) ) {
  1813 		$parent_slug = $_parent_pages[ $menu_slug ];
  1840 		$parent_slug = $_parent_pages[ $menu_slug ];
  1814 
  1841 
  1821 		$url = '';
  1848 		$url = '';
  1822 	}
  1849 	}
  1823 
  1850 
  1824 	$url = esc_url( $url );
  1851 	$url = esc_url( $url );
  1825 
  1852 
  1826 	if ( $echo ) {
  1853 	if ( $display ) {
  1827 		echo $url;
  1854 		echo $url;
  1828 	}
  1855 	}
  1829 
  1856 
  1830 	return $url;
  1857 	return $url;
  1831 }
  1858 }
  1839  * @since 1.5.0
  1866  * @since 1.5.0
  1840  *
  1867  *
  1841  * @global string $parent_file
  1868  * @global string $parent_file
  1842  * @global array  $menu
  1869  * @global array  $menu
  1843  * @global array  $submenu
  1870  * @global array  $submenu
  1844  * @global string $pagenow
  1871  * @global string $pagenow              The filename of the current screen.
  1845  * @global string $typenow
  1872  * @global string $typenow              The post type of the current screen.
  1846  * @global string $plugin_page
  1873  * @global string $plugin_page
  1847  * @global array  $_wp_real_parent_file
  1874  * @global array  $_wp_real_parent_file
  1848  * @global array  $_wp_menu_nopriv
  1875  * @global array  $_wp_menu_nopriv
  1849  * @global array  $_wp_submenu_nopriv
  1876  * @global array  $_wp_submenu_nopriv
  1850  *
  1877  *
  1851  * @param string $parent The slug name for the parent menu (or the file name of a standard
  1878  * @param string $parent_page Optional. The slug name for the parent menu (or the file name
  1852  *                       WordPress admin page). Default empty string.
  1879  *                            of a standard WordPress admin page). Default empty string.
  1853  * @return string The parent file of the current admin page.
  1880  * @return string The parent file of the current admin page.
  1854  */
  1881  */
  1855 function get_admin_page_parent( $parent = '' ) {
  1882 function get_admin_page_parent( $parent_page = '' ) {
  1856 	global $parent_file, $menu, $submenu, $pagenow, $typenow,
  1883 	global $parent_file, $menu, $submenu, $pagenow, $typenow,
  1857 		$plugin_page, $_wp_real_parent_file, $_wp_menu_nopriv, $_wp_submenu_nopriv;
  1884 		$plugin_page, $_wp_real_parent_file, $_wp_menu_nopriv, $_wp_submenu_nopriv;
  1858 
  1885 
  1859 	if ( ! empty( $parent ) && 'admin.php' !== $parent ) {
  1886 	if ( ! empty( $parent_page ) && 'admin.php' !== $parent_page ) {
  1860 		if ( isset( $_wp_real_parent_file[ $parent ] ) ) {
  1887 		if ( isset( $_wp_real_parent_file[ $parent_page ] ) ) {
  1861 			$parent = $_wp_real_parent_file[ $parent ];
  1888 			$parent_page = $_wp_real_parent_file[ $parent_page ];
  1862 		}
  1889 		}
  1863 
  1890 
  1864 		return $parent;
  1891 		return $parent_page;
  1865 	}
  1892 	}
  1866 
  1893 
  1867 	if ( 'admin.php' === $pagenow && isset( $plugin_page ) ) {
  1894 	if ( 'admin.php' === $pagenow && isset( $plugin_page ) ) {
  1868 		foreach ( (array) $menu as $parent_menu ) {
  1895 		foreach ( (array) $menu as $parent_menu ) {
  1869 			if ( $parent_menu[2] === $plugin_page ) {
  1896 			if ( $parent_menu[2] === $plugin_page ) {
  1895 		}
  1922 		}
  1896 
  1923 
  1897 		return $parent_file;
  1924 		return $parent_file;
  1898 	}
  1925 	}
  1899 
  1926 
  1900 	foreach ( array_keys( (array) $submenu ) as $parent ) {
  1927 	foreach ( array_keys( (array) $submenu ) as $parent_page ) {
  1901 		foreach ( $submenu[ $parent ] as $submenu_array ) {
  1928 		foreach ( $submenu[ $parent_page ] as $submenu_array ) {
  1902 			if ( isset( $_wp_real_parent_file[ $parent ] ) ) {
  1929 			if ( isset( $_wp_real_parent_file[ $parent_page ] ) ) {
  1903 				$parent = $_wp_real_parent_file[ $parent ];
  1930 				$parent_page = $_wp_real_parent_file[ $parent_page ];
  1904 			}
  1931 			}
  1905 
  1932 
  1906 			if ( ! empty( $typenow ) && "$pagenow?post_type=$typenow" === $submenu_array[2] ) {
  1933 			if ( ! empty( $typenow ) && "$pagenow?post_type=$typenow" === $submenu_array[2] ) {
  1907 				$parent_file = $parent;
  1934 				$parent_file = $parent_page;
  1908 				return $parent;
  1935 				return $parent_page;
  1909 			} elseif ( empty( $typenow ) && $pagenow === $submenu_array[2]
  1936 			} elseif ( empty( $typenow ) && $pagenow === $submenu_array[2]
  1910 				&& ( empty( $parent_file ) || false === strpos( $parent_file, '?' ) )
  1937 				&& ( empty( $parent_file ) || false === strpos( $parent_file, '?' ) )
  1911 			) {
  1938 			) {
  1912 				$parent_file = $parent;
  1939 				$parent_file = $parent_page;
  1913 				return $parent;
  1940 				return $parent_page;
  1914 			} elseif ( isset( $plugin_page ) && $plugin_page === $submenu_array[2] ) {
  1941 			} elseif ( isset( $plugin_page ) && $plugin_page === $submenu_array[2] ) {
  1915 				$parent_file = $parent;
  1942 				$parent_file = $parent_page;
  1916 				return $parent;
  1943 				return $parent_page;
  1917 			}
  1944 			}
  1918 		}
  1945 		}
  1919 	}
  1946 	}
  1920 
  1947 
  1921 	if ( empty( $parent_file ) ) {
  1948 	if ( empty( $parent_file ) ) {
  1928  * Gets the title of the current admin page.
  1955  * Gets the title of the current admin page.
  1929  *
  1956  *
  1930  * @since 1.5.0
  1957  * @since 1.5.0
  1931  *
  1958  *
  1932  * @global string $title
  1959  * @global string $title
  1933  * @global array $menu
  1960  * @global array  $menu
  1934  * @global array $submenu
  1961  * @global array  $submenu
  1935  * @global string $pagenow
  1962  * @global string $pagenow     The filename of the current screen.
       
  1963  * @global string $typenow     The post type of the current screen.
  1936  * @global string $plugin_page
  1964  * @global string $plugin_page
  1937  * @global string $typenow
       
  1938  *
  1965  *
  1939  * @return string The title of the current admin page.
  1966  * @return string The title of the current admin page.
  1940  */
  1967  */
  1941 function get_admin_page_title() {
  1968 function get_admin_page_title() {
  1942 	global $title, $menu, $submenu, $pagenow, $plugin_page, $typenow;
  1969 	global $title, $menu, $submenu, $pagenow, $typenow, $plugin_page;
  1943 
  1970 
  1944 	if ( ! empty( $title ) ) {
  1971 	if ( ! empty( $title ) ) {
  1945 		return $title;
  1972 		return $title;
  1946 	}
  1973 	}
  1947 
  1974 
  2065 /**
  2092 /**
  2066  * Determines whether the current user can access the current admin page.
  2093  * Determines whether the current user can access the current admin page.
  2067  *
  2094  *
  2068  * @since 1.5.0
  2095  * @since 1.5.0
  2069  *
  2096  *
  2070  * @global string $pagenow
  2097  * @global string $pagenow            The filename of the current screen.
  2071  * @global array  $menu
  2098  * @global array  $menu
  2072  * @global array  $submenu
  2099  * @global array  $submenu
  2073  * @global array  $_wp_menu_nopriv
  2100  * @global array  $_wp_menu_nopriv
  2074  * @global array  $_wp_submenu_nopriv
  2101  * @global array  $_wp_submenu_nopriv
  2075  * @global string $plugin_page
  2102  * @global string $plugin_page
  2240 
  2267 
  2241 	return $allowed_options;
  2268 	return $allowed_options;
  2242 }
  2269 }
  2243 
  2270 
  2244 /**
  2271 /**
  2245  * Output nonce, action, and option_page fields for a settings page.
  2272  * Outputs nonce, action, and option_page fields for a settings page.
  2246  *
  2273  *
  2247  * @since 2.7.0
  2274  * @since 2.7.0
  2248  *
  2275  *
  2249  * @param string $option_group A settings group name. This should match the group name
  2276  * @param string $option_group A settings group name. This should match the group name
  2250  *                             used in register_setting().
  2277  *                             used in register_setting().
  2268 	}
  2295 	}
  2269 	wp_cache_delete( 'plugins', 'plugins' );
  2296 	wp_cache_delete( 'plugins', 'plugins' );
  2270 }
  2297 }
  2271 
  2298 
  2272 /**
  2299 /**
  2273  * Load a given plugin attempt to generate errors.
  2300  * Loads a given plugin attempt to generate errors.
  2274  *
  2301  *
  2275  * @since 3.0.0
  2302  * @since 3.0.0
  2276  * @since 4.4.0 Function was moved into the `wp-admin/includes/plugin.php` file.
  2303  * @since 4.4.0 Function was moved into the `wp-admin/includes/plugin.php` file.
  2277  *
  2304  *
  2278  * @param string $plugin Path to the plugin file relative to the plugins directory.
  2305  * @param string $plugin Path to the plugin file relative to the plugins directory.
  2285 	wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
  2312 	wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
  2286 	include_once WP_PLUGIN_DIR . '/' . $plugin;
  2313 	include_once WP_PLUGIN_DIR . '/' . $plugin;
  2287 }
  2314 }
  2288 
  2315 
  2289 /**
  2316 /**
  2290  * Helper function for adding content to the Privacy Policy Guide.
  2317  * Declares a helper function for adding content to the Privacy Policy Guide.
  2291  *
  2318  *
  2292  * Plugins and themes should suggest text for inclusion in the site's privacy policy.
  2319  * Plugins and themes should suggest text for inclusion in the site's privacy policy.
  2293  * The suggested text should contain information about any functionality that affects user privacy,
  2320  * The suggested text should contain information about any functionality that affects user privacy,
  2294  * and will be shown on the Privacy Policy Guide screen.
  2321  * and will be shown on the Privacy Policy Guide screen.
  2295  *
  2322  *
  2448 /**
  2475 /**
  2449  * Renders an admin notice in case some plugins have been paused due to errors.
  2476  * Renders an admin notice in case some plugins have been paused due to errors.
  2450  *
  2477  *
  2451  * @since 5.2.0
  2478  * @since 5.2.0
  2452  *
  2479  *
  2453  * @global string $pagenow
  2480  * @global string $pagenow The filename of the current screen.
  2454  */
  2481  */
  2455 function paused_plugins_notice() {
  2482 function paused_plugins_notice() {
  2456 	if ( 'plugins.php' === $GLOBALS['pagenow'] ) {
  2483 	if ( 'plugins.php' === $GLOBALS['pagenow'] ) {
  2457 		return;
  2484 		return;
  2458 	}
  2485 	}
  2481  * upgrade due to incompatibility with the current version of WordPress.
  2508  * upgrade due to incompatibility with the current version of WordPress.
  2482  *
  2509  *
  2483  * @since 5.8.0
  2510  * @since 5.8.0
  2484  * @access private
  2511  * @access private
  2485  *
  2512  *
  2486  * @global string $pagenow
  2513  * @global string $pagenow    The filename of the current screen.
  2487  * @global string $wp_version
  2514  * @global string $wp_version The WordPress version string.
  2488  */
  2515  */
  2489 function deactivated_plugins_notice() {
  2516 function deactivated_plugins_notice() {
  2490 	if ( 'plugins.php' === $GLOBALS['pagenow'] ) {
  2517 	if ( 'plugins.php' === $GLOBALS['pagenow'] ) {
  2491 		return;
  2518 		return;
  2492 	}
  2519 	}
  2519 	$deactivated_plugins = array_merge( $blog_deactivated_plugins, $site_deactivated_plugins );
  2546 	$deactivated_plugins = array_merge( $blog_deactivated_plugins, $site_deactivated_plugins );
  2520 
  2547 
  2521 	foreach ( $deactivated_plugins as $plugin ) {
  2548 	foreach ( $deactivated_plugins as $plugin ) {
  2522 		if ( ! empty( $plugin['version_compatible'] ) && ! empty( $plugin['version_deactivated'] ) ) {
  2549 		if ( ! empty( $plugin['version_compatible'] ) && ! empty( $plugin['version_deactivated'] ) ) {
  2523 			$explanation = sprintf(
  2550 			$explanation = sprintf(
  2524 				/* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version, 4: Compatible plugin version */
  2551 				/* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version, 4: Compatible plugin version. */
  2525 				__( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s, please upgrade to %1$s %4$s or later.' ),
  2552 				__( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s, please upgrade to %1$s %4$s or later.' ),
  2526 				$plugin['plugin_name'],
  2553 				$plugin['plugin_name'],
  2527 				$plugin['version_deactivated'],
  2554 				$plugin['version_deactivated'],
  2528 				$GLOBALS['wp_version'],
  2555 				$GLOBALS['wp_version'],
  2529 				$plugin['version_compatible']
  2556 				$plugin['version_compatible']
  2530 			);
  2557 			);
  2531 		} else {
  2558 		} else {
  2532 			$explanation = sprintf(
  2559 			$explanation = sprintf(
  2533 				/* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version */
  2560 				/* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version. */
  2534 				__( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s.' ),
  2561 				__( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s.' ),
  2535 				$plugin['plugin_name'],
  2562 				$plugin['plugin_name'],
  2536 				! empty( $plugin['version_deactivated'] ) ? $plugin['version_deactivated'] : '',
  2563 				! empty( $plugin['version_deactivated'] ) ? $plugin['version_deactivated'] : '',
  2537 				$GLOBALS['wp_version'],
  2564 				$GLOBALS['wp_version'],
  2538 				$plugin['version_compatible']
  2565 				$plugin['version_compatible']
  2540 		}
  2567 		}
  2541 
  2568 
  2542 		printf(
  2569 		printf(
  2543 			'<div class="notice notice-warning"><p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p></div>',
  2570 			'<div class="notice notice-warning"><p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p></div>',
  2544 			sprintf(
  2571 			sprintf(
  2545 				/* translators: %s: Name of deactivated plugin */
  2572 				/* translators: %s: Name of deactivated plugin. */
  2546 				__( '%s plugin deactivated during WordPress upgrade.' ),
  2573 				__( '%s plugin deactivated during WordPress upgrade.' ),
  2547 				$plugin['plugin_name']
  2574 				$plugin['plugin_name']
  2548 			),
  2575 			),
  2549 			$explanation,
  2576 			$explanation,
  2550 			esc_url( admin_url( 'plugins.php?plugin_status=inactive' ) ),
  2577 			esc_url( admin_url( 'plugins.php?plugin_status=inactive' ) ),