|
1 <?php |
|
2 /** |
|
3 * User API: WP_User class |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage Users |
|
7 * @since 4.4.0 |
|
8 */ |
|
9 |
|
10 /** |
|
11 * Core class used to implement the WP_User object. |
|
12 * |
|
13 * @since 2.0.0 |
|
14 * |
|
15 * @property string $nickname |
|
16 * @property string $description |
|
17 * @property string $user_description |
|
18 * @property string $first_name |
|
19 * @property string $user_firstname |
|
20 * @property string $last_name |
|
21 * @property string $user_lastname |
|
22 * @property string $user_login |
|
23 * @property string $user_pass |
|
24 * @property string $user_nicename |
|
25 * @property string $user_email |
|
26 * @property string $user_url |
|
27 * @property string $user_registered |
|
28 * @property string $user_activation_key |
|
29 * @property string $user_status |
|
30 * @property int $user_level |
|
31 * @property string $display_name |
|
32 * @property string $spam |
|
33 * @property string $deleted |
|
34 * @property string $locale |
|
35 * @property string $rich_editing |
|
36 * @property string $syntax_highlighting |
|
37 */ |
|
38 class WP_User { |
|
39 /** |
|
40 * User data container. |
|
41 * |
|
42 * @since 2.0.0 |
|
43 * @var object |
|
44 */ |
|
45 public $data; |
|
46 |
|
47 /** |
|
48 * The user's ID. |
|
49 * |
|
50 * @since 2.1.0 |
|
51 * @var int |
|
52 */ |
|
53 public $ID = 0; |
|
54 |
|
55 /** |
|
56 * The individual capabilities the user has been given. |
|
57 * |
|
58 * @since 2.0.0 |
|
59 * @var array |
|
60 */ |
|
61 public $caps = array(); |
|
62 |
|
63 /** |
|
64 * User metadata option name. |
|
65 * |
|
66 * @since 2.0.0 |
|
67 * @var string |
|
68 */ |
|
69 public $cap_key; |
|
70 |
|
71 /** |
|
72 * The roles the user is part of. |
|
73 * |
|
74 * @since 2.0.0 |
|
75 * @var array |
|
76 */ |
|
77 public $roles = array(); |
|
78 |
|
79 /** |
|
80 * All capabilities the user has, including individual and role based. |
|
81 * |
|
82 * @since 2.0.0 |
|
83 * @var array |
|
84 */ |
|
85 public $allcaps = array(); |
|
86 |
|
87 /** |
|
88 * The filter context applied to user data fields. |
|
89 * |
|
90 * @since 2.9.0 |
|
91 * @var string |
|
92 */ |
|
93 public $filter = null; |
|
94 |
|
95 /** |
|
96 * The site ID the capabilities of this user are initialized for. |
|
97 * |
|
98 * @since 4.9.0 |
|
99 * @var int |
|
100 */ |
|
101 private $site_id = 0; |
|
102 |
|
103 /** |
|
104 * @static |
|
105 * @since 3.3.0 |
|
106 * @var array |
|
107 */ |
|
108 private static $back_compat_keys; |
|
109 |
|
110 /** |
|
111 * Constructor. |
|
112 * |
|
113 * Retrieves the userdata and passes it to WP_User::init(). |
|
114 * |
|
115 * @since 2.0.0 |
|
116 * |
|
117 * @global wpdb $wpdb WordPress database abstraction object. |
|
118 * |
|
119 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB. |
|
120 * @param string $name Optional. User's username |
|
121 * @param int $site_id Optional Site ID, defaults to current site. |
|
122 */ |
|
123 public function __construct( $id = 0, $name = '', $site_id = '' ) { |
|
124 if ( ! isset( self::$back_compat_keys ) ) { |
|
125 $prefix = $GLOBALS['wpdb']->prefix; |
|
126 self::$back_compat_keys = array( |
|
127 'user_firstname' => 'first_name', |
|
128 'user_lastname' => 'last_name', |
|
129 'user_description' => 'description', |
|
130 'user_level' => $prefix . 'user_level', |
|
131 $prefix . 'usersettings' => $prefix . 'user-settings', |
|
132 $prefix . 'usersettingstime' => $prefix . 'user-settings-time', |
|
133 ); |
|
134 } |
|
135 |
|
136 if ( $id instanceof WP_User ) { |
|
137 $this->init( $id->data, $site_id ); |
|
138 return; |
|
139 } elseif ( is_object( $id ) ) { |
|
140 $this->init( $id, $site_id ); |
|
141 return; |
|
142 } |
|
143 |
|
144 if ( ! empty( $id ) && ! is_numeric( $id ) ) { |
|
145 $name = $id; |
|
146 $id = 0; |
|
147 } |
|
148 |
|
149 if ( $id ) { |
|
150 $data = self::get_data_by( 'id', $id ); |
|
151 } else { |
|
152 $data = self::get_data_by( 'login', $name ); |
|
153 } |
|
154 |
|
155 if ( $data ) { |
|
156 $this->init( $data, $site_id ); |
|
157 } else { |
|
158 $this->data = new stdClass; |
|
159 } |
|
160 } |
|
161 |
|
162 /** |
|
163 * Sets up object properties, including capabilities. |
|
164 * |
|
165 * @since 3.3.0 |
|
166 * |
|
167 * @param object $data User DB row object. |
|
168 * @param int $site_id Optional. The site ID to initialize for. |
|
169 */ |
|
170 public function init( $data, $site_id = '' ) { |
|
171 $this->data = $data; |
|
172 $this->ID = (int) $data->ID; |
|
173 |
|
174 $this->for_site( $site_id ); |
|
175 } |
|
176 |
|
177 /** |
|
178 * Return only the main user fields |
|
179 * |
|
180 * @since 3.3.0 |
|
181 * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter. |
|
182 * |
|
183 * @static |
|
184 * |
|
185 * @global wpdb $wpdb WordPress database abstraction object. |
|
186 * |
|
187 * @param string $field The field to query against: 'id', 'ID', 'slug', 'email' or 'login'. |
|
188 * @param string|int $value The field value |
|
189 * @return object|false Raw user object |
|
190 */ |
|
191 public static function get_data_by( $field, $value ) { |
|
192 global $wpdb; |
|
193 |
|
194 // 'ID' is an alias of 'id'. |
|
195 if ( 'ID' === $field ) { |
|
196 $field = 'id'; |
|
197 } |
|
198 |
|
199 if ( 'id' == $field ) { |
|
200 // Make sure the value is numeric to avoid casting objects, for example, |
|
201 // to int 1. |
|
202 if ( ! is_numeric( $value ) ) |
|
203 return false; |
|
204 $value = intval( $value ); |
|
205 if ( $value < 1 ) |
|
206 return false; |
|
207 } else { |
|
208 $value = trim( $value ); |
|
209 } |
|
210 |
|
211 if ( !$value ) |
|
212 return false; |
|
213 |
|
214 switch ( $field ) { |
|
215 case 'id': |
|
216 $user_id = $value; |
|
217 $db_field = 'ID'; |
|
218 break; |
|
219 case 'slug': |
|
220 $user_id = wp_cache_get($value, 'userslugs'); |
|
221 $db_field = 'user_nicename'; |
|
222 break; |
|
223 case 'email': |
|
224 $user_id = wp_cache_get($value, 'useremail'); |
|
225 $db_field = 'user_email'; |
|
226 break; |
|
227 case 'login': |
|
228 $value = sanitize_user( $value ); |
|
229 $user_id = wp_cache_get($value, 'userlogins'); |
|
230 $db_field = 'user_login'; |
|
231 break; |
|
232 default: |
|
233 return false; |
|
234 } |
|
235 |
|
236 if ( false !== $user_id ) { |
|
237 if ( $user = wp_cache_get( $user_id, 'users' ) ) |
|
238 return $user; |
|
239 } |
|
240 |
|
241 if ( !$user = $wpdb->get_row( $wpdb->prepare( |
|
242 "SELECT * FROM $wpdb->users WHERE $db_field = %s", $value |
|
243 ) ) ) |
|
244 return false; |
|
245 |
|
246 update_user_caches( $user ); |
|
247 |
|
248 return $user; |
|
249 } |
|
250 |
|
251 /** |
|
252 * Magic method for checking the existence of a certain custom field. |
|
253 * |
|
254 * @since 3.3.0 |
|
255 * |
|
256 * @param string $key User meta key to check if set. |
|
257 * @return bool Whether the given user meta key is set. |
|
258 */ |
|
259 public function __isset( $key ) { |
|
260 if ( 'id' == $key ) { |
|
261 _deprecated_argument( 'WP_User->id', '2.1.0', |
|
262 sprintf( |
|
263 /* translators: %s: WP_User->ID */ |
|
264 __( 'Use %s instead.' ), |
|
265 '<code>WP_User->ID</code>' |
|
266 ) |
|
267 ); |
|
268 $key = 'ID'; |
|
269 } |
|
270 |
|
271 if ( isset( $this->data->$key ) ) |
|
272 return true; |
|
273 |
|
274 if ( isset( self::$back_compat_keys[ $key ] ) ) |
|
275 $key = self::$back_compat_keys[ $key ]; |
|
276 |
|
277 return metadata_exists( 'user', $this->ID, $key ); |
|
278 } |
|
279 |
|
280 /** |
|
281 * Magic method for accessing custom fields. |
|
282 * |
|
283 * @since 3.3.0 |
|
284 * |
|
285 * @param string $key User meta key to retrieve. |
|
286 * @return mixed Value of the given user meta key (if set). If `$key` is 'id', the user ID. |
|
287 */ |
|
288 public function __get( $key ) { |
|
289 if ( 'id' == $key ) { |
|
290 _deprecated_argument( 'WP_User->id', '2.1.0', |
|
291 sprintf( |
|
292 /* translators: %s: WP_User->ID */ |
|
293 __( 'Use %s instead.' ), |
|
294 '<code>WP_User->ID</code>' |
|
295 ) |
|
296 ); |
|
297 return $this->ID; |
|
298 } |
|
299 |
|
300 if ( isset( $this->data->$key ) ) { |
|
301 $value = $this->data->$key; |
|
302 } else { |
|
303 if ( isset( self::$back_compat_keys[ $key ] ) ) |
|
304 $key = self::$back_compat_keys[ $key ]; |
|
305 $value = get_user_meta( $this->ID, $key, true ); |
|
306 } |
|
307 |
|
308 if ( $this->filter ) { |
|
309 $value = sanitize_user_field( $key, $value, $this->ID, $this->filter ); |
|
310 } |
|
311 |
|
312 return $value; |
|
313 } |
|
314 |
|
315 /** |
|
316 * Magic method for setting custom user fields. |
|
317 * |
|
318 * This method does not update custom fields in the database. It only stores |
|
319 * the value on the WP_User instance. |
|
320 * |
|
321 * @since 3.3.0 |
|
322 * |
|
323 * @param string $key User meta key. |
|
324 * @param mixed $value User meta value. |
|
325 */ |
|
326 public function __set( $key, $value ) { |
|
327 if ( 'id' == $key ) { |
|
328 _deprecated_argument( 'WP_User->id', '2.1.0', |
|
329 sprintf( |
|
330 /* translators: %s: WP_User->ID */ |
|
331 __( 'Use %s instead.' ), |
|
332 '<code>WP_User->ID</code>' |
|
333 ) |
|
334 ); |
|
335 $this->ID = $value; |
|
336 return; |
|
337 } |
|
338 |
|
339 $this->data->$key = $value; |
|
340 } |
|
341 |
|
342 /** |
|
343 * Magic method for unsetting a certain custom field. |
|
344 * |
|
345 * @since 4.4.0 |
|
346 * |
|
347 * @param string $key User meta key to unset. |
|
348 */ |
|
349 public function __unset( $key ) { |
|
350 if ( 'id' == $key ) { |
|
351 _deprecated_argument( 'WP_User->id', '2.1.0', |
|
352 sprintf( |
|
353 /* translators: %s: WP_User->ID */ |
|
354 __( 'Use %s instead.' ), |
|
355 '<code>WP_User->ID</code>' |
|
356 ) |
|
357 ); |
|
358 } |
|
359 |
|
360 if ( isset( $this->data->$key ) ) { |
|
361 unset( $this->data->$key ); |
|
362 } |
|
363 |
|
364 if ( isset( self::$back_compat_keys[ $key ] ) ) { |
|
365 unset( self::$back_compat_keys[ $key ] ); |
|
366 } |
|
367 } |
|
368 |
|
369 /** |
|
370 * Determine whether the user exists in the database. |
|
371 * |
|
372 * @since 3.4.0 |
|
373 * |
|
374 * @return bool True if user exists in the database, false if not. |
|
375 */ |
|
376 public function exists() { |
|
377 return ! empty( $this->ID ); |
|
378 } |
|
379 |
|
380 /** |
|
381 * Retrieve the value of a property or meta key. |
|
382 * |
|
383 * Retrieves from the users and usermeta table. |
|
384 * |
|
385 * @since 3.3.0 |
|
386 * |
|
387 * @param string $key Property |
|
388 * @return mixed |
|
389 */ |
|
390 public function get( $key ) { |
|
391 return $this->__get( $key ); |
|
392 } |
|
393 |
|
394 /** |
|
395 * Determine whether a property or meta key is set |
|
396 * |
|
397 * Consults the users and usermeta tables. |
|
398 * |
|
399 * @since 3.3.0 |
|
400 * |
|
401 * @param string $key Property |
|
402 * @return bool |
|
403 */ |
|
404 public function has_prop( $key ) { |
|
405 return $this->__isset( $key ); |
|
406 } |
|
407 |
|
408 /** |
|
409 * Return an array representation. |
|
410 * |
|
411 * @since 3.5.0 |
|
412 * |
|
413 * @return array Array representation. |
|
414 */ |
|
415 public function to_array() { |
|
416 return get_object_vars( $this->data ); |
|
417 } |
|
418 |
|
419 /** |
|
420 * Makes private/protected methods readable for backward compatibility. |
|
421 * |
|
422 * @since 4.3.0 |
|
423 * |
|
424 * @param callable $name Method to call. |
|
425 * @param array $arguments Arguments to pass when calling. |
|
426 * @return mixed|false Return value of the callback, false otherwise. |
|
427 */ |
|
428 public function __call( $name, $arguments ) { |
|
429 if ( '_init_caps' === $name ) { |
|
430 return call_user_func_array( array( $this, $name ), $arguments ); |
|
431 } |
|
432 return false; |
|
433 } |
|
434 |
|
435 /** |
|
436 * Set up capability object properties. |
|
437 * |
|
438 * Will set the value for the 'cap_key' property to current database table |
|
439 * prefix, followed by 'capabilities'. Will then check to see if the |
|
440 * property matching the 'cap_key' exists and is an array. If so, it will be |
|
441 * used. |
|
442 * |
|
443 * @since 2.1.0 |
|
444 * @deprecated 4.9.0 Use WP_User::for_site() |
|
445 * |
|
446 * @global wpdb $wpdb WordPress database abstraction object. |
|
447 * |
|
448 * @param string $cap_key Optional capability key |
|
449 */ |
|
450 protected function _init_caps( $cap_key = '' ) { |
|
451 global $wpdb; |
|
452 |
|
453 _deprecated_function( __METHOD__, '4.9.0', 'WP_User::for_site()' ); |
|
454 |
|
455 if ( empty( $cap_key ) ) { |
|
456 $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities'; |
|
457 } else { |
|
458 $this->cap_key = $cap_key; |
|
459 } |
|
460 |
|
461 $this->caps = $this->get_caps_data(); |
|
462 |
|
463 $this->get_role_caps(); |
|
464 } |
|
465 |
|
466 /** |
|
467 * Retrieve all of the role capabilities and merge with individual capabilities. |
|
468 * |
|
469 * All of the capabilities of the roles the user belongs to are merged with |
|
470 * the users individual roles. This also means that the user can be denied |
|
471 * specific roles that their role might have, but the specific user isn't |
|
472 * granted permission to. |
|
473 * |
|
474 * @since 2.0.0 |
|
475 * |
|
476 * @return array List of all capabilities for the user. |
|
477 */ |
|
478 public function get_role_caps() { |
|
479 $switch_site = false; |
|
480 if ( is_multisite() && $this->site_id != get_current_blog_id() ) { |
|
481 $switch_site = true; |
|
482 |
|
483 switch_to_blog( $this->site_id ); |
|
484 } |
|
485 |
|
486 $wp_roles = wp_roles(); |
|
487 |
|
488 //Filter out caps that are not role names and assign to $this->roles |
|
489 if ( is_array( $this->caps ) ) |
|
490 $this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) ); |
|
491 |
|
492 //Build $allcaps from role caps, overlay user's $caps |
|
493 $this->allcaps = array(); |
|
494 foreach ( (array) $this->roles as $role ) { |
|
495 $the_role = $wp_roles->get_role( $role ); |
|
496 $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities ); |
|
497 } |
|
498 $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps ); |
|
499 |
|
500 if ( $switch_site ) { |
|
501 restore_current_blog(); |
|
502 } |
|
503 |
|
504 return $this->allcaps; |
|
505 } |
|
506 |
|
507 /** |
|
508 * Add role to user. |
|
509 * |
|
510 * Updates the user's meta data option with capabilities and roles. |
|
511 * |
|
512 * @since 2.0.0 |
|
513 * |
|
514 * @param string $role Role name. |
|
515 */ |
|
516 public function add_role( $role ) { |
|
517 if ( empty( $role ) ) { |
|
518 return; |
|
519 } |
|
520 |
|
521 $this->caps[$role] = true; |
|
522 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
523 $this->get_role_caps(); |
|
524 $this->update_user_level_from_caps(); |
|
525 |
|
526 /** |
|
527 * Fires immediately after the user has been given a new role. |
|
528 * |
|
529 * @since 4.3.0 |
|
530 * |
|
531 * @param int $user_id The user ID. |
|
532 * @param string $role The new role. |
|
533 */ |
|
534 do_action( 'add_user_role', $this->ID, $role ); |
|
535 } |
|
536 |
|
537 /** |
|
538 * Remove role from user. |
|
539 * |
|
540 * @since 2.0.0 |
|
541 * |
|
542 * @param string $role Role name. |
|
543 */ |
|
544 public function remove_role( $role ) { |
|
545 if ( !in_array($role, $this->roles) ) |
|
546 return; |
|
547 unset( $this->caps[$role] ); |
|
548 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
549 $this->get_role_caps(); |
|
550 $this->update_user_level_from_caps(); |
|
551 |
|
552 /** |
|
553 * Fires immediately after a role as been removed from a user. |
|
554 * |
|
555 * @since 4.3.0 |
|
556 * |
|
557 * @param int $user_id The user ID. |
|
558 * @param string $role The removed role. |
|
559 */ |
|
560 do_action( 'remove_user_role', $this->ID, $role ); |
|
561 } |
|
562 |
|
563 /** |
|
564 * Set the role of the user. |
|
565 * |
|
566 * This will remove the previous roles of the user and assign the user the |
|
567 * new one. You can set the role to an empty string and it will remove all |
|
568 * of the roles from the user. |
|
569 * |
|
570 * @since 2.0.0 |
|
571 * |
|
572 * @param string $role Role name. |
|
573 */ |
|
574 public function set_role( $role ) { |
|
575 if ( 1 == count( $this->roles ) && $role == current( $this->roles ) ) |
|
576 return; |
|
577 |
|
578 foreach ( (array) $this->roles as $oldrole ) |
|
579 unset( $this->caps[$oldrole] ); |
|
580 |
|
581 $old_roles = $this->roles; |
|
582 if ( !empty( $role ) ) { |
|
583 $this->caps[$role] = true; |
|
584 $this->roles = array( $role => true ); |
|
585 } else { |
|
586 $this->roles = false; |
|
587 } |
|
588 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
589 $this->get_role_caps(); |
|
590 $this->update_user_level_from_caps(); |
|
591 |
|
592 /** |
|
593 * Fires after the user's role has changed. |
|
594 * |
|
595 * @since 2.9.0 |
|
596 * @since 3.6.0 Added $old_roles to include an array of the user's previous roles. |
|
597 * |
|
598 * @param int $user_id The user ID. |
|
599 * @param string $role The new role. |
|
600 * @param array $old_roles An array of the user's previous roles. |
|
601 */ |
|
602 do_action( 'set_user_role', $this->ID, $role, $old_roles ); |
|
603 } |
|
604 |
|
605 /** |
|
606 * Choose the maximum level the user has. |
|
607 * |
|
608 * Will compare the level from the $item parameter against the $max |
|
609 * parameter. If the item is incorrect, then just the $max parameter value |
|
610 * will be returned. |
|
611 * |
|
612 * Used to get the max level based on the capabilities the user has. This |
|
613 * is also based on roles, so if the user is assigned the Administrator role |
|
614 * then the capability 'level_10' will exist and the user will get that |
|
615 * value. |
|
616 * |
|
617 * @since 2.0.0 |
|
618 * |
|
619 * @param int $max Max level of user. |
|
620 * @param string $item Level capability name. |
|
621 * @return int Max Level. |
|
622 */ |
|
623 public function level_reduction( $max, $item ) { |
|
624 if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { |
|
625 $level = intval( $matches[1] ); |
|
626 return max( $max, $level ); |
|
627 } else { |
|
628 return $max; |
|
629 } |
|
630 } |
|
631 |
|
632 /** |
|
633 * Update the maximum user level for the user. |
|
634 * |
|
635 * Updates the 'user_level' user metadata (includes prefix that is the |
|
636 * database table prefix) with the maximum user level. Gets the value from |
|
637 * the all of the capabilities that the user has. |
|
638 * |
|
639 * @since 2.0.0 |
|
640 * |
|
641 * @global wpdb $wpdb WordPress database abstraction object. |
|
642 */ |
|
643 public function update_user_level_from_caps() { |
|
644 global $wpdb; |
|
645 $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); |
|
646 update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); |
|
647 } |
|
648 |
|
649 /** |
|
650 * Add capability and grant or deny access to capability. |
|
651 * |
|
652 * @since 2.0.0 |
|
653 * |
|
654 * @param string $cap Capability name. |
|
655 * @param bool $grant Whether to grant capability to user. |
|
656 */ |
|
657 public function add_cap( $cap, $grant = true ) { |
|
658 $this->caps[$cap] = $grant; |
|
659 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
660 $this->get_role_caps(); |
|
661 $this->update_user_level_from_caps(); |
|
662 } |
|
663 |
|
664 /** |
|
665 * Remove capability from user. |
|
666 * |
|
667 * @since 2.0.0 |
|
668 * |
|
669 * @param string $cap Capability name. |
|
670 */ |
|
671 public function remove_cap( $cap ) { |
|
672 if ( ! isset( $this->caps[ $cap ] ) ) { |
|
673 return; |
|
674 } |
|
675 unset( $this->caps[ $cap ] ); |
|
676 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
677 $this->get_role_caps(); |
|
678 $this->update_user_level_from_caps(); |
|
679 } |
|
680 |
|
681 /** |
|
682 * Remove all of the capabilities of the user. |
|
683 * |
|
684 * @since 2.1.0 |
|
685 * |
|
686 * @global wpdb $wpdb WordPress database abstraction object. |
|
687 */ |
|
688 public function remove_all_caps() { |
|
689 global $wpdb; |
|
690 $this->caps = array(); |
|
691 delete_user_meta( $this->ID, $this->cap_key ); |
|
692 delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); |
|
693 $this->get_role_caps(); |
|
694 } |
|
695 |
|
696 /** |
|
697 * Whether the user has a specific capability. |
|
698 * |
|
699 * While checking against a role in place of a capability is supported in part, this practice is discouraged as it |
|
700 * may produce unreliable results. |
|
701 * |
|
702 * @since 2.0.0 |
|
703 * |
|
704 * @see map_meta_cap() |
|
705 * |
|
706 * @param string $cap Capability name. |
|
707 * @param int $object_id,... Optional. ID of a specific object to check against if `$cap` is a "meta" capability. |
|
708 * Meta capabilities such as `edit_post` and `edit_user` are capabilities used by |
|
709 * by the `map_meta_cap()` function to map to primitive capabilities that a user or |
|
710 * role has, such as `edit_posts` and `edit_others_posts`. |
|
711 * @return bool Whether the user has the given capability, or, if `$object_id` is passed, whether the user has |
|
712 * the given capability for that object. |
|
713 */ |
|
714 public function has_cap( $cap ) { |
|
715 if ( is_numeric( $cap ) ) { |
|
716 _deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) ); |
|
717 $cap = $this->translate_level_to_cap( $cap ); |
|
718 } |
|
719 |
|
720 $args = array_slice( func_get_args(), 1 ); |
|
721 $args = array_merge( array( $cap, $this->ID ), $args ); |
|
722 $caps = call_user_func_array( 'map_meta_cap', $args ); |
|
723 |
|
724 // Multisite super admin has all caps by definition, Unless specifically denied. |
|
725 if ( is_multisite() && is_super_admin( $this->ID ) ) { |
|
726 if ( in_array('do_not_allow', $caps) ) |
|
727 return false; |
|
728 return true; |
|
729 } |
|
730 |
|
731 /** |
|
732 * Dynamically filter a user's capabilities. |
|
733 * |
|
734 * @since 2.0.0 |
|
735 * @since 3.7.0 Added the user object. |
|
736 * |
|
737 * @param array $allcaps An array of all the user's capabilities. |
|
738 * @param array $caps Actual capabilities for meta capability. |
|
739 * @param array $args Optional parameters passed to has_cap(), typically object ID. |
|
740 * @param WP_User $user The user object. |
|
741 */ |
|
742 $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); |
|
743 |
|
744 // Everyone is allowed to exist. |
|
745 $capabilities['exist'] = true; |
|
746 |
|
747 // Nobody is allowed to do things they are not allowed to do. |
|
748 unset( $capabilities['do_not_allow'] ); |
|
749 |
|
750 // Must have ALL requested caps. |
|
751 foreach ( (array) $caps as $cap ) { |
|
752 if ( empty( $capabilities[ $cap ] ) ) |
|
753 return false; |
|
754 } |
|
755 |
|
756 return true; |
|
757 } |
|
758 |
|
759 /** |
|
760 * Convert numeric level to level capability name. |
|
761 * |
|
762 * Prepends 'level_' to level number. |
|
763 * |
|
764 * @since 2.0.0 |
|
765 * |
|
766 * @param int $level Level number, 1 to 10. |
|
767 * @return string |
|
768 */ |
|
769 public function translate_level_to_cap( $level ) { |
|
770 return 'level_' . $level; |
|
771 } |
|
772 |
|
773 /** |
|
774 * Set the site to operate on. Defaults to the current site. |
|
775 * |
|
776 * @since 3.0.0 |
|
777 * @deprecated 4.9.0 Use WP_User::for_site() |
|
778 * |
|
779 * @global wpdb $wpdb WordPress database abstraction object. |
|
780 * |
|
781 * @param int $blog_id Optional. Site ID, defaults to current site. |
|
782 */ |
|
783 public function for_blog( $blog_id = '' ) { |
|
784 _deprecated_function( __METHOD__, '4.9.0', 'WP_User::for_site()' ); |
|
785 |
|
786 $this->for_site( $blog_id ); |
|
787 } |
|
788 |
|
789 /** |
|
790 * Sets the site to operate on. Defaults to the current site. |
|
791 * |
|
792 * @since 4.9.0 |
|
793 * |
|
794 * @global wpdb $wpdb WordPress database abstraction object. |
|
795 * |
|
796 * @param int $site_id Site ID to initialize user capabilities for. Default is the current site. |
|
797 */ |
|
798 public function for_site( $site_id = '' ) { |
|
799 global $wpdb; |
|
800 |
|
801 if ( ! empty( $site_id ) ) { |
|
802 $this->site_id = absint( $site_id ); |
|
803 } else { |
|
804 $this->site_id = get_current_blog_id(); |
|
805 } |
|
806 |
|
807 $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities'; |
|
808 |
|
809 $this->caps = $this->get_caps_data(); |
|
810 |
|
811 $this->get_role_caps(); |
|
812 } |
|
813 |
|
814 /** |
|
815 * Gets the ID of the site for which the user's capabilities are currently initialized. |
|
816 * |
|
817 * @since 4.9.0 |
|
818 * |
|
819 * @return int Site ID. |
|
820 */ |
|
821 public function get_site_id() { |
|
822 return $this->site_id; |
|
823 } |
|
824 |
|
825 /** |
|
826 * Gets the available user capabilities data. |
|
827 * |
|
828 * @since 4.9.0 |
|
829 * |
|
830 * @return array User capabilities array. |
|
831 */ |
|
832 private function get_caps_data() { |
|
833 $caps = get_user_meta( $this->ID, $this->cap_key, true ); |
|
834 |
|
835 if ( ! is_array( $caps ) ) { |
|
836 return array(); |
|
837 } |
|
838 |
|
839 return $caps; |
|
840 } |
|
841 } |