WordPress 4.7
[autoinstalls/wordpress.git] / wp-includes / class-wp-roles.php
1 <?php
2 /**
3  * User API: WP_Roles class
4  *
5  * @package WordPress
6  * @subpackage Users
7  * @since 4.4.0
8  */
9
10 /**
11  * Core class used to implement a user roles API.
12  *
13  * The role option is simple, the structure is organized by role name that store
14  * the name in value of the 'name' key. The capabilities are stored as an array
15  * in the value of the 'capability' key.
16  *
17  *     array (
18  *              'rolename' => array (
19  *                      'name' => 'rolename',
20  *                      'capabilities' => array()
21  *              )
22  *     )
23  *
24  * @since 2.0.0
25  */
26 class WP_Roles {
27         /**
28          * List of roles and capabilities.
29          *
30          * @since 2.0.0
31          * @access public
32          * @var array
33          */
34         public $roles;
35
36         /**
37          * List of the role objects.
38          *
39          * @since 2.0.0
40          * @access public
41          * @var array
42          */
43         public $role_objects = array();
44
45         /**
46          * List of role names.
47          *
48          * @since 2.0.0
49          * @access public
50          * @var array
51          */
52         public $role_names = array();
53
54         /**
55          * Option name for storing role list.
56          *
57          * @since 2.0.0
58          * @access public
59          * @var string
60          */
61         public $role_key;
62
63         /**
64          * Whether to use the database for retrieval and storage.
65          *
66          * @since 2.1.0
67          * @access public
68          * @var bool
69          */
70         public $use_db = true;
71
72         /**
73          * Constructor
74          *
75          * @since 2.0.0
76          */
77         public function __construct() {
78                 $this->_init();
79         }
80
81         /**
82          * Make private/protected methods readable for backward compatibility.
83          *
84          * @since 4.0.0
85          * @access public
86          *
87          * @param callable $name      Method to call.
88          * @param array    $arguments Arguments to pass when calling.
89          * @return mixed|false Return value of the callback, false otherwise.
90          */
91         public function __call( $name, $arguments ) {
92                 if ( '_init' === $name ) {
93                         return call_user_func_array( array( $this, $name ), $arguments );
94                 }
95                 return false;
96         }
97
98         /**
99          * Set up the object properties.
100          *
101          * The role key is set to the current prefix for the $wpdb object with
102          * 'user_roles' appended. If the $wp_user_roles global is set, then it will
103          * be used and the role option will not be updated or used.
104          *
105          * @since 2.1.0
106          * @access protected
107          *
108          * @global array $wp_user_roles Used to set the 'roles' property value.
109          */
110         protected function _init() {
111                 global $wp_user_roles, $wpdb;
112
113                 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles';
114                 if ( ! empty( $wp_user_roles ) ) {
115                         $this->roles = $wp_user_roles;
116                         $this->use_db = false;
117                 } else {
118                         $this->roles = get_option( $this->role_key );
119                 }
120
121                 if ( empty( $this->roles ) )
122                         return;
123
124                 $this->role_objects = array();
125                 $this->role_names =  array();
126                 foreach ( array_keys( $this->roles ) as $role ) {
127                         $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
128                         $this->role_names[$role] = $this->roles[$role]['name'];
129                 }
130
131                 /**
132                  * After the roles have been initialized, allow plugins to add their own roles.
133                  *
134                  * @since 4.7.0
135                  *
136                  * @param WP_Roles $this A reference to the WP_Roles object.
137                  */
138                 do_action( 'wp_roles_init', $this );
139         }
140
141         /**
142          * Reinitialize the object
143          *
144          * Recreates the role objects. This is typically called only by switch_to_blog()
145          * after switching wpdb to a new site ID.
146          *
147          * @since 3.5.0
148          * @deprecated 4.7.0 Use new WP_Roles()
149          * @access public
150          */
151         public function reinit() {
152                 _deprecated_function( __METHOD__, '4.7.0', 'new WP_Roles()' );
153                 $this->_init();
154         }
155
156         /**
157          * Add role name with capabilities to list.
158          *
159          * Updates the list of roles, if the role doesn't already exist.
160          *
161          * The capabilities are defined in the following format `array( 'read' => true );`
162          * To explicitly deny a role a capability you set the value for that capability to false.
163          *
164          * @since 2.0.0
165          * @access public
166          *
167          * @param string $role Role name.
168          * @param string $display_name Role display name.
169          * @param array $capabilities List of role capabilities in the above format.
170          * @return WP_Role|void WP_Role object, if role is added.
171          */
172         public function add_role( $role, $display_name, $capabilities = array() ) {
173                 if ( empty( $role ) || isset( $this->roles[ $role ] ) ) {
174                         return;
175                 }
176
177                 $this->roles[$role] = array(
178                         'name' => $display_name,
179                         'capabilities' => $capabilities
180                         );
181                 if ( $this->use_db )
182                         update_option( $this->role_key, $this->roles );
183                 $this->role_objects[$role] = new WP_Role( $role, $capabilities );
184                 $this->role_names[$role] = $display_name;
185                 return $this->role_objects[$role];
186         }
187
188         /**
189          * Remove role by name.
190          *
191          * @since 2.0.0
192          * @access public
193          *
194          * @param string $role Role name.
195          */
196         public function remove_role( $role ) {
197                 if ( ! isset( $this->role_objects[$role] ) )
198                         return;
199
200                 unset( $this->role_objects[$role] );
201                 unset( $this->role_names[$role] );
202                 unset( $this->roles[$role] );
203
204                 if ( $this->use_db )
205                         update_option( $this->role_key, $this->roles );
206
207                 if ( get_option( 'default_role' ) == $role )
208                         update_option( 'default_role', 'subscriber' );
209         }
210
211         /**
212          * Add capability to role.
213          *
214          * @since 2.0.0
215          * @access public
216          *
217          * @param string $role Role name.
218          * @param string $cap Capability name.
219          * @param bool $grant Optional, default is true. Whether role is capable of performing capability.
220          */
221         public function add_cap( $role, $cap, $grant = true ) {
222                 if ( ! isset( $this->roles[$role] ) )
223                         return;
224
225                 $this->roles[$role]['capabilities'][$cap] = $grant;
226                 if ( $this->use_db )
227                         update_option( $this->role_key, $this->roles );
228         }
229
230         /**
231          * Remove capability from role.
232          *
233          * @since 2.0.0
234          * @access public
235          *
236          * @param string $role Role name.
237          * @param string $cap Capability name.
238          */
239         public function remove_cap( $role, $cap ) {
240                 if ( ! isset( $this->roles[$role] ) )
241                         return;
242
243                 unset( $this->roles[$role]['capabilities'][$cap] );
244                 if ( $this->use_db )
245                         update_option( $this->role_key, $this->roles );
246         }
247
248         /**
249          * Retrieve role object by name.
250          *
251          * @since 2.0.0
252          * @access public
253          *
254          * @param string $role Role name.
255          * @return WP_Role|null WP_Role object if found, null if the role does not exist.
256          */
257         public function get_role( $role ) {
258                 if ( isset( $this->role_objects[$role] ) )
259                         return $this->role_objects[$role];
260                 else
261                         return null;
262         }
263
264         /**
265          * Retrieve list of role names.
266          *
267          * @since 2.0.0
268          * @access public
269          *
270          * @return array List of role names.
271          */
272         public function get_names() {
273                 return $this->role_names;
274         }
275
276         /**
277          * Whether role name is currently in the list of available roles.
278          *
279          * @since 2.0.0
280          * @access public
281          *
282          * @param string $role Role name to look up.
283          * @return bool
284          */
285         public function is_role( $role ) {
286                 return isset( $this->role_names[$role] );
287         }
288 }