WordPress 4.5
[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 backwards 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 wpdb  $wpdb          WordPress database abstraction object.
109          * @global array $wp_user_roles Used to set the 'roles' property value.
110          */
111         protected function _init() {
112                 global $wpdb, $wp_user_roles;
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         /**
133          * Reinitialize the object
134          *
135          * Recreates the role objects. This is typically called only by switch_to_blog()
136          * after switching wpdb to a new site ID.
137          *
138          * @since 3.5.0
139          * @access public
140          *
141          * @global wpdb $wpdb WordPress database abstraction object.
142          */
143         public function reinit() {
144                 // There is no need to reinit if using the wp_user_roles global.
145                 if ( ! $this->use_db )
146                         return;
147
148                 global $wpdb;
149
150                 // Duplicated from _init() to avoid an extra function call.
151                 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles';
152                 $this->roles = get_option( $this->role_key );
153                 if ( empty( $this->roles ) )
154                         return;
155
156                 $this->role_objects = array();
157                 $this->role_names =  array();
158                 foreach ( array_keys( $this->roles ) as $role ) {
159                         $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
160                         $this->role_names[$role] = $this->roles[$role]['name'];
161                 }
162         }
163
164         /**
165          * Add role name with capabilities to list.
166          *
167          * Updates the list of roles, if the role doesn't already exist.
168          *
169          * The capabilities are defined in the following format `array( 'read' => true );`
170          * To explicitly deny a role a capability you set the value for that capability to false.
171          *
172          * @since 2.0.0
173          * @access public
174          *
175          * @param string $role Role name.
176          * @param string $display_name Role display name.
177          * @param array $capabilities List of role capabilities in the above format.
178          * @return WP_Role|void WP_Role object, if role is added.
179          */
180         public function add_role( $role, $display_name, $capabilities = array() ) {
181                 if ( empty( $role ) || isset( $this->roles[ $role ] ) ) {
182                         return;
183                 }
184
185                 $this->roles[$role] = array(
186                         'name' => $display_name,
187                         'capabilities' => $capabilities
188                         );
189                 if ( $this->use_db )
190                         update_option( $this->role_key, $this->roles );
191                 $this->role_objects[$role] = new WP_Role( $role, $capabilities );
192                 $this->role_names[$role] = $display_name;
193                 return $this->role_objects[$role];
194         }
195
196         /**
197          * Remove role by name.
198          *
199          * @since 2.0.0
200          * @access public
201          *
202          * @param string $role Role name.
203          */
204         public function remove_role( $role ) {
205                 if ( ! isset( $this->role_objects[$role] ) )
206                         return;
207
208                 unset( $this->role_objects[$role] );
209                 unset( $this->role_names[$role] );
210                 unset( $this->roles[$role] );
211
212                 if ( $this->use_db )
213                         update_option( $this->role_key, $this->roles );
214
215                 if ( get_option( 'default_role' ) == $role )
216                         update_option( 'default_role', 'subscriber' );
217         }
218
219         /**
220          * Add capability to role.
221          *
222          * @since 2.0.0
223          * @access public
224          *
225          * @param string $role Role name.
226          * @param string $cap Capability name.
227          * @param bool $grant Optional, default is true. Whether role is capable of performing capability.
228          */
229         public function add_cap( $role, $cap, $grant = true ) {
230                 if ( ! isset( $this->roles[$role] ) )
231                         return;
232
233                 $this->roles[$role]['capabilities'][$cap] = $grant;
234                 if ( $this->use_db )
235                         update_option( $this->role_key, $this->roles );
236         }
237
238         /**
239          * Remove capability from role.
240          *
241          * @since 2.0.0
242          * @access public
243          *
244          * @param string $role Role name.
245          * @param string $cap Capability name.
246          */
247         public function remove_cap( $role, $cap ) {
248                 if ( ! isset( $this->roles[$role] ) )
249                         return;
250
251                 unset( $this->roles[$role]['capabilities'][$cap] );
252                 if ( $this->use_db )
253                         update_option( $this->role_key, $this->roles );
254         }
255
256         /**
257          * Retrieve role object by name.
258          *
259          * @since 2.0.0
260          * @access public
261          *
262          * @param string $role Role name.
263          * @return WP_Role|null WP_Role object if found, null if the role does not exist.
264          */
265         public function get_role( $role ) {
266                 if ( isset( $this->role_objects[$role] ) )
267                         return $this->role_objects[$role];
268                 else
269                         return null;
270         }
271
272         /**
273          * Retrieve list of role names.
274          *
275          * @since 2.0.0
276          * @access public
277          *
278          * @return array List of role names.
279          */
280         public function get_names() {
281                 return $this->role_names;
282         }
283
284         /**
285          * Whether role name is currently in the list of available roles.
286          *
287          * @since 2.0.0
288          * @access public
289          *
290          * @param string $role Role name to look up.
291          * @return bool
292          */
293         public function is_role( $role ) {
294                 return isset( $this->role_names[$role] );
295         }
296 }