5 * @package WordPress |
5 * @package WordPress |
6 * @subpackage Users |
6 * @subpackage Users |
7 */ |
7 */ |
8 |
8 |
9 /** |
9 /** |
10 * Maps meta capabilities to primitive capabilities. |
10 * Maps a capability to the primitive capabilities required of the given user to |
|
11 * satisfy the capability being checked. |
11 * |
12 * |
12 * This function also accepts an ID of an object to map against if the capability is a meta capability. Meta |
13 * This function also accepts an ID of an object to map against if the capability is a meta capability. Meta |
13 * capabilities such as `edit_post` and `edit_user` are capabilities used by this function to map to primitive |
14 * capabilities such as `edit_post` and `edit_user` are capabilities used by this function to map to primitive |
14 * capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`. |
15 * capabilities that a user or role requires, such as `edit_posts` and `edit_others_posts`. |
15 * |
16 * |
16 * Example usage: |
17 * Example usage: |
17 * |
18 * |
18 * map_meta_cap( 'edit_posts', $user->ID ); |
19 * map_meta_cap( 'edit_posts', $user->ID ); |
19 * map_meta_cap( 'edit_post', $user->ID, $post->ID ); |
20 * map_meta_cap( 'edit_post', $user->ID, $post->ID ); |
20 * map_meta_cap( 'edit_post_meta', $user->ID, $post->ID, $meta_key ); |
21 * map_meta_cap( 'edit_post_meta', $user->ID, $post->ID, $meta_key ); |
21 * |
22 * |
22 * This does not actually compare whether the user ID has the actual capability, |
23 * This function does not check whether the user has the required capabilities, |
23 * just what the capability or capabilities are. Meta capability list value can |
24 * it just returns what the required capabilities are. |
24 * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post', |
|
25 * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'. |
|
26 * |
25 * |
27 * @since 2.0.0 |
26 * @since 2.0.0 |
|
27 * @since 4.9.6 Added the `export_others_personal_data`, `erase_others_personal_data`, |
|
28 * and `manage_privacy_options` capabilities. |
|
29 * @since 5.1.0 Added the `update_php` capability. |
|
30 * @since 5.2.0 Added the `resume_plugin` and `resume_theme` capabilities. |
28 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
31 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
29 * by adding it to the function signature. |
32 * by adding it to the function signature. |
|
33 * @since 5.7.0 Added the `create_app_password`, `list_app_passwords`, `read_app_password`, |
|
34 * `edit_app_password`, `delete_app_passwords`, `delete_app_password`, |
|
35 * and `update_https` capabilities. |
30 * |
36 * |
31 * @global array $post_type_meta_caps Used to get post type meta capabilities. |
37 * @global array $post_type_meta_caps Used to get post type meta capabilities. |
32 * |
38 * |
33 * @param string $cap Capability name. |
39 * @param string $cap Capability being checked. |
34 * @param int $user_id User ID. |
40 * @param int $user_id User ID. |
35 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
41 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
36 * @return string[] Actual capabilities for meta capability. |
42 * @return string[] Primitive capabilities required of the user. |
37 */ |
43 */ |
38 function map_meta_cap( $cap, $user_id, ...$args ) { |
44 function map_meta_cap( $cap, $user_id, ...$args ) { |
39 $caps = array(); |
45 $caps = array(); |
40 |
46 |
41 switch ( $cap ) { |
47 switch ( $cap ) { |
238 $cap = $post_type->cap->$cap; |
244 $cap = $post_type->cap->$cap; |
239 } |
245 } |
240 break; |
246 break; |
241 } |
247 } |
242 |
248 |
243 $status_obj = get_post_status_object( $post->post_status ); |
249 $status_obj = get_post_status_object( get_post_status( $post ) ); |
244 if ( ! $status_obj ) { |
250 if ( ! $status_obj ) { |
245 /* translators: 1: Post status, 2: Capability name. */ |
251 /* translators: 1: Post status, 2: Capability name. */ |
246 _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' ); |
252 _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' ); |
247 $caps[] = 'edit_others_posts'; |
253 $caps[] = 'edit_others_posts'; |
248 break; |
254 break; |
249 } |
255 } |
250 |
256 |
251 if ( $status_obj->public ) { |
257 if ( $status_obj->public ) { |
586 $caps[] = 'do_not_allow'; |
592 $caps[] = 'do_not_allow'; |
587 } else { |
593 } else { |
588 $caps[] = 'update_core'; |
594 $caps[] = 'update_core'; |
589 } |
595 } |
590 break; |
596 break; |
|
597 case 'update_https': |
|
598 if ( is_multisite() && ! is_super_admin( $user_id ) ) { |
|
599 $caps[] = 'do_not_allow'; |
|
600 } else { |
|
601 $caps[] = 'manage_options'; |
|
602 $caps[] = 'update_core'; |
|
603 } |
|
604 break; |
591 case 'export_others_personal_data': |
605 case 'export_others_personal_data': |
592 case 'erase_others_personal_data': |
606 case 'erase_others_personal_data': |
593 case 'manage_privacy_options': |
607 case 'manage_privacy_options': |
594 $caps[] = is_multisite() ? 'manage_network' : 'manage_options'; |
608 $caps[] = is_multisite() ? 'manage_network' : 'manage_options'; |
|
609 break; |
|
610 case 'create_app_password': |
|
611 case 'list_app_passwords': |
|
612 case 'read_app_password': |
|
613 case 'edit_app_password': |
|
614 case 'delete_app_passwords': |
|
615 case 'delete_app_password': |
|
616 $caps = map_meta_cap( 'edit_user', $user_id, $args[0] ); |
595 break; |
617 break; |
596 default: |
618 default: |
597 // Handle meta capabilities for custom post types. |
619 // Handle meta capabilities for custom post types. |
598 global $post_type_meta_caps; |
620 global $post_type_meta_caps; |
599 if ( isset( $post_type_meta_caps[ $cap ] ) ) { |
621 if ( isset( $post_type_meta_caps[ $cap ] ) ) { |
620 // If no meta caps match, return the original cap. |
642 // If no meta caps match, return the original cap. |
621 $caps[] = $cap; |
643 $caps[] = $cap; |
622 } |
644 } |
623 |
645 |
624 /** |
646 /** |
625 * Filters a user's capabilities depending on specific context and/or privilege. |
647 * Filters the primitive capabilities required of the given user to satisfy the |
|
648 * capability being checked. |
626 * |
649 * |
627 * @since 2.8.0 |
650 * @since 2.8.0 |
628 * |
651 * |
629 * @param string[] $caps Array of the user's capabilities. |
652 * @param string[] $caps Primitive capabilities required of the user. |
630 * @param string $cap Capability name. |
653 * @param string $cap Capability being checked. |
631 * @param int $user_id The user ID. |
654 * @param int $user_id The user ID. |
632 * @param array $args Adds the context to the cap. Typically the object ID. |
655 * @param array $args Adds context to the capability check, typically |
|
656 * starting with an object ID. |
633 */ |
657 */ |
634 return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); |
658 return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); |
635 } |
659 } |
636 |
660 |
637 /** |
661 /** |
653 * Note: Will always return true if the current user is a super admin, unless specifically denied. |
677 * Note: Will always return true if the current user is a super admin, unless specifically denied. |
654 * |
678 * |
655 * @since 2.0.0 |
679 * @since 2.0.0 |
656 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
680 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
657 * by adding it to the function signature. |
681 * by adding it to the function signature. |
|
682 * @since 5.8.0 Converted to wrapper for the user_can() function. |
658 * |
683 * |
659 * @see WP_User::has_cap() |
684 * @see WP_User::has_cap() |
660 * @see map_meta_cap() |
685 * @see map_meta_cap() |
661 * |
686 * |
662 * @param string $capability Capability name. |
687 * @param string $capability Capability name. |
663 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
688 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
664 * @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is |
689 * @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is |
665 * passed, whether the current user has the given meta capability for the given object. |
690 * passed, whether the current user has the given meta capability for the given object. |
666 */ |
691 */ |
667 function current_user_can( $capability, ...$args ) { |
692 function current_user_can( $capability, ...$args ) { |
668 $current_user = wp_get_current_user(); |
693 return user_can( wp_get_current_user(), $capability, ...$args ); |
669 |
|
670 if ( empty( $current_user ) ) { |
|
671 return false; |
|
672 } |
|
673 |
|
674 return $current_user->has_cap( $capability, ...$args ); |
|
675 } |
694 } |
676 |
695 |
677 /** |
696 /** |
678 * Returns whether the current user has the specified capability for a given site. |
697 * Returns whether the current user has the specified capability for a given site. |
679 * |
698 * |
688 * current_user_can_for_blog( $blog_id, 'edit_post_meta', $post->ID, $meta_key ); |
707 * current_user_can_for_blog( $blog_id, 'edit_post_meta', $post->ID, $meta_key ); |
689 * |
708 * |
690 * @since 3.0.0 |
709 * @since 3.0.0 |
691 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
710 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
692 * by adding it to the function signature. |
711 * by adding it to the function signature. |
|
712 * @since 5.8.0 Wraps current_user_can() after switching to blog. |
693 * |
713 * |
694 * @param int $blog_id Site ID. |
714 * @param int $blog_id Site ID. |
695 * @param string $capability Capability name. |
715 * @param string $capability Capability name. |
696 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
716 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
697 * @return bool Whether the user has the given capability. |
717 * @return bool Whether the user has the given capability. |
698 */ |
718 */ |
699 function current_user_can_for_blog( $blog_id, $capability, ...$args ) { |
719 function current_user_can_for_blog( $blog_id, $capability, ...$args ) { |
700 $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; |
720 $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; |
701 |
721 |
702 $current_user = wp_get_current_user(); |
722 $can = current_user_can( $capability, ...$args ); |
703 |
|
704 if ( empty( $current_user ) ) { |
|
705 if ( $switched ) { |
|
706 restore_current_blog(); |
|
707 } |
|
708 return false; |
|
709 } |
|
710 |
|
711 $can = $current_user->has_cap( $capability, ...$args ); |
|
712 |
723 |
713 if ( $switched ) { |
724 if ( $switched ) { |
714 restore_current_blog(); |
725 restore_current_blog(); |
715 } |
726 } |
716 |
727 |
779 function user_can( $user, $capability, ...$args ) { |
790 function user_can( $user, $capability, ...$args ) { |
780 if ( ! is_object( $user ) ) { |
791 if ( ! is_object( $user ) ) { |
781 $user = get_userdata( $user ); |
792 $user = get_userdata( $user ); |
782 } |
793 } |
783 |
794 |
784 if ( ! $user || ! $user->exists() ) { |
795 if ( empty( $user ) ) { |
785 return false; |
796 // User is logged out, create anonymous user object. |
|
797 $user = new WP_User( 0 ); |
|
798 $user->init( new stdClass ); |
786 } |
799 } |
787 |
800 |
788 return $user->has_cap( $capability, ...$args ); |
801 return $user->has_cap( $capability, ...$args ); |
789 } |
802 } |
790 |
803 |