--- a/wp/wp-includes/capabilities.php Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/capabilities.php Tue Dec 15 13:49:49 2020 +0100
@@ -7,7 +7,17 @@
*/
/**
- * Map meta capabilities to primitive capabilities.
+ * Maps meta capabilities to primitive capabilities.
+ *
+ * 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 has, 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 does not actually compare whether the user ID has the actual capability,
* just what the capability or capabilities are. Meta capability list value can
@@ -15,19 +25,17 @@
* 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'.
*
* @since 2.0.0
+ * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
+ * by adding it to the function signature.
*
* @global array $post_type_meta_caps Used to get post type meta capabilities.
*
- * @param string $cap Capability name.
- * @param int $user_id User ID.
- * @param int $object_id Optional. ID of the specific object to check against if `$cap` is a "meta" cap.
- * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used
- * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',
- * 'edit_others_posts', etc. The parameter is accessed via func_get_args().
- * @return array Actual capabilities for meta capability.
+ * @param string $cap Capability name.
+ * @param int $user_id User ID.
+ * @param mixed ...$args Optional further parameters, typically starting with an object ID.
+ * @return string[] Actual capabilities for meta capability.
*/
-function map_meta_cap( $cap, $user_id ) {
- $args = array_slice( func_get_args(), 2 );
+function map_meta_cap( $cap, $user_id, ...$args ) {
$caps = array();
switch ( $cap ) {
@@ -45,8 +53,8 @@
break;
case 'edit_user':
case 'edit_users':
- // Allow user to edit itself
- if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] ) {
+ // Allow user to edit themselves.
+ if ( 'edit_user' === $cap && isset( $args[0] ) && $user_id == $args[0] ) {
break;
}
@@ -65,12 +73,9 @@
break;
}
- if ( 'revision' == $post->post_type ) {
- $post = get_post( $post->post_parent );
- if ( ! $post ) {
- $caps[] = 'do_not_allow';
- break;
- }
+ if ( 'revision' === $post->post_type ) {
+ $caps[] = 'do_not_allow';
+ break;
}
if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) {
@@ -80,7 +85,7 @@
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
- /* translators: 1: post type, 2: capability name */
+ /* translators: 1: Post type, 2: Capability name. */
_doing_it_wrong( __FUNCTION__, sprintf( __( '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.' ), $post->post_type, $cap ), '4.4.0' );
$caps[] = 'edit_others_posts';
break;
@@ -89,7 +94,7 @@
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 ) {
+ if ( 'delete_post' === $cap ) {
$cap = $post_type->cap->$cap;
}
break;
@@ -100,7 +105,7 @@
// 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 ) {
+ } 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;
@@ -117,7 +122,7 @@
// 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 ) {
+ } elseif ( 'private' === $post->post_status ) {
$caps[] = $post_type->cap->delete_private_posts;
}
}
@@ -132,7 +137,7 @@
break;
// edit_post breaks down to edit_posts, edit_published_posts, or
- // edit_others_posts
+ // edit_others_posts.
case 'edit_post':
case 'edit_page':
$post = get_post( $args[0] );
@@ -141,7 +146,7 @@
break;
}
- if ( 'revision' == $post->post_type ) {
+ if ( 'revision' === $post->post_type ) {
$post = get_post( $post->post_parent );
if ( ! $post ) {
$caps[] = 'do_not_allow';
@@ -151,7 +156,7 @@
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
- /* translators: 1: post type, 2: capability name */
+ /* translators: 1: Post type, 2: Capability name. */
_doing_it_wrong( __FUNCTION__, sprintf( __( '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.' ), $post->post_type, $cap ), '4.4.0' );
$caps[] = 'edit_others_posts';
break;
@@ -160,7 +165,7 @@
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 ) {
+ if ( 'edit_post' === $cap ) {
$cap = $post_type->cap->$cap;
}
break;
@@ -171,7 +176,7 @@
// 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 ) {
+ } 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;
@@ -188,7 +193,7 @@
// 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 ) {
+ } elseif ( 'private' === $post->post_status ) {
$caps[] = $post_type->cap->edit_private_posts;
}
}
@@ -210,7 +215,7 @@
break;
}
- if ( 'revision' == $post->post_type ) {
+ if ( 'revision' === $post->post_type ) {
$post = get_post( $post->post_parent );
if ( ! $post ) {
$caps[] = 'do_not_allow';
@@ -220,7 +225,7 @@
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
- /* translators: 1: post type, 2: capability name */
+ /* translators: 1: Post type, 2: Capability name. */
_doing_it_wrong( __FUNCTION__, sprintf( __( '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.' ), $post->post_type, $cap ), '4.4.0' );
$caps[] = 'edit_others_posts';
break;
@@ -229,13 +234,20 @@
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 ) {
+ if ( 'read_post' === $cap ) {
$cap = $post_type->cap->$cap;
}
break;
}
$status_obj = get_post_status_object( $post->post_status );
+ if ( ! $status_obj ) {
+ /* translators: 1: Post status, 2: Capability name. */
+ _doing_it_wrong( __FUNCTION__, sprintf( __( '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.' ), $post->post_status, $cap ), '5.4.0' );
+ $caps[] = 'edit_others_posts';
+ break;
+ }
+
if ( $status_obj->public ) {
$caps[] = $post_type->cap->read;
break;
@@ -258,7 +270,7 @@
$post_type = get_post_type_object( $post->post_type );
if ( ! $post_type ) {
- /* translators: 1: post type, 2: capability name */
+ /* translators: 1: Post type, 2: Capability name. */
_doing_it_wrong( __FUNCTION__, sprintf( __( '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.' ), $post->post_type, $cap ), '4.4.0' );
$caps[] = 'edit_others_posts';
break;
@@ -278,8 +290,8 @@
case 'edit_user_meta':
case 'delete_user_meta':
case 'add_user_meta':
- list( $_, $object_type, $_ ) = explode( '_', $cap );
- $object_id = (int) $args[0];
+ $object_type = explode( '_', $cap )[1];
+ $object_id = (int) $args[0];
$object_subtype = get_object_subtype( $object_type, $object_id );
@@ -349,8 +361,9 @@
* The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
*
* @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`.
- * @since 4.7.0
- * @deprecated 4.9.8 Use `auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}`
+ * @since 4.7.0 Renamed from `auth_post_{$post_type}_meta_{$meta_key}` to
+ * `auth_{$object_type}_{$object_subtype}_meta_{$meta_key}`.
+ * @deprecated 4.9.8 Use {@see 'auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}'} instead.
*
* @param bool $allowed Whether the user can add the object meta. Default false.
* @param string $meta_key The meta key.
@@ -359,7 +372,12 @@
* @param string $cap Capability name.
* @param string[] $caps Array of the user's capabilities.
*/
- $allowed = apply_filters_deprecated( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", array( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ), '4.9.8', "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" );
+ $allowed = apply_filters_deprecated(
+ "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}",
+ array( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ),
+ '4.9.8',
+ "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}"
+ );
}
if ( ! $allowed ) {
@@ -521,7 +539,10 @@
break;
}
- if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) {
+ if ( 'delete_term' === $cap
+ && ( get_option( 'default_' . $term->taxonomy ) == $term->term_id
+ || get_option( 'default_term_' . $term->taxonomy ) == $term->term_id )
+ ) {
$caps[] = 'do_not_allow';
break;
}
@@ -576,8 +597,7 @@
// Handle meta capabilities for custom post types.
global $post_type_meta_caps;
if ( isset( $post_type_meta_caps[ $cap ] ) ) {
- $args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
- return call_user_func_array( 'map_meta_cap', $args );
+ return map_meta_cap( $post_type_meta_caps[ $cap ], $user_id, ...$args );
}
// Block capabilities map to their post equivalent.
@@ -615,7 +635,17 @@
}
/**
- * Whether the current user has a specific capability.
+ * Returns whether the current user has the specified capability.
+ *
+ * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
+ * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
+ * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
+ *
+ * Example usage:
+ *
+ * current_user_can( 'edit_posts' );
+ * current_user_can( 'edit_post', $post->ID );
+ * current_user_can( 'edit_post_meta', $post->ID, $meta_key );
*
* While checking against particular roles in place of a capability is supported
* in part, this practice is discouraged as it may produce unreliable results.
@@ -623,42 +653,50 @@
* Note: Will always return true if the current user is a super admin, unless specifically denied.
*
* @since 2.0.0
+ * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
+ * by adding it to the function signature.
*
* @see WP_User::has_cap()
* @see map_meta_cap()
*
* @param string $capability Capability name.
- * @param int $object_id Optional. ID of the specific object to check against if `$capability` is a "meta" cap.
- * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used
- * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',
- * 'edit_others_posts', etc. Accessed via func_get_args() and passed to WP_User::has_cap(),
- * then map_meta_cap().
+ * @param mixed ...$args Optional further parameters, typically starting with an object ID.
* @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is
* passed, whether the current user has the given meta capability for the given object.
*/
-function current_user_can( $capability ) {
+function current_user_can( $capability, ...$args ) {
$current_user = wp_get_current_user();
if ( empty( $current_user ) ) {
return false;
}
- $args = array_slice( func_get_args(), 1 );
- $args = array_merge( array( $capability ), $args );
-
- return call_user_func_array( array( $current_user, 'has_cap' ), $args );
+ return $current_user->has_cap( $capability, ...$args );
}
/**
- * Whether the current user has a specific capability for a given site.
+ * Returns whether the current user has the specified capability for a given site.
+ *
+ * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
+ * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
+ * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
+ *
+ * Example usage:
+ *
+ * current_user_can_for_blog( $blog_id, 'edit_posts' );
+ * current_user_can_for_blog( $blog_id, 'edit_post', $post->ID );
+ * current_user_can_for_blog( $blog_id, 'edit_post_meta', $post->ID, $meta_key );
*
* @since 3.0.0
+ * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
+ * by adding it to the function signature.
*
* @param int $blog_id Site ID.
* @param string $capability Capability name.
+ * @param mixed ...$args Optional further parameters, typically starting with an object ID.
* @return bool Whether the user has the given capability.
*/
-function current_user_can_for_blog( $blog_id, $capability ) {
+function current_user_can_for_blog( $blog_id, $capability, ...$args ) {
$switched = is_multisite() ? switch_to_blog( $blog_id ) : false;
$current_user = wp_get_current_user();
@@ -670,10 +708,7 @@
return false;
}
- $args = array_slice( func_get_args(), 2 );
- $args = array_merge( array( $capability ), $args );
-
- $can = call_user_func_array( array( $current_user, 'has_cap' ), $args );
+ $can = $current_user->has_cap( $capability, ...$args );
if ( $switched ) {
restore_current_blog();
@@ -683,16 +718,30 @@
}
/**
- * Whether the author of the supplied post has a specific capability.
+ * Returns whether the author of the supplied post has the specified capability.
+ *
+ * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
+ * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
+ * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
+ *
+ * Example usage:
+ *
+ * author_can( $post, 'edit_posts' );
+ * author_can( $post, 'edit_post', $post->ID );
+ * author_can( $post, 'edit_post_meta', $post->ID, $meta_key );
*
* @since 2.9.0
+ * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
+ * by adding it to the function signature.
*
* @param int|WP_Post $post Post ID or post object.
* @param string $capability Capability name.
+ * @param mixed ...$args Optional further parameters, typically starting with an object ID.
* @return bool Whether the post author has the given capability.
*/
-function author_can( $post, $capability ) {
- if ( ! $post = get_post( $post ) ) {
+function author_can( $post, $capability, ...$args ) {
+ $post = get_post( $post );
+ if ( ! $post ) {
return false;
}
@@ -702,22 +751,32 @@
return false;
}
- $args = array_slice( func_get_args(), 2 );
- $args = array_merge( array( $capability ), $args );
-
- return call_user_func_array( array( $author, 'has_cap' ), $args );
+ return $author->has_cap( $capability, ...$args );
}
/**
- * Whether a particular user has a specific capability.
+ * Returns whether a particular user has the specified capability.
+ *
+ * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
+ * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
+ * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
+ *
+ * Example usage:
+ *
+ * user_can( $user->ID, 'edit_posts' );
+ * user_can( $user->ID, 'edit_post', $post->ID );
+ * user_can( $user->ID, 'edit_post_meta', $post->ID, $meta_key );
*
* @since 3.1.0
+ * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
+ * by adding it to the function signature.
*
* @param int|WP_User $user User ID or object.
* @param string $capability Capability name.
+ * @param mixed ...$args Optional further parameters, typically starting with an object ID.
* @return bool Whether the user has the given capability.
*/
-function user_can( $user, $capability ) {
+function user_can( $user, $capability, ...$args ) {
if ( ! is_object( $user ) ) {
$user = get_userdata( $user );
}
@@ -726,10 +785,7 @@
return false;
}
- $args = array_slice( func_get_args(), 2 );
- $args = array_merge( array( $capability ), $args );
-
- return call_user_func_array( array( $user, 'has_cap' ), $args );
+ return $user->has_cap( $capability, ...$args );
}
/**
@@ -737,7 +793,7 @@
*
* @since 4.3.0
*
- * @global WP_Roles $wp_roles WP_Roles global instance.
+ * @global WP_Roles $wp_roles WordPress role management object.
*
* @return WP_Roles WP_Roles global instance if not already instantiated.
*/
@@ -767,9 +823,10 @@
*
* @since 2.0.0
*
- * @param string $role Role name.
+ * @param string $role Role name.
* @param string $display_name Display name for role.
- * @param array $capabilities List of capabilities, e.g. array( 'edit_posts' => true, 'delete_posts' => false );
+ * @param bool[] $capabilities List of capabilities keyed by the capability name,
+ * e.g. array( 'edit_posts' => true, 'delete_posts' => false ).
* @return WP_Role|null WP_Role object if role is added, null if already exists.
*/
function add_role( $role, $display_name, $capabilities = array() ) {
@@ -797,7 +854,7 @@
*
* @global array $super_admins
*
- * @return array List of super admin logins
+ * @return string[] List of super admin logins.
*/
function get_super_admins() {
global $super_admins;
@@ -818,7 +875,7 @@
* @return bool True if the user is a site admin.
*/
function is_super_admin( $user_id = false ) {
- if ( ! $user_id || $user_id == get_current_user_id() ) {
+ if ( ! $user_id || get_current_user_id() == $user_id ) {
$user = wp_get_current_user();
} else {
$user = get_userdata( $user_id );
@@ -830,7 +887,7 @@
if ( is_multisite() ) {
$super_admins = get_super_admins();
- if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) {
+ if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins, true ) ) {
return true;
}
} else {
@@ -868,11 +925,11 @@
*/
do_action( 'grant_super_admin', $user_id );
- // Directly fetch site_admins instead of using get_super_admins()
+ // Directly fetch site_admins instead of using get_super_admins().
$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
$user = get_userdata( $user_id );
- if ( $user && ! in_array( $user->user_login, $super_admins ) ) {
+ if ( $user && ! in_array( $user->user_login, $super_admins, true ) ) {
$super_admins[] = $user->user_login;
update_site_option( 'site_admins', $super_admins );
@@ -915,12 +972,13 @@
*/
do_action( 'revoke_super_admin', $user_id );
- // Directly fetch site_admins instead of using get_super_admins()
+ // Directly fetch site_admins instead of using get_super_admins().
$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
$user = get_userdata( $user_id );
if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) {
- if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) {
+ $key = array_search( $user->user_login, $super_admins, true );
+ if ( false !== $key ) {
unset( $super_admins[ $key ] );
update_site_option( 'site_admins', $super_admins );
@@ -1007,13 +1065,13 @@
return;
// Dummy gettext calls to get strings in the catalog.
-/* translators: user role for administrators */
+/* translators: User role for administrators. */
_x( 'Administrator', 'User role' );
-/* translators: user role for editors */
+/* translators: User role for editors. */
_x( 'Editor', 'User role' );
-/* translators: user role for authors */
+/* translators: User role for authors. */
_x( 'Author', 'User role' );
-/* translators: user role for contributors */
+/* translators: User role for contributors. */
_x( 'Contributor', 'User role' );
-/* translators: user role for subscriber */
+/* translators: User role for subscribers. */
_x( 'Subscriber', 'User role' );