File "capabilities-20241224182720.php"
Full Path: /home/ycoalition/public_html/blog/wp-includes/widgets/capabilities-20241224182720.php
File size: 12 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Core User Role & Capabilities API
*
* @package WordPress
* @subpackage Users
*/
/**
* Maps a capability to the primitive capabilities required of the given user to
* satisfy the capability being checked.
*
* This function also accepts an ID of an object to map against if the capability is a meta capability. Meta
* capabilities such as `edit_post` and `edit_user` are capabilities used by this function to map to primitive
* capabilities that a user or role requires, such as `edit_posts` and `edit_others_posts`.
*
* Example usage:
*
* map_meta_cap( 'edit_posts', $user->ID );
* map_meta_cap( 'edit_post', $user->ID, $post->ID );
* map_meta_cap( 'edit_post_meta', $user->ID, $post->ID, $meta_key );
*
* This function does not check whether the user has the required capabilities,
* it just returns what the required capabilities are.
*
* @since 2.0.0
* @since 4.9.6 Added the `export_others_personal_data`, `erase_others_personal_data`,
* and `manage_privacy_options` capabilities.
* @since 5.1.0 Added the `update_php` capability.
* @since 5.2.0 Added the `resume_plugin` and `resume_theme` capabilities.
* @since 5.3.0 Formalized the existing and already documented `...$args` parameter
* by adding it to the function signature.
* @since 5.7.0 Added the `create_app_password`, `list_app_passwords`, `read_app_password`,
* `edit_app_password`, `delete_app_passwords`, `delete_app_password`,
* and `update_https` capabilities.
* @since 6.7.0 Added the `edit_block_binding` capability.
*
* @global array $post_type_meta_caps Used to get post type meta capabilities.
*
* @param string $cap Capability being checked.
* @param int $user_id User ID.
* @param mixed ...$args Optional further parameters, typically starting with an object ID.
* @return string[] Primitive capabilities required of the user.
*/
function map_meta_cap( $cap, $user_id, ...$args ) {
$caps = array();
switch ( $cap ) {
case 'remove_user':
// In multisite the user must be a super admin to remove themselves.
if ( isset( $args[0] ) && $user_id === (int) $args[0] && ! is_super_admin( $user_id ) ) {
$caps[] = 'do_not_allow';
} else {
$caps[] = 'remove_users';
}
break;
case 'promote_user':
case 'add_users':
$caps[] = 'promote_users';
break;
case 'edit_user':
case 'edit_users':
// Allow user to edit themselves.
if ( 'edit_user' === $cap && isset( $args[0] ) && $user_id === (int) $args[0] ) {
break;
}
// In multisite the user must have manage_network_users caps. If editing a super admin, the user must be a super admin.
if ( is_multisite() && ( ( ! is_super_admin( $user_id ) && 'edit_user' === $cap && is_super_admin( $args[0] ) ) || ! user_can( $user_id, 'manage_network_users' ) ) ) {
$caps[] = 'do_not_allow';
} else {
$caps[] = 'edit_users'; // edit_user maps to edit_users.
}
break;
case 'delete_post':
case 'delete_page':
if ( ! isset( $args[0] ) ) {
if ( 'delete_post' === $cap ) {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
} else {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific page.' );
}
_doing_it_wrong(
__FUNCTION__,
sprintf( $message, '<code>' . $cap . '</code>' ),
'6.1.0'
);
$caps[] = 'do_not_allow';
break;
}
$post = get_post( $args[0] );
if ( ! $post ) {
$caps[] = 'do_not_allow';
break;
}
if ( 'revision' === $post->post_type ) {
$caps[] = 'do_not_allow';
break;
}
if ( (int) get_option( 'page_for_posts' ) === $post->ID
|| (int) get_option( 'page_on_front' ) === $post->ID
) {
$caps[] = 'manage_options';
break;
}
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
/* translators: 1: Post type, 2: Capability name. */
$message = __( 'The post type %1$s is not registered, so it may not be reliable to check the capability %2$s against a post of that type.' );
_doing_it_wrong(
__FUNCTION__,
sprintf(
$message,
'<code>' . $post->post_type . '</code>',
'<code>' . $cap . '</code>'
),
'4.4.0'
);
$caps[] = 'edit_others_posts';
break;
}
if ( ! $post_type->map_meta_cap ) {
$caps[] = $post_type->cap->$cap;
// Prior to 3.1 we would re-call map_meta_cap here.
if ( 'delete_post' === $cap ) {
$cap = $post_type->cap->$cap;
}
break;
}
// If the post author is set and the user is the author...
if ( $post->post_author && $user_id === (int) $post->post_author ) {
// If the post is published or scheduled...
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
$caps[] = $post_type->cap->delete_published_posts;
} elseif ( 'trash' === $post->post_status ) {
$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
$caps[] = $post_type->cap->delete_published_posts;
} else {
$caps[] = $post_type->cap->delete_posts;
}
} else {
// If the post is draft...
$caps[] = $post_type->cap->delete_posts;
}
} else {
// The user is trying to edit someone else's post.
$caps[] = $post_type->cap->delete_others_posts;
// The post is published or scheduled, extra cap required.
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
$caps[] = $post_type->cap->delete_published_posts;
} elseif ( 'private' === $post->post_status ) {
$caps[] = $post_type->cap->delete_private_posts;
}
}
/*
* Setting the privacy policy page requires `manage_privacy_options`,
* so deleting it should require that too.
*/
if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
}
break;
/*
* edit_post breaks down to edit_posts, edit_published_posts, or
* edit_others_posts.
*/
case 'edit_post':
case 'edit_page':
if ( ! isset( $args[0] ) ) {
if ( 'edit_post' === $cap ) {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
} else {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific page.' );
}
_doing_it_wrong(
__FUNCTION__,
sprintf( $message, '<code>' . $cap . '</code>' ),
'6.1.0'
);
$caps[] = 'do_not_allow';
break;
}
$post = get_post( $args[0] );
if ( ! $post ) {
$caps[] = 'do_not_allow';
break;
}
if ( 'revision' === $post->post_type ) {
$post = get_post( $post->post_parent );
if ( ! $post ) {
$caps[] = 'do_not_allow';
break;
}
}
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
/* translators: 1: Post type, 2: Capability name. */
$message = __( 'The post type %1$s is not registered, so it may not be reliable to check the capability %2$s against a post of that type.' );
_doing_it_wrong(
__FUNCTION__,
sprintf(
$message,
'<code>' . $post->post_type . '</code>',
'<code>' . $cap . '</code>'
),
'4.4.0'
);
$caps[] = 'edit_others_posts';
break;
}
if ( ! $post_type->map_meta_cap ) {
$caps[] = $post_type->cap->$cap;
// Prior to 3.1 we would re-call map_meta_cap here.
if ( 'edit_post' === $cap ) {
$cap = $post_type->cap->$cap;
}
break;
}
// If the post author is set and the user is the author...
if ( $post->post_author && $user_id === (int) $post->post_author ) {
// If the post is published or scheduled...
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
$caps[] = $post_type->cap->edit_published_posts;
} elseif ( 'trash' === $post->post_status ) {
$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
$caps[] = $post_type->cap->edit_published_posts;
} else {
$caps[] = $post_type->cap->edit_posts;
}
} else {
// If the post is draft...
$caps[] = $post_type->cap->edit_posts;
}
} else {
// The user is trying to edit someone else's post.
$caps[] = $post_type->cap->edit_others_posts;
// The post is published or scheduled, extra cap required.
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
$caps[] = $post_type->cap->edit_published_posts;
} elseif ( 'private' === $post->post_status ) {
$caps[] = $post_type->cap->edit_private_posts;
}
}
/*
* Setting the privacy policy page requires `manage_privacy_options`,
* so editing it should require that too.
*/
if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
}
break;
case 'read_post':
case 'read_page':
if ( ! isset( $args[0] ) ) {
if ( 'read_post' === $cap ) {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
} else {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific page.' );
}
_doing_it_wrong(
__FUNCTION__,
sprintf( $message, '<code>' . $cap . '</code>' ),
'6.1.0'
);
$caps[] = 'do_not_allow';
break;
}
$post = get_post( $args[0] );
if ( ! $post ) {
$caps[] = 'do_not_allow';
break;
}
if ( 'revision' === $post->post_type ) {
$post = get_post( $post->post_parent );
if ( ! $post ) {
$caps[] = 'do_not_allow';
break;
}
}
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
/* translators: 1: Post type, 2: Capability name. */
$message = __( 'The post type %1$s is not registered, so it may not be reliable to check the capability %2$s against a post of that type.' );
_doing_it_wrong(
__FUNCTION__,
sprintf(
$message,
'<code>' . $post->post_type . '</code>',
'<code>' . $cap . '</code>'
),
'4.4.0'
);
$caps[] = 'edit_others_posts';
break;
}
if ( ! $post_type->map_meta_cap ) {
$caps[] = $post_type->cap->$cap;
// Prior to 3.1 we would re-call map_meta_cap here.
if ( 'read_post' === $cap ) {
$cap = $post_type->cap->$cap;
}
break;
}
$status_obj = get_post_status_object( get_post_status( $post ) );
if ( ! $status_obj ) {
/* translators: 1: Post status, 2: Capability name. */
$message = __( 'The post status %1$s is not registered, so it may not be reliable to check the capability %2$s against a post with that status.' );
_doing_it_wrong(
__FUNCTION__,
sprintf(
$message,
'<code>' . get_post_status( $post ) . '</code>',
'<code>' . $cap . '</code>'
),
'5.4.0'
);
$caps[] = 'edit_others_posts';
break;
}
if ( $status_obj->public ) {
$caps[] = $post_type->cap->read;
break;
}
if ( $post->post_author && $user_id === (int) $post->post_author ) {
$caps[] = $post_type->cap->read;
} elseif ( $status_obj->private ) {
$caps[] = $post_type->cap->read_private_posts;
} else {
$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
}
break;
case 'publish_post':
if ( ! isset( $args[0] ) ) {
/* translators: %s: Capability name. */
$message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
_doing_it_wrong(
__FUNCTION__,
sprintf( $message, '<code>' . $cap . '</code>' ),
'6.1.0'
);
$caps[] = 'do_not_allow';
break;
}
$post = get_post( $args[0] );
if ( !