[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Roles and Capabilities. 4 * 5 * @package WordPress 6 * @subpackage User 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 * <code> 17 * array ( 18 * 'rolename' => array ( 19 * 'name' => 'rolename', 20 * 'capabilities' => array() 21 * ) 22 * ) 23 * </code> 24 * 25 * @since 2.0.0 26 * @package WordPress 27 * @subpackage User 28 */ 29 class WP_Roles { 30 /** 31 * List of roles and capabilities. 32 * 33 * @since 2.0.0 34 * @access public 35 * @var array 36 */ 37 var $roles; 38 39 /** 40 * List of the role objects. 41 * 42 * @since 2.0.0 43 * @access public 44 * @var array 45 */ 46 var $role_objects = array(); 47 48 /** 49 * List of role names. 50 * 51 * @since 2.0.0 52 * @access public 53 * @var array 54 */ 55 var $role_names = array(); 56 57 /** 58 * Option name for storing role list. 59 * 60 * @since 2.0.0 61 * @access public 62 * @var string 63 */ 64 var $role_key; 65 66 /** 67 * Whether to use the database for retrieval and storage. 68 * 69 * @since 2.1.0 70 * @access public 71 * @var bool 72 */ 73 var $use_db = true; 74 75 /** 76 * Constructor 77 * 78 * @since 2.0.0 79 */ 80 function __construct() { 81 $this->_init(); 82 } 83 84 /** 85 * Set up the object properties. 86 * 87 * The role key is set to the current prefix for the $wpdb object with 88 * '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. 90 * 91 * @since 2.1.0 92 * @access protected 93 * @uses $wpdb Used to get the database prefix. 94 * @global array $wp_user_roles Used to set the 'roles' property value. 95 */ 96 function _init () { 97 global $wpdb, $wp_user_roles; 98 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; 99 if ( ! empty( $wp_user_roles ) ) { 100 $this->roles = $wp_user_roles; 101 $this->use_db = false; 102 } else { 103 $this->roles = get_option( $this->role_key ); 104 } 105 106 if ( empty( $this->roles ) ) 107 return; 108 109 $this->role_objects = array(); 110 $this->role_names = array(); 111 foreach ( array_keys( $this->roles ) as $role ) { 112 $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] ); 113 $this->role_names[$role] = $this->roles[$role]['name']; 114 } 115 } 116 117 /** 118 * Reinitialize the object 119 * 120 * Recreates the role objects. This is typically called only by switch_to_blog() 121 * after switching wpdb to a new blog ID. 122 * 123 * @since 3.5.0 124 * @access public 125 */ 126 function reinit() { 127 // There is no need to reinit if using the wp_user_roles global. 128 if ( ! $this->use_db ) 129 return; 130 131 global $wpdb, $wp_user_roles; 132 133 // Duplicated from _init() to avoid an extra function call. 134 $this->role_key = $wpdb->get_blog_prefix() . 'user_roles'; 135 $this->roles = get_option( $this->role_key ); 136 if ( empty( $this->roles ) ) 137 return; 138 139 $this->role_objects = array(); 140 $this->role_names = array(); 141 foreach ( array_keys( $this->roles ) as $role ) { 142 $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] ); 143 $this->role_names[$role] = $this->roles[$role]['name']; 144 } 145 } 146 147 /** 148 * Add role name with capabilities to list. 149 * 150 * Updates the list of roles, if the role doesn't already exist. 151 * 152 * The capabilities are defined in the following format `array( 'read' => true );` 153 * To explicitly deny a role a capability you set the value for that capability to false. 154 * 155 * @since 2.0.0 156 * @access public 157 * 158 * @param string $role Role name. 159 * @param string $display_name Role display name. 160 * @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. 162 */ 163 function add_role( $role, $display_name, $capabilities = array() ) { 164 if ( isset( $this->roles[$role] ) ) 165 return; 166 167 $this->roles[$role] = array( 168 'name' => $display_name, 169 'capabilities' => $capabilities 170 ); 171 if ( $this->use_db ) 172 update_option( $this->role_key, $this->roles ); 173 $this->role_objects[$role] = new WP_Role( $role, $capabilities ); 174 $this->role_names[$role] = $display_name; 175 return $this->role_objects[$role]; 176 } 177 178 /** 179 * Remove role by name. 180 * 181 * @since 2.0.0 182 * @access public 183 * 184 * @param string $role Role name. 185 */ 186 function remove_role( $role ) { 187 if ( ! isset( $this->role_objects[$role] ) ) 188 return; 189 190 unset( $this->role_objects[$role] ); 191 unset( $this->role_names[$role] ); 192 unset( $this->roles[$role] ); 193 194 if ( $this->use_db ) 195 update_option( $this->role_key, $this->roles ); 196 197 if ( get_option( 'default_role' ) == $role ) 198 update_option( 'default_role', 'subscriber' ); 199 } 200 201 /** 202 * Add capability to role. 203 * 204 * @since 2.0.0 205 * @access public 206 * 207 * @param string $role Role name. 208 * @param string $cap Capability name. 209 * @param bool $grant Optional, default is true. Whether role is capable of performing capability. 210 */ 211 function add_cap( $role, $cap, $grant = true ) { 212 if ( ! isset( $this->roles[$role] ) ) 213 return; 214 215 $this->roles[$role]['capabilities'][$cap] = $grant; 216 if ( $this->use_db ) 217 update_option( $this->role_key, $this->roles ); 218 } 219 220 /** 221 * Remove capability from role. 222 * 223 * @since 2.0.0 224 * @access public 225 * 226 * @param string $role Role name. 227 * @param string $cap Capability name. 228 */ 229 function remove_cap( $role, $cap ) { 230 if ( ! isset( $this->roles[$role] ) ) 231 return; 232 233 unset( $this->roles[$role]['capabilities'][$cap] ); 234 if ( $this->use_db ) 235 update_option( $this->role_key, $this->roles ); 236 } 237 238 /** 239 * Retrieve role object by name. 240 * 241 * @since 2.0.0 242 * @access public 243 * 244 * @param string $role Role name. 245 * @return WP_Role|null WP_Role object if found, null if the role does not exist. 246 */ 247 function get_role( $role ) { 248 if ( isset( $this->role_objects[$role] ) ) 249 return $this->role_objects[$role]; 250 else 251 return null; 252 } 253 254 /** 255 * Retrieve list of role names. 256 * 257 * @since 2.0.0 258 * @access public 259 * 260 * @return array List of role names. 261 */ 262 function get_names() { 263 return $this->role_names; 264 } 265 266 /** 267 * Whether role name is currently in the list of available roles. 268 * 269 * @since 2.0.0 270 * @access public 271 * 272 * @param string $role Role name to look up. 273 * @return bool 274 */ 275 function is_role( $role ) { 276 return isset( $this->role_names[$role] ); 277 } 278 } 279 280 /** 281 * WordPress Role class. 282 * 283 * @since 2.0.0 284 * @package WordPress 285 * @subpackage User 286 */ 287 class WP_Role { 288 /** 289 * Role name. 290 * 291 * @since 2.0.0 292 * @access public 293 * @var string 294 */ 295 var $name; 296 297 /** 298 * List of capabilities the role contains. 299 * 300 * @since 2.0.0 301 * @access public 302 * @var array 303 */ 304 var $capabilities; 305 306 /** 307 * Constructor - Set up object properties. 308 * 309 * The list of capabilities, must have the key as the name of the capability 310 * and the value a boolean of whether it is granted to the role. 311 * 312 * @since 2.0.0 313 * @access public 314 * 315 * @param string $role Role name. 316 * @param array $capabilities List of capabilities. 317 */ 318 function __construct( $role, $capabilities ) { 319 $this->name = $role; 320 $this->capabilities = $capabilities; 321 } 322 323 /** 324 * Assign role a capability. 325 * 326 * @see WP_Roles::add_cap() Method uses implementation for role. 327 * @since 2.0.0 328 * @access public 329 * 330 * @param string $cap Capability name. 331 * @param bool $grant Whether role has capability privilege. 332 */ 333 function add_cap( $cap, $grant = true ) { 334 global $wp_roles; 335 336 if ( ! isset( $wp_roles ) ) 337 $wp_roles = new WP_Roles(); 338 339 $this->capabilities[$cap] = $grant; 340 $wp_roles->add_cap( $this->name, $cap, $grant ); 341 } 342 343 /** 344 * Remove capability from role. 345 * 346 * This is a container for {@link WP_Roles::remove_cap()} to remove the 347 * capability from the role. That is to say, that {@link 348 * WP_Roles::remove_cap()} implements the functionality, but it also makes 349 * sense to use this class, because you don't need to enter the role name. 350 * 351 * @since 2.0.0 352 * @access public 353 * 354 * @param string $cap Capability name. 355 */ 356 function remove_cap( $cap ) { 357 global $wp_roles; 358 359 if ( ! isset( $wp_roles ) ) 360 $wp_roles = new WP_Roles(); 361 362 unset( $this->capabilities[$cap] ); 363 $wp_roles->remove_cap( $this->name, $cap ); 364 } 365 366 /** 367 * Whether role has capability. 368 * 369 * The capabilities is passed through the 'role_has_cap' filter. The first 370 * parameter for the hook is the list of capabilities the class has 371 * assigned. The second parameter is the capability name to look for. The 372 * third and final parameter for the hook is the role name. 373 * 374 * @since 2.0.0 375 * @access public 376 * 377 * @param string $cap Capability name. 378 * @return bool True, if user has capability. False, if doesn't have capability. 379 */ 380 function has_cap( $cap ) { 381 /** 382 * Filter which capabilities a role has. 383 * 384 * @since 2.0.0 385 * 386 * @param array $capabilities Array of role capabilities. 387 * @param string $cap Capability name. 388 * @param string $name Role name. 389 */ 390 $capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name ); 391 if ( !empty( $capabilities[$cap] ) ) 392 return $capabilities[$cap]; 393 else 394 return false; 395 } 396 397 } 398 399 /** 400 * WordPress User class. 401 * 402 * @since 2.0.0 403 * @package WordPress 404 * @subpackage User 405 */ 406 class WP_User { 407 /** 408 * User data container. 409 * 410 * @since 2.0.0 411 * @access private 412 * @var array 413 */ 414 var $data; 415 416 /** 417 * The user's ID. 418 * 419 * @since 2.1.0 420 * @access public 421 * @var int 422 */ 423 var $ID = 0; 424 425 /** 426 * The individual capabilities the user has been given. 427 * 428 * @since 2.0.0 429 * @access public 430 * @var array 431 */ 432 var $caps = array(); 433 434 /** 435 * User metadata option name. 436 * 437 * @since 2.0.0 438 * @access public 439 * @var string 440 */ 441 var $cap_key; 442 443 /** 444 * The roles the user is part of. 445 * 446 * @since 2.0.0 447 * @access public 448 * @var array 449 */ 450 var $roles = array(); 451 452 /** 453 * All capabilities the user has, including individual and role based. 454 * 455 * @since 2.0.0 456 * @access public 457 * @var array 458 */ 459 var $allcaps = array(); 460 461 /** 462 * The filter context applied to user data fields. 463 * 464 * @since 2.9.0 465 * @access private 466 * @var string 467 */ 468 var $filter = null; 469 470 private static $back_compat_keys; 471 472 /** 473 * Constructor 474 * 475 * Retrieves the userdata and passes it to {@link WP_User::init()}. 476 * 477 * @since 2.0.0 478 * @access public 479 * 480 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB. 481 * @param string $name Optional. User's username 482 * @param int $blog_id Optional Blog ID, defaults to current blog. 483 * @return WP_User 484 */ 485 function __construct( $id = 0, $name = '', $blog_id = '' ) { 486 if ( ! isset( self::$back_compat_keys ) ) { 487 $prefix = $GLOBALS['wpdb']->prefix; 488 self::$back_compat_keys = array( 489 'user_firstname' => 'first_name', 490 'user_lastname' => 'last_name', 491 'user_description' => 'description', 492 'user_level' => $prefix . 'user_level', 493 $prefix . 'usersettings' => $prefix . 'user-settings', 494 $prefix . 'usersettingstime' => $prefix . 'user-settings-time', 495 ); 496 } 497 498 if ( is_a( $id, 'WP_User' ) ) { 499 $this->init( $id->data, $blog_id ); 500 return; 501 } elseif ( is_object( $id ) ) { 502 $this->init( $id, $blog_id ); 503 return; 504 } 505 506 if ( ! empty( $id ) && ! is_numeric( $id ) ) { 507 $name = $id; 508 $id = 0; 509 } 510 511 if ( $id ) 512 $data = self::get_data_by( 'id', $id ); 513 else 514 $data = self::get_data_by( 'login', $name ); 515 516 if ( $data ) 517 $this->init( $data, $blog_id ); 518 } 519 520 /** 521 * Sets up object properties, including capabilities. 522 * 523 * @param object $data User DB row object 524 * @param int $blog_id Optional. The blog id to initialize for 525 */ 526 function init( $data, $blog_id = '' ) { 527 $this->data = $data; 528 $this->ID = (int) $data->ID; 529 530 $this->for_blog( $blog_id ); 531 } 532 533 /** 534 * Return only the main user fields 535 * 536 * @since 3.3.0 537 * 538 * @param string $field The field to query against: 'id', 'slug', 'email' or 'login' 539 * @param string|int $value The field value 540 * @return object Raw user object 541 */ 542 static function get_data_by( $field, $value ) { 543 global $wpdb; 544 545 if ( 'id' == $field ) { 546 // Make sure the value is numeric to avoid casting objects, for example, 547 // to int 1. 548 if ( ! is_numeric( $value ) ) 549 return false; 550 $value = intval( $value ); 551 if ( $value < 1 ) 552 return false; 553 } else { 554 $value = trim( $value ); 555 } 556 557 if ( !$value ) 558 return false; 559 560 switch ( $field ) { 561 case 'id': 562 $user_id = $value; 563 $db_field = 'ID'; 564 break; 565 case 'slug': 566 $user_id = wp_cache_get($value, 'userslugs'); 567 $db_field = 'user_nicename'; 568 break; 569 case 'email': 570 $user_id = wp_cache_get($value, 'useremail'); 571 $db_field = 'user_email'; 572 break; 573 case 'login': 574 $value = sanitize_user( $value ); 575 $user_id = wp_cache_get($value, 'userlogins'); 576 $db_field = 'user_login'; 577 break; 578 default: 579 return false; 580 } 581 582 if ( false !== $user_id ) { 583 if ( $user = wp_cache_get( $user_id, 'users' ) ) 584 return $user; 585 } 586 587 if ( !$user = $wpdb->get_row( $wpdb->prepare( 588 "SELECT * FROM $wpdb->users WHERE $db_field = %s", $value 589 ) ) ) 590 return false; 591 592 update_user_caches( $user ); 593 594 return $user; 595 } 596 597 /** 598 * Magic method for checking the existence of a certain custom field 599 * 600 * @since 3.3.0 601 */ 602 function __isset( $key ) { 603 if ( 'id' == $key ) { 604 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); 605 $key = 'ID'; 606 } 607 608 if ( isset( $this->data->$key ) ) 609 return true; 610 611 if ( isset( self::$back_compat_keys[ $key ] ) ) 612 $key = self::$back_compat_keys[ $key ]; 613 614 return metadata_exists( 'user', $this->ID, $key ); 615 } 616 617 /** 618 * Magic method for accessing custom fields 619 * 620 * @since 3.3.0 621 */ 622 function __get( $key ) { 623 if ( 'id' == $key ) { 624 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); 625 return $this->ID; 626 } 627 628 if ( isset( $this->data->$key ) ) { 629 $value = $this->data->$key; 630 } else { 631 if ( isset( self::$back_compat_keys[ $key ] ) ) 632 $key = self::$back_compat_keys[ $key ]; 633 $value = get_user_meta( $this->ID, $key, true ); 634 } 635 636 if ( $this->filter ) { 637 $value = sanitize_user_field( $key, $value, $this->ID, $this->filter ); 638 } 639 640 return $value; 641 } 642 643 /** 644 * Magic method for setting custom fields 645 * 646 * @since 3.3.0 647 */ 648 function __set( $key, $value ) { 649 if ( 'id' == $key ) { 650 _deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) ); 651 $this->ID = $value; 652 return; 653 } 654 655 $this->data->$key = $value; 656 } 657 658 /** 659 * Determine whether the user exists in the database. 660 * 661 * @since 3.4.0 662 * @access public 663 * 664 * @return bool True if user exists in the database, false if not. 665 */ 666 function exists() { 667 return ! empty( $this->ID ); 668 } 669 670 /** 671 * Retrieve the value of a property or meta key. 672 * 673 * Retrieves from the users and usermeta table. 674 * 675 * @since 3.3.0 676 * 677 * @param string $key Property 678 */ 679 function get( $key ) { 680 return $this->__get( $key ); 681 } 682 683 /** 684 * Determine whether a property or meta key is set 685 * 686 * Consults the users and usermeta tables. 687 * 688 * @since 3.3.0 689 * 690 * @param string $key Property 691 */ 692 function has_prop( $key ) { 693 return $this->__isset( $key ); 694 } 695 696 /** 697 * Return an array representation. 698 * 699 * @since 3.5.0 700 * 701 * @return array Array representation. 702 */ 703 function to_array() { 704 return get_object_vars( $this->data ); 705 } 706 707 /** 708 * Set up capability object properties. 709 * 710 * Will set the value for the 'cap_key' property to current database table 711 * prefix, followed by 'capabilities'. Will then check to see if the 712 * property matching the 'cap_key' exists and is an array. If so, it will be 713 * used. 714 * 715 * @access protected 716 * @since 2.1.0 717 * 718 * @param string $cap_key Optional capability key 719 */ 720 function _init_caps( $cap_key = '' ) { 721 global $wpdb; 722 723 if ( empty($cap_key) ) 724 $this->cap_key = $wpdb->get_blog_prefix() . 'capabilities'; 725 else 726 $this->cap_key = $cap_key; 727 728 $this->caps = get_user_meta( $this->ID, $this->cap_key, true ); 729 730 if ( ! is_array( $this->caps ) ) 731 $this->caps = array(); 732 733 $this->get_role_caps(); 734 } 735 736 /** 737 * Retrieve all of the role capabilities and merge with individual capabilities. 738 * 739 * All of the capabilities of the roles the user belongs to are merged with 740 * the users individual roles. This also means that the user can be denied 741 * specific roles that their role might have, but the specific user isn't 742 * granted permission to. 743 * 744 * @since 2.0.0 745 * @uses $wp_roles 746 * @access public 747 * 748 * @return array List of all capabilities for the user. 749 */ 750 function get_role_caps() { 751 global $wp_roles; 752 753 if ( ! isset( $wp_roles ) ) 754 $wp_roles = new WP_Roles(); 755 756 //Filter out caps that are not role names and assign to $this->roles 757 if ( is_array( $this->caps ) ) 758 $this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) ); 759 760 //Build $allcaps from role caps, overlay user's $caps 761 $this->allcaps = array(); 762 foreach ( (array) $this->roles as $role ) { 763 $the_role = $wp_roles->get_role( $role ); 764 $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities ); 765 } 766 $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps ); 767 768 return $this->allcaps; 769 } 770 771 /** 772 * Add role to user. 773 * 774 * Updates the user's meta data option with capabilities and roles. 775 * 776 * @since 2.0.0 777 * @access public 778 * 779 * @param string $role Role name. 780 */ 781 function add_role( $role ) { 782 $this->caps[$role] = true; 783 update_user_meta( $this->ID, $this->cap_key, $this->caps ); 784 $this->get_role_caps(); 785 $this->update_user_level_from_caps(); 786 } 787 788 /** 789 * Remove role from user. 790 * 791 * @since 2.0.0 792 * @access public 793 * 794 * @param string $role Role name. 795 */ 796 function remove_role( $role ) { 797 if ( !in_array($role, $this->roles) ) 798 return; 799 unset( $this->caps[$role] ); 800 update_user_meta( $this->ID, $this->cap_key, $this->caps ); 801 $this->get_role_caps(); 802 $this->update_user_level_from_caps(); 803 } 804 805 /** 806 * Set the role of the user. 807 * 808 * This will remove the previous roles of the user and assign the user the 809 * new one. You can set the role to an empty string and it will remove all 810 * of the roles from the user. 811 * 812 * @since 2.0.0 813 * @access public 814 * 815 * @param string $role Role name. 816 */ 817 function set_role( $role ) { 818 if ( 1 == count( $this->roles ) && $role == current( $this->roles ) ) 819 return; 820 821 foreach ( (array) $this->roles as $oldrole ) 822 unset( $this->caps[$oldrole] ); 823 824 $old_roles = $this->roles; 825 if ( !empty( $role ) ) { 826 $this->caps[$role] = true; 827 $this->roles = array( $role => true ); 828 } else { 829 $this->roles = false; 830 } 831 update_user_meta( $this->ID, $this->cap_key, $this->caps ); 832 $this->get_role_caps(); 833 $this->update_user_level_from_caps(); 834 835 /** 836 * Fires after the user's role has changed. 837 * 838 * @since 2.9.0 839 * @since 3.6.0 Added $old_roles to include an array of the user's previous roles. 840 * 841 * @param int $user_id The user ID. 842 * @param string $role The new role. 843 * @param array $old_roles An array of the user's previous roles. 844 */ 845 do_action( 'set_user_role', $this->ID, $role, $old_roles ); 846 } 847 848 /** 849 * Choose the maximum level the user has. 850 * 851 * Will compare the level from the $item parameter against the $max 852 * parameter. If the item is incorrect, then just the $max parameter value 853 * will be returned. 854 * 855 * Used to get the max level based on the capabilities the user has. This 856 * is also based on roles, so if the user is assigned the Administrator role 857 * then the capability 'level_10' will exist and the user will get that 858 * value. 859 * 860 * @since 2.0.0 861 * @access public 862 * 863 * @param int $max Max level of user. 864 * @param string $item Level capability name. 865 * @return int Max Level. 866 */ 867 function level_reduction( $max, $item ) { 868 if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { 869 $level = intval( $matches[1] ); 870 return max( $max, $level ); 871 } else { 872 return $max; 873 } 874 } 875 876 /** 877 * Update the maximum user level for the user. 878 * 879 * Updates the 'user_level' user metadata (includes prefix that is the 880 * database table prefix) with the maximum user level. Gets the value from 881 * the all of the capabilities that the user has. 882 * 883 * @since 2.0.0 884 * @access public 885 */ 886 function update_user_level_from_caps() { 887 global $wpdb; 888 $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); 889 update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); 890 } 891 892 /** 893 * Add capability and grant or deny access to capability. 894 * 895 * @since 2.0.0 896 * @access public 897 * 898 * @param string $cap Capability name. 899 * @param bool $grant Whether to grant capability to user. 900 */ 901 function add_cap( $cap, $grant = true ) { 902 $this->caps[$cap] = $grant; 903 update_user_meta( $this->ID, $this->cap_key, $this->caps ); 904 } 905 906 /** 907 * Remove capability from user. 908 * 909 * @since 2.0.0 910 * @access public 911 * 912 * @param string $cap Capability name. 913 */ 914 function remove_cap( $cap ) { 915 if ( ! isset( $this->caps[$cap] ) ) 916 return; 917 unset( $this->caps[$cap] ); 918 update_user_meta( $this->ID, $this->cap_key, $this->caps ); 919 } 920 921 /** 922 * Remove all of the capabilities of the user. 923 * 924 * @since 2.1.0 925 * @access public 926 */ 927 function remove_all_caps() { 928 global $wpdb; 929 $this->caps = array(); 930 delete_user_meta( $this->ID, $this->cap_key ); 931 delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); 932 $this->get_role_caps(); 933 } 934 935 /** 936 * Whether user has capability or role name. 937 * 938 * This is useful for looking up whether the user has a specific role 939 * assigned to the user. The second optional parameter can also be used to 940 * check for capabilities against a specific object, such as a post or user. 941 * 942 * @since 2.0.0 943 * @access public 944 * 945 * @param string|int $cap Capability or role name to search. 946 * @return bool True, if user has capability; false, if user does not have capability. 947 */ 948 function has_cap( $cap ) { 949 if ( is_numeric( $cap ) ) { 950 _deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); 951 $cap = $this->translate_level_to_cap( $cap ); 952 } 953 954 $args = array_slice( func_get_args(), 1 ); 955 $args = array_merge( array( $cap, $this->ID ), $args ); 956 $caps = call_user_func_array( 'map_meta_cap', $args ); 957 958 // Multisite super admin has all caps by definition, Unless specifically denied. 959 if ( is_multisite() && is_super_admin( $this->ID ) ) { 960 if ( in_array('do_not_allow', $caps) ) 961 return false; 962 return true; 963 } 964 965 /** 966 * Dynamically filter a user's capabilities. 967 * 968 * @since 2.0.0 969 * @since 3.7.0 Added the user object. 970 * 971 * @param array $allcaps An array of all the role's capabilities. 972 * @param array $caps Actual capabilities for meta capability. 973 * @param array $args Optional parameters passed to has_cap(), typically object ID. 974 * @param WP_User $user The user object. 975 */ 976 // Must have ALL requested caps 977 $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); 978 $capabilities['exist'] = true; // Everyone is allowed to exist 979 foreach ( (array) $caps as $cap ) { 980 if ( empty( $capabilities[ $cap ] ) ) 981 return false; 982 } 983 984 return true; 985 } 986 987 /** 988 * Convert numeric level to level capability name. 989 * 990 * Prepends 'level_' to level number. 991 * 992 * @since 2.0.0 993 * @access public 994 * 995 * @param int $level Level number, 1 to 10. 996 * @return string 997 */ 998 function translate_level_to_cap( $level ) { 999 return 'level_' . $level; 1000 } 1001 1002 /** 1003 * Set the blog to operate on. Defaults to the current blog. 1004 * 1005 * @since 3.0.0 1006 * 1007 * @param int $blog_id Optional Blog ID, defaults to current blog. 1008 */ 1009 function for_blog( $blog_id = '' ) { 1010 global $wpdb; 1011 if ( ! empty( $blog_id ) ) 1012 $cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; 1013 else 1014 $cap_key = ''; 1015 $this->_init_caps( $cap_key ); 1016 } 1017 } 1018 1019 /** 1020 * Map meta capabilities to primitive capabilities. 1021 * 1022 * This does not actually compare whether the user ID has the actual capability, 1023 * just what the capability or capabilities are. Meta capability list value can 1024 * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post', 1025 * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'. 1026 * 1027 * @since 2.0.0 1028 * 1029 * @param string $cap Capability name. 1030 * @param int $user_id User ID. 1031 * @return array Actual capabilities for meta capability. 1032 */ 1033 function map_meta_cap( $cap, $user_id ) { 1034 $args = array_slice( func_get_args(), 2 ); 1035 $caps = array(); 1036 1037 switch ( $cap ) { 1038 case 'remove_user': 1039 $caps[] = 'remove_users'; 1040 break; 1041 case 'promote_user': 1042 $caps[] = 'promote_users'; 1043 break; 1044 case 'edit_user': 1045 case 'edit_users': 1046 // Allow user to edit itself 1047 if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] ) 1048 break; 1049 1050 // If multisite these caps are allowed only for super admins. 1051 if ( is_multisite() && !is_super_admin( $user_id ) ) 1052 $caps[] = 'do_not_allow'; 1053 else 1054 $caps[] = 'edit_users'; // edit_user maps to edit_users. 1055 break; 1056 case 'delete_post': 1057 case 'delete_page': 1058 $post = get_post( $args[0] ); 1059 1060 if ( 'revision' == $post->post_type ) { 1061 $post = get_post( $post->post_parent ); 1062 } 1063 1064 $post_type = get_post_type_object( $post->post_type ); 1065 1066 if ( ! $post_type->map_meta_cap ) { 1067 $caps[] = $post_type->cap->$cap; 1068 // Prior to 3.1 we would re-call map_meta_cap here. 1069 if ( 'delete_post' == $cap ) 1070 $cap = $post_type->cap->$cap; 1071 break; 1072 } 1073 1074 $post_author_id = $post->post_author; 1075 1076 // If no author set yet, default to current user for cap checks. 1077 if ( ! $post_author_id ) 1078 $post_author_id = $user_id; 1079 1080 // If the user is the author... 1081 if ( $user_id == $post_author_id ) { 1082 // If the post is published... 1083 if ( 'publish' == $post->post_status ) { 1084 $caps[] = $post_type->cap->delete_published_posts; 1085 } elseif ( 'trash' == $post->post_status ) { 1086 if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) 1087 $caps[] = $post_type->cap->delete_published_posts; 1088 } else { 1089 // If the post is draft... 1090 $caps[] = $post_type->cap->delete_posts; 1091 } 1092 } else { 1093 // The user is trying to edit someone else's post. 1094 $caps[] = $post_type->cap->delete_others_posts; 1095 // The post is published, extra cap required. 1096 if ( 'publish' == $post->post_status ) 1097 $caps[] = $post_type->cap->delete_published_posts; 1098 elseif ( 'private' == $post->post_status ) 1099 $caps[] = $post_type->cap->delete_private_posts; 1100 } 1101 break; 1102 // edit_post breaks down to edit_posts, edit_published_posts, or 1103 // edit_others_posts 1104 case 'edit_post': 1105 case 'edit_page': 1106 $post = get_post( $args[0] ); 1107 if ( empty( $post ) ) 1108 break; 1109 1110 if ( 'revision' == $post->post_type ) { 1111 $post = get_post( $post->post_parent ); 1112 } 1113 1114 $post_type = get_post_type_object( $post->post_type ); 1115 1116 if ( ! $post_type->map_meta_cap ) { 1117 $caps[] = $post_type->cap->$cap; 1118 // Prior to 3.1 we would re-call map_meta_cap here. 1119 if ( 'edit_post' == $cap ) 1120 $cap = $post_type->cap->$cap; 1121 break; 1122 } 1123 1124 $post_author_id = $post->post_author; 1125 1126 // If no author set yet, default to current user for cap checks. 1127 if ( ! $post_author_id ) 1128 $post_author_id = $user_id; 1129 1130 // If the user is the author... 1131 if ( $user_id == $post_author_id ) { 1132 // If the post is published... 1133 if ( 'publish' == $post->post_status ) { 1134 $caps[] = $post_type->cap->edit_published_posts; 1135 } elseif ( 'trash' == $post->post_status ) { 1136 if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) 1137 $caps[] = $post_type->cap->edit_published_posts; 1138 } else { 1139 // If the post is draft... 1140 $caps[] = $post_type->cap->edit_posts; 1141 } 1142 } else { 1143 // The user is trying to edit someone else's post. 1144 $caps[] = $post_type->cap->edit_others_posts; 1145 // The post is published, extra cap required. 1146 if ( 'publish' == $post->post_status ) 1147 $caps[] = $post_type->cap->edit_published_posts; 1148 elseif ( 'private' == $post->post_status ) 1149 $caps[] = $post_type->cap->edit_private_posts; 1150 } 1151 break; 1152 case 'read_post': 1153 case 'read_page': 1154 $post = get_post( $args[0] ); 1155 1156 if ( 'revision' == $post->post_type ) { 1157 $post = get_post( $post->post_parent ); 1158 } 1159 1160 $post_type = get_post_type_object( $post->post_type ); 1161 1162 if ( ! $post_type->map_meta_cap ) { 1163 $caps[] = $post_type->cap->$cap; 1164 // Prior to 3.1 we would re-call map_meta_cap here. 1165 if ( 'read_post' == $cap ) 1166 $cap = $post_type->cap->$cap; 1167 break; 1168 } 1169 1170 $status_obj = get_post_status_object( $post->post_status ); 1171 if ( $status_obj->public ) { 1172 $caps[] = $post_type->cap->read; 1173 break; 1174 } 1175 1176 $post_author_id = $post->post_author; 1177 1178 // If no author set yet, default to current user for cap checks. 1179 if ( ! $post_author_id ) 1180 $post_author_id = $user_id; 1181 1182 if ( $user_id == $post_author_id ) 1183 $caps[] = $post_type->cap->read; 1184 elseif ( $status_obj->private ) 1185 $caps[] = $post_type->cap->read_private_posts; 1186 else 1187 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 1188 break; 1189 case 'publish_post': 1190 $post = get_post( $args[0] ); 1191 $post_type = get_post_type_object( $post->post_type ); 1192 1193 $caps[] = $post_type->cap->publish_posts; 1194 break; 1195 case 'edit_post_meta': 1196 case 'delete_post_meta': 1197 case 'add_post_meta': 1198 $post = get_post( $args[0] ); 1199 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 1200 1201 $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false; 1202 1203 if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) { 1204 /** 1205 * Filter whether the user is allowed to add post meta to a post. 1206 * 1207 * The dynamic portion of the hook name, $meta_key, refers to the 1208 * meta key passed to map_meta_cap(). 1209 * 1210 * @since 3.3.0 1211 * 1212 * @param bool $allowed Whether the user can add the post meta. Default false. 1213 * @param string $meta_key The meta key. 1214 * @param int $post_id Post ID. 1215 * @param int $user_id User ID. 1216 * @param string $cap Capability name. 1217 * @param array $caps User capabilities. 1218 */ 1219 $allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps ); 1220 if ( ! $allowed ) 1221 $caps[] = $cap; 1222 } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) { 1223 $caps[] = $cap; 1224 } 1225 break; 1226 case 'edit_comment': 1227 $comment = get_comment( $args[0] ); 1228 if ( empty( $comment ) ) 1229 break; 1230 $post = get_post( $comment->comment_post_ID ); 1231 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 1232 break; 1233 case 'unfiltered_upload': 1234 if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) ) 1235 $caps[] = $cap; 1236 else 1237 $caps[] = 'do_not_allow'; 1238 break; 1239 case 'unfiltered_html' : 1240 // Disallow unfiltered_html for all users, even admins and super admins. 1241 if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) 1242 $caps[] = 'do_not_allow'; 1243 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) 1244 $caps[] = 'do_not_allow'; 1245 else 1246 $caps[] = $cap; 1247 break; 1248 case 'edit_files': 1249 case 'edit_plugins': 1250 case 'edit_themes': 1251 // Disallow the file editors. 1252 if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) 1253 $caps[] = 'do_not_allow'; 1254 elseif ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) 1255 $caps[] = 'do_not_allow'; 1256 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) 1257 $caps[] = 'do_not_allow'; 1258 else 1259 $caps[] = $cap; 1260 break; 1261 case 'update_plugins': 1262 case 'delete_plugins': 1263 case 'install_plugins': 1264 case 'update_themes': 1265 case 'delete_themes': 1266 case 'install_themes': 1267 case 'update_core': 1268 // Disallow anything that creates, deletes, or updates core, plugin, or theme files. 1269 // Files in uploads are excepted. 1270 if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) 1271 $caps[] = 'do_not_allow'; 1272 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) 1273 $caps[] = 'do_not_allow'; 1274 else 1275 $caps[] = $cap; 1276 break; 1277 case 'activate_plugins': 1278 $caps[] = $cap; 1279 if ( is_multisite() ) { 1280 // update_, install_, and delete_ are handled above with is_super_admin(). 1281 $menu_perms = get_site_option( 'menu_items', array() ); 1282 if ( empty( $menu_perms['plugins'] ) ) 1283 $caps[] = 'manage_network_plugins'; 1284 } 1285 break; 1286 case 'delete_user': 1287 case 'delete_users': 1288 // If multisite only super admins can delete users. 1289 if ( is_multisite() && ! is_super_admin( $user_id ) ) 1290 $caps[] = 'do_not_allow'; 1291 else 1292 $caps[] = 'delete_users'; // delete_user maps to delete_users. 1293 break; 1294 case 'create_users': 1295 if ( !is_multisite() ) 1296 $caps[] = $cap; 1297 elseif ( is_super_admin() || get_site_option( 'add_new_users' ) ) 1298 $caps[] = $cap; 1299 else 1300 $caps[] = 'do_not_allow'; 1301 break; 1302 case 'manage_links' : 1303 if ( get_option( 'link_manager_enabled' ) ) 1304 $caps[] = $cap; 1305 else 1306 $caps[] = 'do_not_allow'; 1307 break; 1308 default: 1309 // Handle meta capabilities for custom post types. 1310 $post_type_meta_caps = _post_type_meta_capabilities(); 1311 if ( isset( $post_type_meta_caps[ $cap ] ) ) { 1312 $args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args ); 1313 return call_user_func_array( 'map_meta_cap', $args ); 1314 } 1315 1316 // If no meta caps match, return the original cap. 1317 $caps[] = $cap; 1318 } 1319 1320 /** 1321 * Filter a user's capabilities depending on specific context and/or privilege. 1322 * 1323 * @since 2.8.0 1324 * 1325 * @param array $caps Returns the user's actual capabilities. 1326 * @param string $cap Capability name. 1327 * @param int $user_id The user ID. 1328 * @param array $args Adds the context to the cap. Typically the object ID. 1329 */ 1330 return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); 1331 } 1332 1333 /** 1334 * Whether current user has capability or role. 1335 * 1336 * @since 2.0.0 1337 * 1338 * @param string $capability Capability or role name. 1339 * @return bool 1340 */ 1341 function current_user_can( $capability ) { 1342 $current_user = wp_get_current_user(); 1343 1344 if ( empty( $current_user ) ) 1345 return false; 1346 1347 $args = array_slice( func_get_args(), 1 ); 1348 $args = array_merge( array( $capability ), $args ); 1349 1350 return call_user_func_array( array( $current_user, 'has_cap' ), $args ); 1351 } 1352 1353 /** 1354 * Whether current user has a capability or role for a given blog. 1355 * 1356 * @since 3.0.0 1357 * 1358 * @param int $blog_id Blog ID 1359 * @param string $capability Capability or role name. 1360 * @return bool 1361 */ 1362 function current_user_can_for_blog( $blog_id, $capability ) { 1363 if ( is_multisite() ) 1364 switch_to_blog( $blog_id ); 1365 1366 $current_user = wp_get_current_user(); 1367 1368 if ( empty( $current_user ) ) 1369 return false; 1370 1371 $args = array_slice( func_get_args(), 2 ); 1372 $args = array_merge( array( $capability ), $args ); 1373 1374 $can = call_user_func_array( array( $current_user, 'has_cap' ), $args ); 1375 1376 if ( is_multisite() ) 1377 restore_current_blog(); 1378 1379 return $can; 1380 } 1381 1382 /** 1383 * Whether author of supplied post has capability or role. 1384 * 1385 * @since 2.9.0 1386 * 1387 * @param int|object $post Post ID or post object. 1388 * @param string $capability Capability or role name. 1389 * @return bool 1390 */ 1391 function author_can( $post, $capability ) { 1392 if ( !$post = get_post($post) ) 1393 return false; 1394 1395 $author = get_userdata( $post->post_author ); 1396 1397 if ( ! $author ) 1398 return false; 1399 1400 $args = array_slice( func_get_args(), 2 ); 1401 $args = array_merge( array( $capability ), $args ); 1402 1403 return call_user_func_array( array( $author, 'has_cap' ), $args ); 1404 } 1405 1406 /** 1407 * Whether a particular user has capability or role. 1408 * 1409 * @since 3.1.0 1410 * 1411 * @param int|object $user User ID or object. 1412 * @param string $capability Capability or role name. 1413 * @return bool 1414 */ 1415 function user_can( $user, $capability ) { 1416 if ( ! is_object( $user ) ) 1417 $user = get_userdata( $user ); 1418 1419 if ( ! $user || ! $user->exists() ) 1420 return false; 1421 1422 $args = array_slice( func_get_args(), 2 ); 1423 $args = array_merge( array( $capability ), $args ); 1424 1425 return call_user_func_array( array( $user, 'has_cap' ), $args ); 1426 } 1427 1428 /** 1429 * Retrieve role object. 1430 * 1431 * @see WP_Roles::get_role() Uses method to retrieve role object. 1432 * @since 2.0.0 1433 * 1434 * @param string $role Role name. 1435 * @return WP_Role|null WP_Role object if found, null if the role does not exist. 1436 */ 1437 function get_role( $role ) { 1438 global $wp_roles; 1439 1440 if ( ! isset( $wp_roles ) ) 1441 $wp_roles = new WP_Roles(); 1442 1443 return $wp_roles->get_role( $role ); 1444 } 1445 1446 /** 1447 * Add role, if it does not exist. 1448 * 1449 * @see WP_Roles::add_role() Uses method to add role. 1450 * @since 2.0.0 1451 * 1452 * @param string $role Role name. 1453 * @param string $display_name Display name for role. 1454 * @param array $capabilities List of capabilities, e.g. array( 'edit_posts' => true, 'delete_posts' => false ); 1455 * @return WP_Role|null WP_Role object if role is added, null if already exists. 1456 */ 1457 function add_role( $role, $display_name, $capabilities = array() ) { 1458 global $wp_roles; 1459 1460 if ( ! isset( $wp_roles ) ) 1461 $wp_roles = new WP_Roles(); 1462 1463 return $wp_roles->add_role( $role, $display_name, $capabilities ); 1464 } 1465 1466 /** 1467 * Remove role, if it exists. 1468 * 1469 * @see WP_Roles::remove_role() Uses method to remove role. 1470 * @since 2.0.0 1471 * 1472 * @param string $role Role name. 1473 */ 1474 function remove_role( $role ) { 1475 global $wp_roles; 1476 1477 if ( ! isset( $wp_roles ) ) 1478 $wp_roles = new WP_Roles(); 1479 1480 $wp_roles->remove_role( $role ); 1481 } 1482 1483 /** 1484 * Retrieve a list of super admins. 1485 * 1486 * @since 3.0.0 1487 * 1488 * @uses $super_admins Super admins global variable, if set. 1489 * 1490 * @return array List of super admin logins 1491 */ 1492 function get_super_admins() { 1493 global $super_admins; 1494 1495 if ( isset($super_admins) ) 1496 return $super_admins; 1497 else 1498 return get_site_option( 'site_admins', array('admin') ); 1499 } 1500 1501 /** 1502 * Determine if user is a site admin. 1503 * 1504 * @since 3.0.0 1505 * 1506 * @param int $user_id (Optional) The ID of a user. Defaults to the current user. 1507 * @return bool True if the user is a site admin. 1508 */ 1509 function is_super_admin( $user_id = false ) { 1510 if ( ! $user_id || $user_id == get_current_user_id() ) 1511 $user = wp_get_current_user(); 1512 else 1513 $user = get_userdata( $user_id ); 1514 1515 if ( ! $user || ! $user->exists() ) 1516 return false; 1517 1518 if ( is_multisite() ) { 1519 $super_admins = get_super_admins(); 1520 if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) 1521 return true; 1522 } else { 1523 if ( $user->has_cap('delete_users') ) 1524 return true; 1525 } 1526 1527 return false; 1528 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |