1 <?php |
1 <?php |
2 /** |
2 /** |
3 * WordPress Roles and Capabilities. |
3 * Core User Role & Capabilities API |
4 * |
4 * |
5 * @package WordPress |
5 * @package WordPress |
6 * @subpackage User |
6 * @subpackage Users |
7 */ |
7 */ |
8 |
|
9 /** |
|
10 * WordPress User Roles. |
|
11 * |
|
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 |
|
14 * in the value of the 'capability' key. |
|
15 * |
|
16 * array ( |
|
17 * 'rolename' => array ( |
|
18 * 'name' => 'rolename', |
|
19 * 'capabilities' => array() |
|
20 * ) |
|
21 * ) |
|
22 * |
|
23 * @since 2.0.0 |
|
24 * @package WordPress |
|
25 * @subpackage User |
|
26 */ |
|
27 class WP_Roles { |
|
28 /** |
|
29 * List of roles and capabilities. |
|
30 * |
|
31 * @since 2.0.0 |
|
32 * @access public |
|
33 * @var array |
|
34 */ |
|
35 public $roles; |
|
36 |
|
37 /** |
|
38 * List of the role objects. |
|
39 * |
|
40 * @since 2.0.0 |
|
41 * @access public |
|
42 * @var array |
|
43 */ |
|
44 public $role_objects = array(); |
|
45 |
|
46 /** |
|
47 * List of role names. |
|
48 * |
|
49 * @since 2.0.0 |
|
50 * @access public |
|
51 * @var array |
|
52 */ |
|
53 public $role_names = array(); |
|
54 |
|
55 /** |
|
56 * Option name for storing role list. |
|
57 * |
|
58 * @since 2.0.0 |
|
59 * @access public |
|
60 * @var string |
|
61 */ |
|
62 public $role_key; |
|
63 |
|
64 /** |
|
65 * Whether to use the database for retrieval and storage. |
|
66 * |
|
67 * @since 2.1.0 |
|
68 * @access public |
|
69 * @var bool |
|
70 */ |
|
71 public $use_db = true; |
|
72 |
|
73 /** |
|
74 * Constructor |
|
75 * |
|
76 * @since 2.0.0 |
|
77 */ |
|
78 public function __construct() { |
|
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; |
|
97 } |
|
98 |
|
99 /** |
|
100 * Set up the object properties. |
|
101 * |
|
102 * The role key is set to the current prefix for the $wpdb object with |
|
103 * 'user_roles' appended. If the $wp_user_roles global is set, then it will |
|
104 * be used and the role option will not be updated or used. |
|
105 * |
|
106 * @since 2.1.0 |
|
107 * @access protected |
|
108 * |
|
109 * @global wpdb $wpdb WordPress database abstraction object. |
|
110 * @global array $wp_user_roles Used to set the 'roles' property value. |
|
111 */ |
|
112 protected function _init() { |
|
113 global $wpdb, $wp_user_roles; |
|
114 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; |
|
115 if ( ! empty( $wp_user_roles ) ) { |
|
116 $this->roles = $wp_user_roles; |
|
117 $this->use_db = false; |
|
118 } else { |
|
119 $this->roles = get_option( $this->role_key ); |
|
120 } |
|
121 |
|
122 if ( empty( $this->roles ) ) |
|
123 return; |
|
124 |
|
125 $this->role_objects = array(); |
|
126 $this->role_names = array(); |
|
127 foreach ( array_keys( $this->roles ) as $role ) { |
|
128 $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] ); |
|
129 $this->role_names[$role] = $this->roles[$role]['name']; |
|
130 } |
|
131 } |
|
132 |
|
133 /** |
|
134 * Reinitialize the object |
|
135 * |
|
136 * Recreates the role objects. This is typically called only by switch_to_blog() |
|
137 * after switching wpdb to a new blog ID. |
|
138 * |
|
139 * @since 3.5.0 |
|
140 * @access public |
|
141 */ |
|
142 public function reinit() { |
|
143 // There is no need to reinit if using the wp_user_roles global. |
|
144 if ( ! $this->use_db ) |
|
145 return; |
|
146 |
|
147 global $wpdb; |
|
148 |
|
149 // Duplicated from _init() to avoid an extra function call. |
|
150 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; |
|
151 $this->roles = get_option( $this->role_key ); |
|
152 if ( empty( $this->roles ) ) |
|
153 return; |
|
154 |
|
155 $this->role_objects = array(); |
|
156 $this->role_names = array(); |
|
157 foreach ( array_keys( $this->roles ) as $role ) { |
|
158 $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] ); |
|
159 $this->role_names[$role] = $this->roles[$role]['name']; |
|
160 } |
|
161 } |
|
162 |
|
163 /** |
|
164 * Add role name with capabilities to list. |
|
165 * |
|
166 * Updates the list of roles, if the role doesn't already exist. |
|
167 * |
|
168 * The capabilities are defined in the following format `array( 'read' => true );` |
|
169 * To explicitly deny a role a capability you set the value for that capability to false. |
|
170 * |
|
171 * @since 2.0.0 |
|
172 * @access public |
|
173 * |
|
174 * @param string $role Role name. |
|
175 * @param string $display_name Role display name. |
|
176 * @param array $capabilities List of role capabilities in the above format. |
|
177 * @return WP_Role|null WP_Role object if role is added, null if already exists. |
|
178 */ |
|
179 public function add_role( $role, $display_name, $capabilities = array() ) { |
|
180 if ( isset( $this->roles[$role] ) ) |
|
181 return; |
|
182 |
|
183 $this->roles[$role] = array( |
|
184 'name' => $display_name, |
|
185 'capabilities' => $capabilities |
|
186 ); |
|
187 if ( $this->use_db ) |
|
188 update_option( $this->role_key, $this->roles ); |
|
189 $this->role_objects[$role] = new WP_Role( $role, $capabilities ); |
|
190 $this->role_names[$role] = $display_name; |
|
191 return $this->role_objects[$role]; |
|
192 } |
|
193 |
|
194 /** |
|
195 * Remove role by name. |
|
196 * |
|
197 * @since 2.0.0 |
|
198 * @access public |
|
199 * |
|
200 * @param string $role Role name. |
|
201 */ |
|
202 public function remove_role( $role ) { |
|
203 if ( ! isset( $this->role_objects[$role] ) ) |
|
204 return; |
|
205 |
|
206 unset( $this->role_objects[$role] ); |
|
207 unset( $this->role_names[$role] ); |
|
208 unset( $this->roles[$role] ); |
|
209 |
|
210 if ( $this->use_db ) |
|
211 update_option( $this->role_key, $this->roles ); |
|
212 |
|
213 if ( get_option( 'default_role' ) == $role ) |
|
214 update_option( 'default_role', 'subscriber' ); |
|
215 } |
|
216 |
|
217 /** |
|
218 * Add capability to role. |
|
219 * |
|
220 * @since 2.0.0 |
|
221 * @access public |
|
222 * |
|
223 * @param string $role Role name. |
|
224 * @param string $cap Capability name. |
|
225 * @param bool $grant Optional, default is true. Whether role is capable of performing capability. |
|
226 */ |
|
227 public function add_cap( $role, $cap, $grant = true ) { |
|
228 if ( ! isset( $this->roles[$role] ) ) |
|
229 return; |
|
230 |
|
231 $this->roles[$role]['capabilities'][$cap] = $grant; |
|
232 if ( $this->use_db ) |
|
233 update_option( $this->role_key, $this->roles ); |
|
234 } |
|
235 |
|
236 /** |
|
237 * Remove capability from role. |
|
238 * |
|
239 * @since 2.0.0 |
|
240 * @access public |
|
241 * |
|
242 * @param string $role Role name. |
|
243 * @param string $cap Capability name. |
|
244 */ |
|
245 public function remove_cap( $role, $cap ) { |
|
246 if ( ! isset( $this->roles[$role] ) ) |
|
247 return; |
|
248 |
|
249 unset( $this->roles[$role]['capabilities'][$cap] ); |
|
250 if ( $this->use_db ) |
|
251 update_option( $this->role_key, $this->roles ); |
|
252 } |
|
253 |
|
254 /** |
|
255 * Retrieve role object by name. |
|
256 * |
|
257 * @since 2.0.0 |
|
258 * @access public |
|
259 * |
|
260 * @param string $role Role name. |
|
261 * @return WP_Role|null WP_Role object if found, null if the role does not exist. |
|
262 */ |
|
263 public function get_role( $role ) { |
|
264 if ( isset( $this->role_objects[$role] ) ) |
|
265 return $this->role_objects[$role]; |
|
266 else |
|
267 return null; |
|
268 } |
|
269 |
|
270 /** |
|
271 * Retrieve list of role names. |
|
272 * |
|
273 * @since 2.0.0 |
|
274 * @access public |
|
275 * |
|
276 * @return array List of role names. |
|
277 */ |
|
278 public function get_names() { |
|
279 return $this->role_names; |
|
280 } |
|
281 |
|
282 /** |
|
283 * Whether role name is currently in the list of available roles. |
|
284 * |
|
285 * @since 2.0.0 |
|
286 * @access public |
|
287 * |
|
288 * @param string $role Role name to look up. |
|
289 * @return bool |
|
290 */ |
|
291 public function is_role( $role ) { |
|
292 return isset( $this->role_names[$role] ); |
|
293 } |
|
294 } |
|
295 |
|
296 /** |
|
297 * WordPress Role class. |
|
298 * |
|
299 * @since 2.0.0 |
|
300 * @package WordPress |
|
301 * @subpackage User |
|
302 */ |
|
303 class WP_Role { |
|
304 /** |
|
305 * Role name. |
|
306 * |
|
307 * @since 2.0.0 |
|
308 * @access public |
|
309 * @var string |
|
310 */ |
|
311 public $name; |
|
312 |
|
313 /** |
|
314 * List of capabilities the role contains. |
|
315 * |
|
316 * @since 2.0.0 |
|
317 * @access public |
|
318 * @var array |
|
319 */ |
|
320 public $capabilities; |
|
321 |
|
322 /** |
|
323 * Constructor - Set up object properties. |
|
324 * |
|
325 * The list of capabilities, must have the key as the name of the capability |
|
326 * and the value a boolean of whether it is granted to the role. |
|
327 * |
|
328 * @since 2.0.0 |
|
329 * @access public |
|
330 * |
|
331 * @param string $role Role name. |
|
332 * @param array $capabilities List of capabilities. |
|
333 */ |
|
334 public function __construct( $role, $capabilities ) { |
|
335 $this->name = $role; |
|
336 $this->capabilities = $capabilities; |
|
337 } |
|
338 |
|
339 /** |
|
340 * Assign role a capability. |
|
341 * |
|
342 * @see WP_Roles::add_cap() Method uses implementation for role. |
|
343 * @since 2.0.0 |
|
344 * @access public |
|
345 * |
|
346 * @param string $cap Capability name. |
|
347 * @param bool $grant Whether role has capability privilege. |
|
348 */ |
|
349 public function add_cap( $cap, $grant = true ) { |
|
350 global $wp_roles; |
|
351 |
|
352 if ( ! isset( $wp_roles ) ) |
|
353 $wp_roles = new WP_Roles(); |
|
354 |
|
355 $this->capabilities[$cap] = $grant; |
|
356 $wp_roles->add_cap( $this->name, $cap, $grant ); |
|
357 } |
|
358 |
|
359 /** |
|
360 * Remove capability from role. |
|
361 * |
|
362 * This is a container for {@link WP_Roles::remove_cap()} to remove the |
|
363 * capability from the role. That is to say, that {@link |
|
364 * WP_Roles::remove_cap()} implements the functionality, but it also makes |
|
365 * sense to use this class, because you don't need to enter the role name. |
|
366 * |
|
367 * @since 2.0.0 |
|
368 * @access public |
|
369 * |
|
370 * @param string $cap Capability name. |
|
371 */ |
|
372 public function remove_cap( $cap ) { |
|
373 global $wp_roles; |
|
374 |
|
375 if ( ! isset( $wp_roles ) ) |
|
376 $wp_roles = new WP_Roles(); |
|
377 |
|
378 unset( $this->capabilities[$cap] ); |
|
379 $wp_roles->remove_cap( $this->name, $cap ); |
|
380 } |
|
381 |
|
382 /** |
|
383 * Whether role has capability. |
|
384 * |
|
385 * The capabilities is passed through the 'role_has_cap' filter. The first |
|
386 * parameter for the hook is the list of capabilities the class has |
|
387 * assigned. The second parameter is the capability name to look for. The |
|
388 * third and final parameter for the hook is the role name. |
|
389 * |
|
390 * @since 2.0.0 |
|
391 * @access public |
|
392 * |
|
393 * @param string $cap Capability name. |
|
394 * @return bool True, if user has capability. False, if doesn't have capability. |
|
395 */ |
|
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 */ |
|
406 $capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name ); |
|
407 if ( !empty( $capabilities[$cap] ) ) |
|
408 return $capabilities[$cap]; |
|
409 else |
|
410 return false; |
|
411 } |
|
412 |
|
413 } |
|
414 |
|
415 /** |
|
416 * WordPress User class. |
|
417 * |
|
418 * @since 2.0.0 |
|
419 * @package WordPress |
|
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 |
|
437 */ |
|
438 class WP_User { |
|
439 /** |
|
440 * User data container. |
|
441 * |
|
442 * @since 2.0.0 |
|
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 |
|
461 * @var array |
|
462 */ |
|
463 public $caps = array(); |
|
464 |
|
465 /** |
|
466 * User metadata option name. |
|
467 * |
|
468 * @since 2.0.0 |
|
469 * @access public |
|
470 * @var string |
|
471 */ |
|
472 public $cap_key; |
|
473 |
|
474 /** |
|
475 * The roles the user is part of. |
|
476 * |
|
477 * @since 2.0.0 |
|
478 * @access public |
|
479 * @var array |
|
480 */ |
|
481 public $roles = array(); |
|
482 |
|
483 /** |
|
484 * All capabilities the user has, including individual and role based. |
|
485 * |
|
486 * @since 2.0.0 |
|
487 * @access public |
|
488 * @var array |
|
489 */ |
|
490 public $allcaps = array(); |
|
491 |
|
492 /** |
|
493 * The filter context applied to user data fields. |
|
494 * |
|
495 * @since 2.9.0 |
|
496 * @access private |
|
497 * @var string |
|
498 */ |
|
499 var $filter = null; |
|
500 |
|
501 private static $back_compat_keys; |
|
502 |
|
503 /** |
|
504 * Constructor |
|
505 * |
|
506 * Retrieves the userdata and passes it to {@link WP_User::init()}. |
|
507 * |
|
508 * @since 2.0.0 |
|
509 * @access public |
|
510 * |
|
511 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB. |
|
512 * @param string $name Optional. User's username |
|
513 * @param int $blog_id Optional Blog ID, defaults to current blog. |
|
514 */ |
|
515 public function __construct( $id = 0, $name = '', $blog_id = '' ) { |
|
516 if ( ! isset( self::$back_compat_keys ) ) { |
|
517 $prefix = $GLOBALS['wpdb']->prefix; |
|
518 self::$back_compat_keys = array( |
|
519 'user_firstname' => 'first_name', |
|
520 'user_lastname' => 'last_name', |
|
521 'user_description' => 'description', |
|
522 'user_level' => $prefix . 'user_level', |
|
523 $prefix . 'usersettings' => $prefix . 'user-settings', |
|
524 $prefix . 'usersettingstime' => $prefix . 'user-settings-time', |
|
525 ); |
|
526 } |
|
527 |
|
528 if ( $id instanceof WP_User ) { |
|
529 $this->init( $id->data, $blog_id ); |
|
530 return; |
|
531 } elseif ( is_object( $id ) ) { |
|
532 $this->init( $id, $blog_id ); |
|
533 return; |
|
534 } |
|
535 |
|
536 if ( ! empty( $id ) && ! is_numeric( $id ) ) { |
|
537 $name = $id; |
|
538 $id = 0; |
|
539 } |
|
540 |
|
541 if ( $id ) { |
|
542 $data = self::get_data_by( 'id', $id ); |
|
543 } else { |
|
544 $data = self::get_data_by( 'login', $name ); |
|
545 } |
|
546 |
|
547 if ( $data ) { |
|
548 $this->init( $data, $blog_id ); |
|
549 } else { |
|
550 $this->data = new stdClass; |
|
551 } |
|
552 } |
|
553 |
|
554 /** |
|
555 * Sets up object properties, including capabilities. |
|
556 * |
|
557 * @param object $data User DB row object |
|
558 * @param int $blog_id Optional. The blog id to initialize for |
|
559 */ |
|
560 public function init( $data, $blog_id = '' ) { |
|
561 $this->data = $data; |
|
562 $this->ID = (int) $data->ID; |
|
563 |
|
564 $this->for_blog( $blog_id ); |
|
565 } |
|
566 |
|
567 /** |
|
568 * Return only the main user fields |
|
569 * |
|
570 * @since 3.3.0 |
|
571 * |
|
572 * @param string $field The field to query against: 'id', 'slug', 'email' or 'login' |
|
573 * @param string|int $value The field value |
|
574 * @return object|false Raw user object |
|
575 */ |
|
576 public static function get_data_by( $field, $value ) { |
|
577 global $wpdb; |
|
578 |
|
579 if ( 'id' == $field ) { |
|
580 // Make sure the value is numeric to avoid casting objects, for example, |
|
581 // to int 1. |
|
582 if ( ! is_numeric( $value ) ) |
|
583 return false; |
|
584 $value = intval( $value ); |
|
585 if ( $value < 1 ) |
|
586 return false; |
|
587 } else { |
|
588 $value = trim( $value ); |
|
589 } |
|
590 |
|
591 if ( !$value ) |
|
592 return false; |
|
593 |
|
594 switch ( $field ) { |
|
595 case 'id': |
|
596 $user_id = $value; |
|
597 $db_field = 'ID'; |
|
598 break; |
|
599 case 'slug': |
|
600 $user_id = wp_cache_get($value, 'userslugs'); |
|
601 $db_field = 'user_nicename'; |
|
602 break; |
|
603 case 'email': |
|
604 $user_id = wp_cache_get($value, 'useremail'); |
|
605 $db_field = 'user_email'; |
|
606 break; |
|
607 case 'login': |
|
608 $value = sanitize_user( $value ); |
|
609 $user_id = wp_cache_get($value, 'userlogins'); |
|
610 $db_field = 'user_login'; |
|
611 break; |
|
612 default: |
|
613 return false; |
|
614 } |
|
615 |
|
616 if ( false !== $user_id ) { |
|
617 if ( $user = wp_cache_get( $user_id, 'users' ) ) |
|
618 return $user; |
|
619 } |
|
620 |
|
621 if ( !$user = $wpdb->get_row( $wpdb->prepare( |
|
622 "SELECT * FROM $wpdb->users WHERE $db_field = %s", $value |
|
623 ) ) ) |
|
624 return false; |
|
625 |
|
626 update_user_caches( $user ); |
|
627 |
|
628 return $user; |
|
629 } |
|
630 |
|
631 /** |
|
632 * Magic method for checking the existence of a certain custom field |
|
633 * |
|
634 * @since 3.3.0 |
|
635 * @param string $key |
|
636 * @return bool |
|
637 */ |
|
638 public function __isset( $key ) { |
|
639 if ( 'id' == $key ) { |
|
640 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); |
|
641 $key = 'ID'; |
|
642 } |
|
643 |
|
644 if ( isset( $this->data->$key ) ) |
|
645 return true; |
|
646 |
|
647 if ( isset( self::$back_compat_keys[ $key ] ) ) |
|
648 $key = self::$back_compat_keys[ $key ]; |
|
649 |
|
650 return metadata_exists( 'user', $this->ID, $key ); |
|
651 } |
|
652 |
|
653 /** |
|
654 * Magic method for accessing custom fields |
|
655 * |
|
656 * @since 3.3.0 |
|
657 * @param string $key |
|
658 * @return mixed |
|
659 */ |
|
660 public function __get( $key ) { |
|
661 if ( 'id' == $key ) { |
|
662 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); |
|
663 return $this->ID; |
|
664 } |
|
665 |
|
666 if ( isset( $this->data->$key ) ) { |
|
667 $value = $this->data->$key; |
|
668 } else { |
|
669 if ( isset( self::$back_compat_keys[ $key ] ) ) |
|
670 $key = self::$back_compat_keys[ $key ]; |
|
671 $value = get_user_meta( $this->ID, $key, true ); |
|
672 } |
|
673 |
|
674 if ( $this->filter ) { |
|
675 $value = sanitize_user_field( $key, $value, $this->ID, $this->filter ); |
|
676 } |
|
677 |
|
678 return $value; |
|
679 } |
|
680 |
|
681 /** |
|
682 * Magic method for setting custom fields |
|
683 * |
|
684 * @since 3.3.0 |
|
685 */ |
|
686 public function __set( $key, $value ) { |
|
687 if ( 'id' == $key ) { |
|
688 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); |
|
689 $this->ID = $value; |
|
690 return; |
|
691 } |
|
692 |
|
693 $this->data->$key = $value; |
|
694 } |
|
695 |
|
696 /** |
|
697 * Determine whether the user exists in the database. |
|
698 * |
|
699 * @since 3.4.0 |
|
700 * @access public |
|
701 * |
|
702 * @return bool True if user exists in the database, false if not. |
|
703 */ |
|
704 public function exists() { |
|
705 return ! empty( $this->ID ); |
|
706 } |
|
707 |
|
708 /** |
|
709 * Retrieve the value of a property or meta key. |
|
710 * |
|
711 * Retrieves from the users and usermeta table. |
|
712 * |
|
713 * @since 3.3.0 |
|
714 * |
|
715 * @param string $key Property |
|
716 */ |
|
717 public function get( $key ) { |
|
718 return $this->__get( $key ); |
|
719 } |
|
720 |
|
721 /** |
|
722 * Determine whether a property or meta key is set |
|
723 * |
|
724 * Consults the users and usermeta tables. |
|
725 * |
|
726 * @since 3.3.0 |
|
727 * |
|
728 * @param string $key Property |
|
729 */ |
|
730 public function has_prop( $key ) { |
|
731 return $this->__isset( $key ); |
|
732 } |
|
733 |
|
734 /** |
|
735 * Return an array representation. |
|
736 * |
|
737 * @since 3.5.0 |
|
738 * |
|
739 * @return array Array representation. |
|
740 */ |
|
741 public function to_array() { |
|
742 return get_object_vars( $this->data ); |
|
743 } |
|
744 |
|
745 /** |
|
746 * Set up capability object properties. |
|
747 * |
|
748 * Will set the value for the 'cap_key' property to current database table |
|
749 * prefix, followed by 'capabilities'. Will then check to see if the |
|
750 * property matching the 'cap_key' exists and is an array. If so, it will be |
|
751 * used. |
|
752 * |
|
753 * @access protected |
|
754 * @since 2.1.0 |
|
755 * |
|
756 * @param string $cap_key Optional capability key |
|
757 */ |
|
758 function _init_caps( $cap_key = '' ) { |
|
759 global $wpdb; |
|
760 |
|
761 if ( empty($cap_key) ) |
|
762 $this->cap_key = $wpdb->get_blog_prefix() . 'capabilities'; |
|
763 else |
|
764 $this->cap_key = $cap_key; |
|
765 |
|
766 $this->caps = get_user_meta( $this->ID, $this->cap_key, true ); |
|
767 |
|
768 if ( ! is_array( $this->caps ) ) |
|
769 $this->caps = array(); |
|
770 |
|
771 $this->get_role_caps(); |
|
772 } |
|
773 |
|
774 /** |
|
775 * Retrieve all of the role capabilities and merge with individual capabilities. |
|
776 * |
|
777 * All of the capabilities of the roles the user belongs to are merged with |
|
778 * the users individual roles. This also means that the user can be denied |
|
779 * specific roles that their role might have, but the specific user isn't |
|
780 * granted permission to. |
|
781 * |
|
782 * @since 2.0.0 |
|
783 * @uses $wp_roles |
|
784 * @access public |
|
785 * |
|
786 * @return array List of all capabilities for the user. |
|
787 */ |
|
788 public function get_role_caps() { |
|
789 global $wp_roles; |
|
790 |
|
791 if ( ! isset( $wp_roles ) ) |
|
792 $wp_roles = new WP_Roles(); |
|
793 |
|
794 //Filter out caps that are not role names and assign to $this->roles |
|
795 if ( is_array( $this->caps ) ) |
|
796 $this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) ); |
|
797 |
|
798 //Build $allcaps from role caps, overlay user's $caps |
|
799 $this->allcaps = array(); |
|
800 foreach ( (array) $this->roles as $role ) { |
|
801 $the_role = $wp_roles->get_role( $role ); |
|
802 $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities ); |
|
803 } |
|
804 $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps ); |
|
805 |
|
806 return $this->allcaps; |
|
807 } |
|
808 |
|
809 /** |
|
810 * Add role to user. |
|
811 * |
|
812 * Updates the user's meta data option with capabilities and roles. |
|
813 * |
|
814 * @since 2.0.0 |
|
815 * @access public |
|
816 * |
|
817 * @param string $role Role name. |
|
818 */ |
|
819 public function add_role( $role ) { |
|
820 $this->caps[$role] = true; |
|
821 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
822 $this->get_role_caps(); |
|
823 $this->update_user_level_from_caps(); |
|
824 } |
|
825 |
|
826 /** |
|
827 * Remove role from user. |
|
828 * |
|
829 * @since 2.0.0 |
|
830 * @access public |
|
831 * |
|
832 * @param string $role Role name. |
|
833 */ |
|
834 public function remove_role( $role ) { |
|
835 if ( !in_array($role, $this->roles) ) |
|
836 return; |
|
837 unset( $this->caps[$role] ); |
|
838 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
839 $this->get_role_caps(); |
|
840 $this->update_user_level_from_caps(); |
|
841 } |
|
842 |
|
843 /** |
|
844 * Set the role of the user. |
|
845 * |
|
846 * This will remove the previous roles of the user and assign the user the |
|
847 * new one. You can set the role to an empty string and it will remove all |
|
848 * of the roles from the user. |
|
849 * |
|
850 * @since 2.0.0 |
|
851 * @access public |
|
852 * |
|
853 * @param string $role Role name. |
|
854 */ |
|
855 public function set_role( $role ) { |
|
856 if ( 1 == count( $this->roles ) && $role == current( $this->roles ) ) |
|
857 return; |
|
858 |
|
859 foreach ( (array) $this->roles as $oldrole ) |
|
860 unset( $this->caps[$oldrole] ); |
|
861 |
|
862 $old_roles = $this->roles; |
|
863 if ( !empty( $role ) ) { |
|
864 $this->caps[$role] = true; |
|
865 $this->roles = array( $role => true ); |
|
866 } else { |
|
867 $this->roles = false; |
|
868 } |
|
869 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
870 $this->get_role_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 */ |
|
883 do_action( 'set_user_role', $this->ID, $role, $old_roles ); |
|
884 } |
|
885 |
|
886 /** |
|
887 * Choose the maximum level the user has. |
|
888 * |
|
889 * Will compare the level from the $item parameter against the $max |
|
890 * parameter. If the item is incorrect, then just the $max parameter value |
|
891 * will be returned. |
|
892 * |
|
893 * Used to get the max level based on the capabilities the user has. This |
|
894 * is also based on roles, so if the user is assigned the Administrator role |
|
895 * then the capability 'level_10' will exist and the user will get that |
|
896 * value. |
|
897 * |
|
898 * @since 2.0.0 |
|
899 * @access public |
|
900 * |
|
901 * @param int $max Max level of user. |
|
902 * @param string $item Level capability name. |
|
903 * @return int Max Level. |
|
904 */ |
|
905 public function level_reduction( $max, $item ) { |
|
906 if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { |
|
907 $level = intval( $matches[1] ); |
|
908 return max( $max, $level ); |
|
909 } else { |
|
910 return $max; |
|
911 } |
|
912 } |
|
913 |
|
914 /** |
|
915 * Update the maximum user level for the user. |
|
916 * |
|
917 * Updates the 'user_level' user metadata (includes prefix that is the |
|
918 * database table prefix) with the maximum user level. Gets the value from |
|
919 * the all of the capabilities that the user has. |
|
920 * |
|
921 * @since 2.0.0 |
|
922 * @access public |
|
923 */ |
|
924 public function update_user_level_from_caps() { |
|
925 global $wpdb; |
|
926 $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); |
|
927 update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); |
|
928 } |
|
929 |
|
930 /** |
|
931 * Add capability and grant or deny access to capability. |
|
932 * |
|
933 * @since 2.0.0 |
|
934 * @access public |
|
935 * |
|
936 * @param string $cap Capability name. |
|
937 * @param bool $grant Whether to grant capability to user. |
|
938 */ |
|
939 public function add_cap( $cap, $grant = true ) { |
|
940 $this->caps[$cap] = $grant; |
|
941 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
942 $this->get_role_caps(); |
|
943 $this->update_user_level_from_caps(); |
|
944 } |
|
945 |
|
946 /** |
|
947 * Remove capability from user. |
|
948 * |
|
949 * @since 2.0.0 |
|
950 * @access public |
|
951 * |
|
952 * @param string $cap Capability name. |
|
953 */ |
|
954 public function remove_cap( $cap ) { |
|
955 if ( ! isset( $this->caps[ $cap ] ) ) { |
|
956 return; |
|
957 } |
|
958 unset( $this->caps[ $cap ] ); |
|
959 update_user_meta( $this->ID, $this->cap_key, $this->caps ); |
|
960 $this->get_role_caps(); |
|
961 $this->update_user_level_from_caps(); |
|
962 } |
|
963 |
|
964 /** |
|
965 * Remove all of the capabilities of the user. |
|
966 * |
|
967 * @since 2.1.0 |
|
968 * @access public |
|
969 */ |
|
970 public function remove_all_caps() { |
|
971 global $wpdb; |
|
972 $this->caps = array(); |
|
973 delete_user_meta( $this->ID, $this->cap_key ); |
|
974 delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); |
|
975 $this->get_role_caps(); |
|
976 } |
|
977 |
|
978 /** |
|
979 * Whether user has capability or role name. |
|
980 * |
|
981 * This is useful for looking up whether the user has a specific role |
|
982 * assigned to the user. The second optional parameter can also be used to |
|
983 * check for capabilities against a specific object, such as a post or user. |
|
984 * |
|
985 * @since 2.0.0 |
|
986 * @access public |
|
987 * |
|
988 * @param string|int $cap Capability or role name to search. |
|
989 * @return bool True, if user has capability; false, if user does not have capability. |
|
990 */ |
|
991 public function has_cap( $cap ) { |
|
992 if ( is_numeric( $cap ) ) { |
|
993 _deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); |
|
994 $cap = $this->translate_level_to_cap( $cap ); |
|
995 } |
|
996 |
|
997 $args = array_slice( func_get_args(), 1 ); |
|
998 $args = array_merge( array( $cap, $this->ID ), $args ); |
|
999 $caps = call_user_func_array( 'map_meta_cap', $args ); |
|
1000 |
|
1001 // Multisite super admin has all caps by definition, Unless specifically denied. |
|
1002 if ( is_multisite() && is_super_admin( $this->ID ) ) { |
|
1003 if ( in_array('do_not_allow', $caps) ) |
|
1004 return false; |
|
1005 return true; |
|
1006 } |
|
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 */ |
|
1019 // Must have ALL requested caps |
|
1020 $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); |
|
1021 $capabilities['exist'] = true; // Everyone is allowed to exist |
|
1022 foreach ( (array) $caps as $cap ) { |
|
1023 if ( empty( $capabilities[ $cap ] ) ) |
|
1024 return false; |
|
1025 } |
|
1026 |
|
1027 return true; |
|
1028 } |
|
1029 |
|
1030 /** |
|
1031 * Convert numeric level to level capability name. |
|
1032 * |
|
1033 * Prepends 'level_' to level number. |
|
1034 * |
|
1035 * @since 2.0.0 |
|
1036 * @access public |
|
1037 * |
|
1038 * @param int $level Level number, 1 to 10. |
|
1039 * @return string |
|
1040 */ |
|
1041 public function translate_level_to_cap( $level ) { |
|
1042 return 'level_' . $level; |
|
1043 } |
|
1044 |
|
1045 /** |
|
1046 * Set the blog to operate on. Defaults to the current blog. |
|
1047 * |
|
1048 * @since 3.0.0 |
|
1049 * |
|
1050 * @param int $blog_id Optional Blog ID, defaults to current blog. |
|
1051 */ |
|
1052 public function for_blog( $blog_id = '' ) { |
|
1053 global $wpdb; |
|
1054 if ( ! empty( $blog_id ) ) |
|
1055 $cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; |
|
1056 else |
|
1057 $cap_key = ''; |
|
1058 $this->_init_caps( $cap_key ); |
|
1059 } |
|
1060 } |
|
1061 |
8 |
1062 /** |
9 /** |
1063 * Map meta capabilities to primitive capabilities. |
10 * Map meta capabilities to primitive capabilities. |
1064 * |
11 * |
1065 * This does not actually compare whether the user ID has the actual capability, |
12 * This does not actually compare whether the user ID has the actual capability, |
1216 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
245 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
1217 } |
246 } |
1218 break; |
247 break; |
1219 case 'publish_post': |
248 case 'publish_post': |
1220 $post = get_post( $args[0] ); |
249 $post = get_post( $args[0] ); |
|
250 if ( ! $post ) { |
|
251 $caps[] = 'do_not_allow'; |
|
252 break; |
|
253 } |
|
254 |
1221 $post_type = get_post_type_object( $post->post_type ); |
255 $post_type = get_post_type_object( $post->post_type ); |
|
256 if ( ! $post_type ) { |
|
257 /* translators: 1: post type, 2: capability name */ |
|
258 _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' ); |
|
259 $caps[] = 'edit_others_posts'; |
|
260 break; |
|
261 } |
1222 |
262 |
1223 $caps[] = $post_type->cap->publish_posts; |
263 $caps[] = $post_type->cap->publish_posts; |
1224 break; |
264 break; |
1225 case 'edit_post_meta': |
265 case 'edit_post_meta': |
1226 case 'delete_post_meta': |
266 case 'delete_post_meta': |
1227 case 'add_post_meta': |
267 case 'add_post_meta': |
1228 $post = get_post( $args[0] ); |
268 case 'edit_comment_meta': |
1229 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
269 case 'delete_comment_meta': |
1230 |
270 case 'add_comment_meta': |
1231 $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false; |
271 case 'edit_term_meta': |
1232 |
272 case 'delete_term_meta': |
1233 if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) { |
273 case 'add_term_meta': |
1234 /** |
274 case 'edit_user_meta': |
1235 * Filter whether the user is allowed to add post meta to a post. |
275 case 'delete_user_meta': |
1236 * |
276 case 'add_user_meta': |
1237 * The dynamic portion of the hook name, `$meta_key`, refers to the |
277 list( $_, $object_type, $_ ) = explode( '_', $cap ); |
1238 * meta key passed to {@see map_meta_cap()}. |
278 $object_id = (int) $args[0]; |
1239 * |
279 $object_subtype = get_object_subtype( $object_type, $object_id ); |
1240 * @since 3.3.0 |
280 |
1241 * |
281 if ( empty( $object_subtype ) ) { |
1242 * @param bool $allowed Whether the user can add the post meta. Default false. |
282 $caps[] = 'do_not_allow'; |
1243 * @param string $meta_key The meta key. |
283 break; |
1244 * @param int $post_id Post ID. |
284 } |
1245 * @param int $user_id User ID. |
285 |
1246 * @param string $cap Capability name. |
286 $caps = map_meta_cap( "edit_{$object_type}", $user_id, $object_id ); |
1247 * @param array $caps User capabilities. |
287 |
1248 */ |
288 $meta_key = isset( $args[1] ) ? $args[1] : false; |
1249 $allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps ); |
289 |
1250 if ( ! $allowed ) |
290 if ( $meta_key ) { |
|
291 $allowed = ! is_protected_meta( $meta_key, $object_type ); |
|
292 |
|
293 if ( ! empty( $object_subtype ) && has_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { |
|
294 |
|
295 /** |
|
296 * Filters whether the user is allowed to edit a specific meta key of a specific object type and subtype. |
|
297 * |
|
298 * The dynamic portions of the hook name, `$object_type`, `$meta_key`, |
|
299 * and `$object_subtype`, refer to the metadata object type (comment, post, term or user), |
|
300 * the meta key value, and the object subtype respectively. |
|
301 * |
|
302 * @since 4.9.8 |
|
303 * |
|
304 * @param bool $allowed Whether the user can add the object meta. Default false. |
|
305 * @param string $meta_key The meta key. |
|
306 * @param int $object_id Object ID. |
|
307 * @param int $user_id User ID. |
|
308 * @param string $cap Capability name. |
|
309 * @param string[] $caps Array of the user's capabilities. |
|
310 */ |
|
311 $allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps ); |
|
312 } else { |
|
313 |
|
314 /** |
|
315 * Filters whether the user is allowed to edit a specific meta key of a specific object type. |
|
316 * |
|
317 * Return true to have the mapped meta caps from `edit_{$object_type}` apply. |
|
318 * |
|
319 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered. |
|
320 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap(). |
|
321 * |
|
322 * @since 3.3.0 As `auth_post_meta_{$meta_key}`. |
|
323 * @since 4.6.0 |
|
324 * |
|
325 * @param bool $allowed Whether the user can add the object meta. Default false. |
|
326 * @param string $meta_key The meta key. |
|
327 * @param int $object_id Object ID. |
|
328 * @param int $user_id User ID. |
|
329 * @param string $cap Capability name. |
|
330 * @param string[] $caps Array of the user's capabilities. |
|
331 */ |
|
332 $allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps ); |
|
333 } |
|
334 |
|
335 if ( ! empty( $object_subtype ) ) { |
|
336 |
|
337 /** |
|
338 * Filters whether the user is allowed to edit meta for specific object types/subtypes. |
|
339 * |
|
340 * Return true to have the mapped meta caps from `edit_{$object_type}` apply. |
|
341 * |
|
342 * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered. |
|
343 * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered. |
|
344 * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap(). |
|
345 * |
|
346 * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`. |
|
347 * @since 4.7.0 |
|
348 * @deprecated 4.9.8 Use `auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}` |
|
349 * |
|
350 * @param bool $allowed Whether the user can add the object meta. Default false. |
|
351 * @param string $meta_key The meta key. |
|
352 * @param int $object_id Object ID. |
|
353 * @param int $user_id User ID. |
|
354 * @param string $cap Capability name. |
|
355 * @param string[] $caps Array of the user's capabilities. |
|
356 */ |
|
357 $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}" ); |
|
358 } |
|
359 |
|
360 if ( ! $allowed ) { |
1251 $caps[] = $cap; |
361 $caps[] = $cap; |
1252 } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) { |
362 } |
1253 $caps[] = $cap; |
|
1254 } |
363 } |
1255 break; |
364 break; |
1256 case 'edit_comment': |
365 case 'edit_comment': |
1257 $comment = get_comment( $args[0] ); |
366 $comment = get_comment( $args[0] ); |
1258 if ( empty( $comment ) ) |
367 if ( ! $comment ) { |
1259 break; |
368 $caps[] = 'do_not_allow'; |
|
369 break; |
|
370 } |
|
371 |
1260 $post = get_post( $comment->comment_post_ID ); |
372 $post = get_post( $comment->comment_post_ID ); |
1261 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
373 |
|
374 /* |
|
375 * If the post doesn't exist, we have an orphaned comment. |
|
376 * Fall back to the edit_posts capability, instead. |
|
377 */ |
|
378 if ( $post ) { |
|
379 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); |
|
380 } else { |
|
381 $caps = map_meta_cap( 'edit_posts', $user_id ); |
|
382 } |
1262 break; |
383 break; |
1263 case 'unfiltered_upload': |
384 case 'unfiltered_upload': |
1264 if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) ) |
385 if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) ) |
1265 $caps[] = $cap; |
386 $caps[] = $cap; |
1266 else |
387 else |
1267 $caps[] = 'do_not_allow'; |
388 $caps[] = 'do_not_allow'; |
1268 break; |
389 break; |
|
390 case 'edit_css' : |
1269 case 'unfiltered_html' : |
391 case 'unfiltered_html' : |
1270 // Disallow unfiltered_html for all users, even admins and super admins. |
392 // Disallow unfiltered_html for all users, even admins and super admins. |
1271 if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) |
393 if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) |
1272 $caps[] = 'do_not_allow'; |
394 $caps[] = 'do_not_allow'; |
1273 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) |
395 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) |
1274 $caps[] = 'do_not_allow'; |
396 $caps[] = 'do_not_allow'; |
1275 else |
397 else |
1276 $caps[] = $cap; |
398 $caps[] = 'unfiltered_html'; |
1277 break; |
399 break; |
1278 case 'edit_files': |
400 case 'edit_files': |
1279 case 'edit_plugins': |
401 case 'edit_plugins': |
1280 case 'edit_themes': |
402 case 'edit_themes': |
1281 // Disallow the file editors. |
403 // Disallow the file editors. |
1282 if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) |
404 if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) |
1283 $caps[] = 'do_not_allow'; |
405 $caps[] = 'do_not_allow'; |
1284 elseif ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) |
406 elseif ( ! wp_is_file_mod_allowed( 'capability_edit_themes' ) ) |
1285 $caps[] = 'do_not_allow'; |
407 $caps[] = 'do_not_allow'; |
1286 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) |
408 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) |
1287 $caps[] = 'do_not_allow'; |
409 $caps[] = 'do_not_allow'; |
1288 else |
410 else |
1289 $caps[] = $cap; |
411 $caps[] = $cap; |