5 * @package WordPress |
5 * @package WordPress |
6 * @subpackage Users |
6 * @subpackage Users |
7 */ |
7 */ |
8 |
8 |
9 /** |
9 /** |
10 * Map meta capabilities to primitive capabilities. |
10 * Maps meta capabilities to primitive capabilities. |
|
11 * |
|
12 * 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 that a user or role has, such as `edit_posts` and `edit_others_posts`. |
|
15 * |
|
16 * Example usage: |
|
17 * |
|
18 * map_meta_cap( 'edit_posts', $user->ID ); |
|
19 * map_meta_cap( 'edit_post', $user->ID, $post->ID ); |
|
20 * map_meta_cap( 'edit_post_meta', $user->ID, $post->ID, $meta_key ); |
11 * |
21 * |
12 * This does not actually compare whether the user ID has the actual capability, |
22 * This does not actually compare whether the user ID has the actual capability, |
13 * just what the capability or capabilities are. Meta capability list value can |
23 * just what the capability or capabilities are. Meta capability list value can |
14 * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post', |
24 * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post', |
15 * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'. |
25 * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'. |
16 * |
26 * |
17 * @since 2.0.0 |
27 * @since 2.0.0 |
|
28 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
29 * by adding it to the function signature. |
18 * |
30 * |
19 * @global array $post_type_meta_caps Used to get post type meta capabilities. |
31 * @global array $post_type_meta_caps Used to get post type meta capabilities. |
20 * |
32 * |
21 * @param string $cap Capability name. |
33 * @param string $cap Capability name. |
22 * @param int $user_id User ID. |
34 * @param int $user_id User ID. |
23 * @param int $object_id Optional. ID of the specific object to check against if `$cap` is a "meta" cap. |
35 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
24 * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used |
36 * @return string[] Actual capabilities for meta capability. |
25 * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts', |
37 */ |
26 * 'edit_others_posts', etc. The parameter is accessed via func_get_args(). |
38 function map_meta_cap( $cap, $user_id, ...$args ) { |
27 * @return array Actual capabilities for meta capability. |
|
28 */ |
|
29 function map_meta_cap( $cap, $user_id ) { |
|
30 $args = array_slice( func_get_args(), 2 ); |
|
31 $caps = array(); |
39 $caps = array(); |
32 |
40 |
33 switch ( $cap ) { |
41 switch ( $cap ) { |
34 case 'remove_user': |
42 case 'remove_user': |
35 // In multisite the user must be a super admin to remove themselves. |
43 // In multisite the user must be a super admin to remove themselves. |
63 if ( ! $post ) { |
71 if ( ! $post ) { |
64 $caps[] = 'do_not_allow'; |
72 $caps[] = 'do_not_allow'; |
65 break; |
73 break; |
66 } |
74 } |
67 |
75 |
68 if ( 'revision' == $post->post_type ) { |
76 if ( 'revision' === $post->post_type ) { |
69 $post = get_post( $post->post_parent ); |
77 $caps[] = 'do_not_allow'; |
70 if ( ! $post ) { |
78 break; |
71 $caps[] = 'do_not_allow'; |
|
72 break; |
|
73 } |
|
74 } |
79 } |
75 |
80 |
76 if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) { |
81 if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) { |
77 $caps[] = 'manage_options'; |
82 $caps[] = 'manage_options'; |
78 break; |
83 break; |
79 } |
84 } |
80 |
85 |
81 $post_type = get_post_type_object( $post->post_type ); |
86 $post_type = get_post_type_object( $post->post_type ); |
82 if ( ! $post_type ) { |
87 if ( ! $post_type ) { |
83 /* translators: 1: post type, 2: capability name */ |
88 /* translators: 1: Post type, 2: Capability name. */ |
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' ); |
89 _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' ); |
85 $caps[] = 'edit_others_posts'; |
90 $caps[] = 'edit_others_posts'; |
86 break; |
91 break; |
87 } |
92 } |
88 |
93 |
89 if ( ! $post_type->map_meta_cap ) { |
94 if ( ! $post_type->map_meta_cap ) { |
90 $caps[] = $post_type->cap->$cap; |
95 $caps[] = $post_type->cap->$cap; |
91 // Prior to 3.1 we would re-call map_meta_cap here. |
96 // Prior to 3.1 we would re-call map_meta_cap here. |
92 if ( 'delete_post' == $cap ) { |
97 if ( 'delete_post' === $cap ) { |
93 $cap = $post_type->cap->$cap; |
98 $cap = $post_type->cap->$cap; |
94 } |
99 } |
95 break; |
100 break; |
96 } |
101 } |
97 |
102 |
98 // If the post author is set and the user is the author... |
103 // If the post author is set and the user is the author... |
99 if ( $post->post_author && $user_id == $post->post_author ) { |
104 if ( $post->post_author && $user_id == $post->post_author ) { |
100 // If the post is published or scheduled... |
105 // If the post is published or scheduled... |
101 if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { |
106 if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { |
102 $caps[] = $post_type->cap->delete_published_posts; |
107 $caps[] = $post_type->cap->delete_published_posts; |
103 } elseif ( 'trash' == $post->post_status ) { |
108 } elseif ( 'trash' === $post->post_status ) { |
104 $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true ); |
109 $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true ); |
105 if ( in_array( $status, array( 'publish', 'future' ), true ) ) { |
110 if ( in_array( $status, array( 'publish', 'future' ), true ) ) { |
106 $caps[] = $post_type->cap->delete_published_posts; |
111 $caps[] = $post_type->cap->delete_published_posts; |
107 } else { |
112 } else { |
108 $caps[] = $post_type->cap->delete_posts; |
113 $caps[] = $post_type->cap->delete_posts; |
130 $caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) ); |
135 $caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) ); |
131 } |
136 } |
132 |
137 |
133 break; |
138 break; |
134 // edit_post breaks down to edit_posts, edit_published_posts, or |
139 // edit_post breaks down to edit_posts, edit_published_posts, or |
135 // edit_others_posts |
140 // edit_others_posts. |
136 case 'edit_post': |
141 case 'edit_post': |
137 case 'edit_page': |
142 case 'edit_page': |
138 $post = get_post( $args[0] ); |
143 $post = get_post( $args[0] ); |
139 if ( ! $post ) { |
144 if ( ! $post ) { |
140 $caps[] = 'do_not_allow'; |
145 $caps[] = 'do_not_allow'; |
141 break; |
146 break; |
142 } |
147 } |
143 |
148 |
144 if ( 'revision' == $post->post_type ) { |
149 if ( 'revision' === $post->post_type ) { |
145 $post = get_post( $post->post_parent ); |
150 $post = get_post( $post->post_parent ); |
146 if ( ! $post ) { |
151 if ( ! $post ) { |
147 $caps[] = 'do_not_allow'; |
152 $caps[] = 'do_not_allow'; |
148 break; |
153 break; |
149 } |
154 } |
150 } |
155 } |
151 |
156 |
152 $post_type = get_post_type_object( $post->post_type ); |
157 $post_type = get_post_type_object( $post->post_type ); |
153 if ( ! $post_type ) { |
158 if ( ! $post_type ) { |
154 /* translators: 1: post type, 2: capability name */ |
159 /* translators: 1: Post type, 2: Capability name. */ |
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' ); |
160 _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' ); |
156 $caps[] = 'edit_others_posts'; |
161 $caps[] = 'edit_others_posts'; |
157 break; |
162 break; |
158 } |
163 } |
159 |
164 |
160 if ( ! $post_type->map_meta_cap ) { |
165 if ( ! $post_type->map_meta_cap ) { |
161 $caps[] = $post_type->cap->$cap; |
166 $caps[] = $post_type->cap->$cap; |
162 // Prior to 3.1 we would re-call map_meta_cap here. |
167 // Prior to 3.1 we would re-call map_meta_cap here. |
163 if ( 'edit_post' == $cap ) { |
168 if ( 'edit_post' === $cap ) { |
164 $cap = $post_type->cap->$cap; |
169 $cap = $post_type->cap->$cap; |
165 } |
170 } |
166 break; |
171 break; |
167 } |
172 } |
168 |
173 |
169 // If the post author is set and the user is the author... |
174 // If the post author is set and the user is the author... |
170 if ( $post->post_author && $user_id == $post->post_author ) { |
175 if ( $post->post_author && $user_id == $post->post_author ) { |
171 // If the post is published or scheduled... |
176 // If the post is published or scheduled... |
172 if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { |
177 if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { |
173 $caps[] = $post_type->cap->edit_published_posts; |
178 $caps[] = $post_type->cap->edit_published_posts; |
174 } elseif ( 'trash' == $post->post_status ) { |
179 } elseif ( 'trash' === $post->post_status ) { |
175 $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true ); |
180 $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true ); |
176 if ( in_array( $status, array( 'publish', 'future' ), true ) ) { |
181 if ( in_array( $status, array( 'publish', 'future' ), true ) ) { |
177 $caps[] = $post_type->cap->edit_published_posts; |
182 $caps[] = $post_type->cap->edit_published_posts; |
178 } else { |
183 } else { |
179 $caps[] = $post_type->cap->edit_posts; |
184 $caps[] = $post_type->cap->edit_posts; |
208 if ( ! $post ) { |
213 if ( ! $post ) { |
209 $caps[] = 'do_not_allow'; |
214 $caps[] = 'do_not_allow'; |
210 break; |
215 break; |
211 } |
216 } |
212 |
217 |
213 if ( 'revision' == $post->post_type ) { |
218 if ( 'revision' === $post->post_type ) { |
214 $post = get_post( $post->post_parent ); |
219 $post = get_post( $post->post_parent ); |
215 if ( ! $post ) { |
220 if ( ! $post ) { |
216 $caps[] = 'do_not_allow'; |
221 $caps[] = 'do_not_allow'; |
217 break; |
222 break; |
218 } |
223 } |
219 } |
224 } |
220 |
225 |
221 $post_type = get_post_type_object( $post->post_type ); |
226 $post_type = get_post_type_object( $post->post_type ); |
222 if ( ! $post_type ) { |
227 if ( ! $post_type ) { |
223 /* translators: 1: post type, 2: capability name */ |
228 /* translators: 1: Post type, 2: Capability name. */ |
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 _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' ); |
225 $caps[] = 'edit_others_posts'; |
230 $caps[] = 'edit_others_posts'; |
226 break; |
231 break; |
227 } |
232 } |
228 |
233 |
229 if ( ! $post_type->map_meta_cap ) { |
234 if ( ! $post_type->map_meta_cap ) { |
230 $caps[] = $post_type->cap->$cap; |
235 $caps[] = $post_type->cap->$cap; |
231 // Prior to 3.1 we would re-call map_meta_cap here. |
236 // Prior to 3.1 we would re-call map_meta_cap here. |
232 if ( 'read_post' == $cap ) { |
237 if ( 'read_post' === $cap ) { |
233 $cap = $post_type->cap->$cap; |
238 $cap = $post_type->cap->$cap; |
234 } |
239 } |
235 break; |
240 break; |
236 } |
241 } |
237 |
242 |
238 $status_obj = get_post_status_object( $post->post_status ); |
243 $status_obj = get_post_status_object( $post->post_status ); |
|
244 if ( ! $status_obj ) { |
|
245 /* 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' ); |
|
247 $caps[] = 'edit_others_posts'; |
|
248 break; |
|
249 } |
|
250 |
239 if ( $status_obj->public ) { |
251 if ( $status_obj->public ) { |
240 $caps[] = $post_type->cap->read; |
252 $caps[] = $post_type->cap->read; |
241 break; |
253 break; |
242 } |
254 } |
243 |
255 |
276 case 'delete_term_meta': |
288 case 'delete_term_meta': |
277 case 'add_term_meta': |
289 case 'add_term_meta': |
278 case 'edit_user_meta': |
290 case 'edit_user_meta': |
279 case 'delete_user_meta': |
291 case 'delete_user_meta': |
280 case 'add_user_meta': |
292 case 'add_user_meta': |
281 list( $_, $object_type, $_ ) = explode( '_', $cap ); |
293 $object_type = explode( '_', $cap )[1]; |
282 $object_id = (int) $args[0]; |
294 $object_id = (int) $args[0]; |
283 |
295 |
284 $object_subtype = get_object_subtype( $object_type, $object_id ); |
296 $object_subtype = get_object_subtype( $object_type, $object_id ); |
285 |
297 |
286 if ( empty( $object_subtype ) ) { |
298 if ( empty( $object_subtype ) ) { |
287 $caps[] = 'do_not_allow'; |
299 $caps[] = 'do_not_allow'; |
347 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered. |
359 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered. |
348 * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered. |
360 * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered. |
349 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap(). |
361 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap(). |
350 * |
362 * |
351 * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`. |
363 * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`. |
352 * @since 4.7.0 |
364 * @since 4.7.0 Renamed from `auth_post_{$post_type}_meta_{$meta_key}` to |
353 * @deprecated 4.9.8 Use `auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}` |
365 * `auth_{$object_type}_{$object_subtype}_meta_{$meta_key}`. |
|
366 * @deprecated 4.9.8 Use {@see 'auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}'} instead. |
354 * |
367 * |
355 * @param bool $allowed Whether the user can add the object meta. Default false. |
368 * @param bool $allowed Whether the user can add the object meta. Default false. |
356 * @param string $meta_key The meta key. |
369 * @param string $meta_key The meta key. |
357 * @param int $object_id Object ID. |
370 * @param int $object_id Object ID. |
358 * @param int $user_id User ID. |
371 * @param int $user_id User ID. |
359 * @param string $cap Capability name. |
372 * @param string $cap Capability name. |
360 * @param string[] $caps Array of the user's capabilities. |
373 * @param string[] $caps Array of the user's capabilities. |
361 */ |
374 */ |
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}" ); |
375 $allowed = apply_filters_deprecated( |
|
376 "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", |
|
377 array( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ), |
|
378 '4.9.8', |
|
379 "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" |
|
380 ); |
363 } |
381 } |
364 |
382 |
365 if ( ! $allowed ) { |
383 if ( ! $allowed ) { |
366 $caps[] = $cap; |
384 $caps[] = $cap; |
367 } |
385 } |
613 */ |
633 */ |
614 return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); |
634 return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); |
615 } |
635 } |
616 |
636 |
617 /** |
637 /** |
618 * Whether the current user has a specific capability. |
638 * Returns whether the current user has the specified capability. |
|
639 * |
|
640 * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta |
|
641 * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to |
|
642 * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`. |
|
643 * |
|
644 * Example usage: |
|
645 * |
|
646 * current_user_can( 'edit_posts' ); |
|
647 * current_user_can( 'edit_post', $post->ID ); |
|
648 * current_user_can( 'edit_post_meta', $post->ID, $meta_key ); |
619 * |
649 * |
620 * While checking against particular roles in place of a capability is supported |
650 * While checking against particular roles in place of a capability is supported |
621 * in part, this practice is discouraged as it may produce unreliable results. |
651 * in part, this practice is discouraged as it may produce unreliable results. |
622 * |
652 * |
623 * Note: Will always return true if the current user is a super admin, unless specifically denied. |
653 * Note: Will always return true if the current user is a super admin, unless specifically denied. |
624 * |
654 * |
625 * @since 2.0.0 |
655 * @since 2.0.0 |
|
656 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
657 * by adding it to the function signature. |
626 * |
658 * |
627 * @see WP_User::has_cap() |
659 * @see WP_User::has_cap() |
628 * @see map_meta_cap() |
660 * @see map_meta_cap() |
629 * |
661 * |
630 * @param string $capability Capability name. |
662 * @param string $capability Capability name. |
631 * @param int $object_id Optional. ID of the specific object to check against if `$capability` is a "meta" cap. |
663 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
632 * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used |
|
633 * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts', |
|
634 * 'edit_others_posts', etc. Accessed via func_get_args() and passed to WP_User::has_cap(), |
|
635 * then map_meta_cap(). |
|
636 * @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is |
664 * @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is |
637 * passed, whether the current user has the given meta capability for the given object. |
665 * passed, whether the current user has the given meta capability for the given object. |
638 */ |
666 */ |
639 function current_user_can( $capability ) { |
667 function current_user_can( $capability, ...$args ) { |
640 $current_user = wp_get_current_user(); |
668 $current_user = wp_get_current_user(); |
641 |
669 |
642 if ( empty( $current_user ) ) { |
670 if ( empty( $current_user ) ) { |
643 return false; |
671 return false; |
644 } |
672 } |
645 |
673 |
646 $args = array_slice( func_get_args(), 1 ); |
674 return $current_user->has_cap( $capability, ...$args ); |
647 $args = array_merge( array( $capability ), $args ); |
675 } |
648 |
676 |
649 return call_user_func_array( array( $current_user, 'has_cap' ), $args ); |
677 /** |
650 } |
678 * Returns whether the current user has the specified capability for a given site. |
651 |
679 * |
652 /** |
680 * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta |
653 * Whether the current user has a specific capability for a given site. |
681 * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to |
|
682 * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`. |
|
683 * |
|
684 * Example usage: |
|
685 * |
|
686 * current_user_can_for_blog( $blog_id, 'edit_posts' ); |
|
687 * current_user_can_for_blog( $blog_id, 'edit_post', $post->ID ); |
|
688 * current_user_can_for_blog( $blog_id, 'edit_post_meta', $post->ID, $meta_key ); |
654 * |
689 * |
655 * @since 3.0.0 |
690 * @since 3.0.0 |
|
691 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
692 * by adding it to the function signature. |
656 * |
693 * |
657 * @param int $blog_id Site ID. |
694 * @param int $blog_id Site ID. |
658 * @param string $capability Capability name. |
695 * @param string $capability Capability name. |
|
696 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
659 * @return bool Whether the user has the given capability. |
697 * @return bool Whether the user has the given capability. |
660 */ |
698 */ |
661 function current_user_can_for_blog( $blog_id, $capability ) { |
699 function current_user_can_for_blog( $blog_id, $capability, ...$args ) { |
662 $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; |
700 $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; |
663 |
701 |
664 $current_user = wp_get_current_user(); |
702 $current_user = wp_get_current_user(); |
665 |
703 |
666 if ( empty( $current_user ) ) { |
704 if ( empty( $current_user ) ) { |
668 restore_current_blog(); |
706 restore_current_blog(); |
669 } |
707 } |
670 return false; |
708 return false; |
671 } |
709 } |
672 |
710 |
673 $args = array_slice( func_get_args(), 2 ); |
711 $can = $current_user->has_cap( $capability, ...$args ); |
674 $args = array_merge( array( $capability ), $args ); |
|
675 |
|
676 $can = call_user_func_array( array( $current_user, 'has_cap' ), $args ); |
|
677 |
712 |
678 if ( $switched ) { |
713 if ( $switched ) { |
679 restore_current_blog(); |
714 restore_current_blog(); |
680 } |
715 } |
681 |
716 |
682 return $can; |
717 return $can; |
683 } |
718 } |
684 |
719 |
685 /** |
720 /** |
686 * Whether the author of the supplied post has a specific capability. |
721 * Returns whether the author of the supplied post has the specified capability. |
|
722 * |
|
723 * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta |
|
724 * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to |
|
725 * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`. |
|
726 * |
|
727 * Example usage: |
|
728 * |
|
729 * author_can( $post, 'edit_posts' ); |
|
730 * author_can( $post, 'edit_post', $post->ID ); |
|
731 * author_can( $post, 'edit_post_meta', $post->ID, $meta_key ); |
687 * |
732 * |
688 * @since 2.9.0 |
733 * @since 2.9.0 |
|
734 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
735 * by adding it to the function signature. |
689 * |
736 * |
690 * @param int|WP_Post $post Post ID or post object. |
737 * @param int|WP_Post $post Post ID or post object. |
691 * @param string $capability Capability name. |
738 * @param string $capability Capability name. |
|
739 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
692 * @return bool Whether the post author has the given capability. |
740 * @return bool Whether the post author has the given capability. |
693 */ |
741 */ |
694 function author_can( $post, $capability ) { |
742 function author_can( $post, $capability, ...$args ) { |
695 if ( ! $post = get_post( $post ) ) { |
743 $post = get_post( $post ); |
|
744 if ( ! $post ) { |
696 return false; |
745 return false; |
697 } |
746 } |
698 |
747 |
699 $author = get_userdata( $post->post_author ); |
748 $author = get_userdata( $post->post_author ); |
700 |
749 |
701 if ( ! $author ) { |
750 if ( ! $author ) { |
702 return false; |
751 return false; |
703 } |
752 } |
704 |
753 |
705 $args = array_slice( func_get_args(), 2 ); |
754 return $author->has_cap( $capability, ...$args ); |
706 $args = array_merge( array( $capability ), $args ); |
755 } |
707 |
756 |
708 return call_user_func_array( array( $author, 'has_cap' ), $args ); |
757 /** |
709 } |
758 * Returns whether a particular user has the specified capability. |
710 |
759 * |
711 /** |
760 * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta |
712 * Whether a particular user has a specific capability. |
761 * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to |
|
762 * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`. |
|
763 * |
|
764 * Example usage: |
|
765 * |
|
766 * user_can( $user->ID, 'edit_posts' ); |
|
767 * user_can( $user->ID, 'edit_post', $post->ID ); |
|
768 * user_can( $user->ID, 'edit_post_meta', $post->ID, $meta_key ); |
713 * |
769 * |
714 * @since 3.1.0 |
770 * @since 3.1.0 |
|
771 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
772 * by adding it to the function signature. |
715 * |
773 * |
716 * @param int|WP_User $user User ID or object. |
774 * @param int|WP_User $user User ID or object. |
717 * @param string $capability Capability name. |
775 * @param string $capability Capability name. |
|
776 * @param mixed ...$args Optional further parameters, typically starting with an object ID. |
718 * @return bool Whether the user has the given capability. |
777 * @return bool Whether the user has the given capability. |
719 */ |
778 */ |
720 function user_can( $user, $capability ) { |
779 function user_can( $user, $capability, ...$args ) { |
721 if ( ! is_object( $user ) ) { |
780 if ( ! is_object( $user ) ) { |
722 $user = get_userdata( $user ); |
781 $user = get_userdata( $user ); |
723 } |
782 } |
724 |
783 |
725 if ( ! $user || ! $user->exists() ) { |
784 if ( ! $user || ! $user->exists() ) { |
726 return false; |
785 return false; |
727 } |
786 } |
728 |
787 |
729 $args = array_slice( func_get_args(), 2 ); |
788 return $user->has_cap( $capability, ...$args ); |
730 $args = array_merge( array( $capability ), $args ); |
|
731 |
|
732 return call_user_func_array( array( $user, 'has_cap' ), $args ); |
|
733 } |
789 } |
734 |
790 |
735 /** |
791 /** |
736 * Retrieves the global WP_Roles instance and instantiates it if necessary. |
792 * Retrieves the global WP_Roles instance and instantiates it if necessary. |
737 * |
793 * |
738 * @since 4.3.0 |
794 * @since 4.3.0 |
739 * |
795 * |
740 * @global WP_Roles $wp_roles WP_Roles global instance. |
796 * @global WP_Roles $wp_roles WordPress role management object. |
741 * |
797 * |
742 * @return WP_Roles WP_Roles global instance if not already instantiated. |
798 * @return WP_Roles WP_Roles global instance if not already instantiated. |
743 */ |
799 */ |
744 function wp_roles() { |
800 function wp_roles() { |
745 global $wp_roles; |
801 global $wp_roles; |
765 /** |
821 /** |
766 * Add role, if it does not exist. |
822 * Add role, if it does not exist. |
767 * |
823 * |
768 * @since 2.0.0 |
824 * @since 2.0.0 |
769 * |
825 * |
770 * @param string $role Role name. |
826 * @param string $role Role name. |
771 * @param string $display_name Display name for role. |
827 * @param string $display_name Display name for role. |
772 * @param array $capabilities List of capabilities, e.g. array( 'edit_posts' => true, 'delete_posts' => false ); |
828 * @param bool[] $capabilities List of capabilities keyed by the capability name, |
|
829 * e.g. array( 'edit_posts' => true, 'delete_posts' => false ). |
773 * @return WP_Role|null WP_Role object if role is added, null if already exists. |
830 * @return WP_Role|null WP_Role object if role is added, null if already exists. |
774 */ |
831 */ |
775 function add_role( $role, $display_name, $capabilities = array() ) { |
832 function add_role( $role, $display_name, $capabilities = array() ) { |
776 if ( empty( $role ) ) { |
833 if ( empty( $role ) ) { |
777 return; |
834 return; |
866 * |
923 * |
867 * @param int $user_id ID of the user that is about to be granted Super Admin privileges. |
924 * @param int $user_id ID of the user that is about to be granted Super Admin privileges. |
868 */ |
925 */ |
869 do_action( 'grant_super_admin', $user_id ); |
926 do_action( 'grant_super_admin', $user_id ); |
870 |
927 |
871 // Directly fetch site_admins instead of using get_super_admins() |
928 // Directly fetch site_admins instead of using get_super_admins(). |
872 $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); |
929 $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); |
873 |
930 |
874 $user = get_userdata( $user_id ); |
931 $user = get_userdata( $user_id ); |
875 if ( $user && ! in_array( $user->user_login, $super_admins ) ) { |
932 if ( $user && ! in_array( $user->user_login, $super_admins, true ) ) { |
876 $super_admins[] = $user->user_login; |
933 $super_admins[] = $user->user_login; |
877 update_site_option( 'site_admins', $super_admins ); |
934 update_site_option( 'site_admins', $super_admins ); |
878 |
935 |
879 /** |
936 /** |
880 * Fires after the user is granted Super Admin privileges. |
937 * Fires after the user is granted Super Admin privileges. |
913 * |
970 * |
914 * @param int $user_id ID of the user Super Admin privileges are being revoked from. |
971 * @param int $user_id ID of the user Super Admin privileges are being revoked from. |
915 */ |
972 */ |
916 do_action( 'revoke_super_admin', $user_id ); |
973 do_action( 'revoke_super_admin', $user_id ); |
917 |
974 |
918 // Directly fetch site_admins instead of using get_super_admins() |
975 // Directly fetch site_admins instead of using get_super_admins(). |
919 $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); |
976 $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); |
920 |
977 |
921 $user = get_userdata( $user_id ); |
978 $user = get_userdata( $user_id ); |
922 if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) { |
979 if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) { |
923 if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) { |
980 $key = array_search( $user->user_login, $super_admins, true ); |
|
981 if ( false !== $key ) { |
924 unset( $super_admins[ $key ] ); |
982 unset( $super_admins[ $key ] ); |
925 update_site_option( 'site_admins', $super_admins ); |
983 update_site_option( 'site_admins', $super_admins ); |
926 |
984 |
927 /** |
985 /** |
928 * Fires after the user's Super Admin privileges are revoked. |
986 * Fires after the user's Super Admin privileges are revoked. |
1005 } |
1063 } |
1006 |
1064 |
1007 return; |
1065 return; |
1008 |
1066 |
1009 // Dummy gettext calls to get strings in the catalog. |
1067 // Dummy gettext calls to get strings in the catalog. |
1010 /* translators: user role for administrators */ |
1068 /* translators: User role for administrators. */ |
1011 _x( 'Administrator', 'User role' ); |
1069 _x( 'Administrator', 'User role' ); |
1012 /* translators: user role for editors */ |
1070 /* translators: User role for editors. */ |
1013 _x( 'Editor', 'User role' ); |
1071 _x( 'Editor', 'User role' ); |
1014 /* translators: user role for authors */ |
1072 /* translators: User role for authors. */ |
1015 _x( 'Author', 'User role' ); |
1073 _x( 'Author', 'User role' ); |
1016 /* translators: user role for contributors */ |
1074 /* translators: User role for contributors. */ |
1017 _x( 'Contributor', 'User role' ); |
1075 _x( 'Contributor', 'User role' ); |
1018 /* translators: user role for subscriber */ |
1076 /* translators: User role for subscribers. */ |
1019 _x( 'Subscriber', 'User role' ); |
1077 _x( 'Subscriber', 'User role' ); |