WP_User

Core class used to implement the WP_User object.

Defined (1)

The class is defined in the following location(s).

/wp-includes/class-wp-user.php  
  1. class WP_User { 
  2. /** 
  3. * User data container. 
  4. * @since 2.0.0 
  5. * @var object 
  6. */ 
  7. public $data; 
  8.  
  9. /** 
  10. * The user's ID. 
  11. * @since 2.1.0 
  12. * @access public 
  13. * @var int 
  14. */ 
  15. public $ID = 0; 
  16.  
  17. /** 
  18. * The individual capabilities the user has been given. 
  19. * @since 2.0.0 
  20. * @access public 
  21. * @var array 
  22. */ 
  23. public $caps = array(); 
  24.  
  25. /** 
  26. * User metadata option name. 
  27. * @since 2.0.0 
  28. * @access public 
  29. * @var string 
  30. */ 
  31. public $cap_key; 
  32.  
  33. /** 
  34. * The roles the user is part of. 
  35. * @since 2.0.0 
  36. * @access public 
  37. * @var array 
  38. */ 
  39. public $roles = array(); 
  40.  
  41. /** 
  42. * All capabilities the user has, including individual and role based. 
  43. * @since 2.0.0 
  44. * @access public 
  45. * @var array 
  46. */ 
  47. public $allcaps = array(); 
  48.  
  49. /** 
  50. * The filter context applied to user data fields. 
  51. * @since 2.9.0 
  52. * @access private 
  53. * @var string 
  54. */ 
  55. var $filter = null; 
  56.  
  57. /** 
  58. * @static 
  59. * @access private 
  60. * @var array 
  61. */ 
  62. private static $back_compat_keys; 
  63.  
  64. /** 
  65. * Constructor. 
  66. * Retrieves the userdata and passes it to WP_User::init(). 
  67. * @since 2.0.0 
  68. * @access public 
  69. * @global wpdb $wpdb WordPress database abstraction object. 
  70. * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB. 
  71. * @param string $name Optional. User's username 
  72. * @param int $blog_id Optional Site ID, defaults to current site. 
  73. */ 
  74. public function __construct( $id = 0, $name = '', $blog_id = '' ) { 
  75. if ( ! isset( self::$back_compat_keys ) ) { 
  76. $prefix = $GLOBALS['wpdb']->prefix; 
  77. self::$back_compat_keys = array( 
  78. 'user_firstname' => 'first_name',  
  79. 'user_lastname' => 'last_name',  
  80. 'user_description' => 'description',  
  81. 'user_level' => $prefix . 'user_level',  
  82. $prefix . 'usersettings' => $prefix . 'user-settings',  
  83. $prefix . 'usersettingstime' => $prefix . 'user-settings-time',  
  84. ); 
  85.  
  86. if ( $id instanceof WP_User ) { 
  87. $this->init( $id->data, $blog_id ); 
  88. return; 
  89. } elseif ( is_object( $id ) ) { 
  90. $this->init( $id, $blog_id ); 
  91. return; 
  92.  
  93. if ( ! empty( $id ) && ! is_numeric( $id ) ) { 
  94. $name = $id; 
  95. $id = 0; 
  96.  
  97. if ( $id ) { 
  98. $data = self::get_data_by( 'id', $id ); 
  99. } else { 
  100. $data = self::get_data_by( 'login', $name ); 
  101.  
  102. if ( $data ) { 
  103. $this->init( $data, $blog_id ); 
  104. } else { 
  105. $this->data = new stdClass; 
  106.  
  107. /** 
  108. * Sets up object properties, including capabilities. 
  109. * @param object $data User DB row object. 
  110. * @param int $blog_id Optional. The site ID to initialize for. 
  111. */ 
  112. public function init( $data, $blog_id = '' ) { 
  113. $this->data = $data; 
  114. $this->ID = (int) $data->ID; 
  115.  
  116. $this->for_blog( $blog_id ); 
  117.  
  118. /** 
  119. * Return only the main user fields 
  120. * @since 3.3.0 
  121. * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter. 
  122. * @static 
  123. * @global wpdb $wpdb WordPress database abstraction object. 
  124. * @param string $field The field to query against: 'id', 'ID', 'slug', 'email' or 'login'. 
  125. * @param string|int $value The field value 
  126. * @return object|false Raw user object 
  127. */ 
  128. public static function get_data_by( $field, $value ) { 
  129. global $wpdb; 
  130.  
  131. // 'ID' is an alias of 'id'. 
  132. if ( 'ID' === $field ) { 
  133. $field = 'id'; 
  134.  
  135. if ( 'id' == $field ) { 
  136. // Make sure the value is numeric to avoid casting objects, for example,  
  137. // to int 1. 
  138. if ( ! is_numeric( $value ) ) 
  139. return false; 
  140. $value = intval( $value ); 
  141. if ( $value < 1 ) 
  142. return false; 
  143. } else { 
  144. $value = trim( $value ); 
  145.  
  146. if ( !$value ) 
  147. return false; 
  148.  
  149. switch ( $field ) { 
  150. case 'id': 
  151. $user_id = $value; 
  152. $db_field = 'ID'; 
  153. break; 
  154. case 'slug': 
  155. $user_id = wp_cache_get($value, 'userslugs'); 
  156. $db_field = 'user_nicename'; 
  157. break; 
  158. case 'email': 
  159. $user_id = wp_cache_get($value, 'useremail'); 
  160. $db_field = 'user_email'; 
  161. break; 
  162. case 'login': 
  163. $value = sanitize_user( $value ); 
  164. $user_id = wp_cache_get($value, 'userlogins'); 
  165. $db_field = 'user_login'; 
  166. break; 
  167. default: 
  168. return false; 
  169.  
  170. if ( false !== $user_id ) { 
  171. if ( $user = wp_cache_get( $user_id, 'users' ) ) 
  172. return $user; 
  173.  
  174. if ( !$user = $wpdb->get_row( $wpdb->prepare( 
  175. "SELECT * FROM $wpdb->users WHERE $db_field = %s", $value 
  176. ) ) ) 
  177. return false; 
  178.  
  179. update_user_caches( $user ); 
  180.  
  181. return $user; 
  182.  
  183. /** 
  184. * Makes private/protected methods readable for backward compatibility. 
  185. * @since 4.3.0 
  186. * @access public 
  187. * @param callable $name Method to call. 
  188. * @param array $arguments Arguments to pass when calling. 
  189. * @return mixed|false Return value of the callback, false otherwise. 
  190. */ 
  191. public function __call( $name, $arguments ) { 
  192. if ( '_init_caps' === $name ) { 
  193. return call_user_func_array( array( $this, $name ), $arguments ); 
  194. return false; 
  195.  
  196. /** 
  197. * Magic method for checking the existence of a certain custom field. 
  198. * @since 3.3.0 
  199. * @access public 
  200. * @param string $key User meta key to check if set. 
  201. * @return bool Whether the given user meta key is set. 
  202. */ 
  203. public function __isset( $key ) { 
  204. if ( 'id' == $key ) { 
  205. _deprecated_argument( 'WP_User->id', '2.1.0',  
  206. sprintf( 
  207. /** translators: %s: WP_User->ID */ 
  208. __( 'Use %s instead.' ),  
  209. '<code>WP_User->ID</code>' 
  210. ); 
  211. $key = 'ID'; 
  212.  
  213. if ( isset( $this->data->$key ) ) 
  214. return true; 
  215.  
  216. if ( isset( self::$back_compat_keys[ $key ] ) ) 
  217. $key = self::$back_compat_keys[ $key ]; 
  218.  
  219. return metadata_exists( 'user', $this->ID, $key ); 
  220.  
  221. /** 
  222. * Magic method for accessing custom fields. 
  223. * @since 3.3.0 
  224. * @access public 
  225. * @param string $key User meta key to retrieve. 
  226. * @return mixed Value of the given user meta key (if set). If `$key` is 'id', the user ID. 
  227. */ 
  228. public function __get( $key ) { 
  229. if ( 'id' == $key ) { 
  230. _deprecated_argument( 'WP_User->id', '2.1.0',  
  231. sprintf( 
  232. /** translators: %s: WP_User->ID */ 
  233. __( 'Use %s instead.' ),  
  234. '<code>WP_User->ID</code>' 
  235. ); 
  236. return $this->ID; 
  237.  
  238. if ( isset( $this->data->$key ) ) { 
  239. $value = $this->data->$key; 
  240. } else { 
  241. if ( isset( self::$back_compat_keys[ $key ] ) ) 
  242. $key = self::$back_compat_keys[ $key ]; 
  243. $value = get_user_meta( $this->ID, $key, true ); 
  244.  
  245. if ( $this->filter ) { 
  246. $value = sanitize_user_field( $key, $value, $this->ID, $this->filter ); 
  247.  
  248. return $value; 
  249.  
  250. /** 
  251. * Magic method for setting custom user fields. 
  252. * This method does not update custom fields in the database. It only stores 
  253. * the value on the WP_User instance. 
  254. * @since 3.3.0 
  255. * @access public 
  256. * @param string $key User meta key. 
  257. * @param mixed $value User meta value. 
  258. */ 
  259. public function __set( $key, $value ) { 
  260. if ( 'id' == $key ) { 
  261. _deprecated_argument( 'WP_User->id', '2.1.0',  
  262. sprintf( 
  263. /** translators: %s: WP_User->ID */ 
  264. __( 'Use %s instead.' ),  
  265. '<code>WP_User->ID</code>' 
  266. ); 
  267. $this->ID = $value; 
  268. return; 
  269.  
  270. $this->data->$key = $value; 
  271.  
  272. /** 
  273. * Magic method for unsetting a certain custom field. 
  274. * @since 4.4.0 
  275. * @access public 
  276. * @param string $key User meta key to unset. 
  277. */ 
  278. public function __unset( $key ) { 
  279. if ( 'id' == $key ) { 
  280. _deprecated_argument( 'WP_User->id', '2.1.0',  
  281. sprintf( 
  282. /** translators: %s: WP_User->ID */ 
  283. __( 'Use %s instead.' ),  
  284. '<code>WP_User->ID</code>' 
  285. ); 
  286.  
  287. if ( isset( $this->data->$key ) ) { 
  288. unset( $this->data->$key ); 
  289.  
  290. if ( isset( self::$back_compat_keys[ $key ] ) ) { 
  291. unset( self::$back_compat_keys[ $key ] ); 
  292.  
  293. /** 
  294. * Determine whether the user exists in the database. 
  295. * @since 3.4.0 
  296. * @access public 
  297. * @return bool True if user exists in the database, false if not. 
  298. */ 
  299. public function exists() { 
  300. return ! empty( $this->ID ); 
  301.  
  302. /** 
  303. * Retrieve the value of a property or meta key. 
  304. * Retrieves from the users and usermeta table. 
  305. * @since 3.3.0 
  306. * @param string $key Property 
  307. * @return mixed 
  308. */ 
  309. public function get( $key ) { 
  310. return $this->__get( $key ); 
  311.  
  312. /** 
  313. * Determine whether a property or meta key is set 
  314. * Consults the users and usermeta tables. 
  315. * @since 3.3.0 
  316. * @param string $key Property 
  317. * @return bool 
  318. */ 
  319. public function has_prop( $key ) { 
  320. return $this->__isset( $key ); 
  321.  
  322. /** 
  323. * Return an array representation. 
  324. * @since 3.5.0 
  325. * @return array Array representation. 
  326. */ 
  327. public function to_array() { 
  328. return get_object_vars( $this->data ); 
  329.  
  330. /** 
  331. * Set up capability object properties. 
  332. * Will set the value for the 'cap_key' property to current database table 
  333. * prefix, followed by 'capabilities'. Will then check to see if the 
  334. * property matching the 'cap_key' exists and is an array. If so, it will be 
  335. * used. 
  336. * @access protected 
  337. * @since 2.1.0 
  338. * @global wpdb $wpdb WordPress database abstraction object. 
  339. * @param string $cap_key Optional capability key 
  340. */ 
  341. protected function _init_caps( $cap_key = '' ) { 
  342. global $wpdb; 
  343.  
  344. if ( empty($cap_key) ) 
  345. $this->cap_key = $wpdb->get_blog_prefix() . 'capabilities'; 
  346. else 
  347. $this->cap_key = $cap_key; 
  348.  
  349. $this->caps = get_user_meta( $this->ID, $this->cap_key, true ); 
  350.  
  351. if ( ! is_array( $this->caps ) ) 
  352. $this->caps = array(); 
  353.  
  354. $this->get_role_caps(); 
  355.  
  356. /** 
  357. * Retrieve all of the role capabilities and merge with individual capabilities. 
  358. * All of the capabilities of the roles the user belongs to are merged with 
  359. * the users individual roles. This also means that the user can be denied 
  360. * specific roles that their role might have, but the specific user isn't 
  361. * granted permission to. 
  362. * @since 2.0.0 
  363. * @access public 
  364. * @return array List of all capabilities for the user. 
  365. */ 
  366. public function get_role_caps() { 
  367. $wp_roles = wp_roles(); 
  368.  
  369. //Filter out caps that are not role names and assign to $this->roles 
  370. if ( is_array( $this->caps ) ) 
  371. $this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) ); 
  372.  
  373. //Build $allcaps from role caps, overlay user's $caps 
  374. $this->allcaps = array(); 
  375. foreach ( (array) $this->roles as $role ) { 
  376. $the_role = $wp_roles->get_role( $role ); 
  377. $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities ); 
  378. $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps ); 
  379.  
  380. return $this->allcaps; 
  381.  
  382. /** 
  383. * Add role to user. 
  384. * Updates the user's meta data option with capabilities and roles. 
  385. * @since 2.0.0 
  386. * @access public 
  387. * @param string $role Role name. 
  388. */ 
  389. public function add_role( $role ) { 
  390. if ( empty( $role ) ) { 
  391. return; 
  392.  
  393. $this->caps[$role] = true; 
  394. update_user_meta( $this->ID, $this->cap_key, $this->caps ); 
  395. $this->get_role_caps(); 
  396. $this->update_user_level_from_caps(); 
  397.  
  398. /** 
  399. * Fires immediately after the user has been given a new role. 
  400. * @since 4.3.0 
  401. * @param int $user_id The user ID. 
  402. * @param string $role The new role. 
  403. */ 
  404. do_action( 'add_user_role', $this->ID, $role ); 
  405.  
  406. /** 
  407. * Remove role from user. 
  408. * @since 2.0.0 
  409. * @access public 
  410. * @param string $role Role name. 
  411. */ 
  412. public function remove_role( $role ) { 
  413. if ( !in_array($role, $this->roles) ) 
  414. return; 
  415. unset( $this->caps[$role] ); 
  416. update_user_meta( $this->ID, $this->cap_key, $this->caps ); 
  417. $this->get_role_caps(); 
  418. $this->update_user_level_from_caps(); 
  419.  
  420. /** 
  421. * Fires immediately after a role as been removed from a user. 
  422. * @since 4.3.0 
  423. * @param int $user_id The user ID. 
  424. * @param string $role The removed role. 
  425. */ 
  426. do_action( 'remove_user_role', $this->ID, $role ); 
  427.  
  428. /** 
  429. * Set the role of the user. 
  430. * This will remove the previous roles of the user and assign the user the 
  431. * new one. You can set the role to an empty string and it will remove all 
  432. * of the roles from the user. 
  433. * @since 2.0.0 
  434. * @access public 
  435. * @param string $role Role name. 
  436. */ 
  437. public function set_role( $role ) { 
  438. if ( 1 == count( $this->roles ) && $role == current( $this->roles ) ) 
  439. return; 
  440.  
  441. foreach ( (array) $this->roles as $oldrole ) 
  442. unset( $this->caps[$oldrole] ); 
  443.  
  444. $old_roles = $this->roles; 
  445. if ( !empty( $role ) ) { 
  446. $this->caps[$role] = true; 
  447. $this->roles = array( $role => true ); 
  448. } else { 
  449. $this->roles = false; 
  450. update_user_meta( $this->ID, $this->cap_key, $this->caps ); 
  451. $this->get_role_caps(); 
  452. $this->update_user_level_from_caps(); 
  453.  
  454. /** 
  455. * Fires after the user's role has changed. 
  456. * @since 2.9.0 
  457. * @since 3.6.0 Added $old_roles to include an array of the user's previous roles. 
  458. * @param int $user_id The user ID. 
  459. * @param string $role The new role. 
  460. * @param array $old_roles An array of the user's previous roles. 
  461. */ 
  462. do_action( 'set_user_role', $this->ID, $role, $old_roles ); 
  463.  
  464. /** 
  465. * Choose the maximum level the user has. 
  466. * Will compare the level from the $item parameter against the $max 
  467. * parameter. If the item is incorrect, then just the $max parameter value 
  468. * will be returned. 
  469. * Used to get the max level based on the capabilities the user has. This 
  470. * is also based on roles, so if the user is assigned the Administrator role 
  471. * then the capability 'level_10' will exist and the user will get that 
  472. * value. 
  473. * @since 2.0.0 
  474. * @access public 
  475. * @param int $max Max level of user. 
  476. * @param string $item Level capability name. 
  477. * @return int Max Level. 
  478. */ 
  479. public function level_reduction( $max, $item ) { 
  480. if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { 
  481. $level = intval( $matches[1] ); 
  482. return max( $max, $level ); 
  483. } else { 
  484. return $max; 
  485.  
  486. /** 
  487. * Update the maximum user level for the user. 
  488. * Updates the 'user_level' user metadata (includes prefix that is the 
  489. * database table prefix) with the maximum user level. Gets the value from 
  490. * the all of the capabilities that the user has. 
  491. * @since 2.0.0 
  492. * @access public 
  493. * @global wpdb $wpdb WordPress database abstraction object. 
  494. */ 
  495. public function update_user_level_from_caps() { 
  496. global $wpdb; 
  497. $this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 ); 
  498. update_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level', $this->user_level ); 
  499.  
  500. /** 
  501. * Add capability and grant or deny access to capability. 
  502. * @since 2.0.0 
  503. * @access public 
  504. * @param string $cap Capability name. 
  505. * @param bool $grant Whether to grant capability to user. 
  506. */ 
  507. public function add_cap( $cap, $grant = true ) { 
  508. $this->caps[$cap] = $grant; 
  509. update_user_meta( $this->ID, $this->cap_key, $this->caps ); 
  510. $this->get_role_caps(); 
  511. $this->update_user_level_from_caps(); 
  512.  
  513. /** 
  514. * Remove capability from user. 
  515. * @since 2.0.0 
  516. * @access public 
  517. * @param string $cap Capability name. 
  518. */ 
  519. public function remove_cap( $cap ) { 
  520. if ( ! isset( $this->caps[ $cap ] ) ) { 
  521. return; 
  522. unset( $this->caps[ $cap ] ); 
  523. update_user_meta( $this->ID, $this->cap_key, $this->caps ); 
  524. $this->get_role_caps(); 
  525. $this->update_user_level_from_caps(); 
  526.  
  527. /** 
  528. * Remove all of the capabilities of the user. 
  529. * @since 2.1.0 
  530. * @access public 
  531. * @global wpdb $wpdb WordPress database abstraction object. 
  532. */ 
  533. public function remove_all_caps() { 
  534. global $wpdb; 
  535. $this->caps = array(); 
  536. delete_user_meta( $this->ID, $this->cap_key ); 
  537. delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' ); 
  538. $this->get_role_caps(); 
  539.  
  540. /** 
  541. * Whether user has capability or role name. 
  542. * While checking against particular roles in place of a capability is supported 
  543. * in part, this practice is discouraged as it may produce unreliable results. 
  544. * @since 2.0.0 
  545. * @access public 
  546. * @see map_meta_cap() 
  547. * @param string $cap Capability name. 
  548. * @param int $object_id, ... Optional. ID of the specific object to check against if `$cap` is a "meta" cap. 
  549. * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used 
  550. * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',  
  551. * 'edit_others_posts', etc. The parameter is accessed via func_get_args() and passed 
  552. * to map_meta_cap(). 
  553. * @return bool Whether the current user has the given capability. If `$cap` is a meta cap and `$object_id` is 
  554. * passed, whether the current user has the given meta capability for the given object. 
  555. */ 
  556. public function has_cap( $cap ) { 
  557. if ( is_numeric( $cap ) ) { 
  558. _deprecated_argument( __FUNCTION__, '2.0.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); 
  559. $cap = $this->translate_level_to_cap( $cap ); 
  560.  
  561. $args = array_slice( func_get_args(), 1 ); 
  562. $args = array_merge( array( $cap, $this->ID ), $args ); 
  563. $caps = call_user_func_array( 'map_meta_cap', $args ); 
  564.  
  565. // Multisite super admin has all caps by definition, Unless specifically denied. 
  566. if ( is_multisite() && is_super_admin( $this->ID ) ) { 
  567. if ( in_array('do_not_allow', $caps) ) 
  568. return false; 
  569. return true; 
  570.  
  571. /** 
  572. * Dynamically filter a user's capabilities. 
  573. * @since 2.0.0 
  574. * @since 3.7.0 Added the user object. 
  575. * @param array $allcaps An array of all the user's capabilities. 
  576. * @param array $caps Actual capabilities for meta capability. 
  577. * @param array $args Optional parameters passed to has_cap(), typically object ID. 
  578. * @param WP_User $user The user object. 
  579. */ 
  580. $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this ); 
  581.  
  582. // Everyone is allowed to exist. 
  583. $capabilities['exist'] = true; 
  584.  
  585. // Must have ALL requested caps. 
  586. foreach ( (array) $caps as $cap ) { 
  587. if ( empty( $capabilities[ $cap ] ) ) 
  588. return false; 
  589.  
  590. return true; 
  591.  
  592. /** 
  593. * Convert numeric level to level capability name. 
  594. * Prepends 'level_' to level number. 
  595. * @since 2.0.0 
  596. * @access public 
  597. * @param int $level Level number, 1 to 10. 
  598. * @return string 
  599. */ 
  600. public function translate_level_to_cap( $level ) { 
  601. return 'level_' . $level; 
  602.  
  603. /** 
  604. * Set the site to operate on. Defaults to the current site. 
  605. * @since 3.0.0 
  606. * @global wpdb $wpdb WordPress database abstraction object. 
  607. * @param int $blog_id Optional. Site ID, defaults to current site. 
  608. */ 
  609. public function for_blog( $blog_id = '' ) { 
  610. global $wpdb; 
  611. if ( ! empty( $blog_id ) ) 
  612. $cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; 
  613. else 
  614. $cap_key = ''; 
  615. $this->_init_caps( $cap_key );