wp/wp-includes/capabilities.php
changeset 0 d970ebf37754
child 5 5e2f62d02dcd
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     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 		$capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name );
       
   382 		if ( !empty( $capabilities[$cap] ) )
       
   383 			return $capabilities[$cap];
       
   384 		else
       
   385 			return false;
       
   386 	}
       
   387 
       
   388 }
       
   389 
       
   390 /**
       
   391  * WordPress User class.
       
   392  *
       
   393  * @since 2.0.0
       
   394  * @package WordPress
       
   395  * @subpackage User
       
   396  */
       
   397 class WP_User {
       
   398 	/**
       
   399 	 * User data container.
       
   400 	 *
       
   401 	 * @since 2.0.0
       
   402 	 * @access private
       
   403 	 * @var array
       
   404 	 */
       
   405 	var $data;
       
   406 
       
   407 	/**
       
   408 	 * The user's ID.
       
   409 	 *
       
   410 	 * @since 2.1.0
       
   411 	 * @access public
       
   412 	 * @var int
       
   413 	 */
       
   414 	var $ID = 0;
       
   415 
       
   416 	/**
       
   417 	 * The individual capabilities the user has been given.
       
   418 	 *
       
   419 	 * @since 2.0.0
       
   420 	 * @access public
       
   421 	 * @var array
       
   422 	 */
       
   423 	var $caps = array();
       
   424 
       
   425 	/**
       
   426 	 * User metadata option name.
       
   427 	 *
       
   428 	 * @since 2.0.0
       
   429 	 * @access public
       
   430 	 * @var string
       
   431 	 */
       
   432 	var $cap_key;
       
   433 
       
   434 	/**
       
   435 	 * The roles the user is part of.
       
   436 	 *
       
   437 	 * @since 2.0.0
       
   438 	 * @access public
       
   439 	 * @var array
       
   440 	 */
       
   441 	var $roles = array();
       
   442 
       
   443 	/**
       
   444 	 * All capabilities the user has, including individual and role based.
       
   445 	 *
       
   446 	 * @since 2.0.0
       
   447 	 * @access public
       
   448 	 * @var array
       
   449 	 */
       
   450 	var $allcaps = array();
       
   451 
       
   452 	/**
       
   453 	 * The filter context applied to user data fields.
       
   454 	 *
       
   455 	 * @since 2.9.0
       
   456 	 * @access private
       
   457 	 * @var string
       
   458 	 */
       
   459 	var $filter = null;
       
   460 
       
   461 	private static $back_compat_keys;
       
   462 
       
   463 	/**
       
   464 	 * Constructor
       
   465 	 *
       
   466 	 * Retrieves the userdata and passes it to {@link WP_User::init()}.
       
   467 	 *
       
   468 	 * @since 2.0.0
       
   469 	 * @access public
       
   470 	 *
       
   471 	 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB.
       
   472 	 * @param string $name Optional. User's username
       
   473 	 * @param int $blog_id Optional Blog ID, defaults to current blog.
       
   474 	 * @return WP_User
       
   475 	 */
       
   476 	function __construct( $id = 0, $name = '', $blog_id = '' ) {
       
   477 		if ( ! isset( self::$back_compat_keys ) ) {
       
   478 			$prefix = $GLOBALS['wpdb']->prefix;
       
   479 			self::$back_compat_keys = array(
       
   480 				'user_firstname' => 'first_name',
       
   481 				'user_lastname' => 'last_name',
       
   482 				'user_description' => 'description',
       
   483 				'user_level' => $prefix . 'user_level',
       
   484 				$prefix . 'usersettings' => $prefix . 'user-settings',
       
   485 				$prefix . 'usersettingstime' => $prefix . 'user-settings-time',
       
   486 			);
       
   487 		}
       
   488 
       
   489 		if ( is_a( $id, 'WP_User' ) ) {
       
   490 			$this->init( $id->data, $blog_id );
       
   491 			return;
       
   492 		} elseif ( is_object( $id ) ) {
       
   493 			$this->init( $id, $blog_id );
       
   494 			return;
       
   495 		}
       
   496 
       
   497 		if ( ! empty( $id ) && ! is_numeric( $id ) ) {
       
   498 			$name = $id;
       
   499 			$id = 0;
       
   500 		}
       
   501 
       
   502 		if ( $id )
       
   503 			$data = self::get_data_by( 'id', $id );
       
   504 		else
       
   505 			$data = self::get_data_by( 'login', $name );
       
   506 
       
   507 		if ( $data )
       
   508 			$this->init( $data, $blog_id );
       
   509 	}
       
   510 
       
   511 	/**
       
   512 	 * Sets up object properties, including capabilities.
       
   513 	 *
       
   514 	 * @param object $data User DB row object
       
   515 	 * @param int $blog_id Optional. The blog id to initialize for
       
   516 	 */
       
   517 	function init( $data, $blog_id = '' ) {
       
   518 		$this->data = $data;
       
   519 		$this->ID = (int) $data->ID;
       
   520 
       
   521 		$this->for_blog( $blog_id );
       
   522 	}
       
   523 
       
   524 	/**
       
   525 	 * Return only the main user fields
       
   526 	 *
       
   527 	 * @since 3.3.0
       
   528 	 *
       
   529 	 * @param string $field The field to query against: 'id', 'slug', 'email' or 'login'
       
   530 	 * @param string|int $value The field value
       
   531 	 * @return object Raw user object
       
   532 	 */
       
   533 	static function get_data_by( $field, $value ) {
       
   534 		global $wpdb;
       
   535 
       
   536 		if ( 'id' == $field ) {
       
   537 			// Make sure the value is numeric to avoid casting objects, for example,
       
   538 			// to int 1.
       
   539 			if ( ! is_numeric( $value ) )
       
   540 				return false;
       
   541 			$value = intval( $value );
       
   542 			if ( $value < 1 )
       
   543 				return false;
       
   544 		} else {
       
   545 			$value = trim( $value );
       
   546 		}
       
   547 
       
   548 		if ( !$value )
       
   549 			return false;
       
   550 
       
   551 		switch ( $field ) {
       
   552 			case 'id':
       
   553 				$user_id = $value;
       
   554 				$db_field = 'ID';
       
   555 				break;
       
   556 			case 'slug':
       
   557 				$user_id = wp_cache_get($value, 'userslugs');
       
   558 				$db_field = 'user_nicename';
       
   559 				break;
       
   560 			case 'email':
       
   561 				$user_id = wp_cache_get($value, 'useremail');
       
   562 				$db_field = 'user_email';
       
   563 				break;
       
   564 			case 'login':
       
   565 				$value = sanitize_user( $value );
       
   566 				$user_id = wp_cache_get($value, 'userlogins');
       
   567 				$db_field = 'user_login';
       
   568 				break;
       
   569 			default:
       
   570 				return false;
       
   571 		}
       
   572 
       
   573 		if ( false !== $user_id ) {
       
   574 			if ( $user = wp_cache_get( $user_id, 'users' ) )
       
   575 				return $user;
       
   576 		}
       
   577 
       
   578 		if ( !$user = $wpdb->get_row( $wpdb->prepare(
       
   579 			"SELECT * FROM $wpdb->users WHERE $db_field = %s", $value
       
   580 		) ) )
       
   581 			return false;
       
   582 
       
   583 		update_user_caches( $user );
       
   584 
       
   585 		return $user;
       
   586 	}
       
   587 
       
   588 	/**
       
   589 	 * Magic method for checking the existence of a certain custom field
       
   590 	 *
       
   591 	 * @since 3.3.0
       
   592 	 */
       
   593 	function __isset( $key ) {
       
   594 		if ( 'id' == $key ) {
       
   595 			_deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) );
       
   596 			$key = 'ID';
       
   597 		}
       
   598 
       
   599 		if ( isset( $this->data->$key ) )
       
   600 			return true;
       
   601 
       
   602 		if ( isset( self::$back_compat_keys[ $key ] ) )
       
   603 			$key = self::$back_compat_keys[ $key ];
       
   604 
       
   605 		return metadata_exists( 'user', $this->ID, $key );
       
   606 	}
       
   607 
       
   608 	/**
       
   609 	 * Magic method for accessing custom fields
       
   610 	 *
       
   611 	 * @since 3.3.0
       
   612 	 */
       
   613 	function __get( $key ) {
       
   614 		if ( 'id' == $key ) {
       
   615 			_deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) );
       
   616 			return $this->ID;
       
   617 		}
       
   618 
       
   619 		if ( isset( $this->data->$key ) ) {
       
   620 			$value = $this->data->$key;
       
   621 		} else {
       
   622 			if ( isset( self::$back_compat_keys[ $key ] ) )
       
   623 				$key = self::$back_compat_keys[ $key ];
       
   624 			$value = get_user_meta( $this->ID, $key, true );
       
   625 		}
       
   626 
       
   627 		if ( $this->filter ) {
       
   628 			$value = sanitize_user_field( $key, $value, $this->ID, $this->filter );
       
   629 		}
       
   630 
       
   631 		return $value;
       
   632 	}
       
   633 
       
   634 	/**
       
   635 	 * Magic method for setting custom fields
       
   636 	 *
       
   637 	 * @since 3.3.0
       
   638 	 */
       
   639 	function __set( $key, $value ) {
       
   640 		if ( 'id' == $key ) {
       
   641 			_deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) );
       
   642 			$this->ID = $value;
       
   643 			return;
       
   644 		}
       
   645 
       
   646 		$this->data->$key = $value;
       
   647 	}
       
   648 
       
   649 	/**
       
   650 	 * Determine whether the user exists in the database.
       
   651 	 *
       
   652 	 * @since 3.4.0
       
   653 	 * @access public
       
   654 	 *
       
   655 	 * @return bool True if user exists in the database, false if not.
       
   656 	 */
       
   657 	function exists() {
       
   658 		return ! empty( $this->ID );
       
   659 	}
       
   660 
       
   661 	/**
       
   662 	 * Retrieve the value of a property or meta key.
       
   663 	 *
       
   664 	 * Retrieves from the users and usermeta table.
       
   665 	 *
       
   666 	 * @since 3.3.0
       
   667 	 *
       
   668 	 * @param string $key Property
       
   669 	 */
       
   670 	function get( $key ) {
       
   671 		return $this->__get( $key );
       
   672 	}
       
   673 
       
   674 	/**
       
   675 	 * Determine whether a property or meta key is set
       
   676 	 *
       
   677 	 * Consults the users and usermeta tables.
       
   678 	 *
       
   679 	 * @since 3.3.0
       
   680 	 *
       
   681 	 * @param string $key Property
       
   682 	 */
       
   683 	function has_prop( $key ) {
       
   684 		return $this->__isset( $key );
       
   685 	}
       
   686 
       
   687 	/*
       
   688 	 * Return an array representation.
       
   689 	 *
       
   690 	 * @since 3.5.0
       
   691 	 *
       
   692 	 * @return array Array representation.
       
   693 	 */
       
   694 	function to_array() {
       
   695 		return get_object_vars( $this->data );
       
   696 	}
       
   697 
       
   698 	/**
       
   699 	 * Set up capability object properties.
       
   700 	 *
       
   701 	 * Will set the value for the 'cap_key' property to current database table
       
   702 	 * prefix, followed by 'capabilities'. Will then check to see if the
       
   703 	 * property matching the 'cap_key' exists and is an array. If so, it will be
       
   704 	 * used.
       
   705 	 *
       
   706 	 * @access protected
       
   707 	 * @since 2.1.0
       
   708 	 *
       
   709 	 * @param string $cap_key Optional capability key
       
   710 	 */
       
   711 	function _init_caps( $cap_key = '' ) {
       
   712 		global $wpdb;
       
   713 
       
   714 		if ( empty($cap_key) )
       
   715 			$this->cap_key = $wpdb->get_blog_prefix() . 'capabilities';
       
   716 		else
       
   717 			$this->cap_key = $cap_key;
       
   718 
       
   719 		$this->caps = get_user_meta( $this->ID, $this->cap_key, true );
       
   720 
       
   721 		if ( ! is_array( $this->caps ) )
       
   722 			$this->caps = array();
       
   723 
       
   724 		$this->get_role_caps();
       
   725 	}
       
   726 
       
   727 	/**
       
   728 	 * Retrieve all of the role capabilities and merge with individual capabilities.
       
   729 	 *
       
   730 	 * All of the capabilities of the roles the user belongs to are merged with
       
   731 	 * the users individual roles. This also means that the user can be denied
       
   732 	 * specific roles that their role might have, but the specific user isn't
       
   733 	 * granted permission to.
       
   734 	 *
       
   735 	 * @since 2.0.0
       
   736 	 * @uses $wp_roles
       
   737 	 * @access public
       
   738 	 *
       
   739 	 * @return array List of all capabilities for the user.
       
   740 	 */
       
   741 	function get_role_caps() {
       
   742 		global $wp_roles;
       
   743 
       
   744 		if ( ! isset( $wp_roles ) )
       
   745 			$wp_roles = new WP_Roles();
       
   746 
       
   747 		//Filter out caps that are not role names and assign to $this->roles
       
   748 		if ( is_array( $this->caps ) )
       
   749 			$this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) );
       
   750 
       
   751 		//Build $allcaps from role caps, overlay user's $caps
       
   752 		$this->allcaps = array();
       
   753 		foreach ( (array) $this->roles as $role ) {
       
   754 			$the_role = $wp_roles->get_role( $role );
       
   755 			$this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities );
       
   756 		}
       
   757 		$this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps );
       
   758 
       
   759 		return $this->allcaps;
       
   760 	}
       
   761 
       
   762 	/**
       
   763 	 * Add role to user.
       
   764 	 *
       
   765 	 * Updates the user's meta data option with capabilities and roles.
       
   766 	 *
       
   767 	 * @since 2.0.0
       
   768 	 * @access public
       
   769 	 *
       
   770 	 * @param string $role Role name.
       
   771 	 */
       
   772 	function add_role( $role ) {
       
   773 		$this->caps[$role] = true;
       
   774 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
       
   775 		$this->get_role_caps();
       
   776 		$this->update_user_level_from_caps();
       
   777 	}
       
   778 
       
   779 	/**
       
   780 	 * Remove role from user.
       
   781 	 *
       
   782 	 * @since 2.0.0
       
   783 	 * @access public
       
   784 	 *
       
   785 	 * @param string $role Role name.
       
   786 	 */
       
   787 	function remove_role( $role ) {
       
   788 		if ( !in_array($role, $this->roles) )
       
   789 			return;
       
   790 		unset( $this->caps[$role] );
       
   791 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
       
   792 		$this->get_role_caps();
       
   793 		$this->update_user_level_from_caps();
       
   794 	}
       
   795 
       
   796 	/**
       
   797 	 * Set the role of the user.
       
   798 	 *
       
   799 	 * This will remove the previous roles of the user and assign the user the
       
   800 	 * new one. You can set the role to an empty string and it will remove all
       
   801 	 * of the roles from the user.
       
   802 	 *
       
   803 	 * @since 2.0.0
       
   804 	 * @access public
       
   805 	 *
       
   806 	 * @param string $role Role name.
       
   807 	 */
       
   808 	function set_role( $role ) {
       
   809 		if ( 1 == count( $this->roles ) && $role == current( $this->roles ) )
       
   810 			return;
       
   811 
       
   812 		foreach ( (array) $this->roles as $oldrole )
       
   813 			unset( $this->caps[$oldrole] );
       
   814 
       
   815 		$old_roles = $this->roles;
       
   816 		if ( !empty( $role ) ) {
       
   817 			$this->caps[$role] = true;
       
   818 			$this->roles = array( $role => true );
       
   819 		} else {
       
   820 			$this->roles = false;
       
   821 		}
       
   822 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
       
   823 		$this->get_role_caps();
       
   824 		$this->update_user_level_from_caps();
       
   825 		do_action( 'set_user_role', $this->ID, $role, $old_roles );
       
   826 	}
       
   827 
       
   828 	/**
       
   829 	 * Choose the maximum level the user has.
       
   830 	 *
       
   831 	 * Will compare the level from the $item parameter against the $max
       
   832 	 * parameter. If the item is incorrect, then just the $max parameter value
       
   833 	 * will be returned.
       
   834 	 *
       
   835 	 * Used to get the max level based on the capabilities the user has. This
       
   836 	 * is also based on roles, so if the user is assigned the Administrator role
       
   837 	 * then the capability 'level_10' will exist and the user will get that
       
   838 	 * value.
       
   839 	 *
       
   840 	 * @since 2.0.0
       
   841 	 * @access public
       
   842 	 *
       
   843 	 * @param int $max Max level of user.
       
   844 	 * @param string $item Level capability name.
       
   845 	 * @return int Max Level.
       
   846 	 */
       
   847 	function level_reduction( $max, $item ) {
       
   848 		if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
       
   849 			$level = intval( $matches[1] );
       
   850 			return max( $max, $level );
       
   851 		} else {
       
   852 			return $max;
       
   853 		}
       
   854 	}
       
   855 
       
   856 	/**
       
   857 	 * Update the maximum user level for the user.
       
   858 	 *
       
   859 	 * Updates the 'user_level' user metadata (includes prefix that is the
       
   860 	 * database table prefix) with the maximum user level. Gets the value from
       
   861 	 * the all of the capabilities that the user has.
       
   862 	 *
       
   863 	 * @since 2.0.0
       
   864 	 * @access public
       
   865 	 */
       
   866 	function update_user_level_from_caps() {
       
   867 		global $wpdb;
       
   868 		$this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 );
       
   869 		update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level );
       
   870 	}
       
   871 
       
   872 	/**
       
   873 	 * Add capability and grant or deny access to capability.
       
   874 	 *
       
   875 	 * @since 2.0.0
       
   876 	 * @access public
       
   877 	 *
       
   878 	 * @param string $cap Capability name.
       
   879 	 * @param bool $grant Whether to grant capability to user.
       
   880 	 */
       
   881 	function add_cap( $cap, $grant = true ) {
       
   882 		$this->caps[$cap] = $grant;
       
   883 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
       
   884 	}
       
   885 
       
   886 	/**
       
   887 	 * Remove capability from user.
       
   888 	 *
       
   889 	 * @since 2.0.0
       
   890 	 * @access public
       
   891 	 *
       
   892 	 * @param string $cap Capability name.
       
   893 	 */
       
   894 	function remove_cap( $cap ) {
       
   895 		if ( ! isset( $this->caps[$cap] ) )
       
   896 			return;
       
   897 		unset( $this->caps[$cap] );
       
   898 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
       
   899 	}
       
   900 
       
   901 	/**
       
   902 	 * Remove all of the capabilities of the user.
       
   903 	 *
       
   904 	 * @since 2.1.0
       
   905 	 * @access public
       
   906 	 */
       
   907 	function remove_all_caps() {
       
   908 		global $wpdb;
       
   909 		$this->caps = array();
       
   910 		delete_user_meta( $this->ID, $this->cap_key );
       
   911 		delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' );
       
   912 		$this->get_role_caps();
       
   913 	}
       
   914 
       
   915 	/**
       
   916 	 * Whether user has capability or role name.
       
   917 	 *
       
   918 	 * This is useful for looking up whether the user has a specific role
       
   919 	 * assigned to the user. The second optional parameter can also be used to
       
   920 	 * check for capabilities against a specific object, such as a post or user.
       
   921 	 *
       
   922 	 * @since 2.0.0
       
   923 	 * @access public
       
   924 	 *
       
   925 	 * @param string|int $cap Capability or role name to search.
       
   926 	 * @return bool True, if user has capability; false, if user does not have capability.
       
   927 	 */
       
   928 	function has_cap( $cap ) {
       
   929 		if ( is_numeric( $cap ) ) {
       
   930 			_deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') );
       
   931 			$cap = $this->translate_level_to_cap( $cap );
       
   932 		}
       
   933 
       
   934 		$args = array_slice( func_get_args(), 1 );
       
   935 		$args = array_merge( array( $cap, $this->ID ), $args );
       
   936 		$caps = call_user_func_array( 'map_meta_cap', $args );
       
   937 
       
   938 		// Multisite super admin has all caps by definition, Unless specifically denied.
       
   939 		if ( is_multisite() && is_super_admin( $this->ID ) ) {
       
   940 			if ( in_array('do_not_allow', $caps) )
       
   941 				return false;
       
   942 			return true;
       
   943 		}
       
   944 
       
   945 		// Must have ALL requested caps
       
   946 		$capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this );
       
   947 		$capabilities['exist'] = true; // Everyone is allowed to exist
       
   948 		foreach ( (array) $caps as $cap ) {
       
   949 			if ( empty( $capabilities[ $cap ] ) )
       
   950 				return false;
       
   951 		}
       
   952 
       
   953 		return true;
       
   954 	}
       
   955 
       
   956 	/**
       
   957 	 * Convert numeric level to level capability name.
       
   958 	 *
       
   959 	 * Prepends 'level_' to level number.
       
   960 	 *
       
   961 	 * @since 2.0.0
       
   962 	 * @access public
       
   963 	 *
       
   964 	 * @param int $level Level number, 1 to 10.
       
   965 	 * @return string
       
   966 	 */
       
   967 	function translate_level_to_cap( $level ) {
       
   968 		return 'level_' . $level;
       
   969 	}
       
   970 
       
   971 	/**
       
   972 	 * Set the blog to operate on. Defaults to the current blog.
       
   973 	 *
       
   974 	 * @since 3.0.0
       
   975 	 *
       
   976 	 * @param int $blog_id Optional Blog ID, defaults to current blog.
       
   977 	 */
       
   978 	function for_blog( $blog_id = '' ) {
       
   979 		global $wpdb;
       
   980 		if ( ! empty( $blog_id ) )
       
   981 			$cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities';
       
   982 		else
       
   983 			$cap_key = '';
       
   984 		$this->_init_caps( $cap_key );
       
   985 	}
       
   986 }
       
   987 
       
   988 /**
       
   989  * Map meta capabilities to primitive capabilities.
       
   990  *
       
   991  * This does not actually compare whether the user ID has the actual capability,
       
   992  * just what the capability or capabilities are. Meta capability list value can
       
   993  * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post',
       
   994  * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'.
       
   995  *
       
   996  * @since 2.0.0
       
   997  *
       
   998  * @param string $cap Capability name.
       
   999  * @param int $user_id User ID.
       
  1000  * @return array Actual capabilities for meta capability.
       
  1001  */
       
  1002 function map_meta_cap( $cap, $user_id ) {
       
  1003 	$args = array_slice( func_get_args(), 2 );
       
  1004 	$caps = array();
       
  1005 
       
  1006 	switch ( $cap ) {
       
  1007 	case 'remove_user':
       
  1008 		$caps[] = 'remove_users';
       
  1009 		break;
       
  1010 	case 'promote_user':
       
  1011 		$caps[] = 'promote_users';
       
  1012 		break;
       
  1013 	case 'edit_user':
       
  1014 	case 'edit_users':
       
  1015 		// Allow user to edit itself
       
  1016 		if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] )
       
  1017 			break;
       
  1018 
       
  1019 		// If multisite these caps are allowed only for super admins.
       
  1020 		if ( is_multisite() && !is_super_admin( $user_id ) )
       
  1021 			$caps[] = 'do_not_allow';
       
  1022 		else
       
  1023 			$caps[] = 'edit_users'; // edit_user maps to edit_users.
       
  1024 		break;
       
  1025 	case 'delete_post':
       
  1026 	case 'delete_page':
       
  1027 		$post = get_post( $args[0] );
       
  1028 
       
  1029 		if ( 'revision' == $post->post_type ) {
       
  1030 			$post = get_post( $post->post_parent );
       
  1031 		}
       
  1032 
       
  1033 		$post_type = get_post_type_object( $post->post_type );
       
  1034 
       
  1035 		if ( ! $post_type->map_meta_cap ) {
       
  1036 			$caps[] = $post_type->cap->$cap;
       
  1037 			// Prior to 3.1 we would re-call map_meta_cap here.
       
  1038 			if ( 'delete_post' == $cap )
       
  1039 				$cap = $post_type->cap->$cap;
       
  1040 			break;
       
  1041 		}
       
  1042 
       
  1043 		$post_author_id = $post->post_author;
       
  1044 
       
  1045 		// If no author set yet, default to current user for cap checks.
       
  1046 		if ( ! $post_author_id )
       
  1047 			$post_author_id = $user_id;
       
  1048 
       
  1049 		// If the user is the author...
       
  1050 		if ( $user_id == $post_author_id ) {
       
  1051 			// If the post is published...
       
  1052 			if ( 'publish' == $post->post_status ) {
       
  1053 				$caps[] = $post_type->cap->delete_published_posts;
       
  1054 			} elseif ( 'trash' == $post->post_status ) {
       
  1055 				if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) )
       
  1056 					$caps[] = $post_type->cap->delete_published_posts;
       
  1057 			} else {
       
  1058 				// If the post is draft...
       
  1059 				$caps[] = $post_type->cap->delete_posts;
       
  1060 			}
       
  1061 		} else {
       
  1062 			// The user is trying to edit someone else's post.
       
  1063 			$caps[] = $post_type->cap->delete_others_posts;
       
  1064 			// The post is published, extra cap required.
       
  1065 			if ( 'publish' == $post->post_status )
       
  1066 				$caps[] = $post_type->cap->delete_published_posts;
       
  1067 			elseif ( 'private' == $post->post_status )
       
  1068 				$caps[] = $post_type->cap->delete_private_posts;
       
  1069 		}
       
  1070 		break;
       
  1071 		// edit_post breaks down to edit_posts, edit_published_posts, or
       
  1072 		// edit_others_posts
       
  1073 	case 'edit_post':
       
  1074 	case 'edit_page':
       
  1075 		$post = get_post( $args[0] );
       
  1076 		if ( empty( $post ) )
       
  1077 			break;
       
  1078 
       
  1079 		if ( 'revision' == $post->post_type ) {
       
  1080 			$post = get_post( $post->post_parent );
       
  1081 		}
       
  1082 
       
  1083 		$post_type = get_post_type_object( $post->post_type );
       
  1084 
       
  1085 		if ( ! $post_type->map_meta_cap ) {
       
  1086 			$caps[] = $post_type->cap->$cap;
       
  1087 			// Prior to 3.1 we would re-call map_meta_cap here.
       
  1088 			if ( 'edit_post' == $cap )
       
  1089 				$cap = $post_type->cap->$cap;
       
  1090 			break;
       
  1091 		}
       
  1092 
       
  1093 		$post_author_id = $post->post_author;
       
  1094 
       
  1095 		// If no author set yet, default to current user for cap checks.
       
  1096 		if ( ! $post_author_id )
       
  1097 			$post_author_id = $user_id;
       
  1098 
       
  1099 		// If the user is the author...
       
  1100 		if ( $user_id == $post_author_id ) {
       
  1101 			// If the post is published...
       
  1102 			if ( 'publish' == $post->post_status ) {
       
  1103 				$caps[] = $post_type->cap->edit_published_posts;
       
  1104 			} elseif ( 'trash' == $post->post_status ) {
       
  1105 				if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) )
       
  1106 					$caps[] = $post_type->cap->edit_published_posts;
       
  1107 			} else {
       
  1108 				// If the post is draft...
       
  1109 				$caps[] = $post_type->cap->edit_posts;
       
  1110 			}
       
  1111 		} else {
       
  1112 			// The user is trying to edit someone else's post.
       
  1113 			$caps[] = $post_type->cap->edit_others_posts;
       
  1114 			// The post is published, extra cap required.
       
  1115 			if ( 'publish' == $post->post_status )
       
  1116 				$caps[] = $post_type->cap->edit_published_posts;
       
  1117 			elseif ( 'private' == $post->post_status )
       
  1118 				$caps[] = $post_type->cap->edit_private_posts;
       
  1119 		}
       
  1120 		break;
       
  1121 	case 'read_post':
       
  1122 	case 'read_page':
       
  1123 		$post = get_post( $args[0] );
       
  1124 
       
  1125 		if ( 'revision' == $post->post_type ) {
       
  1126 			$post = get_post( $post->post_parent );
       
  1127 		}
       
  1128 
       
  1129 		$post_type = get_post_type_object( $post->post_type );
       
  1130 
       
  1131 		if ( ! $post_type->map_meta_cap ) {
       
  1132 			$caps[] = $post_type->cap->$cap;
       
  1133 			// Prior to 3.1 we would re-call map_meta_cap here.
       
  1134 			if ( 'read_post' == $cap )
       
  1135 				$cap = $post_type->cap->$cap;
       
  1136 			break;
       
  1137 		}
       
  1138 
       
  1139 		$status_obj = get_post_status_object( $post->post_status );
       
  1140 		if ( $status_obj->public ) {
       
  1141 			$caps[] = $post_type->cap->read;
       
  1142 			break;
       
  1143 		}
       
  1144 
       
  1145 		$post_author_id = $post->post_author;
       
  1146 
       
  1147 		// If no author set yet, default to current user for cap checks.
       
  1148 		if ( ! $post_author_id )
       
  1149 			$post_author_id = $user_id;
       
  1150 
       
  1151 		if ( $user_id == $post_author_id )
       
  1152 			$caps[] = $post_type->cap->read;
       
  1153 		elseif ( $status_obj->private )
       
  1154 			$caps[] = $post_type->cap->read_private_posts;
       
  1155 		else
       
  1156 			$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
       
  1157 		break;
       
  1158 	case 'publish_post':
       
  1159 		$post = get_post( $args[0] );
       
  1160 		$post_type = get_post_type_object( $post->post_type );
       
  1161 
       
  1162 		$caps[] = $post_type->cap->publish_posts;
       
  1163 		break;
       
  1164 	case 'edit_post_meta':
       
  1165 	case 'delete_post_meta':
       
  1166 	case 'add_post_meta':
       
  1167 		$post = get_post( $args[0] );
       
  1168 		$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
       
  1169 
       
  1170 		$meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;
       
  1171 
       
  1172 		if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) {
       
  1173 			$allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps );
       
  1174 			if ( ! $allowed )
       
  1175 				$caps[] = $cap;
       
  1176 		} elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) {
       
  1177 			$caps[] = $cap;
       
  1178 		}
       
  1179 		break;
       
  1180 	case 'edit_comment':
       
  1181 		$comment = get_comment( $args[0] );
       
  1182 		if ( empty( $comment ) )
       
  1183 			break;
       
  1184 		$post = get_post( $comment->comment_post_ID );
       
  1185 		$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
       
  1186 		break;
       
  1187 	case 'unfiltered_upload':
       
  1188 		if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) )  )
       
  1189 			$caps[] = $cap;
       
  1190 		else
       
  1191 			$caps[] = 'do_not_allow';
       
  1192 		break;
       
  1193 	case 'unfiltered_html' :
       
  1194 		// Disallow unfiltered_html for all users, even admins and super admins.
       
  1195 		if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML )
       
  1196 			$caps[] = 'do_not_allow';
       
  1197 		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
       
  1198 			$caps[] = 'do_not_allow';
       
  1199 		else
       
  1200 			$caps[] = $cap;
       
  1201 		break;
       
  1202 	case 'edit_files':
       
  1203 	case 'edit_plugins':
       
  1204 	case 'edit_themes':
       
  1205 		// Disallow the file editors.
       
  1206 		if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT )
       
  1207 			$caps[] = 'do_not_allow';
       
  1208 		elseif ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
       
  1209 			$caps[] = 'do_not_allow';
       
  1210 		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
       
  1211 			$caps[] = 'do_not_allow';
       
  1212 		else
       
  1213 			$caps[] = $cap;
       
  1214 		break;
       
  1215 	case 'update_plugins':
       
  1216 	case 'delete_plugins':
       
  1217 	case 'install_plugins':
       
  1218 	case 'update_themes':
       
  1219 	case 'delete_themes':
       
  1220 	case 'install_themes':
       
  1221 	case 'update_core':
       
  1222 		// Disallow anything that creates, deletes, or updates core, plugin, or theme files.
       
  1223 		// Files in uploads are excepted.
       
  1224 		if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
       
  1225 			$caps[] = 'do_not_allow';
       
  1226 		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
       
  1227 			$caps[] = 'do_not_allow';
       
  1228 		else
       
  1229 			$caps[] = $cap;
       
  1230 		break;
       
  1231 	case 'activate_plugins':
       
  1232 		$caps[] = $cap;
       
  1233 		if ( is_multisite() ) {
       
  1234 			// update_, install_, and delete_ are handled above with is_super_admin().
       
  1235 			$menu_perms = get_site_option( 'menu_items', array() );
       
  1236 			if ( empty( $menu_perms['plugins'] ) )
       
  1237 				$caps[] = 'manage_network_plugins';
       
  1238 		}
       
  1239 		break;
       
  1240 	case 'delete_user':
       
  1241 	case 'delete_users':
       
  1242 		// If multisite only super admins can delete users.
       
  1243 		if ( is_multisite() && ! is_super_admin( $user_id ) )
       
  1244 			$caps[] = 'do_not_allow';
       
  1245 		else
       
  1246 			$caps[] = 'delete_users'; // delete_user maps to delete_users.
       
  1247 		break;
       
  1248 	case 'create_users':
       
  1249 		if ( !is_multisite() )
       
  1250 			$caps[] = $cap;
       
  1251 		elseif ( is_super_admin() || get_site_option( 'add_new_users' ) )
       
  1252 			$caps[] = $cap;
       
  1253 		else
       
  1254 			$caps[] = 'do_not_allow';
       
  1255 		break;
       
  1256 	case 'manage_links' :
       
  1257 		if ( get_option( 'link_manager_enabled' ) )
       
  1258 			$caps[] = $cap;
       
  1259 		else
       
  1260 			$caps[] = 'do_not_allow';
       
  1261 		break;
       
  1262 	default:
       
  1263 		// Handle meta capabilities for custom post types.
       
  1264 		$post_type_meta_caps = _post_type_meta_capabilities();
       
  1265 		if ( isset( $post_type_meta_caps[ $cap ] ) ) {
       
  1266 			$args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
       
  1267 			return call_user_func_array( 'map_meta_cap', $args );
       
  1268 		}
       
  1269 
       
  1270 		// If no meta caps match, return the original cap.
       
  1271 		$caps[] = $cap;
       
  1272 	}
       
  1273 
       
  1274 	return apply_filters('map_meta_cap', $caps, $cap, $user_id, $args);
       
  1275 }
       
  1276 
       
  1277 /**
       
  1278  * Whether current user has capability or role.
       
  1279  *
       
  1280  * @since 2.0.0
       
  1281  *
       
  1282  * @param string $capability Capability or role name.
       
  1283  * @return bool
       
  1284  */
       
  1285 function current_user_can( $capability ) {
       
  1286 	$current_user = wp_get_current_user();
       
  1287 
       
  1288 	if ( empty( $current_user ) )
       
  1289 		return false;
       
  1290 
       
  1291 	$args = array_slice( func_get_args(), 1 );
       
  1292 	$args = array_merge( array( $capability ), $args );
       
  1293 
       
  1294 	return call_user_func_array( array( $current_user, 'has_cap' ), $args );
       
  1295 }
       
  1296 
       
  1297 /**
       
  1298  * Whether current user has a capability or role for a given blog.
       
  1299  *
       
  1300  * @since 3.0.0
       
  1301  *
       
  1302  * @param int $blog_id Blog ID
       
  1303  * @param string $capability Capability or role name.
       
  1304  * @return bool
       
  1305  */
       
  1306 function current_user_can_for_blog( $blog_id, $capability ) {
       
  1307 	if ( is_multisite() )
       
  1308 		switch_to_blog( $blog_id );
       
  1309 
       
  1310 	$current_user = wp_get_current_user();
       
  1311 
       
  1312 	if ( empty( $current_user ) )
       
  1313 		return false;
       
  1314 
       
  1315 	$args = array_slice( func_get_args(), 2 );
       
  1316 	$args = array_merge( array( $capability ), $args );
       
  1317 
       
  1318 	$can = call_user_func_array( array( $current_user, 'has_cap' ), $args );
       
  1319 
       
  1320 	if ( is_multisite() )
       
  1321 		restore_current_blog();
       
  1322 
       
  1323 	return $can;
       
  1324 }
       
  1325 
       
  1326 /**
       
  1327  * Whether author of supplied post has capability or role.
       
  1328  *
       
  1329  * @since 2.9.0
       
  1330  *
       
  1331  * @param int|object $post Post ID or post object.
       
  1332  * @param string $capability Capability or role name.
       
  1333  * @return bool
       
  1334  */
       
  1335 function author_can( $post, $capability ) {
       
  1336 	if ( !$post = get_post($post) )
       
  1337 		return false;
       
  1338 
       
  1339 	$author = get_userdata( $post->post_author );
       
  1340 
       
  1341 	if ( ! $author )
       
  1342 		return false;
       
  1343 
       
  1344 	$args = array_slice( func_get_args(), 2 );
       
  1345 	$args = array_merge( array( $capability ), $args );
       
  1346 
       
  1347 	return call_user_func_array( array( $author, 'has_cap' ), $args );
       
  1348 }
       
  1349 
       
  1350 /**
       
  1351  * Whether a particular user has capability or role.
       
  1352  *
       
  1353  * @since 3.1.0
       
  1354  *
       
  1355  * @param int|object $user User ID or object.
       
  1356  * @param string $capability Capability or role name.
       
  1357  * @return bool
       
  1358  */
       
  1359 function user_can( $user, $capability ) {
       
  1360 	if ( ! is_object( $user ) )
       
  1361 		$user = get_userdata( $user );
       
  1362 
       
  1363 	if ( ! $user || ! $user->exists() )
       
  1364 		return false;
       
  1365 
       
  1366 	$args = array_slice( func_get_args(), 2 );
       
  1367 	$args = array_merge( array( $capability ), $args );
       
  1368 
       
  1369 	return call_user_func_array( array( $user, 'has_cap' ), $args );
       
  1370 }
       
  1371 
       
  1372 /**
       
  1373  * Retrieve role object.
       
  1374  *
       
  1375  * @see WP_Roles::get_role() Uses method to retrieve role object.
       
  1376  * @since 2.0.0
       
  1377  *
       
  1378  * @param string $role Role name.
       
  1379  * @return WP_Role|null WP_Role object if found, null if the role does not exist.
       
  1380  */
       
  1381 function get_role( $role ) {
       
  1382 	global $wp_roles;
       
  1383 
       
  1384 	if ( ! isset( $wp_roles ) )
       
  1385 		$wp_roles = new WP_Roles();
       
  1386 
       
  1387 	return $wp_roles->get_role( $role );
       
  1388 }
       
  1389 
       
  1390 /**
       
  1391  * Add role, if it does not exist.
       
  1392  *
       
  1393  * @see WP_Roles::add_role() Uses method to add role.
       
  1394  * @since 2.0.0
       
  1395  *
       
  1396  * @param string $role Role name.
       
  1397  * @param string $display_name Display name for role.
       
  1398  * @param array $capabilities List of capabilities, e.g. array( 'edit_posts' => true, 'delete_posts' => false );
       
  1399  * @return WP_Role|null WP_Role object if role is added, null if already exists.
       
  1400  */
       
  1401 function add_role( $role, $display_name, $capabilities = array() ) {
       
  1402 	global $wp_roles;
       
  1403 
       
  1404 	if ( ! isset( $wp_roles ) )
       
  1405 		$wp_roles = new WP_Roles();
       
  1406 
       
  1407 	return $wp_roles->add_role( $role, $display_name, $capabilities );
       
  1408 }
       
  1409 
       
  1410 /**
       
  1411  * Remove role, if it exists.
       
  1412  *
       
  1413  * @see WP_Roles::remove_role() Uses method to remove role.
       
  1414  * @since 2.0.0
       
  1415  *
       
  1416  * @param string $role Role name.
       
  1417  */
       
  1418 function remove_role( $role ) {
       
  1419 	global $wp_roles;
       
  1420 
       
  1421 	if ( ! isset( $wp_roles ) )
       
  1422 		$wp_roles = new WP_Roles();
       
  1423 
       
  1424 	$wp_roles->remove_role( $role );
       
  1425 }
       
  1426 
       
  1427 /**
       
  1428  * Retrieve a list of super admins.
       
  1429  *
       
  1430  * @since 3.0.0
       
  1431  *
       
  1432  * @uses $super_admins Super admins global variable, if set.
       
  1433  *
       
  1434  * @return array List of super admin logins
       
  1435  */
       
  1436 function get_super_admins() {
       
  1437 	global $super_admins;
       
  1438 
       
  1439 	if ( isset($super_admins) )
       
  1440 		return $super_admins;
       
  1441 	else
       
  1442 		return get_site_option( 'site_admins', array('admin') );
       
  1443 }
       
  1444 
       
  1445 /**
       
  1446  * Determine if user is a site admin.
       
  1447  *
       
  1448  * @since 3.0.0
       
  1449  *
       
  1450  * @param int $user_id (Optional) The ID of a user. Defaults to the current user.
       
  1451  * @return bool True if the user is a site admin.
       
  1452  */
       
  1453 function is_super_admin( $user_id = false ) {
       
  1454 	if ( ! $user_id || $user_id == get_current_user_id() )
       
  1455 		$user = wp_get_current_user();
       
  1456 	else
       
  1457 		$user = get_userdata( $user_id );
       
  1458 
       
  1459 	if ( ! $user || ! $user->exists() )
       
  1460 		return false;
       
  1461 
       
  1462 	if ( is_multisite() ) {
       
  1463 		$super_admins = get_super_admins();
       
  1464 		if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) )
       
  1465 			return true;
       
  1466 	} else {
       
  1467 		if ( $user->has_cap('delete_users') )
       
  1468 			return true;
       
  1469 	}
       
  1470 
       
  1471 	return false;
       
  1472 }