* Screen API: WP_Screen class
* @subpackage Administration
* Core class used to implement an admin screen API.
* Any action associated with the screen.
* 'add' for *-add.php and *-new.php screens. Empty otherwise.
* The base type of the screen.
* This is typically the same as `$id` but with any post types and taxonomies stripped.
* For example, for an `$id` of 'edit-post' the base is 'edit'.
* The number of columns to display. Access with get_columns().
* The unique ID of the screen.
* Which admin the screen is in. network | user | site | false
* Whether the screen is in the network admin.
* Deprecated. Use in_admin() instead.
* Whether the screen is in the user admin.
* Deprecated. Use in_admin() instead.
* This is derived from `$parent_file` by removing the query string and any .php extension.
* `$parent_file` values of 'edit.php?post_type=page' and 'edit.php?post_type=post'
* have a `$parent_base` of 'edit'.
* The parent_file for the screen per the admin menu system.
* Some `$parent_file` values are 'edit.php?post_type=page', 'edit.php', and 'options-general.php'.
* The post type associated with the screen, if any.
* The 'edit.php?post_type=page' screen has a post type of 'page'.
* The 'edit-tags.php?taxonomy=$taxonomy&post_type=page' screen has a post type of 'page'.
* The taxonomy associated with the screen, if any.
* The 'edit-tags.php?taxonomy=category' screen has a taxonomy of 'category'.
* The help tab data associated with the screen, if any.
private $_help_tabs = array();
* The help sidebar data associated with screen, if any.
private $_help_sidebar = '';
* The accessible hidden headings and text associated with the screen, if any.
private $_screen_reader_content = array();
* Stores old string-based help.
private static $_old_compat_help = array();
* The screen options associated with screen, if any.
private $_options = array();
* The screen object registry.
private static $_registry = array();
* Stores the result of the public show_screen_options function.
private $_show_screen_options;
* Stores the 'screen_settings' section of screen options.
private $_screen_settings;
* Whether the screen is using the block editor.
public $is_block_editor = false;
* Fetches a screen object.
* @global string $hook_suffix
* @param string|WP_Screen $hook_name Optional. The hook name (also known as the hook suffix) used to determine the screen.
* Defaults to the current $hook_suffix global.
* @return WP_Screen Screen object.
public static function get( $hook_name = '' ) {
if ( $hook_name instanceof WP_Screen ) {
$is_block_editor = false;
$id = $GLOBALS['hook_suffix'];
// For those pesky meta boxes.
if ( $hook_name && post_type_exists( $hook_name ) ) {
$id = 'post'; // Changes later. Ends up being $base.
if ( '.php' === substr( $id, -4 ) ) {
$id = substr( $id, 0, -4 );
if ( in_array( $id, array( 'post-new', 'link-add', 'media-new', 'user-new' ), true ) ) {
$id = substr( $id, 0, -4 );
if ( ! $post_type && $hook_name ) {
if ( '-network' === substr( $id, -8 ) ) {
$id = substr( $id, 0, -8 );
} elseif ( '-user' === substr( $id, -5 ) ) {
$id = substr( $id, 0, -5 );
$id = sanitize_key( $id );
if ( 'edit-comments' !== $id && 'edit-tags' !== $id && 'edit-' === substr( $id, 0, 5 ) ) {
$maybe = substr( $id, 5 );
if ( taxonomy_exists( $maybe ) ) {
} elseif ( post_type_exists( $maybe ) ) {
if ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN ) {
} elseif ( defined( 'WP_USER_ADMIN' ) && WP_USER_ADMIN ) {
} elseif ( 'front' === $id ) {
// If this is the current screen, see if we can be more accurate for post types and taxonomies.
if ( isset( $_REQUEST['post_type'] ) ) {
$post_type = post_type_exists( $_REQUEST['post_type'] ) ? $_REQUEST['post_type'] : false;
if ( isset( $_REQUEST['taxonomy'] ) ) {
$taxonomy = taxonomy_exists( $_REQUEST['taxonomy'] ) ? $_REQUEST['taxonomy'] : false;
if ( isset( $_GET['post'] ) && isset( $_POST['post_ID'] ) && (int) $_GET['post'] !== (int) $_POST['post_ID'] ) {
wp_die( __( 'A post ID mismatch has been detected.' ), __( 'Sorry, you are not allowed to edit this item.' ), 400 );
} elseif ( isset( $_GET['post'] ) ) {
$post_id = (int) $_GET['post'];
} elseif ( isset( $_POST['post_ID'] ) ) {
$post_id = (int) $_POST['post_ID'];
$post = get_post( $post_id );
$post_type = $post->post_type;
/** This filter is documented in wp-admin/post.php */
$replace_editor = apply_filters( 'replace_editor', false, $post );
if ( ! $replace_editor ) {
$is_block_editor = use_block_editor_for_post( $post );
if ( null === $post_type && is_object_in_taxonomy( 'post', $taxonomy ? $taxonomy : 'post_tag' ) ) {
$post_type = 'attachment';
if ( null === $post_type ) {
// When creating a new post, use the default block editor support value for the post type.
if ( empty( $post_id ) ) {
$is_block_editor = use_block_editor_for_post_type( $post_type );
if ( null === $post_type ) {
if ( null === $taxonomy ) {
// The edit-tags ID does not contain the post type. Look for it in the request.
if ( null === $post_type ) {
if ( isset( $_REQUEST['post_type'] ) && post_type_exists( $_REQUEST['post_type'] ) ) {
$post_type = $_REQUEST['post_type'];
$id = 'edit-' . $taxonomy;
if ( 'network' === $in_admin ) {
} elseif ( 'user' === $in_admin ) {
if ( isset( self::$_registry[ $id ] ) ) {
$screen = self::$_registry[ $id ];
if ( get_current_screen() === $screen ) {
$screen->action = $action;
$screen->post_type = (string) $post_type;
$screen->taxonomy = (string) $taxonomy;
$screen->is_user = ( 'user' === $in_admin );
$screen->is_network = ( 'network' === $in_admin );
$screen->in_admin = $in_admin;
$screen->is_block_editor = $is_block_editor;
self::$_registry[ $id ] = $screen;
* Makes the screen object the current screen.
* @see set_current_screen()
* @global WP_Screen $current_screen WordPress current screen object.
* @global string $typenow
public function set_current_screen() {
global $current_screen, $taxnow, $typenow;
$taxnow = $this->taxonomy;
$typenow = $this->post_type;
* Fires after the current screen has been set.
* @param WP_Screen $current_screen Current WP_Screen object.
do_action( 'current_screen', $current_screen );
private function __construct() {}
* Indicates whether the screen is in a particular admin
* @param string $admin The admin to check against (network | user | site).
* If empty any of the three admins will result in true.
* @return bool True if the screen is in the indicated admin, false otherwise.
public function in_admin( $admin = null ) {
return (bool) $this->in_admin;
return ( $admin === $this->in_admin );
* Sets or returns whether the block editor is loading on the current screen.
* @param bool $set Optional. Sets whether the block editor is loading on the current screen or not.
* @return bool True if the block editor is being loaded, false otherwise.
public function is_block_editor( $set = null ) {
$this->is_block_editor = (bool) $set;
return $this->is_block_editor;
* Sets the old string-based contextual help for the screen for backward compatibility.
* @param WP_Screen $screen A screen object.
* @param string $help Help text.
public static function add_old_compat_help( $screen, $help ) {
self::$_old_compat_help[ $screen->id ] = $help;
* Set the parent information for the screen.
* This is called in admin-header.php after the menu parent for the screen has been determined.
* @param string $parent_file The parent file of the screen. Typically the $parent_file global.
public function set_parentage( $parent_file ) {
$this->parent_file = $parent_file;
list( $this->parent_base ) = explode( '?', $parent_file );
$this->parent_base = str_replace( '.php', '', $this->parent_base );
* Adds an option for the screen.
* Call this in template files after admin.php is loaded and before admin-header.php is loaded
* @param string $option Option ID.
* @param mixed $args Option-dependent arguments.