wp/wp-includes/capabilities.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
--- 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, '<code>' . $cap . '</code>' ),
+					'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,
+						'<code>' . $post->post_type . '</code>',
+						'<code>' . $cap . '</code>'
+					),
+					'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, '<code>' . $cap . '</code>' ),
+					'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,
+						'<code>' . $post->post_type . '</code>',
+						'<code>' . $cap . '</code>'
+					),
+					'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, '<code>' . $cap . '</code>' ),
+					'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,
+						'<code>' . $post->post_type . '</code>',
+						'<code>' . $cap . '</code>'
+					),
+					'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,
+						'<code>' . get_post_status( $post ) . '</code>',
+						'<code>' . $cap . '</code>'
+					),
+					'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, '<code>' . $cap . '</code>' ),
+					'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,
+						'<code>' . $post->post_type . '</code>',
+						'<code>' . $cap . '</code>'
+					),
+					'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, '<code>' . $cap . '</code>' ),
+					'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, '<code>' . $cap . '</code>' ),
+					'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, '<code>' . $cap . '</code>' ),
+					'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;