diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-includes/capabilities.php --- a/wp/wp-includes/capabilities.php Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-includes/capabilities.php Fri Sep 05 18:40:08 2025 +0200 @@ -73,6 +73,25 @@ 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, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + $post = get_post( $args[0] ); if ( ! $post ) { $caps[] = 'do_not_allow'; @@ -92,7 +111,18 @@ $post_type = get_post_type_object( $post->post_type ); if ( ! $post_type ) { /* 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' ); + $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, + '' . $post->post_type . '', + '' . $cap . '' + ), + '4.4.0' + ); + $caps[] = 'edit_others_posts'; break; } @@ -142,10 +172,31 @@ } break; - // edit_post breaks down to edit_posts, edit_published_posts, or - // edit_others_posts. + /* + * 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, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + $post = get_post( $args[0] ); if ( ! $post ) { $caps[] = 'do_not_allow'; @@ -163,7 +214,18 @@ $post_type = get_post_type_object( $post->post_type ); if ( ! $post_type ) { /* 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' ); + $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, + '' . $post->post_type . '', + '' . $cap . '' + ), + '4.4.0' + ); + $caps[] = 'edit_others_posts'; break; } @@ -215,6 +277,25 @@ 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, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + $post = get_post( $args[0] ); if ( ! $post ) { $caps[] = 'do_not_allow'; @@ -232,7 +313,18 @@ $post_type = get_post_type_object( $post->post_type ); if ( ! $post_type ) { /* 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' ); + $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, + '' . $post->post_type . '', + '' . $cap . '' + ), + '4.4.0' + ); + $caps[] = 'edit_others_posts'; break; } @@ -249,7 +341,18 @@ $status_obj = get_post_status_object( get_post_status( $post ) ); 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.' ), get_post_status( $post ), $cap ), '5.4.0' ); + $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, + '' . get_post_status( $post ) . '', + '' . $cap . '' + ), + '5.4.0' + ); + $caps[] = 'edit_others_posts'; break; } @@ -268,6 +371,20 @@ } 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, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + $post = get_post( $args[0] ); if ( ! $post ) { $caps[] = 'do_not_allow'; @@ -277,7 +394,18 @@ $post_type = get_post_type_object( $post->post_type ); if ( ! $post_type ) { /* 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' ); + $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, + '' . $post->post_type . '', + '' . $cap . '' + ), + '4.4.0' + ); + $caps[] = 'edit_others_posts'; break; } @@ -297,7 +425,33 @@ case 'delete_user_meta': case 'add_user_meta': $object_type = explode( '_', $cap )[1]; - $object_id = (int) $args[0]; + + if ( ! isset( $args[0] ) ) { + if ( 'post' === $object_type ) { + /* translators: %s: Capability name. */ + $message = __( 'When checking for the %s capability, you must always check it against a specific post.' ); + } elseif ( 'comment' === $object_type ) { + /* translators: %s: Capability name. */ + $message = __( 'When checking for the %s capability, you must always check it against a specific comment.' ); + } elseif ( 'term' === $object_type ) { + /* translators: %s: Capability name. */ + $message = __( 'When checking for the %s capability, you must always check it against a specific term.' ); + } else { + /* translators: %s: Capability name. */ + $message = __( 'When checking for the %s capability, you must always check it against a specific user.' ); + } + + _doing_it_wrong( + __FUNCTION__, + sprintf( $message, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + + $object_id = (int) $args[0]; $object_subtype = get_object_subtype( $object_type, $object_id ); @@ -392,6 +546,20 @@ } break; case 'edit_comment': + if ( ! isset( $args[0] ) ) { + /* translators: %s: Capability name. */ + $message = __( 'When checking for the %s capability, you must always check it against a specific comment.' ); + + _doing_it_wrong( + __FUNCTION__, + sprintf( $message, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + $comment = get_comment( $args[0] ); if ( ! $comment ) { $caps[] = 'do_not_allow'; @@ -451,8 +619,10 @@ case 'install_themes': case 'upload_themes': case 'update_core': - // Disallow anything that creates, deletes, or updates core, plugin, or theme files. - // Files in uploads are excepted. + /* + * Disallow anything that creates, deletes, or updates core, plugin, or theme files. + * Files in uploads are excepted. + */ if ( ! wp_is_file_mod_allowed( 'capability_update_core' ) ) { $caps[] = 'do_not_allow'; } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) { @@ -532,6 +702,20 @@ case 'edit_term': case 'delete_term': case 'assign_term': + if ( ! isset( $args[0] ) ) { + /* translators: %s: Capability name. */ + $message = __( 'When checking for the %s capability, you must always check it against a specific term.' ); + + _doing_it_wrong( + __FUNCTION__, + sprintf( $message, '' . $cap . '' ), + '6.1.0' + ); + + $caps[] = 'do_not_allow'; + break; + } + $term_id = (int) $args[0]; $term = get_term( $term_id ); if ( ! $term || is_wp_error( $term ) ) { @@ -795,7 +979,7 @@ if ( empty( $user ) ) { // User is logged out, create anonymous user object. $user = new WP_User( 0 ); - $user->init( new stdClass ); + $user->init( new stdClass() ); } return $user->has_cap( $capability, ...$args ); @@ -840,12 +1024,13 @@ * @param string $display_name Display name for role. * @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. + * @return WP_Role|void WP_Role object, if the role is added. */ function add_role( $role, $display_name, $capabilities = array() ) { if ( empty( $role ) ) { return; } + return wp_roles()->add_role( $role, $display_name, $capabilities ); } @@ -903,10 +1088,8 @@ if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins, true ) ) { return true; } - } else { - if ( $user->has_cap( 'delete_users' ) ) { - return true; - } + } elseif ( $user->has_cap( 'delete_users' ) ) { + return true; } return false;