[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ -> capabilities.php (source)

   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  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu