[ Index ]

PHP Cross Reference of WordPress

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


Generated: Wed Feb 8 03:55:56 2012 Hosted by follow the white rabbit.