[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> class-wp-user.php (source)

   1  <?php
   2  /**
   3   * User API: WP_User class
   4   *
   5   * @package WordPress
   6   * @subpackage Users
   7   * @since 4.4.0
   8   */
   9  
  10  /**
  11   * Core class used to implement the WP_User object.
  12   *
  13   * @since 2.0.0
  14   * @since 6.8.0 The `user_pass` property is now hashed using bcrypt by default instead of phpass.
  15   *              Existing passwords may still be hashed using phpass.
  16   *
  17   * @property string     $nickname
  18   * @property string     $description
  19   * @property string     $user_description
  20   * @property string     $first_name
  21   * @property string     $user_firstname
  22   * @property string     $last_name
  23   * @property string     $user_lastname
  24   * @property string     $user_login
  25   * @property string     $user_pass
  26   * @property string     $user_nicename
  27   * @property string     $user_email
  28   * @property string     $user_url
  29   * @property string     $user_registered
  30   * @property string     $user_activation_key
  31   * @property string     $user_status
  32   * @property int|string $user_level
  33   * @property string     $display_name
  34   * @property string     $spam
  35   * @property string     $deleted
  36   * @property string     $locale
  37   * @property string     $rich_editing
  38   * @property string     $syntax_highlighting
  39   * @property string     $use_ssl
  40   *
  41   * @phpstan-property numeric-string        $user_status
  42   * @phpstan-property int|numeric-string|'' $user_level
  43   */
  44  #[AllowDynamicProperties]
  45  class WP_User {
  46      /**
  47       * User data container.
  48       *
  49       * @since 2.0.0
  50       * @var stdClass
  51       */
  52      public $data;
  53  
  54      /**
  55       * The user's ID.
  56       *
  57       * @since 2.1.0
  58       * @var int
  59       */
  60      public $ID = 0;
  61  
  62      /**
  63       * Capabilities that the individual user has been granted outside of those inherited from their role.
  64       *
  65       * @since 2.0.0
  66       * @var bool[] Array of key/value pairs where keys represent a capability name
  67       *             and boolean values represent whether the user has that capability.
  68       */
  69      public $caps = array();
  70  
  71      /**
  72       * User metadata option name.
  73       *
  74       * @since 2.0.0
  75       * @var string
  76       */
  77      public $cap_key;
  78  
  79      /**
  80       * The roles the user is part of.
  81       *
  82       * @since 2.0.0
  83       * @var string[]
  84       */
  85      public $roles = array();
  86  
  87      /**
  88       * All capabilities the user has, including individual and role based.
  89       *
  90       * @since 2.0.0
  91       * @var bool[] Array of key/value pairs where keys represent a capability name
  92       *             and boolean values represent whether the user has that capability.
  93       */
  94      public $allcaps = array();
  95  
  96      /**
  97       * The filter context applied to user data fields.
  98       *
  99       * @since 2.9.0
 100       * @var string
 101       */
 102      public $filter = null;
 103  
 104      /**
 105       * The site ID the capabilities of this user are initialized for.
 106       *
 107       * @since 4.9.0
 108       * @var int
 109       */
 110      private $site_id = 0;
 111  
 112      /**
 113       * @since 3.3.0
 114       * @var array
 115       */
 116      private static $back_compat_keys;
 117  
 118      /**
 119       * Constructor.
 120       *
 121       * Retrieves the userdata and passes it to WP_User::init().
 122       *
 123       * @since 2.0.0
 124       *
 125       * @global wpdb $wpdb WordPress database abstraction object.
 126       *
 127       * @param int|string|object $id      User's ID, a WP_User object, or a user object from the DB.
 128       * @param string            $name    Optional. User's username
 129       * @param int               $site_id Optional Site ID, defaults to current site.
 130       */
 131  	public function __construct( $id = 0, $name = '', $site_id = 0 ) {
 132          global $wpdb;
 133  
 134          if ( ! isset( self::$back_compat_keys ) ) {
 135              $prefix = $wpdb->prefix;
 136  
 137              self::$back_compat_keys = array(
 138                  'user_firstname'             => 'first_name',
 139                  'user_lastname'              => 'last_name',
 140                  'user_description'           => 'description',
 141                  'user_level'                 => $prefix . 'user_level',
 142                  $prefix . 'usersettings'     => $prefix . 'user-settings',
 143                  $prefix . 'usersettingstime' => $prefix . 'user-settings-time',
 144              );
 145          }
 146  
 147          if ( $id instanceof WP_User ) {
 148              $this->init( $id->data, $site_id );
 149              return;
 150          } elseif ( is_object( $id ) ) {
 151              $this->init( $id, $site_id );
 152              return;
 153          }
 154  
 155          if ( ! empty( $id ) && ! is_numeric( $id ) ) {
 156              $name = $id;
 157              $id   = 0;
 158          }
 159  
 160          if ( $id ) {
 161              $data = self::get_data_by( 'id', $id );
 162          } else {
 163              $data = self::get_data_by( 'login', $name );
 164          }
 165  
 166          if ( $data ) {
 167              $this->init( $data, $site_id );
 168          } else {
 169              $this->data = new stdClass();
 170          }
 171      }
 172  
 173      /**
 174       * Sets up object properties, including capabilities.
 175       *
 176       * @since 3.3.0
 177       *
 178       * @param object $data    User DB row object.
 179       * @param int    $site_id Optional. The site ID to initialize for.
 180       */
 181  	public function init( $data, $site_id = 0 ) {
 182          if ( ! isset( $data->ID ) ) {
 183              $data->ID = 0;
 184          }
 185          $this->data = $data;
 186          $this->ID   = (int) $data->ID;
 187  
 188          $this->for_site( $site_id );
 189      }
 190  
 191      /**
 192       * Returns only the main user fields.
 193       *
 194       * @since 3.3.0
 195       * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter.
 196       *
 197       * @global wpdb $wpdb WordPress database abstraction object.
 198       *
 199       * @param string     $field The field to query against: Accepts 'id', 'ID', 'slug', 'email' or 'login'.
 200       * @param string|int $value The field value.
 201       * @return object|false Raw user object.
 202       */
 203  	public static function get_data_by( $field, $value ) {
 204          global $wpdb;
 205  
 206          // 'ID' is an alias of 'id'.
 207          if ( 'ID' === $field ) {
 208              $field = 'id';
 209          }
 210  
 211          if ( 'id' === $field ) {
 212              // Make sure the value is numeric to avoid casting objects, for example, to int 1.
 213              if ( ! is_numeric( $value ) ) {
 214                  return false;
 215              }
 216              $value = (int) $value;
 217              if ( $value < 1 ) {
 218                  return false;
 219              }
 220          } else {
 221              $value = trim( $value );
 222          }
 223  
 224          if ( ! $value ) {
 225              return false;
 226          }
 227  
 228          switch ( $field ) {
 229              case 'id':
 230                  $user_id  = $value;
 231                  $db_field = 'ID';
 232                  break;
 233              case 'slug':
 234                  $user_id  = wp_cache_get( $value, 'userslugs' );
 235                  $db_field = 'user_nicename';
 236                  break;
 237              case 'email':
 238                  $user_id  = wp_cache_get( $value, 'useremail' );
 239                  $db_field = 'user_email';
 240                  break;
 241              case 'login':
 242                  $value    = sanitize_user( $value );
 243                  $user_id  = wp_cache_get( $value, 'userlogins' );
 244                  $db_field = 'user_login';
 245                  break;
 246              default:
 247                  return false;
 248          }
 249  
 250          if ( false !== $user_id ) {
 251              $user = wp_cache_get( $user_id, 'users' );
 252              if ( $user ) {
 253                  return $user;
 254              }
 255          }
 256  
 257          $user = $wpdb->get_row(
 258              $wpdb->prepare(
 259                  "SELECT * FROM $wpdb->users WHERE $db_field = %s LIMIT 1",
 260                  $value
 261              )
 262          );
 263          if ( ! $user ) {
 264              return false;
 265          }
 266  
 267          update_user_caches( $user );
 268  
 269          return $user;
 270      }
 271  
 272      /**
 273       * Magic method for checking the existence of a certain custom field.
 274       *
 275       * @since 3.3.0
 276       *
 277       * @param string $key User meta key to check if set.
 278       * @return bool Whether the given user meta key is set.
 279       */
 280  	public function __isset( $key ) {
 281          if ( 'id' === $key ) {
 282              _deprecated_argument(
 283                  'WP_User->id',
 284                  '2.1.0',
 285                  sprintf(
 286                      /* translators: %s: WP_User->ID */
 287                      __( 'Use %s instead.' ),
 288                      '<code>WP_User->ID</code>'
 289                  )
 290              );
 291              $key = 'ID';
 292          }
 293  
 294          if ( isset( $this->data->$key ) ) {
 295              return true;
 296          }
 297  
 298          if ( isset( self::$back_compat_keys[ $key ] ) ) {
 299              $key = self::$back_compat_keys[ $key ];
 300          }
 301  
 302          return metadata_exists( 'user', $this->ID, $key );
 303      }
 304  
 305      /**
 306       * Magic method for accessing custom fields.
 307       *
 308       * @since 3.3.0
 309       *
 310       * @param string $key User meta key to retrieve.
 311       * @return mixed Value of the given user meta key (if set). If `$key` is 'id', the user ID.
 312       */
 313  	public function __get( $key ) {
 314          if ( 'id' === $key ) {
 315              _deprecated_argument(
 316                  'WP_User->id',
 317                  '2.1.0',
 318                  sprintf(
 319                      /* translators: %s: WP_User->ID */
 320                      __( 'Use %s instead.' ),
 321                      '<code>WP_User->ID</code>'
 322                  )
 323              );
 324              return $this->ID;
 325          }
 326  
 327          if ( isset( $this->data->$key ) ) {
 328              $value = $this->data->$key;
 329          } else {
 330              if ( isset( self::$back_compat_keys[ $key ] ) ) {
 331                  $key = self::$back_compat_keys[ $key ];
 332              }
 333              $value = get_user_meta( $this->ID, $key, true );
 334          }
 335  
 336          if ( $this->filter ) {
 337              $value = sanitize_user_field( $key, $value, $this->ID, $this->filter );
 338          }
 339  
 340          return $value;
 341      }
 342  
 343      /**
 344       * Magic method for setting custom user fields.
 345       *
 346       * This method does not update custom fields in the database. It only stores
 347       * the value on the WP_User instance.
 348       *
 349       * @since 3.3.0
 350       *
 351       * @param string $key   User meta key.
 352       * @param mixed  $value User meta value.
 353       */
 354  	public function __set( $key, $value ) {
 355          if ( 'id' === $key ) {
 356              _deprecated_argument(
 357                  'WP_User->id',
 358                  '2.1.0',
 359                  sprintf(
 360                      /* translators: %s: WP_User->ID */
 361                      __( 'Use %s instead.' ),
 362                      '<code>WP_User->ID</code>'
 363                  )
 364              );
 365              $this->ID = $value;
 366              return;
 367          }
 368  
 369          $this->data->$key = $value;
 370      }
 371  
 372      /**
 373       * Magic method for unsetting a certain custom field.
 374       *
 375       * @since 4.4.0
 376       *
 377       * @param string $key User meta key to unset.
 378       */
 379  	public function __unset( $key ) {
 380          if ( 'id' === $key ) {
 381              _deprecated_argument(
 382                  'WP_User->id',
 383                  '2.1.0',
 384                  sprintf(
 385                      /* translators: %s: WP_User->ID */
 386                      __( 'Use %s instead.' ),
 387                      '<code>WP_User->ID</code>'
 388                  )
 389              );
 390          }
 391  
 392          if ( isset( $this->data->$key ) ) {
 393              unset( $this->data->$key );
 394          }
 395  
 396          if ( isset( self::$back_compat_keys[ $key ] ) ) {
 397              unset( self::$back_compat_keys[ $key ] );
 398          }
 399      }
 400  
 401      /**
 402       * Determines whether the user exists in the database.
 403       *
 404       * @since 3.4.0
 405       *
 406       * @return bool True if user exists in the database, false if not.
 407       */
 408  	public function exists() {
 409          return ! empty( $this->ID );
 410      }
 411  
 412      /**
 413       * Retrieves the value of a property or meta key.
 414       *
 415       * Retrieves from the users and usermeta table.
 416       *
 417       * @since 3.3.0
 418       *
 419       * @param string $key Property
 420       * @return mixed
 421       */
 422  	public function get( $key ) {
 423          return $this->__get( $key );
 424      }
 425  
 426      /**
 427       * Determines whether a property or meta key is set.
 428       *
 429       * Consults the users and usermeta tables.
 430       *
 431       * @since 3.3.0
 432       *
 433       * @param string $key Property.
 434       * @return bool
 435       */
 436  	public function has_prop( $key ) {
 437          return $this->__isset( $key );
 438      }
 439  
 440      /**
 441       * Returns an array representation.
 442       *
 443       * @since 3.5.0
 444       *
 445       * @return array Array representation.
 446       */
 447  	public function to_array() {
 448          return get_object_vars( $this->data );
 449      }
 450  
 451      /**
 452       * Makes private/protected methods readable for backward compatibility.
 453       *
 454       * @since 4.3.0
 455       *
 456       * @param string $name      Method to call.
 457       * @param array  $arguments Arguments to pass when calling.
 458       * @return mixed|false Return value of the callback, false otherwise.
 459       */
 460  	public function __call( $name, $arguments ) {
 461          if ( '_init_caps' === $name ) {
 462              return $this->_init_caps( ...$arguments );
 463          }
 464          return false;
 465      }
 466  
 467      /**
 468       * Sets up capability object properties.
 469       *
 470       * Will set the value for the 'cap_key' property to current database table
 471       * prefix, followed by 'capabilities'. Will then check to see if the
 472       * property matching the 'cap_key' exists and is an array. If so, it will be
 473       * used.
 474       *
 475       * @since 2.1.0
 476       * @deprecated 4.9.0 Use WP_User::for_site()
 477       *
 478       * @global wpdb $wpdb WordPress database abstraction object.
 479       *
 480       * @param string $cap_key Optional capability key
 481       */
 482  	protected function _init_caps( $cap_key = '' ) {
 483          global $wpdb;
 484  
 485          _deprecated_function( __METHOD__, '4.9.0', 'WP_User::for_site()' );
 486  
 487          if ( empty( $cap_key ) ) {
 488              $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities';
 489          } else {
 490              $this->cap_key = $cap_key;
 491          }
 492  
 493          $this->caps = $this->get_caps_data();
 494  
 495          $this->get_role_caps();
 496      }
 497  
 498      /**
 499       * Retrieves all of the capabilities of the user's roles, and merges them with
 500       * individual user capabilities.
 501       *
 502       * All of the capabilities of the user's roles are merged with the user's individual
 503       * capabilities. This means that the user can be denied specific capabilities that
 504       * their role might have, but the user is specifically denied.
 505       *
 506       * @since 2.0.0
 507       *
 508       * @return bool[] Array of key/value pairs where keys represent a capability name
 509       *                and boolean values represent whether the user has that capability.
 510       */
 511  	public function get_role_caps() {
 512          $switch_site = false;
 513          if ( is_multisite() && get_current_blog_id() !== $this->site_id ) {
 514              $switch_site = true;
 515  
 516              switch_to_blog( $this->site_id );
 517          }
 518  
 519          $wp_roles = wp_roles();
 520  
 521          // Select caps that are role names and assign to $this->roles.
 522          if ( is_array( $this->caps ) ) {
 523              $this->roles = array();
 524  
 525              foreach ( $this->caps as $key => $value ) {
 526                  if ( $wp_roles->is_role( $key ) ) {
 527                      $this->roles[] = $key;
 528                  }
 529              }
 530          }
 531  
 532          // Build $allcaps from role caps, overlay user's $caps.
 533          $this->allcaps = array();
 534          foreach ( (array) $this->roles as $role ) {
 535              $the_role      = $wp_roles->get_role( $role );
 536              $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities );
 537          }
 538          $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps );
 539  
 540          if ( $switch_site ) {
 541              restore_current_blog();
 542          }
 543  
 544          return $this->allcaps;
 545      }
 546  
 547      /**
 548       * Adds role to user.
 549       *
 550       * Updates the user's meta data option with capabilities and roles.
 551       *
 552       * @since 2.0.0
 553       *
 554       * @param string $role Role name.
 555       */
 556  	public function add_role( $role ) {
 557          if ( empty( $role ) ) {
 558              return;
 559          }
 560  
 561          if ( in_array( $role, $this->roles, true ) ) {
 562              return;
 563          }
 564  
 565          $this->caps[ $role ] = true;
 566          update_user_meta( $this->ID, $this->cap_key, $this->caps );
 567          $this->get_role_caps();
 568          $this->update_user_level_from_caps();
 569  
 570          /**
 571           * Fires immediately after the user has been given a new role.
 572           *
 573           * @since 4.3.0
 574           *
 575           * @param int    $user_id The user ID.
 576           * @param string $role    The new role.
 577           */
 578          do_action( 'add_user_role', $this->ID, $role );
 579      }
 580  
 581      /**
 582       * Removes role from user.
 583       *
 584       * @since 2.0.0
 585       *
 586       * @param string $role Role name.
 587       */
 588  	public function remove_role( $role ) {
 589          if ( ! in_array( $role, $this->roles, true ) ) {
 590              return;
 591          }
 592  
 593          unset( $this->caps[ $role ] );
 594          update_user_meta( $this->ID, $this->cap_key, $this->caps );
 595          $this->get_role_caps();
 596          $this->update_user_level_from_caps();
 597  
 598          /**
 599           * Fires immediately after a role as been removed from a user.
 600           *
 601           * @since 4.3.0
 602           *
 603           * @param int    $user_id The user ID.
 604           * @param string $role    The removed role.
 605           */
 606          do_action( 'remove_user_role', $this->ID, $role );
 607      }
 608  
 609      /**
 610       * Sets the role of the user.
 611       *
 612       * This will remove the previous roles of the user and assign the user the
 613       * new one. You can set the role to an empty string and it will remove all
 614       * of the roles from the user.
 615       *
 616       * @since 2.0.0
 617       *
 618       * @param string $role Role name.
 619       */
 620  	public function set_role( $role ) {
 621          if ( 1 === count( $this->roles ) && current( $this->roles ) === $role ) {
 622              return;
 623          }
 624  
 625          foreach ( (array) $this->roles as $oldrole ) {
 626              unset( $this->caps[ $oldrole ] );
 627          }
 628  
 629          $old_roles = $this->roles;
 630  
 631          if ( ! empty( $role ) ) {
 632              $this->caps[ $role ] = true;
 633              $this->roles         = array( $role => true );
 634          } else {
 635              $this->roles = array();
 636          }
 637  
 638          update_user_meta( $this->ID, $this->cap_key, $this->caps );
 639          $this->get_role_caps();
 640          $this->update_user_level_from_caps();
 641  
 642          foreach ( $old_roles as $old_role ) {
 643              if ( ! $old_role || $old_role === $role ) {
 644                  continue;
 645              }
 646  
 647              /** This action is documented in wp-includes/class-wp-user.php */
 648              do_action( 'remove_user_role', $this->ID, $old_role );
 649          }
 650  
 651          if ( $role && ! in_array( $role, $old_roles, true ) ) {
 652              /** This action is documented in wp-includes/class-wp-user.php */
 653              do_action( 'add_user_role', $this->ID, $role );
 654          }
 655  
 656          /**
 657           * Fires after the user's role has changed.
 658           *
 659           * @since 2.9.0
 660           * @since 3.6.0 Added `$old_roles` to include an array of the user's previous roles.
 661           *
 662           * @param int      $user_id   The user ID.
 663           * @param string   $role      The new role.
 664           * @param string[] $old_roles An array of the user's previous roles.
 665           */
 666          do_action( 'set_user_role', $this->ID, $role, $old_roles );
 667      }
 668  
 669      /**
 670       * Chooses the maximum level the user has.
 671       *
 672       * Will compare the level from the $item parameter against the $max
 673       * parameter. If the item is incorrect, then just the $max parameter value
 674       * will be returned.
 675       *
 676       * Used to get the max level based on the capabilities the user has. This
 677       * is also based on roles, so if the user is assigned the Administrator role
 678       * then the capability 'level_10' will exist and the user will get that
 679       * value.
 680       *
 681       * @since 2.0.0
 682       *
 683       * @param int    $max  Max level of user.
 684       * @param string $item Level capability name.
 685       * @return int Max Level.
 686       */
 687  	public function level_reduction( $max, $item ) {
 688          if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
 689              $level = (int) $matches[1];
 690              return max( $max, $level );
 691          } else {
 692              return $max;
 693          }
 694      }
 695  
 696      /**
 697       * Updates the maximum user level for the user.
 698       *
 699       * Updates the 'user_level' user metadata (includes prefix that is the
 700       * database table prefix) with the maximum user level. Gets the value from
 701       * the all of the capabilities that the user has.
 702       *
 703       * @since 2.0.0
 704       *
 705       * @global wpdb $wpdb WordPress database abstraction object.
 706       */
 707  	public function update_user_level_from_caps() {
 708          global $wpdb;
 709          $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 );
 710          update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level );
 711      }
 712  
 713      /**
 714       * Adds capability and grant or deny access to capability.
 715       *
 716       * @since 2.0.0
 717       *
 718       * @param string $cap   Capability name.
 719       * @param bool   $grant Whether to grant capability to user.
 720       */
 721  	public function add_cap( $cap, $grant = true ) {
 722          $this->caps[ $cap ] = $grant;
 723          update_user_meta( $this->ID, $this->cap_key, $this->caps );
 724          $this->get_role_caps();
 725          $this->update_user_level_from_caps();
 726      }
 727  
 728      /**
 729       * Removes capability from user.
 730       *
 731       * @since 2.0.0
 732       *
 733       * @param string $cap Capability name.
 734       */
 735  	public function remove_cap( $cap ) {
 736          if ( ! isset( $this->caps[ $cap ] ) ) {
 737              return;
 738          }
 739          unset( $this->caps[ $cap ] );
 740          update_user_meta( $this->ID, $this->cap_key, $this->caps );
 741          $this->get_role_caps();
 742          $this->update_user_level_from_caps();
 743      }
 744  
 745      /**
 746       * Removes all of the capabilities of the user.
 747       *
 748       * @since 2.1.0
 749       *
 750       * @global wpdb $wpdb WordPress database abstraction object.
 751       */
 752  	public function remove_all_caps() {
 753          global $wpdb;
 754          $this->caps = array();
 755          delete_user_meta( $this->ID, $this->cap_key );
 756          delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' );
 757          $this->get_role_caps();
 758      }
 759  
 760      /**
 761       * Returns whether the user has the specified capability.
 762       *
 763       * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
 764       * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
 765       * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
 766       *
 767       * Example usage:
 768       *
 769       *     $user->has_cap( 'edit_posts' );
 770       *     $user->has_cap( 'edit_post', $post->ID );
 771       *     $user->has_cap( 'edit_post_meta', $post->ID, $meta_key );
 772       *
 773       * While checking against a role in place of a capability is supported in part, this practice is discouraged as it
 774       * may produce unreliable results.
 775       *
 776       * @since 2.0.0
 777       * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
 778       *              by adding it to the function signature.
 779       *
 780       * @see map_meta_cap()
 781       *
 782       * @param string $cap     Capability name.
 783       * @param mixed  ...$args Optional further parameters, typically starting with an object ID.
 784       * @return bool Whether the user has the given capability, or, if an object ID is passed, whether the user has
 785       *              the given capability for that object.
 786       */
 787  	public function has_cap( $cap, ...$args ) {
 788          if ( is_numeric( $cap ) ) {
 789              _deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) );
 790              $cap = $this->translate_level_to_cap( $cap );
 791          }
 792  
 793          $caps = map_meta_cap( $cap, $this->ID, ...$args );
 794  
 795          // Multisite super admin has all caps by definition, Unless specifically denied.
 796          if ( is_multisite() && is_super_admin( $this->ID ) ) {
 797              if ( in_array( 'do_not_allow', $caps, true ) ) {
 798                  return false;
 799              }
 800              return true;
 801          }
 802  
 803          // Maintain BC for the argument passed to the "user_has_cap" filter.
 804          $args = array_merge( array( $cap, $this->ID ), $args );
 805  
 806          /**
 807           * Dynamically filter a user's capabilities.
 808           *
 809           * @since 2.0.0
 810           * @since 3.7.0 Added the `$user` parameter.
 811           *
 812           * @param bool[]   $allcaps Array of key/value pairs where keys represent a capability name
 813           *                          and boolean values represent whether the user has that capability.
 814           * @param string[] $caps    Required primitive capabilities for the requested capability.
 815           * @param array    $args {
 816           *     Arguments that accompany the requested capability check.
 817           *
 818           *     @type string    $0 Requested capability.
 819           *     @type int       $1 Concerned user ID.
 820           *     @type mixed  ...$2 Optional second and further parameters, typically object ID.
 821           * }
 822           * @param WP_User  $user    The user object.
 823           */
 824          $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this );
 825  
 826          // Everyone is allowed to exist.
 827          $capabilities['exist'] = true;
 828  
 829          // Nobody is allowed to do things they are not allowed to do.
 830          unset( $capabilities['do_not_allow'] );
 831  
 832          // Must have ALL requested caps.
 833          return array_all( (array) $caps, fn( $cap, $key ) => ! empty( $capabilities[ $cap ] ) );
 834      }
 835  
 836      /**
 837       * Converts numeric level to level capability name.
 838       *
 839       * Prepends 'level_' to level number.
 840       *
 841       * @since 2.0.0
 842       *
 843       * @param int $level Level number, 1 to 10.
 844       * @return string
 845       */
 846  	public function translate_level_to_cap( $level ) {
 847          return 'level_' . $level;
 848      }
 849  
 850      /**
 851       * Sets the site to operate on. Defaults to the current site.
 852       *
 853       * @since 3.0.0
 854       * @deprecated 4.9.0 Use WP_User::for_site()
 855       *
 856       * @param int $blog_id Optional. Site ID, defaults to current site.
 857       */
 858  	public function for_blog( $blog_id = 0 ) {
 859          _deprecated_function( __METHOD__, '4.9.0', 'WP_User::for_site()' );
 860  
 861          $this->for_site( $blog_id );
 862      }
 863  
 864      /**
 865       * Sets the site to operate on. Defaults to the current site.
 866       *
 867       * @since 4.9.0
 868       *
 869       * @global wpdb $wpdb WordPress database abstraction object.
 870       *
 871       * @param int $site_id Site ID to initialize user capabilities for. Default is the current site.
 872       */
 873  	public function for_site( $site_id = 0 ) {
 874          global $wpdb;
 875  
 876          if ( ! empty( $site_id ) ) {
 877              $this->site_id = absint( $site_id );
 878          } else {
 879              $this->site_id = get_current_blog_id();
 880          }
 881  
 882          $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities';
 883  
 884          $this->caps = $this->get_caps_data();
 885  
 886          $this->get_role_caps();
 887      }
 888  
 889      /**
 890       * Gets the ID of the site for which the user's capabilities are currently initialized.
 891       *
 892       * @since 4.9.0
 893       *
 894       * @return int Site ID.
 895       */
 896  	public function get_site_id() {
 897          return $this->site_id;
 898      }
 899  
 900      /**
 901       * Gets the available user capabilities data.
 902       *
 903       * @since 4.9.0
 904       *
 905       * @return bool[] List of capabilities keyed by the capability name,
 906       *                e.g. `array( 'edit_posts' => true, 'delete_posts' => false )`.
 907       */
 908  	private function get_caps_data() {
 909          $caps = get_user_meta( $this->ID, $this->cap_key, true );
 910  
 911          if ( ! is_array( $caps ) ) {
 912              return array();
 913          }
 914  
 915          return $caps;
 916      }
 917  }


Generated : Mon Jul 6 08:20:14 2026 Cross-referenced by PHPXref