wp/wp-includes/class-wp-user.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    51 	 * @var int
    51 	 * @var int
    52 	 */
    52 	 */
    53 	public $ID = 0;
    53 	public $ID = 0;
    54 
    54 
    55 	/**
    55 	/**
    56 	 * The individual capabilities the user has been given.
    56 	 * Capabilities that the individual user has been granted outside of those inherited from their role.
    57 	 *
    57 	 *
    58 	 * @since 2.0.0
    58 	 * @since 2.0.0
    59 	 * @var array
    59 	 * @var bool[] Array of key/value pairs where keys represent a capability name
       
    60 	 *             and boolean values represent whether the user has that capability.
    60 	 */
    61 	 */
    61 	public $caps = array();
    62 	public $caps = array();
    62 
    63 
    63 	/**
    64 	/**
    64 	 * User metadata option name.
    65 	 * User metadata option name.
    70 
    71 
    71 	/**
    72 	/**
    72 	 * The roles the user is part of.
    73 	 * The roles the user is part of.
    73 	 *
    74 	 *
    74 	 * @since 2.0.0
    75 	 * @since 2.0.0
    75 	 * @var array
    76 	 * @var string[]
    76 	 */
    77 	 */
    77 	public $roles = array();
    78 	public $roles = array();
    78 
    79 
    79 	/**
    80 	/**
    80 	 * All capabilities the user has, including individual and role based.
    81 	 * All capabilities the user has, including individual and role based.
    81 	 *
    82 	 *
    82 	 * @since 2.0.0
    83 	 * @since 2.0.0
    83 	 * @var bool[] Array of key/value pairs where keys represent a capability name and boolean values
    84 	 * @var bool[] Array of key/value pairs where keys represent a capability name
    84 	 *             represent whether the user has that capability.
    85 	 *             and boolean values represent whether the user has that capability.
    85 	 */
    86 	 */
    86 	public $allcaps = array();
    87 	public $allcaps = array();
    87 
    88 
    88 	/**
    89 	/**
    89 	 * The filter context applied to user data fields.
    90 	 * The filter context applied to user data fields.
   112 	 *
   113 	 *
   113 	 * Retrieves the userdata and passes it to WP_User::init().
   114 	 * Retrieves the userdata and passes it to WP_User::init().
   114 	 *
   115 	 *
   115 	 * @since 2.0.0
   116 	 * @since 2.0.0
   116 	 *
   117 	 *
   117 	 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB.
   118 	 * @param int|string|stdClass|WP_User $id      User's ID, a WP_User object, or a user object from the DB.
   118 	 * @param string $name Optional. User's username
   119 	 * @param string                      $name    Optional. User's username
   119 	 * @param int $site_id Optional Site ID, defaults to current site.
   120 	 * @param int                         $site_id Optional Site ID, defaults to current site.
   120 	 */
   121 	 */
   121 	public function __construct( $id = 0, $name = '', $site_id = '' ) {
   122 	public function __construct( $id = 0, $name = '', $site_id = '' ) {
   122 		if ( ! isset( self::$back_compat_keys ) ) {
   123 		if ( ! isset( self::$back_compat_keys ) ) {
   123 			$prefix                 = $GLOBALS['wpdb']->prefix;
   124 			$prefix                 = $GLOBALS['wpdb']->prefix;
   124 			self::$back_compat_keys = array(
   125 			self::$back_compat_keys = array(
   158 	}
   159 	}
   159 
   160 
   160 	/**
   161 	/**
   161 	 * Sets up object properties, including capabilities.
   162 	 * Sets up object properties, including capabilities.
   162 	 *
   163 	 *
   163 	 * @since  3.3.0
   164 	 * @since 3.3.0
   164 	 *
   165 	 *
   165 	 * @param object $data    User DB row object.
   166 	 * @param object $data    User DB row object.
   166 	 * @param int    $site_id Optional. The site ID to initialize for.
   167 	 * @param int    $site_id Optional. The site ID to initialize for.
   167 	 */
   168 	 */
   168 	public function init( $data, $site_id = '' ) {
   169 	public function init( $data, $site_id = '' ) {
   178 	 * @since 3.3.0
   179 	 * @since 3.3.0
   179 	 * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter.
   180 	 * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter.
   180 	 *
   181 	 *
   181 	 * @global wpdb $wpdb WordPress database abstraction object.
   182 	 * @global wpdb $wpdb WordPress database abstraction object.
   182 	 *
   183 	 *
   183 	 * @param string $field The field to query against: 'id', 'ID', 'slug', 'email' or 'login'.
   184 	 * @param string     $field The field to query against: 'id', 'ID', 'slug', 'email' or 'login'.
   184 	 * @param string|int $value The field value
   185 	 * @param string|int $value The field value
   185 	 * @return object|false Raw user object
   186 	 * @return object|false Raw user object
   186 	 */
   187 	 */
   187 	public static function get_data_by( $field, $value ) {
   188 	public static function get_data_by( $field, $value ) {
   188 		global $wpdb;
   189 		global $wpdb;
   190 		// 'ID' is an alias of 'id'.
   191 		// 'ID' is an alias of 'id'.
   191 		if ( 'ID' === $field ) {
   192 		if ( 'ID' === $field ) {
   192 			$field = 'id';
   193 			$field = 'id';
   193 		}
   194 		}
   194 
   195 
   195 		if ( 'id' == $field ) {
   196 		if ( 'id' === $field ) {
   196 			// Make sure the value is numeric to avoid casting objects, for example,
   197 			// Make sure the value is numeric to avoid casting objects, for example,
   197 			// to int 1.
   198 			// to int 1.
   198 			if ( ! is_numeric( $value ) ) {
   199 			if ( ! is_numeric( $value ) ) {
   199 				return false;
   200 				return false;
   200 			}
   201 			}
   231 			default:
   232 			default:
   232 				return false;
   233 				return false;
   233 		}
   234 		}
   234 
   235 
   235 		if ( false !== $user_id ) {
   236 		if ( false !== $user_id ) {
   236 			if ( $user = wp_cache_get( $user_id, 'users' ) ) {
   237 			$user = wp_cache_get( $user_id, 'users' );
       
   238 			if ( $user ) {
   237 				return $user;
   239 				return $user;
   238 			}
   240 			}
   239 		}
   241 		}
   240 
   242 
   241 		if ( ! $user = $wpdb->get_row(
   243 		$user = $wpdb->get_row(
   242 			$wpdb->prepare(
   244 			$wpdb->prepare(
   243 				"SELECT * FROM $wpdb->users WHERE $db_field = %s LIMIT 1",
   245 				"SELECT * FROM $wpdb->users WHERE $db_field = %s LIMIT 1",
   244 				$value
   246 				$value
   245 			)
   247 			)
   246 		) ) {
   248 		);
       
   249 		if ( ! $user ) {
   247 			return false;
   250 			return false;
   248 		}
   251 		}
   249 
   252 
   250 		update_user_caches( $user );
   253 		update_user_caches( $user );
   251 
   254 
   259 	 *
   262 	 *
   260 	 * @param string $key User meta key to check if set.
   263 	 * @param string $key User meta key to check if set.
   261 	 * @return bool Whether the given user meta key is set.
   264 	 * @return bool Whether the given user meta key is set.
   262 	 */
   265 	 */
   263 	public function __isset( $key ) {
   266 	public function __isset( $key ) {
   264 		if ( 'id' == $key ) {
   267 		if ( 'id' === $key ) {
   265 			_deprecated_argument(
   268 			_deprecated_argument(
   266 				'WP_User->id',
   269 				'WP_User->id',
   267 				'2.1.0',
   270 				'2.1.0',
   268 				sprintf(
   271 				sprintf(
   269 					/* translators: %s: WP_User->ID */
   272 					/* translators: %s: WP_User->ID */
   292 	 *
   295 	 *
   293 	 * @param string $key User meta key to retrieve.
   296 	 * @param string $key User meta key to retrieve.
   294 	 * @return mixed Value of the given user meta key (if set). If `$key` is 'id', the user ID.
   297 	 * @return mixed Value of the given user meta key (if set). If `$key` is 'id', the user ID.
   295 	 */
   298 	 */
   296 	public function __get( $key ) {
   299 	public function __get( $key ) {
   297 		if ( 'id' == $key ) {
   300 		if ( 'id' === $key ) {
   298 			_deprecated_argument(
   301 			_deprecated_argument(
   299 				'WP_User->id',
   302 				'WP_User->id',
   300 				'2.1.0',
   303 				'2.1.0',
   301 				sprintf(
   304 				sprintf(
   302 					/* translators: %s: WP_User->ID */
   305 					/* translators: %s: WP_User->ID */
   333 	 *
   336 	 *
   334 	 * @param string $key   User meta key.
   337 	 * @param string $key   User meta key.
   335 	 * @param mixed  $value User meta value.
   338 	 * @param mixed  $value User meta value.
   336 	 */
   339 	 */
   337 	public function __set( $key, $value ) {
   340 	public function __set( $key, $value ) {
   338 		if ( 'id' == $key ) {
   341 		if ( 'id' === $key ) {
   339 			_deprecated_argument(
   342 			_deprecated_argument(
   340 				'WP_User->id',
   343 				'WP_User->id',
   341 				'2.1.0',
   344 				'2.1.0',
   342 				sprintf(
   345 				sprintf(
   343 					/* translators: %s: WP_User->ID */
   346 					/* translators: %s: WP_User->ID */
   358 	 * @since 4.4.0
   361 	 * @since 4.4.0
   359 	 *
   362 	 *
   360 	 * @param string $key User meta key to unset.
   363 	 * @param string $key User meta key to unset.
   361 	 */
   364 	 */
   362 	public function __unset( $key ) {
   365 	public function __unset( $key ) {
   363 		if ( 'id' == $key ) {
   366 		if ( 'id' === $key ) {
   364 			_deprecated_argument(
   367 			_deprecated_argument(
   365 				'WP_User->id',
   368 				'WP_User->id',
   366 				'2.1.0',
   369 				'2.1.0',
   367 				sprintf(
   370 				sprintf(
   368 					/* translators: %s: WP_User->ID */
   371 					/* translators: %s: WP_User->ID */
   434 	/**
   437 	/**
   435 	 * Makes private/protected methods readable for backward compatibility.
   438 	 * Makes private/protected methods readable for backward compatibility.
   436 	 *
   439 	 *
   437 	 * @since 4.3.0
   440 	 * @since 4.3.0
   438 	 *
   441 	 *
   439 	 * @param string   $name      Method to call.
   442 	 * @param string $name      Method to call.
   440 	 * @param array    $arguments Arguments to pass when calling.
   443 	 * @param array  $arguments Arguments to pass when calling.
   441 	 * @return mixed|false Return value of the callback, false otherwise.
   444 	 * @return mixed|false Return value of the callback, false otherwise.
   442 	 */
   445 	 */
   443 	public function __call( $name, $arguments ) {
   446 	public function __call( $name, $arguments ) {
   444 		if ( '_init_caps' === $name ) {
   447 		if ( '_init_caps' === $name ) {
   445 			return call_user_func_array( array( $this, $name ), $arguments );
   448 			return $this->_init_caps( ...$arguments );
   446 		}
   449 		}
   447 		return false;
   450 		return false;
   448 	}
   451 	}
   449 
   452 
   450 	/**
   453 	/**
   477 
   480 
   478 		$this->get_role_caps();
   481 		$this->get_role_caps();
   479 	}
   482 	}
   480 
   483 
   481 	/**
   484 	/**
   482 	 * Retrieves all of the capabilities of the roles of the user, and merges them with individual user capabilities.
   485 	 * Retrieves all of the capabilities of the user's roles, and merges them with
   483 	 *
   486 	 * individual user capabilities.
   484 	 * All of the capabilities of the roles of the user are merged with the user's individual capabilities. This means
   487 	 *
   485 	 * that the user can be denied specific capabilities that their role might have, but the user is specifically denied.
   488 	 * All of the capabilities of the user's roles are merged with the user's individual
   486 	 *
   489 	 * capabilities. This means that the user can be denied specific capabilities that
   487 	 * @since 2.0.0
   490 	 * their role might have, but the user is specifically denied.
   488 	 *
   491 	 *
   489 	 * @return bool[] Array of key/value pairs where keys represent a capability name and boolean values
   492 	 * @since 2.0.0
   490 	 *                represent whether the user has that capability.
   493 	 *
       
   494 	 * @return bool[] Array of key/value pairs where keys represent a capability name
       
   495 	 *                and boolean values represent whether the user has that capability.
   491 	 */
   496 	 */
   492 	public function get_role_caps() {
   497 	public function get_role_caps() {
   493 		$switch_site = false;
   498 		$switch_site = false;
   494 		if ( is_multisite() && $this->site_id != get_current_blog_id() ) {
   499 		if ( is_multisite() && get_current_blog_id() != $this->site_id ) {
   495 			$switch_site = true;
   500 			$switch_site = true;
   496 
   501 
   497 			switch_to_blog( $this->site_id );
   502 			switch_to_blog( $this->site_id );
   498 		}
   503 		}
   499 
   504 
   555 	 * @since 2.0.0
   560 	 * @since 2.0.0
   556 	 *
   561 	 *
   557 	 * @param string $role Role name.
   562 	 * @param string $role Role name.
   558 	 */
   563 	 */
   559 	public function remove_role( $role ) {
   564 	public function remove_role( $role ) {
   560 		if ( ! in_array( $role, $this->roles ) ) {
   565 		if ( ! in_array( $role, $this->roles, true ) ) {
   561 			return;
   566 			return;
   562 		}
   567 		}
   563 		unset( $this->caps[ $role ] );
   568 		unset( $this->caps[ $role ] );
   564 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
   569 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
   565 		$this->get_role_caps();
   570 		$this->get_role_caps();
   586 	 * @since 2.0.0
   591 	 * @since 2.0.0
   587 	 *
   592 	 *
   588 	 * @param string $role Role name.
   593 	 * @param string $role Role name.
   589 	 */
   594 	 */
   590 	public function set_role( $role ) {
   595 	public function set_role( $role ) {
   591 		if ( 1 == count( $this->roles ) && $role == current( $this->roles ) ) {
   596 		if ( 1 === count( $this->roles ) && current( $this->roles ) == $role ) {
   592 			return;
   597 			return;
   593 		}
   598 		}
   594 
   599 
   595 		foreach ( (array) $this->roles as $oldrole ) {
   600 		foreach ( (array) $this->roles as $oldrole ) {
   596 			unset( $this->caps[ $oldrole ] );
   601 			unset( $this->caps[ $oldrole ] );
   632 	 * then the capability 'level_10' will exist and the user will get that
   637 	 * then the capability 'level_10' will exist and the user will get that
   633 	 * value.
   638 	 * value.
   634 	 *
   639 	 *
   635 	 * @since 2.0.0
   640 	 * @since 2.0.0
   636 	 *
   641 	 *
   637 	 * @param int $max Max level of user.
   642 	 * @param int    $max  Max level of user.
   638 	 * @param string $item Level capability name.
   643 	 * @param string $item Level capability name.
   639 	 * @return int Max Level.
   644 	 * @return int Max Level.
   640 	 */
   645 	 */
   641 	public function level_reduction( $max, $item ) {
   646 	public function level_reduction( $max, $item ) {
   642 		if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
   647 		if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
   667 	/**
   672 	/**
   668 	 * Add capability and grant or deny access to capability.
   673 	 * Add capability and grant or deny access to capability.
   669 	 *
   674 	 *
   670 	 * @since 2.0.0
   675 	 * @since 2.0.0
   671 	 *
   676 	 *
   672 	 * @param string $cap Capability name.
   677 	 * @param string $cap   Capability name.
   673 	 * @param bool $grant Whether to grant capability to user.
   678 	 * @param bool   $grant Whether to grant capability to user.
   674 	 */
   679 	 */
   675 	public function add_cap( $cap, $grant = true ) {
   680 	public function add_cap( $cap, $grant = true ) {
   676 		$this->caps[ $cap ] = $grant;
   681 		$this->caps[ $cap ] = $grant;
   677 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
   682 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
   678 		$this->get_role_caps();
   683 		$this->get_role_caps();
   710 		delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' );
   715 		delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' );
   711 		$this->get_role_caps();
   716 		$this->get_role_caps();
   712 	}
   717 	}
   713 
   718 
   714 	/**
   719 	/**
   715 	 * Whether the user has a specific capability.
   720 	 * Returns whether the user has the specified capability.
       
   721 	 *
       
   722 	 * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
       
   723 	 * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
       
   724 	 * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
       
   725 	 *
       
   726 	 * Example usage:
       
   727 	 *
       
   728 	 *     $user->has_cap( 'edit_posts' );
       
   729 	 *     $user->has_cap( 'edit_post', $post->ID );
       
   730 	 *     $user->has_cap( 'edit_post_meta', $post->ID, $meta_key );
   716 	 *
   731 	 *
   717 	 * While checking against a role in place of a capability is supported in part, this practice is discouraged as it
   732 	 * While checking against a role in place of a capability is supported in part, this practice is discouraged as it
   718 	 * may produce unreliable results.
   733 	 * may produce unreliable results.
   719 	 *
   734 	 *
   720 	 * @since 2.0.0
   735 	 * @since 2.0.0
       
   736 	 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
       
   737 	 *              by adding it to the function signature.
   721 	 *
   738 	 *
   722 	 * @see map_meta_cap()
   739 	 * @see map_meta_cap()
   723 	 *
   740 	 *
   724 	 * @param string $cap           Capability name.
   741 	 * @param string $cap     Capability name.
   725 	 * @param int    $object_id,... Optional. ID of a specific object to check against if `$cap` is a "meta" capability.
   742 	 * @param mixed  ...$args Optional further parameters, typically starting with an object ID.
   726 	 *                              Meta capabilities such as `edit_post` and `edit_user` are capabilities used by
   743 	 * @return bool Whether the user has the given capability, or, if an object ID is passed, whether the user has
   727 	 *                              by the `map_meta_cap()` function to map to primitive capabilities that a user or
       
   728 	 *                              role has, such as `edit_posts` and `edit_others_posts`.
       
   729 	 * @return bool Whether the user has the given capability, or, if `$object_id` is passed, whether the user has
       
   730 	 *              the given capability for that object.
   744 	 *              the given capability for that object.
   731 	 */
   745 	 */
   732 	public function has_cap( $cap ) {
   746 	public function has_cap( $cap, ...$args ) {
   733 		if ( is_numeric( $cap ) ) {
   747 		if ( is_numeric( $cap ) ) {
   734 			_deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) );
   748 			_deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) );
   735 			$cap = $this->translate_level_to_cap( $cap );
   749 			$cap = $this->translate_level_to_cap( $cap );
   736 		}
   750 		}
   737 
   751 
   738 		$args = array_slice( func_get_args(), 1 );
   752 		$caps = map_meta_cap( $cap, $this->ID, ...$args );
   739 		$args = array_merge( array( $cap, $this->ID ), $args );
       
   740 		$caps = call_user_func_array( 'map_meta_cap', $args );
       
   741 
   753 
   742 		// Multisite super admin has all caps by definition, Unless specifically denied.
   754 		// Multisite super admin has all caps by definition, Unless specifically denied.
   743 		if ( is_multisite() && is_super_admin( $this->ID ) ) {
   755 		if ( is_multisite() && is_super_admin( $this->ID ) ) {
   744 			if ( in_array( 'do_not_allow', $caps ) ) {
   756 			if ( in_array( 'do_not_allow', $caps, true ) ) {
   745 				return false;
   757 				return false;
   746 			}
   758 			}
   747 			return true;
   759 			return true;
   748 		}
   760 		}
       
   761 
       
   762 		// Maintain BC for the argument passed to the "user_has_cap" filter.
       
   763 		$args = array_merge( array( $cap, $this->ID ), $args );
   749 
   764 
   750 		/**
   765 		/**
   751 		 * Dynamically filter a user's capabilities.
   766 		 * Dynamically filter a user's capabilities.
   752 		 *
   767 		 *
   753 		 * @since 2.0.0
   768 		 * @since 2.0.0
   754 		 * @since 3.7.0 Added the `$user` parameter.
   769 		 * @since 3.7.0 Added the `$user` parameter.
   755 		 *
   770 		 *
   756 		 * @param bool[]   $allcaps Array of key/value pairs where keys represent a capability name and boolean values
   771 		 * @param bool[]   $allcaps Array of key/value pairs where keys represent a capability name
   757 		 *                          represent whether the user has that capability.
   772 		 *                          and boolean values represent whether the user has that capability.
   758 		 * @param string[] $caps    Required primitive capabilities for the requested capability.
   773 		 * @param string[] $caps    Required primitive capabilities for the requested capability.
   759 		 * @param array    $args {
   774 		 * @param array    $args {
   760 		 *     Arguments that accompany the requested capability check.
   775 		 *     Arguments that accompany the requested capability check.
   761 		 *
   776 		 *
   762 		 *     @type string    $0 Requested capability.
   777 		 *     @type string    $0 Requested capability.
   850 	/**
   865 	/**
   851 	 * Gets the available user capabilities data.
   866 	 * Gets the available user capabilities data.
   852 	 *
   867 	 *
   853 	 * @since 4.9.0
   868 	 * @since 4.9.0
   854 	 *
   869 	 *
   855 	 * @return array User capabilities array.
   870 	 * @return bool[] List of capabilities keyed by the capability name,
       
   871 	 *                e.g. array( 'edit_posts' => true, 'delete_posts' => false ).
   856 	 */
   872 	 */
   857 	private function get_caps_data() {
   873 	private function get_caps_data() {
   858 		$caps = get_user_meta( $this->ID, $this->cap_key, true );
   874 		$caps = get_user_meta( $this->ID, $this->cap_key, true );
   859 
   875 
   860 		if ( ! is_array( $caps ) ) {
   876 		if ( ! is_array( $caps ) ) {