$caps[] = $cap; if ( is_multisite() ) { // update_, install_, and delete_ are handled above with is_super_admin(). $menu_perms = get_site_option( 'menu_items', array() ); if ( empty( $menu_perms['plugins'] ) ) $caps[] = 'manage_network_plugins'; } break; case 'delete_user': case 'delete_users': // If multisite only super admins can delete users. if ( is_multisite() && ! is_super_admin( $user_id ) ) $caps[] = 'do_not_allow'; else $caps[] = 'delete_users'; // delete_user maps to delete_users. break; case 'create_users': if ( !is_multisite() ) $caps[] = $cap; elseif ( is_super_admin( $user_id ) || get_site_option( 'add_new_users' ) ) $caps[] = $cap; else $caps[] = 'do_not_allow'; break; case 'manage_links' : if ( get_option( 'link_manager_enabled' ) ) $caps[] = $cap; else $caps[] = 'do_not_allow'; break; case 'customize' : $caps[] = 'edit_theme_options'; break; case 'delete_site': $caps[] = 'manage_options'; break; case 'edit_term': case 'delete_term': case 'assign_term': $term_id = (int) $args[0]; $term = get_term( $term_id ); if ( ! $term || is_wp_error( $term ) ) { $caps[] = 'do_not_allow'; break; } $tax = get_taxonomy( $term->taxonomy ); if ( ! $tax ) { $caps[] = 'do_not_allow'; break; } if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) { $caps[] = 'do_not_allow'; break; } $taxo_cap = $cap . 's'; $caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id ); break; case 'manage_post_tags': case 'edit_categories': case 'edit_post_tags': case 'delete_categories': case 'delete_post_tags': $caps[] = 'manage_categories'; break; case 'assign_categories': case 'assign_post_tags': $caps[] = 'edit_posts'; break; case 'create_sites': case 'delete_sites': case 'manage_network': case 'manage_sites': case 'manage_network_users': case 'manage_network_plugins': case 'manage_network_themes': case 'manage_network_options': $caps[] = $cap; break; default: // 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 ); } // If no meta caps match, return the original cap. $caps[] = $cap; } /** * Filters a user's capabilities depending on specific context and/or privilege. * * @since 2.8.0 * * @param array $caps Returns the user's actual capabilities. * @param string $cap Capability name. * @param int $user_id The user ID. * @param array $args Adds the context to the cap. Typically the object ID. */ return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); } /** * Whether the current user has a specific capability. * * While checking against particular roles in place of a capability is supported * in part, this practice is discouraged as it may produce unreliable results. * * Note: Will always return true if the current user is a super admin, unless specifically denied. * * @since 2.0.0 * * @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(). * @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 ) { $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 ); } /** * Whether current user has a capability or role for a given site. * * @since 3.0.0 * * @param int $blog_id Site ID. * @param string $capability Capability or role name. * @return bool */ function current_user_can_for_blog( $blog_id, $capability ) { $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; $current_user = wp_get_current_user(); if ( empty( $current_user ) ) { if ( $switched ) { restore_current_blog(); } 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 ); if ( $switched ) { restore_current_blog(); } return $can; } /** * Whether author of supplied post has capability or role. * * @since 2.9.0 * * @param int|object $post Post ID or post object. * @param string $capability Capability or role name. * @return bool */ function author_can( $post, $capability ) { if ( !$post = get_post($post) ) return false; $author = get_userdata( $post->post_author ); if ( ! $author ) 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 ); } /** * Whether a particular user has capability or role. * * @since 3.1.0 * * @param int|object $user User ID or object. * @param string $capability Capability or role name. * @return bool */ function user_can( $user, $capability ) { if ( ! is_object( $user ) ) $user = get_userdata( $user ); if ( ! $user || ! $user->exists() ) 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 ); } /** * Retrieves the global WP_Roles instance and instantiates it if necessary. * * @since 4.3.0 * * @global WP_Roles $wp_roles WP_Roles global instance. * * @return WP_Roles WP_Roles global instance if not already instantiated. */ function wp_roles() { global $wp_roles; if ( ! isset( $wp_roles ) ) { $wp_roles = new WP_Roles(); } return $wp_roles; } /** * Retrieve role object. * * @since 2.0.0 * * @param string $role Role name. * @return WP_Role|null WP_Role object if found, null if the role does not exist. */ function get_role( $role ) { return wp_roles()->get_role( $role ); } /** * Add role, if it does not exist. * * @since 2.0.0 * * @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 ); * @return WP_Role|null WP_Role object if role is added, null if already exists. */ function add_role( $role, $display_name, $capabilities = array() ) { if ( empty( $role ) ) { return; } return wp_roles()->add_role( $role, $display_name, $capabilities ); } /** * Remove role, if it exists. * * @since 2.0.0 * * @param string $role Role name. */ function remove_role( $role ) { wp_roles()->remove_role( $role ); } /** * Retrieve a list of super admins. * * @since 3.0.0 * * @global array $super_admins * * @return array List of super admin logins */ function get_super_admins() { global $super_admins; if ( isset($super_admins) ) return $super_admins; else return get_site_option( 'site_admins', array('admin') ); } /** * Determine if user is a site admin. * * @since 3.0.0 * * @param int $user_id (Optional) The ID of a user. Defaults to the current user. * @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() ) $user = wp_get_current_user(); else $user = get_userdata( $user_id ); if ( ! $user || ! $user->exists() ) return false; if ( is_multisite() ) { $super_admins = get_super_admins(); if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) return true; } else { if ( $user->has_cap('delete_users') ) return true; } return false; } /** * Grants Super Admin privileges. * * @since 3.0.0 * * @global array $super_admins * * @param int $user_id ID of the user to be granted Super Admin privileges. * @return bool True on success, false on failure. This can fail when the user is * already a super admin or when the `$super_admins` global is defined. */ function grant_super_admin( $user_id ) { // If global super_admins override is defined, there is nothing to do here. if ( isset( $GLOBALS['super_admins'] ) || ! is_multisite() ) { return false; } /** * Fires before the user is granted Super Admin privileges. * * @since 3.0.0 * * @param int $user_id ID of the user that is about to be granted Super Admin privileges. */ do_action( 'grant_super_admin', $user_id ); // 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 ) ) { $super_admins[] = $user->user_login; update_site_option( 'site_admins' , $super_admins ); /** * Fires after the user is granted Super Admin privileges. * * @since 3.0.0 * * @param int $user_id ID of the user that was granted Super Admin privileges. */ do_action( 'granted_super_admin', $user_id ); return true; } return false; } /** * Revokes Super Admin privileges. * * @since 3.0.0 * * @global array $super_admins * * @param int $user_id ID of the user Super Admin privileges to be revoked from. * @return bool True on success, false on failure. This can fail when the user's email * is the network admin email or when the `$super_admins` global is defined. */ function revoke_super_admin( $user_id ) { // If global super_admins override is defined, there is nothing to do here. if ( isset( $GLOBALS['super_admins'] ) || ! is_multisite() ) { return false; } /** * Fires before the user's Super Admin privileges are revoked. * * @since 3.0.0 * * @param int $user_id ID of the user Super Admin privileges are being revoked from. */ do_action( 'revoke_super_admin', $user_id ); // 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 ) ) ) { unset( $super_admins[$key] ); update_site_option( 'site_admins', $super_admins ); /** * Fires after the user's Super Admin privileges are revoked. * * @since 3.0.0 * * @param int $user_id ID of the user Super Admin privileges were revoked from. */ do_action( 'revoked_super_admin', $user_id ); return true; } } return false; }