wp/wp-includes/capabilities.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    29 function map_meta_cap( $cap, $user_id ) {
    29 function map_meta_cap( $cap, $user_id ) {
    30 	$args = array_slice( func_get_args(), 2 );
    30 	$args = array_slice( func_get_args(), 2 );
    31 	$caps = array();
    31 	$caps = array();
    32 
    32 
    33 	switch ( $cap ) {
    33 	switch ( $cap ) {
    34 	case 'remove_user':
    34 		case 'remove_user':
    35 		// In multisite the user must be a super admin to remove themselves.
    35 			// In multisite the user must be a super admin to remove themselves.
    36 		if ( isset( $args[0] ) && $user_id == $args[0] && ! is_super_admin( $user_id ) ) {
    36 			if ( isset( $args[0] ) && $user_id == $args[0] && ! is_super_admin( $user_id ) ) {
    37 			$caps[] = 'do_not_allow';
    37 				$caps[] = 'do_not_allow';
    38 		} else {
    38 			} else {
    39 			$caps[] = 'remove_users';
    39 				$caps[] = 'remove_users';
    40 		}
    40 			}
    41 		break;
    41 			break;
    42 	case 'promote_user':
    42 		case 'promote_user':
    43 	case 'add_users':
    43 		case 'add_users':
    44 		$caps[] = 'promote_users';
    44 			$caps[] = 'promote_users';
    45 		break;
    45 			break;
    46 	case 'edit_user':
    46 		case 'edit_user':
    47 	case 'edit_users':
    47 		case 'edit_users':
    48 		// Allow user to edit itself
    48 			// Allow user to edit itself
    49 		if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] )
    49 			if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] ) {
    50 			break;
    50 				break;
    51 
    51 			}
    52 		// In multisite the user must have manage_network_users caps. If editing a super admin, the user must be a super admin.
    52 
    53 		if ( is_multisite() && ( ( ! is_super_admin( $user_id ) && 'edit_user' === $cap && is_super_admin( $args[0] ) ) || ! user_can( $user_id, 'manage_network_users' ) ) ) {
    53 			// In multisite the user must have manage_network_users caps. If editing a super admin, the user must be a super admin.
    54 			$caps[] = 'do_not_allow';
    54 			if ( is_multisite() && ( ( ! is_super_admin( $user_id ) && 'edit_user' === $cap && is_super_admin( $args[0] ) ) || ! user_can( $user_id, 'manage_network_users' ) ) ) {
    55 		} else {
    55 				$caps[] = 'do_not_allow';
    56 			$caps[] = 'edit_users'; // edit_user maps to edit_users.
    56 			} else {
    57 		}
    57 				$caps[] = 'edit_users'; // edit_user maps to edit_users.
    58 		break;
    58 			}
    59 	case 'delete_post':
    59 			break;
    60 	case 'delete_page':
    60 		case 'delete_post':
    61 		$post = get_post( $args[0] );
    61 		case 'delete_page':
    62 		if ( ! $post ) {
    62 			$post = get_post( $args[0] );
    63 			$caps[] = 'do_not_allow';
       
    64 			break;
       
    65 		}
       
    66 
       
    67 		if ( 'revision' == $post->post_type ) {
       
    68 			$post = get_post( $post->post_parent );
       
    69 			if ( ! $post ) {
    63 			if ( ! $post ) {
    70 				$caps[] = 'do_not_allow';
    64 				$caps[] = 'do_not_allow';
    71 				break;
    65 				break;
    72 			}
    66 			}
    73 		}
    67 
    74 
    68 			if ( 'revision' == $post->post_type ) {
    75 		if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) {
    69 				$post = get_post( $post->post_parent );
    76 			$caps[] = 'manage_options';
    70 				if ( ! $post ) {
    77 			break;
    71 					$caps[] = 'do_not_allow';
    78 		}
    72 					break;
    79 
    73 				}
    80 		$post_type = get_post_type_object( $post->post_type );
    74 			}
    81 		if ( ! $post_type ) {
    75 
    82 			/* translators: 1: post type, 2: capability name */
    76 			if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) {
    83 			_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' );
    77 				$caps[] = 'manage_options';
    84 			$caps[] = 'edit_others_posts';
    78 				break;
    85 			break;
    79 			}
    86 		}
    80 
    87 
    81 			$post_type = get_post_type_object( $post->post_type );
    88 		if ( ! $post_type->map_meta_cap ) {
    82 			if ( ! $post_type ) {
    89 			$caps[] = $post_type->cap->$cap;
    83 				/* translators: 1: post type, 2: capability name */
    90 			// Prior to 3.1 we would re-call map_meta_cap here.
    84 				_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' );
    91 			if ( 'delete_post' == $cap )
    85 				$caps[] = 'edit_others_posts';
    92 				$cap = $post_type->cap->$cap;
    86 				break;
    93 			break;
    87 			}
    94 		}
    88 
    95 
    89 			if ( ! $post_type->map_meta_cap ) {
    96 		// If the post author is set and the user is the author...
    90 				$caps[] = $post_type->cap->$cap;
    97 		if ( $post->post_author && $user_id == $post->post_author ) {
    91 				// Prior to 3.1 we would re-call map_meta_cap here.
    98 			// If the post is published or scheduled...
    92 				if ( 'delete_post' == $cap ) {
    99 			if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
    93 					$cap = $post_type->cap->$cap;
   100 				$caps[] = $post_type->cap->delete_published_posts;
    94 				}
   101 			} elseif ( 'trash' == $post->post_status ) {
    95 				break;
   102 				$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
    96 			}
   103 				if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
    97 
       
    98 			// If the post author is set and the user is the author...
       
    99 			if ( $post->post_author && $user_id == $post->post_author ) {
       
   100 				// If the post is published or scheduled...
       
   101 				if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   104 					$caps[] = $post_type->cap->delete_published_posts;
   102 					$caps[] = $post_type->cap->delete_published_posts;
       
   103 				} elseif ( 'trash' == $post->post_status ) {
       
   104 					$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
       
   105 					if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
       
   106 						$caps[] = $post_type->cap->delete_published_posts;
       
   107 					} else {
       
   108 						$caps[] = $post_type->cap->delete_posts;
       
   109 					}
   105 				} else {
   110 				} else {
       
   111 					// If the post is draft...
   106 					$caps[] = $post_type->cap->delete_posts;
   112 					$caps[] = $post_type->cap->delete_posts;
   107 				}
   113 				}
   108 			} else {
   114 			} else {
   109 				// If the post is draft...
   115 				// The user is trying to edit someone else's post.
   110 				$caps[] = $post_type->cap->delete_posts;
   116 				$caps[] = $post_type->cap->delete_others_posts;
   111 			}
   117 				// The post is published or scheduled, extra cap required.
   112 		} else {
   118 				if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   113 			// The user is trying to edit someone else's post.
   119 					$caps[] = $post_type->cap->delete_published_posts;
   114 			$caps[] = $post_type->cap->delete_others_posts;
   120 				} elseif ( 'private' == $post->post_status ) {
   115 			// The post is published or scheduled, extra cap required.
   121 					$caps[] = $post_type->cap->delete_private_posts;
   116 			if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   122 				}
   117 				$caps[] = $post_type->cap->delete_published_posts;
   123 			}
   118 			} elseif ( 'private' == $post->post_status ) {
   124 
   119 				$caps[] = $post_type->cap->delete_private_posts;
   125 			/*
   120 			}
   126 			 * Setting the privacy policy page requires `manage_privacy_options`,
   121 		}
   127 			 * so deleting it should require that too.
   122 
   128 			 */
   123 		/*
   129 			if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
   124 		 * Setting the privacy policy page requires `manage_privacy_options`,
   130 				$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
   125 		 * so deleting it should require that too.
   131 			}
   126 		 */
   132 
   127 		if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
   133 			break;
   128 			$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
       
   129 		}
       
   130 
       
   131 		break;
       
   132 		// edit_post breaks down to edit_posts, edit_published_posts, or
   134 		// edit_post breaks down to edit_posts, edit_published_posts, or
   133 		// edit_others_posts
   135 		// edit_others_posts
   134 	case 'edit_post':
   136 		case 'edit_post':
   135 	case 'edit_page':
   137 		case 'edit_page':
   136 		$post = get_post( $args[0] );
   138 			$post = get_post( $args[0] );
   137 		if ( ! $post ) {
       
   138 			$caps[] = 'do_not_allow';
       
   139 			break;
       
   140 		}
       
   141 
       
   142 		if ( 'revision' == $post->post_type ) {
       
   143 			$post = get_post( $post->post_parent );
       
   144 			if ( ! $post ) {
   139 			if ( ! $post ) {
   145 				$caps[] = 'do_not_allow';
   140 				$caps[] = 'do_not_allow';
   146 				break;
   141 				break;
   147 			}
   142 			}
   148 		}
   143 
   149 
   144 			if ( 'revision' == $post->post_type ) {
   150 		$post_type = get_post_type_object( $post->post_type );
   145 				$post = get_post( $post->post_parent );
   151 		if ( ! $post_type ) {
   146 				if ( ! $post ) {
   152 			/* translators: 1: post type, 2: capability name */
   147 					$caps[] = 'do_not_allow';
   153 			_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' );
   148 					break;
   154 			$caps[] = 'edit_others_posts';
   149 				}
   155 			break;
   150 			}
   156 		}
   151 
   157 
   152 			$post_type = get_post_type_object( $post->post_type );
   158 		if ( ! $post_type->map_meta_cap ) {
   153 			if ( ! $post_type ) {
   159 			$caps[] = $post_type->cap->$cap;
   154 				/* translators: 1: post type, 2: capability name */
   160 			// Prior to 3.1 we would re-call map_meta_cap here.
   155 				_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' );
   161 			if ( 'edit_post' == $cap )
   156 				$caps[] = 'edit_others_posts';
   162 				$cap = $post_type->cap->$cap;
   157 				break;
   163 			break;
   158 			}
   164 		}
   159 
   165 
   160 			if ( ! $post_type->map_meta_cap ) {
   166 		// If the post author is set and the user is the author...
   161 				$caps[] = $post_type->cap->$cap;
   167 		if ( $post->post_author && $user_id == $post->post_author ) {
   162 				// Prior to 3.1 we would re-call map_meta_cap here.
   168 			// If the post is published or scheduled...
   163 				if ( 'edit_post' == $cap ) {
   169 			if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   164 					$cap = $post_type->cap->$cap;
   170 				$caps[] = $post_type->cap->edit_published_posts;
   165 				}
   171 			} elseif ( 'trash' == $post->post_status ) {
   166 				break;
   172 				$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
   167 			}
   173 				if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
   168 
       
   169 			// If the post author is set and the user is the author...
       
   170 			if ( $post->post_author && $user_id == $post->post_author ) {
       
   171 				// If the post is published or scheduled...
       
   172 				if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   174 					$caps[] = $post_type->cap->edit_published_posts;
   173 					$caps[] = $post_type->cap->edit_published_posts;
       
   174 				} elseif ( 'trash' == $post->post_status ) {
       
   175 					$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
       
   176 					if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
       
   177 						$caps[] = $post_type->cap->edit_published_posts;
       
   178 					} else {
       
   179 						$caps[] = $post_type->cap->edit_posts;
       
   180 					}
   175 				} else {
   181 				} else {
       
   182 					// If the post is draft...
   176 					$caps[] = $post_type->cap->edit_posts;
   183 					$caps[] = $post_type->cap->edit_posts;
   177 				}
   184 				}
   178 			} else {
   185 			} else {
   179 				// If the post is draft...
   186 				// The user is trying to edit someone else's post.
   180 				$caps[] = $post_type->cap->edit_posts;
   187 				$caps[] = $post_type->cap->edit_others_posts;
   181 			}
   188 				// The post is published or scheduled, extra cap required.
   182 		} else {
   189 				if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   183 			// The user is trying to edit someone else's post.
   190 					$caps[] = $post_type->cap->edit_published_posts;
   184 			$caps[] = $post_type->cap->edit_others_posts;
   191 				} elseif ( 'private' == $post->post_status ) {
   185 			// The post is published or scheduled, extra cap required.
   192 					$caps[] = $post_type->cap->edit_private_posts;
   186 			if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
   193 				}
   187 				$caps[] = $post_type->cap->edit_published_posts;
   194 			}
   188 			} elseif ( 'private' == $post->post_status ) {
   195 
   189 				$caps[] = $post_type->cap->edit_private_posts;
   196 			/*
   190 			}
   197 			 * Setting the privacy policy page requires `manage_privacy_options`,
   191 		}
   198 			 * so editing it should require that too.
   192 
   199 			 */
   193 		/*
   200 			if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
   194 		 * Setting the privacy policy page requires `manage_privacy_options`,
   201 				$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
   195 		 * so editing it should require that too.
   202 			}
   196 		 */
   203 
   197 		if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
   204 			break;
   198 			$caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
   205 		case 'read_post':
   199 		}
   206 		case 'read_page':
   200 
   207 			$post = get_post( $args[0] );
   201 		break;
       
   202 	case 'read_post':
       
   203 	case 'read_page':
       
   204 		$post = get_post( $args[0] );
       
   205 		if ( ! $post ) {
       
   206 			$caps[] = 'do_not_allow';
       
   207 			break;
       
   208 		}
       
   209 
       
   210 		if ( 'revision' == $post->post_type ) {
       
   211 			$post = get_post( $post->post_parent );
       
   212 			if ( ! $post ) {
   208 			if ( ! $post ) {
   213 				$caps[] = 'do_not_allow';
   209 				$caps[] = 'do_not_allow';
   214 				break;
   210 				break;
   215 			}
   211 			}
   216 		}
   212 
   217 
   213 			if ( 'revision' == $post->post_type ) {
   218 		$post_type = get_post_type_object( $post->post_type );
   214 				$post = get_post( $post->post_parent );
   219 		if ( ! $post_type ) {
   215 				if ( ! $post ) {
   220 			/* translators: 1: post type, 2: capability name */
   216 					$caps[] = 'do_not_allow';
   221 			_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' );
   217 					break;
   222 			$caps[] = 'edit_others_posts';
   218 				}
   223 			break;
   219 			}
   224 		}
   220 
   225 
   221 			$post_type = get_post_type_object( $post->post_type );
   226 		if ( ! $post_type->map_meta_cap ) {
   222 			if ( ! $post_type ) {
   227 			$caps[] = $post_type->cap->$cap;
   223 				/* translators: 1: post type, 2: capability name */
   228 			// Prior to 3.1 we would re-call map_meta_cap here.
   224 				_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' );
   229 			if ( 'read_post' == $cap )
   225 				$caps[] = 'edit_others_posts';
   230 				$cap = $post_type->cap->$cap;
   226 				break;
   231 			break;
   227 			}
   232 		}
   228 
   233 
   229 			if ( ! $post_type->map_meta_cap ) {
   234 		$status_obj = get_post_status_object( $post->post_status );
   230 				$caps[] = $post_type->cap->$cap;
   235 		if ( $status_obj->public ) {
   231 				// Prior to 3.1 we would re-call map_meta_cap here.
   236 			$caps[] = $post_type->cap->read;
   232 				if ( 'read_post' == $cap ) {
   237 			break;
   233 					$cap = $post_type->cap->$cap;
   238 		}
   234 				}
   239 
   235 				break;
   240 		if ( $post->post_author && $user_id == $post->post_author ) {
   236 			}
   241 			$caps[] = $post_type->cap->read;
   237 
   242 		} elseif ( $status_obj->private ) {
   238 			$status_obj = get_post_status_object( $post->post_status );
   243 			$caps[] = $post_type->cap->read_private_posts;
   239 			if ( $status_obj->public ) {
   244 		} else {
   240 				$caps[] = $post_type->cap->read;
   245 			$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
   241 				break;
   246 		}
   242 			}
   247 		break;
   243 
   248 	case 'publish_post':
   244 			if ( $post->post_author && $user_id == $post->post_author ) {
   249 		$post = get_post( $args[0] );
   245 				$caps[] = $post_type->cap->read;
   250 		if ( ! $post ) {
   246 			} elseif ( $status_obj->private ) {
   251 			$caps[] = 'do_not_allow';
   247 				$caps[] = $post_type->cap->read_private_posts;
   252 			break;
   248 			} else {
   253 		}
   249 				$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
   254 
   250 			}
   255 		$post_type = get_post_type_object( $post->post_type );
   251 			break;
   256 		if ( ! $post_type ) {
   252 		case 'publish_post':
   257 			/* translators: 1: post type, 2: capability name */
   253 			$post = get_post( $args[0] );
   258 			_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' );
   254 			if ( ! $post ) {
   259 			$caps[] = 'edit_others_posts';
   255 				$caps[] = 'do_not_allow';
   260 			break;
   256 				break;
   261 		}
   257 			}
   262 
   258 
   263 		$caps[] = $post_type->cap->publish_posts;
   259 			$post_type = get_post_type_object( $post->post_type );
   264 		break;
   260 			if ( ! $post_type ) {
   265 	case 'edit_post_meta':
   261 				/* translators: 1: post type, 2: capability name */
   266 	case 'delete_post_meta':
   262 				_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' );
   267 	case 'add_post_meta':
   263 				$caps[] = 'edit_others_posts';
   268 	case 'edit_comment_meta':
   264 				break;
   269 	case 'delete_comment_meta':
   265 			}
   270 	case 'add_comment_meta':
   266 
   271 	case 'edit_term_meta':
   267 			$caps[] = $post_type->cap->publish_posts;
   272 	case 'delete_term_meta':
   268 			break;
   273 	case 'add_term_meta':
   269 		case 'edit_post_meta':
   274 	case 'edit_user_meta':
   270 		case 'delete_post_meta':
   275 	case 'delete_user_meta':
   271 		case 'add_post_meta':
   276 	case 'add_user_meta':
   272 		case 'edit_comment_meta':
   277 		list( $_, $object_type, $_ ) = explode( '_', $cap );
   273 		case 'delete_comment_meta':
   278 		$object_id = (int) $args[0];
   274 		case 'add_comment_meta':
   279 		$object_subtype = get_object_subtype( $object_type, $object_id );
   275 		case 'edit_term_meta':
   280 
   276 		case 'delete_term_meta':
   281 		if ( empty( $object_subtype ) ) {
   277 		case 'add_term_meta':
   282 			$caps[] = 'do_not_allow';
   278 		case 'edit_user_meta':
   283 			break;
   279 		case 'delete_user_meta':
   284 		}
   280 		case 'add_user_meta':
   285 
   281 			list( $_, $object_type, $_ ) = explode( '_', $cap );
   286 		$caps = map_meta_cap( "edit_{$object_type}", $user_id, $object_id );
   282 			$object_id                   = (int) $args[0];
   287 
   283 
   288 		$meta_key = isset( $args[1] ) ? $args[1] : false;
   284 			$object_subtype = get_object_subtype( $object_type, $object_id );
   289 
   285 
   290 		if ( $meta_key ) {
   286 			if ( empty( $object_subtype ) ) {
   291 			$allowed = ! is_protected_meta( $meta_key, $object_type );
   287 				$caps[] = 'do_not_allow';
   292 
   288 				break;
   293 			if ( ! empty( $object_subtype ) && has_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
   289 			}
   294 
   290 
   295 				/**
   291 			$caps = map_meta_cap( "edit_{$object_type}", $user_id, $object_id );
   296 				 * Filters whether the user is allowed to edit a specific meta key of a specific object type and subtype.
   292 
   297 				 *
   293 			$meta_key = isset( $args[1] ) ? $args[1] : false;
   298 				 * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
   294 
   299 				 * and `$object_subtype`, refer to the metadata object type (comment, post, term or user),
   295 			if ( $meta_key ) {
   300 				 * the meta key value, and the object subtype respectively.
   296 				$allowed = ! is_protected_meta( $meta_key, $object_type );
   301 				 *
   297 
   302 				 * @since 4.9.8
   298 				if ( ! empty( $object_subtype ) && has_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
   303 				 *
   299 
   304 				 * @param bool     $allowed   Whether the user can add the object meta. Default false.
   300 					/**
   305 				 * @param string   $meta_key  The meta key.
   301 					 * Filters whether the user is allowed to edit a specific meta key of a specific object type and subtype.
   306 				 * @param int      $object_id Object ID.
   302 					 *
   307 				 * @param int      $user_id   User ID.
   303 					 * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
   308 				 * @param string   $cap       Capability name.
   304 					 * and `$object_subtype`, refer to the metadata object type (comment, post, term or user),
   309 				 * @param string[] $caps      Array of the user's capabilities.
   305 					 * the meta key value, and the object subtype respectively.
   310 				 */
   306 					 *
   311 				$allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps );
   307 					 * @since 4.9.8
   312 			} else {
   308 					 *
   313 
   309 					 * @param bool     $allowed   Whether the user can add the object meta. Default false.
   314 				/**
   310 					 * @param string   $meta_key  The meta key.
   315 				 * Filters whether the user is allowed to edit a specific meta key of a specific object type.
   311 					 * @param int      $object_id Object ID.
   316 				 *
   312 					 * @param int      $user_id   User ID.
   317 				 * Return true to have the mapped meta caps from `edit_{$object_type}` apply.
   313 					 * @param string   $cap       Capability name.
   318 				 *
   314 					 * @param string[] $caps      Array of the user's capabilities.
   319 				 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered.
   315 					 */
   320 				 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
   316 					$allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps );
   321 				 *
   317 				} else {
   322 				 * @since 3.3.0 As `auth_post_meta_{$meta_key}`.
   318 
   323 				 * @since 4.6.0
   319 					/**
   324 				 *
   320 					 * Filters whether the user is allowed to edit a specific meta key of a specific object type.
   325 				 * @param bool     $allowed   Whether the user can add the object meta. Default false.
   321 					 *
   326 				 * @param string   $meta_key  The meta key.
   322 					 * Return true to have the mapped meta caps from `edit_{$object_type}` apply.
   327 				 * @param int      $object_id Object ID.
   323 					 *
   328 				 * @param int      $user_id   User ID.
   324 					 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered.
   329 				 * @param string   $cap       Capability name.
   325 					 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
   330 				 * @param string[] $caps      Array of the user's capabilities.
   326 					 *
   331 				 */
   327 					 * @since 3.3.0 As `auth_post_meta_{$meta_key}`.
   332 				$allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps );
   328 					 * @since 4.6.0
   333 			}
   329 					 *
   334 
   330 					 * @param bool     $allowed   Whether the user can add the object meta. Default false.
   335 			if ( ! empty( $object_subtype ) ) {
   331 					 * @param string   $meta_key  The meta key.
   336 
   332 					 * @param int      $object_id Object ID.
   337 				/**
   333 					 * @param int      $user_id   User ID.
   338 				 * Filters whether the user is allowed to edit meta for specific object types/subtypes.
   334 					 * @param string   $cap       Capability name.
   339 				 *
   335 					 * @param string[] $caps      Array of the user's capabilities.
   340 				 * Return true to have the mapped meta caps from `edit_{$object_type}` apply.
   336 					 */
   341 				 *
   337 					$allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps );
   342 				 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered.
   338 				}
   343 				 * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered.
   339 
   344 				 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
   340 				if ( ! empty( $object_subtype ) ) {
   345 				 *
   341 
   346 				 * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`.
   342 					/**
   347 				 * @since 4.7.0
   343 					 * Filters whether the user is allowed to edit meta for specific object types/subtypes.
   348 				 * @deprecated 4.9.8 Use `auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}`
   344 					 *
   349 				 *
   345 					 * Return true to have the mapped meta caps from `edit_{$object_type}` apply.
   350 				 * @param bool     $allowed   Whether the user can add the object meta. Default false.
   346 					 *
   351 				 * @param string   $meta_key  The meta key.
   347 					 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered.
   352 				 * @param int      $object_id Object ID.
   348 					 * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered.
   353 				 * @param int      $user_id   User ID.
   349 					 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
   354 				 * @param string   $cap       Capability name.
   350 					 *
   355 				 * @param string[] $caps      Array of the user's capabilities.
   351 					 * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`.
   356 				 */
   352 					 * @since 4.7.0
   357 				$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}" );
   353 					 * @deprecated 4.9.8 Use `auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}`
   358 			}
   354 					 *
   359 
   355 					 * @param bool     $allowed   Whether the user can add the object meta. Default false.
   360 			if ( ! $allowed ) {
   356 					 * @param string   $meta_key  The meta key.
       
   357 					 * @param int      $object_id Object ID.
       
   358 					 * @param int      $user_id   User ID.
       
   359 					 * @param string   $cap       Capability name.
       
   360 					 * @param string[] $caps      Array of the user's capabilities.
       
   361 					 */
       
   362 					$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}" );
       
   363 				}
       
   364 
       
   365 				if ( ! $allowed ) {
       
   366 					$caps[] = $cap;
       
   367 				}
       
   368 			}
       
   369 			break;
       
   370 		case 'edit_comment':
       
   371 			$comment = get_comment( $args[0] );
       
   372 			if ( ! $comment ) {
       
   373 				$caps[] = 'do_not_allow';
       
   374 				break;
       
   375 			}
       
   376 
       
   377 			$post = get_post( $comment->comment_post_ID );
       
   378 
       
   379 			/*
       
   380 			 * If the post doesn't exist, we have an orphaned comment.
       
   381 			 * Fall back to the edit_posts capability, instead.
       
   382 			 */
       
   383 			if ( $post ) {
       
   384 				$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
       
   385 			} else {
       
   386 				$caps = map_meta_cap( 'edit_posts', $user_id );
       
   387 			}
       
   388 			break;
       
   389 		case 'unfiltered_upload':
       
   390 			if ( defined( 'ALLOW_UNFILTERED_UPLOADS' ) && ALLOW_UNFILTERED_UPLOADS && ( ! is_multisite() || is_super_admin( $user_id ) ) ) {
   361 				$caps[] = $cap;
   391 				$caps[] = $cap;
   362 			}
   392 			} else {
   363 		}
   393 				$caps[] = 'do_not_allow';
   364 		break;
   394 			}
   365 	case 'edit_comment':
   395 			break;
   366 		$comment = get_comment( $args[0] );
   396 		case 'edit_css':
   367 		if ( ! $comment ) {
   397 		case 'unfiltered_html':
   368 			$caps[] = 'do_not_allow';
   398 			// Disallow unfiltered_html for all users, even admins and super admins.
   369 			break;
   399 			if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) {
   370 		}
   400 				$caps[] = 'do_not_allow';
   371 
   401 			} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
   372 		$post = get_post( $comment->comment_post_ID );
   402 				$caps[] = 'do_not_allow';
   373 
   403 			} else {
   374 		/*
   404 				$caps[] = 'unfiltered_html';
   375 		 * If the post doesn't exist, we have an orphaned comment.
   405 			}
   376 		 * Fall back to the edit_posts capability, instead.
   406 			break;
   377 		 */
   407 		case 'edit_files':
   378 		if ( $post ) {
   408 		case 'edit_plugins':
   379 			$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
   409 		case 'edit_themes':
   380 		} else {
   410 			// Disallow the file editors.
   381 			$caps = map_meta_cap( 'edit_posts', $user_id );
   411 			if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) {
   382 		}
   412 				$caps[] = 'do_not_allow';
   383 		break;
   413 			} elseif ( ! wp_is_file_mod_allowed( 'capability_edit_themes' ) ) {
   384 	case 'unfiltered_upload':
   414 				$caps[] = 'do_not_allow';
   385 		if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) )  )
   415 			} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
       
   416 				$caps[] = 'do_not_allow';
       
   417 			} else {
       
   418 				$caps[] = $cap;
       
   419 			}
       
   420 			break;
       
   421 		case 'update_plugins':
       
   422 		case 'delete_plugins':
       
   423 		case 'install_plugins':
       
   424 		case 'upload_plugins':
       
   425 		case 'update_themes':
       
   426 		case 'delete_themes':
       
   427 		case 'install_themes':
       
   428 		case 'upload_themes':
       
   429 		case 'update_core':
       
   430 			// Disallow anything that creates, deletes, or updates core, plugin, or theme files.
       
   431 			// Files in uploads are excepted.
       
   432 			if ( ! wp_is_file_mod_allowed( 'capability_update_core' ) ) {
       
   433 				$caps[] = 'do_not_allow';
       
   434 			} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
       
   435 				$caps[] = 'do_not_allow';
       
   436 			} elseif ( 'upload_themes' === $cap ) {
       
   437 				$caps[] = 'install_themes';
       
   438 			} elseif ( 'upload_plugins' === $cap ) {
       
   439 				$caps[] = 'install_plugins';
       
   440 			} else {
       
   441 				$caps[] = $cap;
       
   442 			}
       
   443 			break;
       
   444 		case 'install_languages':
       
   445 		case 'update_languages':
       
   446 			if ( ! wp_is_file_mod_allowed( 'can_install_language_pack' ) ) {
       
   447 				$caps[] = 'do_not_allow';
       
   448 			} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
       
   449 				$caps[] = 'do_not_allow';
       
   450 			} else {
       
   451 				$caps[] = 'install_languages';
       
   452 			}
       
   453 			break;
       
   454 		case 'activate_plugins':
       
   455 		case 'deactivate_plugins':
       
   456 		case 'activate_plugin':
       
   457 		case 'deactivate_plugin':
       
   458 			$caps[] = 'activate_plugins';
       
   459 			if ( is_multisite() ) {
       
   460 				// update_, install_, and delete_ are handled above with is_super_admin().
       
   461 				$menu_perms = get_site_option( 'menu_items', array() );
       
   462 				if ( empty( $menu_perms['plugins'] ) ) {
       
   463 					$caps[] = 'manage_network_plugins';
       
   464 				}
       
   465 			}
       
   466 			break;
       
   467 		case 'resume_plugin':
       
   468 			$caps[] = 'resume_plugins';
       
   469 			break;
       
   470 		case 'resume_theme':
       
   471 			$caps[] = 'resume_themes';
       
   472 			break;
       
   473 		case 'delete_user':
       
   474 		case 'delete_users':
       
   475 			// If multisite only super admins can delete users.
       
   476 			if ( is_multisite() && ! is_super_admin( $user_id ) ) {
       
   477 				$caps[] = 'do_not_allow';
       
   478 			} else {
       
   479 				$caps[] = 'delete_users'; // delete_user maps to delete_users.
       
   480 			}
       
   481 			break;
       
   482 		case 'create_users':
       
   483 			if ( ! is_multisite() ) {
       
   484 				$caps[] = $cap;
       
   485 			} elseif ( is_super_admin( $user_id ) || get_site_option( 'add_new_users' ) ) {
       
   486 				$caps[] = $cap;
       
   487 			} else {
       
   488 				$caps[] = 'do_not_allow';
       
   489 			}
       
   490 			break;
       
   491 		case 'manage_links':
       
   492 			if ( get_option( 'link_manager_enabled' ) ) {
       
   493 				$caps[] = $cap;
       
   494 			} else {
       
   495 				$caps[] = 'do_not_allow';
       
   496 			}
       
   497 			break;
       
   498 		case 'customize':
       
   499 			$caps[] = 'edit_theme_options';
       
   500 			break;
       
   501 		case 'delete_site':
       
   502 			if ( is_multisite() ) {
       
   503 				$caps[] = 'manage_options';
       
   504 			} else {
       
   505 				$caps[] = 'do_not_allow';
       
   506 			}
       
   507 			break;
       
   508 		case 'edit_term':
       
   509 		case 'delete_term':
       
   510 		case 'assign_term':
       
   511 			$term_id = (int) $args[0];
       
   512 			$term    = get_term( $term_id );
       
   513 			if ( ! $term || is_wp_error( $term ) ) {
       
   514 				$caps[] = 'do_not_allow';
       
   515 				break;
       
   516 			}
       
   517 
       
   518 			$tax = get_taxonomy( $term->taxonomy );
       
   519 			if ( ! $tax ) {
       
   520 				$caps[] = 'do_not_allow';
       
   521 				break;
       
   522 			}
       
   523 
       
   524 			if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) {
       
   525 				$caps[] = 'do_not_allow';
       
   526 				break;
       
   527 			}
       
   528 
       
   529 			$taxo_cap = $cap . 's';
       
   530 
       
   531 			$caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id );
       
   532 
       
   533 			break;
       
   534 		case 'manage_post_tags':
       
   535 		case 'edit_categories':
       
   536 		case 'edit_post_tags':
       
   537 		case 'delete_categories':
       
   538 		case 'delete_post_tags':
       
   539 			$caps[] = 'manage_categories';
       
   540 			break;
       
   541 		case 'assign_categories':
       
   542 		case 'assign_post_tags':
       
   543 			$caps[] = 'edit_posts';
       
   544 			break;
       
   545 		case 'create_sites':
       
   546 		case 'delete_sites':
       
   547 		case 'manage_network':
       
   548 		case 'manage_sites':
       
   549 		case 'manage_network_users':
       
   550 		case 'manage_network_plugins':
       
   551 		case 'manage_network_themes':
       
   552 		case 'manage_network_options':
       
   553 		case 'upgrade_network':
   386 			$caps[] = $cap;
   554 			$caps[] = $cap;
   387 		else
   555 			break;
   388 			$caps[] = 'do_not_allow';
   556 		case 'setup_network':
   389 		break;
   557 			if ( is_multisite() ) {
   390 	case 'edit_css' :
   558 				$caps[] = 'manage_network_options';
   391 	case 'unfiltered_html' :
   559 			} else {
   392 		// Disallow unfiltered_html for all users, even admins and super admins.
   560 				$caps[] = 'manage_options';
   393 		if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML )
   561 			}
   394 			$caps[] = 'do_not_allow';
   562 			break;
   395 		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
   563 		case 'update_php':
   396 			$caps[] = 'do_not_allow';
   564 			if ( is_multisite() && ! is_super_admin( $user_id ) ) {
   397 		else
   565 				$caps[] = 'do_not_allow';
   398 			$caps[] = 'unfiltered_html';
   566 			} else {
   399 		break;
   567 				$caps[] = 'update_core';
   400 	case 'edit_files':
   568 			}
   401 	case 'edit_plugins':
   569 			break;
   402 	case 'edit_themes':
   570 		case 'export_others_personal_data':
   403 		// Disallow the file editors.
   571 		case 'erase_others_personal_data':
   404 		if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT )
   572 		case 'manage_privacy_options':
   405 			$caps[] = 'do_not_allow';
   573 			$caps[] = is_multisite() ? 'manage_network' : 'manage_options';
   406 		elseif ( ! wp_is_file_mod_allowed( 'capability_edit_themes' ) )
   574 			break;
   407 			$caps[] = 'do_not_allow';
   575 		default:
   408 		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
   576 			// Handle meta capabilities for custom post types.
   409 			$caps[] = 'do_not_allow';
   577 			global $post_type_meta_caps;
   410 		else
   578 			if ( isset( $post_type_meta_caps[ $cap ] ) ) {
       
   579 				$args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
       
   580 				return call_user_func_array( 'map_meta_cap', $args );
       
   581 			}
       
   582 
       
   583 			// Block capabilities map to their post equivalent.
       
   584 			$block_caps = array(
       
   585 				'edit_blocks',
       
   586 				'edit_others_blocks',
       
   587 				'publish_blocks',
       
   588 				'read_private_blocks',
       
   589 				'delete_blocks',
       
   590 				'delete_private_blocks',
       
   591 				'delete_published_blocks',
       
   592 				'delete_others_blocks',
       
   593 				'edit_private_blocks',
       
   594 				'edit_published_blocks',
       
   595 			);
       
   596 			if ( in_array( $cap, $block_caps, true ) ) {
       
   597 				$cap = str_replace( '_blocks', '_posts', $cap );
       
   598 			}
       
   599 
       
   600 			// If no meta caps match, return the original cap.
   411 			$caps[] = $cap;
   601 			$caps[] = $cap;
   412 		break;
       
   413 	case 'update_plugins':
       
   414 	case 'delete_plugins':
       
   415 	case 'install_plugins':
       
   416 	case 'upload_plugins':
       
   417 	case 'update_themes':
       
   418 	case 'delete_themes':
       
   419 	case 'install_themes':
       
   420 	case 'upload_themes':
       
   421 	case 'update_core':
       
   422 		// Disallow anything that creates, deletes, or updates core, plugin, or theme files.
       
   423 		// Files in uploads are excepted.
       
   424 		if ( ! wp_is_file_mod_allowed( 'capability_update_core' ) ) {
       
   425 			$caps[] = 'do_not_allow';
       
   426 		} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
       
   427 			$caps[] = 'do_not_allow';
       
   428 		} elseif ( 'upload_themes' === $cap ) {
       
   429 			$caps[] = 'install_themes';
       
   430 		} elseif ( 'upload_plugins' === $cap ) {
       
   431 			$caps[] = 'install_plugins';
       
   432 		} else {
       
   433 			$caps[] = $cap;
       
   434 		}
       
   435 		break;
       
   436 	case 'install_languages':
       
   437 	case 'update_languages':
       
   438 		if ( ! wp_is_file_mod_allowed( 'can_install_language_pack' ) ) {
       
   439 			$caps[] = 'do_not_allow';
       
   440 		} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
       
   441 			$caps[] = 'do_not_allow';
       
   442 		} else {
       
   443 			$caps[] = 'install_languages';
       
   444 		}
       
   445 		break;
       
   446 	case 'activate_plugins':
       
   447 	case 'deactivate_plugins':
       
   448 	case 'activate_plugin':
       
   449 	case 'deactivate_plugin':
       
   450 		$caps[] = 'activate_plugins';
       
   451 		if ( is_multisite() ) {
       
   452 			// update_, install_, and delete_ are handled above with is_super_admin().
       
   453 			$menu_perms = get_site_option( 'menu_items', array() );
       
   454 			if ( empty( $menu_perms['plugins'] ) )
       
   455 				$caps[] = 'manage_network_plugins';
       
   456 		}
       
   457 		break;
       
   458 	case 'delete_user':
       
   459 	case 'delete_users':
       
   460 		// If multisite only super admins can delete users.
       
   461 		if ( is_multisite() && ! is_super_admin( $user_id ) )
       
   462 			$caps[] = 'do_not_allow';
       
   463 		else
       
   464 			$caps[] = 'delete_users'; // delete_user maps to delete_users.
       
   465 		break;
       
   466 	case 'create_users':
       
   467 		if ( !is_multisite() )
       
   468 			$caps[] = $cap;
       
   469 		elseif ( is_super_admin( $user_id ) || get_site_option( 'add_new_users' ) )
       
   470 			$caps[] = $cap;
       
   471 		else
       
   472 			$caps[] = 'do_not_allow';
       
   473 		break;
       
   474 	case 'manage_links' :
       
   475 		if ( get_option( 'link_manager_enabled' ) )
       
   476 			$caps[] = $cap;
       
   477 		else
       
   478 			$caps[] = 'do_not_allow';
       
   479 		break;
       
   480 	case 'customize' :
       
   481 		$caps[] = 'edit_theme_options';
       
   482 		break;
       
   483 	case 'delete_site':
       
   484 		if ( is_multisite() ) {
       
   485 			$caps[] = 'manage_options';
       
   486 		} else {
       
   487 			$caps[] = 'do_not_allow';
       
   488 		}
       
   489 		break;
       
   490 	case 'edit_term':
       
   491 	case 'delete_term':
       
   492 	case 'assign_term':
       
   493 		$term_id = (int) $args[0];
       
   494 		$term = get_term( $term_id );
       
   495 		if ( ! $term || is_wp_error( $term ) ) {
       
   496 			$caps[] = 'do_not_allow';
       
   497 			break;
       
   498 		}
       
   499 
       
   500 		$tax = get_taxonomy( $term->taxonomy );
       
   501 		if ( ! $tax ) {
       
   502 			$caps[] = 'do_not_allow';
       
   503 			break;
       
   504 		}
       
   505 
       
   506 		if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) {
       
   507 			$caps[] = 'do_not_allow';
       
   508 			break;
       
   509 		}
       
   510 
       
   511 		$taxo_cap = $cap . 's';
       
   512 
       
   513 		$caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id );
       
   514 
       
   515 		break;
       
   516 	case 'manage_post_tags':
       
   517 	case 'edit_categories':
       
   518 	case 'edit_post_tags':
       
   519 	case 'delete_categories':
       
   520 	case 'delete_post_tags':
       
   521 		$caps[] = 'manage_categories';
       
   522 		break;
       
   523 	case 'assign_categories':
       
   524 	case 'assign_post_tags':
       
   525 		$caps[] = 'edit_posts';
       
   526 		break;
       
   527 	case 'create_sites':
       
   528 	case 'delete_sites':
       
   529 	case 'manage_network':
       
   530 	case 'manage_sites':
       
   531 	case 'manage_network_users':
       
   532 	case 'manage_network_plugins':
       
   533 	case 'manage_network_themes':
       
   534 	case 'manage_network_options':
       
   535 	case 'upgrade_network':
       
   536 		$caps[] = $cap;
       
   537 		break;
       
   538 	case 'setup_network':
       
   539 		if ( is_multisite() ) {
       
   540 			$caps[] = 'manage_network_options';
       
   541 		} else {
       
   542 			$caps[] = 'manage_options';
       
   543 		}
       
   544 		break;
       
   545 	case 'export_others_personal_data':
       
   546 	case 'erase_others_personal_data':
       
   547 	case 'manage_privacy_options':
       
   548 		$caps[] = is_multisite() ? 'manage_network' : 'manage_options';
       
   549 		break;
       
   550 	default:
       
   551 		// Handle meta capabilities for custom post types.
       
   552 		global $post_type_meta_caps;
       
   553 		if ( isset( $post_type_meta_caps[ $cap ] ) ) {
       
   554 			$args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
       
   555 			return call_user_func_array( 'map_meta_cap', $args );
       
   556 		}
       
   557 
       
   558 		// If no meta caps match, return the original cap.
       
   559 		$caps[] = $cap;
       
   560 	}
   602 	}
   561 
   603 
   562 	/**
   604 	/**
   563 	 * Filters a user's capabilities depending on specific context and/or privilege.
   605 	 * Filters a user's capabilities depending on specific context and/or privilege.
   564 	 *
   606 	 *
   565 	 * @since 2.8.0
   607 	 * @since 2.8.0
   566 	 *
   608 	 *
   567 	 * @param array  $caps    Returns the user's actual capabilities.
   609 	 * @param string[] $caps    Array of the user's capabilities.
   568 	 * @param string $cap     Capability name.
   610 	 * @param string   $cap     Capability name.
   569 	 * @param int    $user_id The user ID.
   611 	 * @param int      $user_id The user ID.
   570 	 * @param array  $args    Adds the context to the cap. Typically the object ID.
   612 	 * @param array    $args    Adds the context to the cap. Typically the object ID.
   571 	 */
   613 	 */
   572 	return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args );
   614 	return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args );
   573 }
   615 }
   574 
   616 
   575 /**
   617 /**
   595  *              passed, whether the current user has the given meta capability for the given object.
   637  *              passed, whether the current user has the given meta capability for the given object.
   596  */
   638  */
   597 function current_user_can( $capability ) {
   639 function current_user_can( $capability ) {
   598 	$current_user = wp_get_current_user();
   640 	$current_user = wp_get_current_user();
   599 
   641 
   600 	if ( empty( $current_user ) )
   642 	if ( empty( $current_user ) ) {
   601 		return false;
   643 		return false;
       
   644 	}
   602 
   645 
   603 	$args = array_slice( func_get_args(), 1 );
   646 	$args = array_slice( func_get_args(), 1 );
   604 	$args = array_merge( array( $capability ), $args );
   647 	$args = array_merge( array( $capability ), $args );
   605 
   648 
   606 	return call_user_func_array( array( $current_user, 'has_cap' ), $args );
   649 	return call_user_func_array( array( $current_user, 'has_cap' ), $args );
   647  * @param int|WP_Post $post       Post ID or post object.
   690  * @param int|WP_Post $post       Post ID or post object.
   648  * @param string      $capability Capability name.
   691  * @param string      $capability Capability name.
   649  * @return bool Whether the post author has the given capability.
   692  * @return bool Whether the post author has the given capability.
   650  */
   693  */
   651 function author_can( $post, $capability ) {
   694 function author_can( $post, $capability ) {
   652 	if ( !$post = get_post($post) )
   695 	if ( ! $post = get_post( $post ) ) {
   653 		return false;
   696 		return false;
       
   697 	}
   654 
   698 
   655 	$author = get_userdata( $post->post_author );
   699 	$author = get_userdata( $post->post_author );
   656 
   700 
   657 	if ( ! $author )
   701 	if ( ! $author ) {
   658 		return false;
   702 		return false;
       
   703 	}
   659 
   704 
   660 	$args = array_slice( func_get_args(), 2 );
   705 	$args = array_slice( func_get_args(), 2 );
   661 	$args = array_merge( array( $capability ), $args );
   706 	$args = array_merge( array( $capability ), $args );
   662 
   707 
   663 	return call_user_func_array( array( $author, 'has_cap' ), $args );
   708 	return call_user_func_array( array( $author, 'has_cap' ), $args );
   671  * @param int|WP_User $user       User ID or object.
   716  * @param int|WP_User $user       User ID or object.
   672  * @param string      $capability Capability name.
   717  * @param string      $capability Capability name.
   673  * @return bool Whether the user has the given capability.
   718  * @return bool Whether the user has the given capability.
   674  */
   719  */
   675 function user_can( $user, $capability ) {
   720 function user_can( $user, $capability ) {
   676 	if ( ! is_object( $user ) )
   721 	if ( ! is_object( $user ) ) {
   677 		$user = get_userdata( $user );
   722 		$user = get_userdata( $user );
   678 
   723 	}
   679 	if ( ! $user || ! $user->exists() )
   724 
       
   725 	if ( ! $user || ! $user->exists() ) {
   680 		return false;
   726 		return false;
       
   727 	}
   681 
   728 
   682 	$args = array_slice( func_get_args(), 2 );
   729 	$args = array_slice( func_get_args(), 2 );
   683 	$args = array_merge( array( $capability ), $args );
   730 	$args = array_merge( array( $capability ), $args );
   684 
   731 
   685 	return call_user_func_array( array( $user, 'has_cap' ), $args );
   732 	return call_user_func_array( array( $user, 'has_cap' ), $args );
   753  * @return array List of super admin logins
   800  * @return array List of super admin logins
   754  */
   801  */
   755 function get_super_admins() {
   802 function get_super_admins() {
   756 	global $super_admins;
   803 	global $super_admins;
   757 
   804 
   758 	if ( isset($super_admins) )
   805 	if ( isset( $super_admins ) ) {
   759 		return $super_admins;
   806 		return $super_admins;
   760 	else
   807 	} else {
   761 		return get_site_option( 'site_admins', array('admin') );
   808 		return get_site_option( 'site_admins', array( 'admin' ) );
       
   809 	}
   762 }
   810 }
   763 
   811 
   764 /**
   812 /**
   765  * Determine if user is a site admin.
   813  * Determine if user is a site admin.
   766  *
   814  *
   768  *
   816  *
   769  * @param int $user_id (Optional) The ID of a user. Defaults to the current user.
   817  * @param int $user_id (Optional) The ID of a user. Defaults to the current user.
   770  * @return bool True if the user is a site admin.
   818  * @return bool True if the user is a site admin.
   771  */
   819  */
   772 function is_super_admin( $user_id = false ) {
   820 function is_super_admin( $user_id = false ) {
   773 	if ( ! $user_id || $user_id == get_current_user_id() )
   821 	if ( ! $user_id || $user_id == get_current_user_id() ) {
   774 		$user = wp_get_current_user();
   822 		$user = wp_get_current_user();
   775 	else
   823 	} else {
   776 		$user = get_userdata( $user_id );
   824 		$user = get_userdata( $user_id );
   777 
   825 	}
   778 	if ( ! $user || ! $user->exists() )
   826 
       
   827 	if ( ! $user || ! $user->exists() ) {
   779 		return false;
   828 		return false;
       
   829 	}
   780 
   830 
   781 	if ( is_multisite() ) {
   831 	if ( is_multisite() ) {
   782 		$super_admins = get_super_admins();
   832 		$super_admins = get_super_admins();
   783 		if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) )
   833 		if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) {
   784 			return true;
   834 			return true;
       
   835 		}
   785 	} else {
   836 	} else {
   786 		if ( $user->has_cap('delete_users') )
   837 		if ( $user->has_cap( 'delete_users' ) ) {
   787 			return true;
   838 			return true;
       
   839 		}
   788 	}
   840 	}
   789 
   841 
   790 	return false;
   842 	return false;
   791 }
   843 }
   792 
   844 
   820 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
   872 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
   821 
   873 
   822 	$user = get_userdata( $user_id );
   874 	$user = get_userdata( $user_id );
   823 	if ( $user && ! in_array( $user->user_login, $super_admins ) ) {
   875 	if ( $user && ! in_array( $user->user_login, $super_admins ) ) {
   824 		$super_admins[] = $user->user_login;
   876 		$super_admins[] = $user->user_login;
   825 		update_site_option( 'site_admins' , $super_admins );
   877 		update_site_option( 'site_admins', $super_admins );
   826 
   878 
   827 		/**
   879 		/**
   828 		 * Fires after the user is granted Super Admin privileges.
   880 		 * Fires after the user is granted Super Admin privileges.
   829 		 *
   881 		 *
   830 		 * @since 3.0.0
   882 		 * @since 3.0.0
   867 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
   919 	$super_admins = get_site_option( 'site_admins', array( 'admin' ) );
   868 
   920 
   869 	$user = get_userdata( $user_id );
   921 	$user = get_userdata( $user_id );
   870 	if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) {
   922 	if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) {
   871 		if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) {
   923 		if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) {
   872 			unset( $super_admins[$key] );
   924 			unset( $super_admins[ $key ] );
   873 			update_site_option( 'site_admins', $super_admins );
   925 			update_site_option( 'site_admins', $super_admins );
   874 
   926 
   875 			/**
   927 			/**
   876 			 * Fires after the user's Super Admin privileges are revoked.
   928 			 * Fires after the user's Super Admin privileges are revoked.
   877 			 *
   929 			 *
   892  * A user must have at least one out of the 'update_core', 'install_plugins', and
   944  * A user must have at least one out of the 'update_core', 'install_plugins', and
   893  * 'install_themes' capabilities to qualify for 'install_languages'.
   945  * 'install_themes' capabilities to qualify for 'install_languages'.
   894  *
   946  *
   895  * @since 4.9.0
   947  * @since 4.9.0
   896  *
   948  *
   897  * @param array $allcaps An array of all the user's capabilities.
   949  * @param bool[] $allcaps An array of all the user's capabilities.
   898  * @return array Filtered array of the user's capabilities.
   950  * @return bool[] Filtered array of the user's capabilities.
   899  */
   951  */
   900 function wp_maybe_grant_install_languages_cap( $allcaps ) {
   952 function wp_maybe_grant_install_languages_cap( $allcaps ) {
   901 	if ( ! empty( $allcaps['update_core'] ) || ! empty( $allcaps['install_plugins'] ) || ! empty( $allcaps['install_themes'] ) ) {
   953 	if ( ! empty( $allcaps['update_core'] ) || ! empty( $allcaps['install_plugins'] ) || ! empty( $allcaps['install_themes'] ) ) {
   902 		$allcaps['install_languages'] = true;
   954 		$allcaps['install_languages'] = true;
   903 	}
   955 	}
   904 
   956 
   905 	return $allcaps;
   957 	return $allcaps;
   906 }
   958 }
       
   959 
       
   960 /**
       
   961  * Filters the user capabilities to grant the 'resume_plugins' and 'resume_themes' capabilities as necessary.
       
   962  *
       
   963  * @since 5.2.0
       
   964  *
       
   965  * @param bool[] $allcaps An array of all the user's capabilities.
       
   966  * @return bool[] Filtered array of the user's capabilities.
       
   967  */
       
   968 function wp_maybe_grant_resume_extensions_caps( $allcaps ) {
       
   969 	// Even in a multisite, regular administrators should be able to resume plugins.
       
   970 	if ( ! empty( $allcaps['activate_plugins'] ) ) {
       
   971 		$allcaps['resume_plugins'] = true;
       
   972 	}
       
   973 
       
   974 	// Even in a multisite, regular administrators should be able to resume themes.
       
   975 	if ( ! empty( $allcaps['switch_themes'] ) ) {
       
   976 		$allcaps['resume_themes'] = true;
       
   977 	}
       
   978 
       
   979 	return $allcaps;
       
   980 }
       
   981 
       
   982 /**
       
   983  * Filters the user capabilities to grant the 'view_site_health_checks' capabilities as necessary.
       
   984  *
       
   985  * @since 5.2.2
       
   986  *
       
   987  * @param bool[]   $allcaps An array of all the user's capabilities.
       
   988  * @param string[] $caps    Required primitive capabilities for the requested capability.
       
   989  * @param array    $args {
       
   990  *     Arguments that accompany the requested capability check.
       
   991  *
       
   992  *     @type string    $0 Requested capability.
       
   993  *     @type int       $1 Concerned user ID.
       
   994  *     @type mixed  ...$2 Optional second and further parameters, typically object ID.
       
   995  * }
       
   996  * @param WP_User  $user    The user object.
       
   997  * @return bool[] Filtered array of the user's capabilities.
       
   998  */
       
   999 function wp_maybe_grant_site_health_caps( $allcaps, $caps, $args, $user ) {
       
  1000 	if ( ! empty( $allcaps['install_plugins'] ) && ( ! is_multisite() || is_super_admin( $user->ID ) ) ) {
       
  1001 		$allcaps['view_site_health_checks'] = true;
       
  1002 	}
       
  1003 
       
  1004 	return $allcaps;
       
  1005 }
       
  1006 
       
  1007 return;
       
  1008 
       
  1009 // Dummy gettext calls to get strings in the catalog.
       
  1010 /* translators: user role for administrators  */
       
  1011 _x( 'Administrator', 'User role' );
       
  1012 /* translators: user role for editors */
       
  1013 _x( 'Editor', 'User role' );
       
  1014 /* translators: user role for authors */
       
  1015 _x( 'Author', 'User role' );
       
  1016 /* translators: user role for contributors */
       
  1017 _x( 'Contributor', 'User role' );
       
  1018 /* translators: user role for subscriber */
       
  1019 _x( 'Subscriber', 'User role' );