11 * |
11 * |
12 * The role option is simple, the structure is organized by role name that store |
12 * The role option is simple, the structure is organized by role name that store |
13 * the name in value of the 'name' key. The capabilities are stored as an array |
13 * the name in value of the 'name' key. The capabilities are stored as an array |
14 * in the value of the 'capability' key. |
14 * in the value of the 'capability' key. |
15 * |
15 * |
16 * <code> |
16 * array ( |
17 * array ( |
17 * 'rolename' => array ( |
18 * 'rolename' => array ( |
18 * 'name' => 'rolename', |
19 * 'name' => 'rolename', |
19 * 'capabilities' => array() |
20 * 'capabilities' => array() |
20 * ) |
21 * ) |
21 * ) |
22 * ) |
|
23 * </code> |
|
24 * |
22 * |
25 * @since 2.0.0 |
23 * @since 2.0.0 |
26 * @package WordPress |
24 * @package WordPress |
27 * @subpackage User |
25 * @subpackage User |
28 */ |
26 */ |
32 * |
30 * |
33 * @since 2.0.0 |
31 * @since 2.0.0 |
34 * @access public |
32 * @access public |
35 * @var array |
33 * @var array |
36 */ |
34 */ |
37 var $roles; |
35 public $roles; |
38 |
36 |
39 /** |
37 /** |
40 * List of the role objects. |
38 * List of the role objects. |
41 * |
39 * |
42 * @since 2.0.0 |
40 * @since 2.0.0 |
43 * @access public |
41 * @access public |
44 * @var array |
42 * @var array |
45 */ |
43 */ |
46 var $role_objects = array(); |
44 public $role_objects = array(); |
47 |
45 |
48 /** |
46 /** |
49 * List of role names. |
47 * List of role names. |
50 * |
48 * |
51 * @since 2.0.0 |
49 * @since 2.0.0 |
52 * @access public |
50 * @access public |
53 * @var array |
51 * @var array |
54 */ |
52 */ |
55 var $role_names = array(); |
53 public $role_names = array(); |
56 |
54 |
57 /** |
55 /** |
58 * Option name for storing role list. |
56 * Option name for storing role list. |
59 * |
57 * |
60 * @since 2.0.0 |
58 * @since 2.0.0 |
61 * @access public |
59 * @access public |
62 * @var string |
60 * @var string |
63 */ |
61 */ |
64 var $role_key; |
62 public $role_key; |
65 |
63 |
66 /** |
64 /** |
67 * Whether to use the database for retrieval and storage. |
65 * Whether to use the database for retrieval and storage. |
68 * |
66 * |
69 * @since 2.1.0 |
67 * @since 2.1.0 |
70 * @access public |
68 * @access public |
71 * @var bool |
69 * @var bool |
72 */ |
70 */ |
73 var $use_db = true; |
71 public $use_db = true; |
74 |
72 |
75 /** |
73 /** |
76 * Constructor |
74 * Constructor |
77 * |
75 * |
78 * @since 2.0.0 |
76 * @since 2.0.0 |
79 */ |
77 */ |
80 function __construct() { |
78 public function __construct() { |
81 $this->_init(); |
79 $this->_init(); |
|
80 } |
|
81 |
|
82 /** |
|
83 * Make private/protected methods readable for backwards compatibility. |
|
84 * |
|
85 * @since 4.0.0 |
|
86 * @access public |
|
87 * |
|
88 * @param callable $name Method to call. |
|
89 * @param array $arguments Arguments to pass when calling. |
|
90 * @return mixed|bool Return value of the callback, false otherwise. |
|
91 */ |
|
92 public function __call( $name, $arguments ) { |
|
93 if ( '_init' === $name ) { |
|
94 return call_user_func_array( array( $this, $name ), $arguments ); |
|
95 } |
|
96 return false; |
82 } |
97 } |
83 |
98 |
84 /** |
99 /** |
85 * Set up the object properties. |
100 * Set up the object properties. |
86 * |
101 * |
88 * 'user_roles' appended. If the $wp_user_roles global is set, then it will |
103 * 'user_roles' appended. If the $wp_user_roles global is set, then it will |
89 * be used and the role option will not be updated or used. |
104 * be used and the role option will not be updated or used. |
90 * |
105 * |
91 * @since 2.1.0 |
106 * @since 2.1.0 |
92 * @access protected |
107 * @access protected |
93 * @uses $wpdb Used to get the database prefix. |
108 * |
|
109 * @global wpdb $wpdb WordPress database abstraction object. |
94 * @global array $wp_user_roles Used to set the 'roles' property value. |
110 * @global array $wp_user_roles Used to set the 'roles' property value. |
95 */ |
111 */ |
96 function _init () { |
112 protected function _init() { |
97 global $wpdb, $wp_user_roles; |
113 global $wpdb, $wp_user_roles; |
98 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; |
114 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; |
99 if ( ! empty( $wp_user_roles ) ) { |
115 if ( ! empty( $wp_user_roles ) ) { |
100 $this->roles = $wp_user_roles; |
116 $this->roles = $wp_user_roles; |
101 $this->use_db = false; |
117 $this->use_db = false; |
121 * after switching wpdb to a new blog ID. |
137 * after switching wpdb to a new blog ID. |
122 * |
138 * |
123 * @since 3.5.0 |
139 * @since 3.5.0 |
124 * @access public |
140 * @access public |
125 */ |
141 */ |
126 function reinit() { |
142 public function reinit() { |
127 // There is no need to reinit if using the wp_user_roles global. |
143 // There is no need to reinit if using the wp_user_roles global. |
128 if ( ! $this->use_db ) |
144 if ( ! $this->use_db ) |
129 return; |
145 return; |
130 |
146 |
131 global $wpdb, $wp_user_roles; |
147 global $wpdb; |
132 |
148 |
133 // Duplicated from _init() to avoid an extra function call. |
149 // Duplicated from _init() to avoid an extra function call. |
134 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; |
150 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; |
135 $this->roles = get_option( $this->role_key ); |
151 $this->roles = get_option( $this->role_key ); |
136 if ( empty( $this->roles ) ) |
152 if ( empty( $this->roles ) ) |
158 * @param string $role Role name. |
174 * @param string $role Role name. |
159 * @param string $display_name Role display name. |
175 * @param string $display_name Role display name. |
160 * @param array $capabilities List of role capabilities in the above format. |
176 * @param array $capabilities List of role capabilities in the above format. |
161 * @return WP_Role|null WP_Role object if role is added, null if already exists. |
177 * @return WP_Role|null WP_Role object if role is added, null if already exists. |
162 */ |
178 */ |
163 function add_role( $role, $display_name, $capabilities = array() ) { |
179 public function add_role( $role, $display_name, $capabilities = array() ) { |
164 if ( isset( $this->roles[$role] ) ) |
180 if ( isset( $this->roles[$role] ) ) |
165 return; |
181 return; |
166 |
182 |
167 $this->roles[$role] = array( |
183 $this->roles[$role] = array( |
168 'name' => $display_name, |
184 'name' => $display_name, |
206 * |
222 * |
207 * @param string $role Role name. |
223 * @param string $role Role name. |
208 * @param string $cap Capability name. |
224 * @param string $cap Capability name. |
209 * @param bool $grant Optional, default is true. Whether role is capable of performing capability. |
225 * @param bool $grant Optional, default is true. Whether role is capable of performing capability. |
210 */ |
226 */ |
211 function add_cap( $role, $cap, $grant = true ) { |
227 public function add_cap( $role, $cap, $grant = true ) { |
212 if ( ! isset( $this->roles[$role] ) ) |
228 if ( ! isset( $this->roles[$role] ) ) |
213 return; |
229 return; |
214 |
230 |
215 $this->roles[$role]['capabilities'][$cap] = $grant; |
231 $this->roles[$role]['capabilities'][$cap] = $grant; |
216 if ( $this->use_db ) |
232 if ( $this->use_db ) |
224 * @access public |
240 * @access public |
225 * |
241 * |
226 * @param string $role Role name. |
242 * @param string $role Role name. |
227 * @param string $cap Capability name. |
243 * @param string $cap Capability name. |
228 */ |
244 */ |
229 function remove_cap( $role, $cap ) { |
245 public function remove_cap( $role, $cap ) { |
230 if ( ! isset( $this->roles[$role] ) ) |
246 if ( ! isset( $this->roles[$role] ) ) |
231 return; |
247 return; |
232 |
248 |
233 unset( $this->roles[$role]['capabilities'][$cap] ); |
249 unset( $this->roles[$role]['capabilities'][$cap] ); |
234 if ( $this->use_db ) |
250 if ( $this->use_db ) |
242 * @access public |
258 * @access public |
243 * |
259 * |
244 * @param string $role Role name. |
260 * @param string $role Role name. |
245 * @return WP_Role|null WP_Role object if found, null if the role does not exist. |
261 * @return WP_Role|null WP_Role object if found, null if the role does not exist. |
246 */ |
262 */ |
247 function get_role( $role ) { |
263 public function get_role( $role ) { |
248 if ( isset( $this->role_objects[$role] ) ) |
264 if ( isset( $this->role_objects[$role] ) ) |
249 return $this->role_objects[$role]; |
265 return $this->role_objects[$role]; |
250 else |
266 else |
251 return null; |
267 return null; |
252 } |
268 } |
328 * @access public |
344 * @access public |
329 * |
345 * |
330 * @param string $cap Capability name. |
346 * @param string $cap Capability name. |
331 * @param bool $grant Whether role has capability privilege. |
347 * @param bool $grant Whether role has capability privilege. |
332 */ |
348 */ |
333 function add_cap( $cap, $grant = true ) { |
349 public function add_cap( $cap, $grant = true ) { |
334 global $wp_roles; |
350 global $wp_roles; |
335 |
351 |
336 if ( ! isset( $wp_roles ) ) |
352 if ( ! isset( $wp_roles ) ) |
337 $wp_roles = new WP_Roles(); |
353 $wp_roles = new WP_Roles(); |
338 |
354 |
375 * @access public |
391 * @access public |
376 * |
392 * |
377 * @param string $cap Capability name. |
393 * @param string $cap Capability name. |
378 * @return bool True, if user has capability. False, if doesn't have capability. |
394 * @return bool True, if user has capability. False, if doesn't have capability. |
379 */ |
395 */ |
380 function has_cap( $cap ) { |
396 public function has_cap( $cap ) { |
|
397 /** |
|
398 * Filter which capabilities a role has. |
|
399 * |
|
400 * @since 2.0.0 |
|
401 * |
|
402 * @param array $capabilities Array of role capabilities. |
|
403 * @param string $cap Capability name. |
|
404 * @param string $name Role name. |
|
405 */ |
381 $capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name ); |
406 $capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name ); |
382 if ( !empty( $capabilities[$cap] ) ) |
407 if ( !empty( $capabilities[$cap] ) ) |
383 return $capabilities[$cap]; |
408 return $capabilities[$cap]; |
384 else |
409 else |
385 return false; |
410 return false; |
391 * WordPress User class. |
416 * WordPress User class. |
392 * |
417 * |
393 * @since 2.0.0 |
418 * @since 2.0.0 |
394 * @package WordPress |
419 * @package WordPress |
395 * @subpackage User |
420 * @subpackage User |
|
421 * |
|
422 * @property string $nickname |
|
423 * @property string $user_description |
|
424 * @property string $user_firstname |
|
425 * @property string $user_lastname |
|
426 * @property string $user_login |
|
427 * @property string $user_pass |
|
428 * @property string $user_nicename |
|
429 * @property string $user_email |
|
430 * @property string $user_url |
|
431 * @property string $user_registered |
|
432 * @property string $user_activation_key |
|
433 * @property string $user_status |
|
434 * @property string $display_name |
|
435 * @property string $spam |
|
436 * @property string $deleted |
396 */ |
437 */ |
397 class WP_User { |
438 class WP_User { |
398 /** |
439 /** |
399 * User data container. |
440 * User data container. |
400 * |
441 * |
401 * @since 2.0.0 |
442 * @since 2.0.0 |
402 * @access private |
443 * @var object |
|
444 */ |
|
445 public $data; |
|
446 |
|
447 /** |
|
448 * The user's ID. |
|
449 * |
|
450 * @since 2.1.0 |
|
451 * @access public |
|
452 * @var int |
|
453 */ |
|
454 public $ID = 0; |
|
455 |
|
456 /** |
|
457 * The individual capabilities the user has been given. |
|
458 * |
|
459 * @since 2.0.0 |
|
460 * @access public |
403 * @var array |
461 * @var array |
404 */ |
462 */ |
405 var $data; |
463 public $caps = array(); |
406 |
464 |
407 /** |
465 /** |
408 * The user's ID. |
466 * User metadata option name. |
409 * |
467 * |
410 * @since 2.1.0 |
468 * @since 2.0.0 |
411 * @access public |
469 * @access public |
412 * @var int |
470 * @var string |
413 */ |
471 */ |
414 var $ID = 0; |
472 public $cap_key; |
415 |
473 |
416 /** |
474 /** |
417 * The individual capabilities the user has been given. |
475 * The roles the user is part of. |
418 * |
476 * |
419 * @since 2.0.0 |
477 * @since 2.0.0 |
420 * @access public |
478 * @access public |
421 * @var array |
479 * @var array |
422 */ |
480 */ |
423 var $caps = array(); |
481 public $roles = array(); |
424 |
482 |
425 /** |
483 /** |
426 * User metadata option name. |
484 * All capabilities the user has, including individual and role based. |
427 * |
|
428 * @since 2.0.0 |
|
429 * @access public |
|
430 * @var string |
|
431 */ |
|
432 var $cap_key; |
|
433 |
|
434 /** |
|
435 * The roles the user is part of. |
|
436 * |
485 * |
437 * @since 2.0.0 |
486 * @since 2.0.0 |
438 * @access public |
487 * @access public |
439 * @var array |
488 * @var array |
440 */ |
489 */ |
441 var $roles = array(); |
490 public $allcaps = array(); |
442 |
|
443 /** |
|
444 * All capabilities the user has, including individual and role based. |
|
445 * |
|
446 * @since 2.0.0 |
|
447 * @access public |
|
448 * @var array |
|
449 */ |
|
450 var $allcaps = array(); |
|
451 |
491 |
452 /** |
492 /** |
453 * The filter context applied to user data fields. |
493 * The filter context applied to user data fields. |
454 * |
494 * |
455 * @since 2.9.0 |
495 * @since 2.9.0 |
469 * @access public |
509 * @access public |
470 * |
510 * |
471 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB. |
511 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB. |
472 * @param string $name Optional. User's username |
512 * @param string $name Optional. User's username |
473 * @param int $blog_id Optional Blog ID, defaults to current blog. |
513 * @param int $blog_id Optional Blog ID, defaults to current blog. |
474 * @return WP_User |
514 */ |
475 */ |
515 public function __construct( $id = 0, $name = '', $blog_id = '' ) { |
476 function __construct( $id = 0, $name = '', $blog_id = '' ) { |
|
477 if ( ! isset( self::$back_compat_keys ) ) { |
516 if ( ! isset( self::$back_compat_keys ) ) { |
478 $prefix = $GLOBALS['wpdb']->prefix; |
517 $prefix = $GLOBALS['wpdb']->prefix; |
479 self::$back_compat_keys = array( |
518 self::$back_compat_keys = array( |
480 'user_firstname' => 'first_name', |
519 'user_firstname' => 'first_name', |
481 'user_lastname' => 'last_name', |
520 'user_lastname' => 'last_name', |
484 $prefix . 'usersettings' => $prefix . 'user-settings', |
523 $prefix . 'usersettings' => $prefix . 'user-settings', |
485 $prefix . 'usersettingstime' => $prefix . 'user-settings-time', |
524 $prefix . 'usersettingstime' => $prefix . 'user-settings-time', |
486 ); |
525 ); |
487 } |
526 } |
488 |
527 |
489 if ( is_a( $id, 'WP_User' ) ) { |
528 if ( $id instanceof WP_User ) { |
490 $this->init( $id->data, $blog_id ); |
529 $this->init( $id->data, $blog_id ); |
491 return; |
530 return; |
492 } elseif ( is_object( $id ) ) { |
531 } elseif ( is_object( $id ) ) { |
493 $this->init( $id, $blog_id ); |
532 $this->init( $id, $blog_id ); |
494 return; |
533 return; |
497 if ( ! empty( $id ) && ! is_numeric( $id ) ) { |
536 if ( ! empty( $id ) && ! is_numeric( $id ) ) { |
498 $name = $id; |
537 $name = $id; |
499 $id = 0; |
538 $id = 0; |
500 } |
539 } |
501 |
540 |
502 if ( $id ) |
541 if ( $id ) { |
503 $data = self::get_data_by( 'id', $id ); |
542 $data = self::get_data_by( 'id', $id ); |
504 else |
543 } else { |
505 $data = self::get_data_by( 'login', $name ); |
544 $data = self::get_data_by( 'login', $name ); |
506 |
545 } |
507 if ( $data ) |
546 |
|
547 if ( $data ) { |
508 $this->init( $data, $blog_id ); |
548 $this->init( $data, $blog_id ); |
|
549 } else { |
|
550 $this->data = new stdClass; |
|
551 } |
509 } |
552 } |
510 |
553 |
511 /** |
554 /** |
512 * Sets up object properties, including capabilities. |
555 * Sets up object properties, including capabilities. |
513 * |
556 * |
514 * @param object $data User DB row object |
557 * @param object $data User DB row object |
515 * @param int $blog_id Optional. The blog id to initialize for |
558 * @param int $blog_id Optional. The blog id to initialize for |
516 */ |
559 */ |
517 function init( $data, $blog_id = '' ) { |
560 public function init( $data, $blog_id = '' ) { |
518 $this->data = $data; |
561 $this->data = $data; |
519 $this->ID = (int) $data->ID; |
562 $this->ID = (int) $data->ID; |
520 |
563 |
521 $this->for_blog( $blog_id ); |
564 $this->for_blog( $blog_id ); |
522 } |
565 } |
526 * |
569 * |
527 * @since 3.3.0 |
570 * @since 3.3.0 |
528 * |
571 * |
529 * @param string $field The field to query against: 'id', 'slug', 'email' or 'login' |
572 * @param string $field The field to query against: 'id', 'slug', 'email' or 'login' |
530 * @param string|int $value The field value |
573 * @param string|int $value The field value |
531 * @return object Raw user object |
574 * @return object|false Raw user object |
532 */ |
575 */ |
533 static function get_data_by( $field, $value ) { |
576 public static function get_data_by( $field, $value ) { |
534 global $wpdb; |
577 global $wpdb; |
535 |
578 |
536 if ( 'id' == $field ) { |
579 if ( 'id' == $field ) { |
537 // Make sure the value is numeric to avoid casting objects, for example, |
580 // Make sure the value is numeric to avoid casting objects, for example, |
538 // to int 1. |
581 // to int 1. |
634 /** |
681 /** |
635 * Magic method for setting custom fields |
682 * Magic method for setting custom fields |
636 * |
683 * |
637 * @since 3.3.0 |
684 * @since 3.3.0 |
638 */ |
685 */ |
639 function __set( $key, $value ) { |
686 public function __set( $key, $value ) { |
640 if ( 'id' == $key ) { |
687 if ( 'id' == $key ) { |
641 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); |
688 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); |
642 $this->ID = $value; |
689 $this->ID = $value; |
643 return; |
690 return; |
644 } |
691 } |
678 * |
725 * |
679 * @since 3.3.0 |
726 * @since 3.3.0 |
680 * |
727 * |
681 * @param string $key Property |
728 * @param string $key Property |
682 */ |
729 */ |
683 function has_prop( $key ) { |
730 public function has_prop( $key ) { |
684 return $this->__isset( $key ); |
731 return $this->__isset( $key ); |
685 } |
732 } |
686 |
733 |
687 /* |
734 /** |
688 * Return an array representation. |
735 * Return an array representation. |
689 * |
736 * |
690 * @since 3.5.0 |
737 * @since 3.5.0 |
691 * |
738 * |
692 * @return array Array representation. |
739 * @return array Array representation. |
693 */ |
740 */ |
694 function to_array() { |
741 public function to_array() { |
695 return get_object_vars( $this->data ); |
742 return get_object_vars( $this->data ); |
696 } |
743 } |
697 |
744 |
698 /** |
745 /** |
699 * Set up capability object properties. |
746 * Set up capability object properties. |
767 * @since 2.0.0 |
814 * @since 2.0.0 |
768 * @access public |
815 * @access public |
769 * |
816 * |
770 * @param string $role Role name. |
817 * @param string $role Role name. |
771 */ |
818 */ |
772 function add_role( $role ) { |
819 public function add_role( $role ) { |
773 $this->caps[$role] = true; |
820 $this->caps[$role] = true; |
774 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
821 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
775 $this->get_role_caps(); |
822 $this->get_role_caps(); |
776 $this->update_user_level_from_caps(); |
823 $this->update_user_level_from_caps(); |
777 } |
824 } |
782 * @since 2.0.0 |
829 * @since 2.0.0 |
783 * @access public |
830 * @access public |
784 * |
831 * |
785 * @param string $role Role name. |
832 * @param string $role Role name. |
786 */ |
833 */ |
787 function remove_role( $role ) { |
834 public function remove_role( $role ) { |
788 if ( !in_array($role, $this->roles) ) |
835 if ( !in_array($role, $this->roles) ) |
789 return; |
836 return; |
790 unset( $this->caps[$role] ); |
837 unset( $this->caps[$role] ); |
791 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
838 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
792 $this->get_role_caps(); |
839 $this->get_role_caps(); |
820 $this->roles = false; |
867 $this->roles = false; |
821 } |
868 } |
822 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
869 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
823 $this->get_role_caps(); |
870 $this->get_role_caps(); |
824 $this->update_user_level_from_caps(); |
871 $this->update_user_level_from_caps(); |
|
872 |
|
873 /** |
|
874 * Fires after the user's role has changed. |
|
875 * |
|
876 * @since 2.9.0 |
|
877 * @since 3.6.0 Added $old_roles to include an array of the user's previous roles. |
|
878 * |
|
879 * @param int $user_id The user ID. |
|
880 * @param string $role The new role. |
|
881 * @param array $old_roles An array of the user's previous roles. |
|
882 */ |
825 do_action( 'set_user_role', $this->ID, $role, $old_roles ); |
883 do_action( 'set_user_role', $this->ID, $role, $old_roles ); |
826 } |
884 } |
827 |
885 |
828 /** |
886 /** |
829 * Choose the maximum level the user has. |
887 * Choose the maximum level the user has. |
842 * |
900 * |
843 * @param int $max Max level of user. |
901 * @param int $max Max level of user. |
844 * @param string $item Level capability name. |
902 * @param string $item Level capability name. |
845 * @return int Max Level. |
903 * @return int Max Level. |
846 */ |
904 */ |
847 function level_reduction( $max, $item ) { |
905 public function level_reduction( $max, $item ) { |
848 if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { |
906 if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { |
849 $level = intval( $matches[1] ); |
907 $level = intval( $matches[1] ); |
850 return max( $max, $level ); |
908 return max( $max, $level ); |
851 } else { |
909 } else { |
852 return $max; |
910 return $max; |
861 * the all of the capabilities that the user has. |
919 * the all of the capabilities that the user has. |
862 * |
920 * |
863 * @since 2.0.0 |
921 * @since 2.0.0 |
864 * @access public |
922 * @access public |
865 */ |
923 */ |
866 function update_user_level_from_caps() { |
924 public function update_user_level_from_caps() { |
867 global $wpdb; |
925 global $wpdb; |
868 $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); |
926 $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); |
869 update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); |
927 update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); |
870 } |
928 } |
871 |
929 |
876 * @access public |
934 * @access public |
877 * |
935 * |
878 * @param string $cap Capability name. |
936 * @param string $cap Capability name. |
879 * @param bool $grant Whether to grant capability to user. |
937 * @param bool $grant Whether to grant capability to user. |
880 */ |
938 */ |
881 function add_cap( $cap, $grant = true ) { |
939 public function add_cap( $cap, $grant = true ) { |
882 $this->caps[$cap] = $grant; |
940 $this->caps[$cap] = $grant; |
883 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
941 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
942 $this->get_role_caps(); |
|
943 $this->update_user_level_from_caps(); |
884 } |
944 } |
885 |
945 |
886 /** |
946 /** |
887 * Remove capability from user. |
947 * Remove capability from user. |
888 * |
948 * |
889 * @since 2.0.0 |
949 * @since 2.0.0 |
890 * @access public |
950 * @access public |
891 * |
951 * |
892 * @param string $cap Capability name. |
952 * @param string $cap Capability name. |
893 */ |
953 */ |
894 function remove_cap( $cap ) { |
954 public function remove_cap( $cap ) { |
895 if ( ! isset( $this->caps[$cap] ) ) |
955 if ( ! isset( $this->caps[ $cap ] ) ) { |
896 return; |
956 return; |
897 unset( $this->caps[$cap] ); |
957 } |
|
958 unset( $this->caps[ $cap ] ); |
898 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
959 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
960 $this->get_role_caps(); |
|
961 $this->update_user_level_from_caps(); |
899 } |
962 } |
900 |
963 |
901 /** |
964 /** |
902 * Remove all of the capabilities of the user. |
965 * Remove all of the capabilities of the user. |
903 * |
966 * |
904 * @since 2.1.0 |
967 * @since 2.1.0 |
905 * @access public |
968 * @access public |
906 */ |
969 */ |
907 function remove_all_caps() { |
970 public function remove_all_caps() { |
908 global $wpdb; |
971 global $wpdb; |
909 $this->caps = array(); |
972 $this->caps = array(); |
910 delete_user_meta( $this->ID, $this->cap_key ); |
973 delete_user_meta( $this->ID, $this->cap_key ); |
911 delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); |
974 delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); |
912 $this->get_role_caps(); |
975 $this->get_role_caps(); |
923 * @access public |
986 * @access public |
924 * |
987 * |
925 * @param string|int $cap Capability or role name to search. |
988 * @param string|int $cap Capability or role name to search. |
926 * @return bool True, if user has capability; false, if user does not have capability. |
989 * @return bool True, if user has capability; false, if user does not have capability. |
927 */ |
990 */ |
928 function has_cap( $cap ) { |
991 public function has_cap( $cap ) { |
929 if ( is_numeric( $cap ) ) { |
992 if ( is_numeric( $cap ) ) { |
930 _deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); |
993 _deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); |
931 $cap = $this->translate_level_to_cap( $cap ); |
994 $cap = $this->translate_level_to_cap( $cap ); |
932 } |
995 } |
933 |
996 |
940 if ( in_array('do_not_allow', $caps) ) |
1003 if ( in_array('do_not_allow', $caps) ) |
941 return false; |
1004 return false; |
942 return true; |
1005 return true; |
943 } |
1006 } |
944 |
1007 |
|
1008 /** |
|
1009 * Dynamically filter a user's capabilities. |
|
1010 * |
|
1011 * @since 2.0.0 |
|
1012 * @since 3.7.0 Added the user object. |
|
1013 * |
|
1014 * @param array $allcaps An array of all the user's capabilities. |
|
1015 * @param array $caps Actual capabilities for meta capability. |
|
1016 * @param array $args Optional parameters passed to has_cap(), typically object ID. |
|
1017 * @param WP_User $user The user object. |
|
1018 */ |
945 // Must have ALL requested caps |
1019 // Must have ALL requested caps |
946 $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); |
1020 $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); |
947 $capabilities['exist'] = true; // Everyone is allowed to exist |
1021 $capabilities['exist'] = true; // Everyone is allowed to exist |
948 foreach ( (array) $caps as $cap ) { |
1022 foreach ( (array) $caps as $cap ) { |
949 if ( empty( $capabilities[ $cap ] ) ) |
1023 if ( empty( $capabilities[ $cap ] ) ) |
962 * @access public |
1036 * @access public |
963 * |
1037 * |
964 * @param int $level Level number, 1 to 10. |
1038 * @param int $level Level number, 1 to 10. |
965 * @return string |
1039 * @return string |
966 */ |
1040 */ |
967 function translate_level_to_cap( $level ) { |
1041 public function translate_level_to_cap( $level ) { |
968 return 'level_' . $level; |
1042 return 'level_' . $level; |
969 } |
1043 } |
970 |
1044 |
971 /** |
1045 /** |
972 * Set the blog to operate on. Defaults to the current blog. |
1046 * Set the blog to operate on. Defaults to the current blog. |
973 * |
1047 * |
974 * @since 3.0.0 |
1048 * @since 3.0.0 |
975 * |
1049 * |
976 * @param int $blog_id Optional Blog ID, defaults to current blog. |
1050 * @param int $blog_id Optional Blog ID, defaults to current blog. |
977 */ |
1051 */ |
978 function for_blog( $blog_id = '' ) { |
1052 public function for_blog( $blog_id = '' ) { |
979 global $wpdb; |
1053 global $wpdb; |
980 if ( ! empty( $blog_id ) ) |
1054 if ( ! empty( $blog_id ) ) |
981 $cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; |
1055 $cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; |
982 else |
1056 else |
983 $cap_key = ''; |
1057 $cap_key = ''; |
1038 if ( 'delete_post' == $cap ) |
1112 if ( 'delete_post' == $cap ) |
1039 $cap = $post_type->cap->$cap; |
1113 $cap = $post_type->cap->$cap; |
1040 break; |
1114 break; |
1041 } |
1115 } |
1042 |
1116 |
1043 $post_author_id = $post->post_author; |
1117 // If the post author is set and the user is the author... |
1044 |
1118 if ( $post->post_author && $user_id == $post->post_author ) { |
1045 // If no author set yet, default to current user for cap checks. |
|
1046 if ( ! $post_author_id ) |
|
1047 $post_author_id = $user_id; |
|
1048 |
|
1049 // If the user is the author... |
|
1050 if ( $user_id == $post_author_id ) { |
|
1051 // If the post is published... |
1119 // If the post is published... |
1052 if ( 'publish' == $post->post_status ) { |
1120 if ( 'publish' == $post->post_status ) { |
1053 $caps[] = $post_type->cap->delete_published_posts; |
1121 $caps[] = $post_type->cap->delete_published_posts; |
1054 } elseif ( 'trash' == $post->post_status ) { |
1122 } elseif ( 'trash' == $post->post_status ) { |
1055 if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) |
1123 if ( 'publish' == get_post_meta( $post->ID, '_wp_trash_meta_status', true ) ) { |
1056 $caps[] = $post_type->cap->delete_published_posts; |
1124 $caps[] = $post_type->cap->delete_published_posts; |
|
1125 } |
1057 } else { |
1126 } else { |
1058 // If the post is draft... |
1127 // If the post is draft... |
1059 $caps[] = $post_type->cap->delete_posts; |
1128 $caps[] = $post_type->cap->delete_posts; |
1060 } |
1129 } |
1061 } else { |
1130 } else { |
1062 // The user is trying to edit someone else's post. |
1131 // The user is trying to edit someone else's post. |
1063 $caps[] = $post_type->cap->delete_others_posts; |
1132 $caps[] = $post_type->cap->delete_others_posts; |
1064 // The post is published, extra cap required. |
1133 // The post is published, extra cap required. |
1065 if ( 'publish' == $post->post_status ) |
1134 if ( 'publish' == $post->post_status ) { |
1066 $caps[] = $post_type->cap->delete_published_posts; |
1135 $caps[] = $post_type->cap->delete_published_posts; |
1067 elseif ( 'private' == $post->post_status ) |
1136 } elseif ( 'private' == $post->post_status ) { |
1068 $caps[] = $post_type->cap->delete_private_posts; |
1137 $caps[] = $post_type->cap->delete_private_posts; |
|
1138 } |
1069 } |
1139 } |
1070 break; |
1140 break; |
1071 // edit_post breaks down to edit_posts, edit_published_posts, or |
1141 // edit_post breaks down to edit_posts, edit_published_posts, or |
1072 // edit_others_posts |
1142 // edit_others_posts |
1073 case 'edit_post': |
1143 case 'edit_post': |
1088 if ( 'edit_post' == $cap ) |
1158 if ( 'edit_post' == $cap ) |
1089 $cap = $post_type->cap->$cap; |
1159 $cap = $post_type->cap->$cap; |
1090 break; |
1160 break; |
1091 } |
1161 } |
1092 |
1162 |
1093 $post_author_id = $post->post_author; |
1163 // If the post author is set and the user is the author... |
1094 |
1164 if ( $post->post_author && $user_id == $post->post_author ) { |
1095 // If no author set yet, default to current user for cap checks. |
|
1096 if ( ! $post_author_id ) |
|
1097 $post_author_id = $user_id; |
|
1098 |
|
1099 // If the user is the author... |
|
1100 if ( $user_id == $post_author_id ) { |
|
1101 // If the post is published... |
1165 // If the post is published... |
1102 if ( 'publish' == $post->post_status ) { |
1166 if ( 'publish' == $post->post_status ) { |
1103 $caps[] = $post_type->cap->edit_published_posts; |
1167 $caps[] = $post_type->cap->edit_published_posts; |
1104 } elseif ( 'trash' == $post->post_status ) { |
1168 } elseif ( 'trash' == $post->post_status ) { |
1105 if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) |
1169 if ( 'publish' == get_post_meta( $post->ID, '_wp_trash_meta_status', true ) ) { |
1106 $caps[] = $post_type->cap->edit_published_posts; |
1170 $caps[] = $post_type->cap->edit_published_posts; |
|
1171 } |
1107 } else { |
1172 } else { |
1108 // If the post is draft... |
1173 // If the post is draft... |
1109 $caps[] = $post_type->cap->edit_posts; |
1174 $caps[] = $post_type->cap->edit_posts; |
1110 } |
1175 } |
1111 } else { |
1176 } else { |
1112 // The user is trying to edit someone else's post. |
1177 // The user is trying to edit someone else's post. |
1113 $caps[] = $post_type->cap->edit_others_posts; |
1178 $caps[] = $post_type->cap->edit_others_posts; |
1114 // The post is published, extra cap required. |
1179 // The post is published, extra cap required. |
1115 if ( 'publish' == $post->post_status ) |
1180 if ( 'publish' == $post->post_status ) { |
1116 $caps[] = $post_type->cap->edit_published_posts; |
1181 $caps[] = $post_type->cap->edit_published_posts; |
1117 elseif ( 'private' == $post->post_status ) |
1182 } elseif ( 'private' == $post->post_status ) { |
1118 $caps[] = $post_type->cap->edit_private_posts; |
1183 $caps[] = $post_type->cap->edit_private_posts; |
|
1184 } |
1119 } |
1185 } |
1120 break; |
1186 break; |
1121 case 'read_post': |
1187 case 'read_post': |
1122 case 'read_page': |
1188 case 'read_page': |
1123 $post = get_post( $args[0] ); |
1189 $post = get_post( $args[0] ); |
1140 if ( $status_obj->public ) { |
1206 if ( $status_obj->public ) { |
1141 $caps[] = $post_type->cap->read; |
1207 $caps[] = $post_type->cap->read; |
1142 break; |
1208 break; |
1143 } |
1209 } |
1144 |
1210 |
1145 $post_author_id = $post->post_author; |
1211 if ( $post->post_author && $user_id == $post->post_author ) { |
1146 |
|
1147 // If no author set yet, default to current user for cap checks. |
|
1148 if ( ! $post_author_id ) |
|
1149 $post_author_id = $user_id; |
|
1150 |
|
1151 if ( $user_id == $post_author_id ) |
|
1152 $caps[] = $post_type->cap->read; |
1212 $caps[] = $post_type->cap->read; |
1153 elseif ( $status_obj->private ) |
1213 } elseif ( $status_obj->private ) { |
1154 $caps[] = $post_type->cap->read_private_posts; |
1214 $caps[] = $post_type->cap->read_private_posts; |
1155 else |
1215 } else { |
1156 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
1216 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
|
1217 } |
1157 break; |
1218 break; |
1158 case 'publish_post': |
1219 case 'publish_post': |
1159 $post = get_post( $args[0] ); |
1220 $post = get_post( $args[0] ); |
1160 $post_type = get_post_type_object( $post->post_type ); |
1221 $post_type = get_post_type_object( $post->post_type ); |
1161 |
1222 |
1168 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
1229 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
1169 |
1230 |
1170 $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false; |
1231 $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false; |
1171 |
1232 |
1172 if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) { |
1233 if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) { |
|
1234 /** |
|
1235 * Filter whether the user is allowed to add post meta to a post. |
|
1236 * |
|
1237 * The dynamic portion of the hook name, `$meta_key`, refers to the |
|
1238 * meta key passed to {@see map_meta_cap()}. |
|
1239 * |
|
1240 * @since 3.3.0 |
|
1241 * |
|
1242 * @param bool $allowed Whether the user can add the post meta. Default false. |
|
1243 * @param string $meta_key The meta key. |
|
1244 * @param int $post_id Post ID. |
|
1245 * @param int $user_id User ID. |
|
1246 * @param string $cap Capability name. |
|
1247 * @param array $caps User capabilities. |
|
1248 */ |
1173 $allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps ); |
1249 $allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps ); |
1174 if ( ! $allowed ) |
1250 if ( ! $allowed ) |
1175 $caps[] = $cap; |
1251 $caps[] = $cap; |
1176 } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) { |
1252 } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) { |
1177 $caps[] = $cap; |
1253 $caps[] = $cap; |
1213 $caps[] = $cap; |
1289 $caps[] = $cap; |
1214 break; |
1290 break; |
1215 case 'update_plugins': |
1291 case 'update_plugins': |
1216 case 'delete_plugins': |
1292 case 'delete_plugins': |
1217 case 'install_plugins': |
1293 case 'install_plugins': |
|
1294 case 'upload_plugins': |
1218 case 'update_themes': |
1295 case 'update_themes': |
1219 case 'delete_themes': |
1296 case 'delete_themes': |
1220 case 'install_themes': |
1297 case 'install_themes': |
|
1298 case 'upload_themes': |
1221 case 'update_core': |
1299 case 'update_core': |
1222 // Disallow anything that creates, deletes, or updates core, plugin, or theme files. |
1300 // Disallow anything that creates, deletes, or updates core, plugin, or theme files. |
1223 // Files in uploads are excepted. |
1301 // Files in uploads are excepted. |
1224 if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) |
1302 if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) { |
1225 $caps[] = 'do_not_allow'; |
1303 $caps[] = 'do_not_allow'; |
1226 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) |
1304 } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) { |
1227 $caps[] = 'do_not_allow'; |
1305 $caps[] = 'do_not_allow'; |
1228 else |
1306 } elseif ( 'upload_themes' === $cap ) { |
|
1307 $caps[] = 'install_themes'; |
|
1308 } elseif ( 'upload_plugins' === $cap ) { |
|
1309 $caps[] = 'install_plugins'; |
|
1310 } else { |
1229 $caps[] = $cap; |
1311 $caps[] = $cap; |
|
1312 } |
1230 break; |
1313 break; |
1231 case 'activate_plugins': |
1314 case 'activate_plugins': |
1232 $caps[] = $cap; |
1315 $caps[] = $cap; |
1233 if ( is_multisite() ) { |
1316 if ( is_multisite() ) { |
1234 // update_, install_, and delete_ are handled above with is_super_admin(). |
1317 // update_, install_, and delete_ are handled above with is_super_admin(). |
1257 if ( get_option( 'link_manager_enabled' ) ) |
1340 if ( get_option( 'link_manager_enabled' ) ) |
1258 $caps[] = $cap; |
1341 $caps[] = $cap; |
1259 else |
1342 else |
1260 $caps[] = 'do_not_allow'; |
1343 $caps[] = 'do_not_allow'; |
1261 break; |
1344 break; |
|
1345 case 'customize' : |
|
1346 $caps[] = 'edit_theme_options'; |
|
1347 break; |
|
1348 case 'delete_site': |
|
1349 $caps[] = 'manage_options'; |
|
1350 break; |
1262 default: |
1351 default: |
1263 // Handle meta capabilities for custom post types. |
1352 // Handle meta capabilities for custom post types. |
1264 $post_type_meta_caps = _post_type_meta_capabilities(); |
1353 $post_type_meta_caps = _post_type_meta_capabilities(); |
1265 if ( isset( $post_type_meta_caps[ $cap ] ) ) { |
1354 if ( isset( $post_type_meta_caps[ $cap ] ) ) { |
1266 $args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args ); |
1355 $args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args ); |
1269 |
1358 |
1270 // If no meta caps match, return the original cap. |
1359 // If no meta caps match, return the original cap. |
1271 $caps[] = $cap; |
1360 $caps[] = $cap; |
1272 } |
1361 } |
1273 |
1362 |
1274 return apply_filters('map_meta_cap', $caps, $cap, $user_id, $args); |
1363 /** |
|
1364 * Filter a user's capabilities depending on specific context and/or privilege. |
|
1365 * |
|
1366 * @since 2.8.0 |
|
1367 * |
|
1368 * @param array $caps Returns the user's actual capabilities. |
|
1369 * @param string $cap Capability name. |
|
1370 * @param int $user_id The user ID. |
|
1371 * @param array $args Adds the context to the cap. Typically the object ID. |
|
1372 */ |
|
1373 return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); |
1275 } |
1374 } |
1276 |
1375 |
1277 /** |
1376 /** |
1278 * Whether current user has capability or role. |
1377 * Whether current user has capability or role. |
1279 * |
1378 * |
1302 * @param int $blog_id Blog ID |
1401 * @param int $blog_id Blog ID |
1303 * @param string $capability Capability or role name. |
1402 * @param string $capability Capability or role name. |
1304 * @return bool |
1403 * @return bool |
1305 */ |
1404 */ |
1306 function current_user_can_for_blog( $blog_id, $capability ) { |
1405 function current_user_can_for_blog( $blog_id, $capability ) { |
1307 if ( is_multisite() ) |
1406 $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; |
1308 switch_to_blog( $blog_id ); |
|
1309 |
1407 |
1310 $current_user = wp_get_current_user(); |
1408 $current_user = wp_get_current_user(); |
1311 |
1409 |
1312 if ( empty( $current_user ) ) |
1410 if ( empty( $current_user ) ) { |
|
1411 if ( $switched ) { |
|
1412 restore_current_blog(); |
|
1413 } |
1313 return false; |
1414 return false; |
|
1415 } |
1314 |
1416 |
1315 $args = array_slice( func_get_args(), 2 ); |
1417 $args = array_slice( func_get_args(), 2 ); |
1316 $args = array_merge( array( $capability ), $args ); |
1418 $args = array_merge( array( $capability ), $args ); |
1317 |
1419 |
1318 $can = call_user_func_array( array( $current_user, 'has_cap' ), $args ); |
1420 $can = call_user_func_array( array( $current_user, 'has_cap' ), $args ); |
1319 |
1421 |
1320 if ( is_multisite() ) |
1422 if ( $switched ) { |
1321 restore_current_blog(); |
1423 restore_current_blog(); |
|
1424 } |
1322 |
1425 |
1323 return $can; |
1426 return $can; |
1324 } |
1427 } |
1325 |
1428 |
1326 /** |
1429 /** |