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


Generated : Fri Sep 4 08:20:24 2026 Cross-referenced by PHPXref