/wp-includes/capabilities.php

  1. <?php 
  2. /** 
  3. * Core User Role & Capabilities API 
  4. * 
  5. * @package WordPress 
  6. * @subpackage Users 
  7. */ 
  8.  
  9. /** 
  10. * Map meta capabilities to primitive capabilities. 
  11. * 
  12. * This does not actually compare whether the user ID has the actual capability,  
  13. * just what the capability or capabilities are. Meta capability list value can 
  14. * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post',  
  15. * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'. 
  16. * 
  17. * @since 2.0.0 
  18. * 
  19. * @global array $post_type_meta_caps Used to get post type meta capabilities. 
  20. * 
  21. * @param string $cap Capability name. 
  22. * @param int $user_id User ID. 
  23. * @param int $object_id Optional. ID of the specific object to check against if `$cap` is a "meta" cap. 
  24. * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used 
  25. * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',  
  26. * 'edit_others_posts', etc. The parameter is accessed via func_get_args(). 
  27. * @return array Actual capabilities for meta capability. 
  28. */ 
  29. function map_meta_cap( $cap, $user_id ) { 
  30. $args = array_slice( func_get_args(), 2 ); 
  31. $caps = array(); 
  32.  
  33. switch ( $cap ) { 
  34. case 'remove_user': 
  35. $caps[] = 'remove_users'; 
  36. break; 
  37. case 'promote_user': 
  38. case 'add_users': 
  39. $caps[] = 'promote_users'; 
  40. break; 
  41. case 'edit_user': 
  42. case 'edit_users': 
  43. // Allow user to edit itself 
  44. if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] ) 
  45. break; 
  46.  
  47. // In multisite the user must have manage_network_users caps. If editing a super admin, the user must be a super admin. 
  48. if ( is_multisite() && ( ( ! is_super_admin( $user_id ) && 'edit_user' === $cap && is_super_admin( $args[0] ) ) || ! user_can( $user_id, 'manage_network_users' ) ) ) { 
  49. $caps[] = 'do_not_allow'; 
  50. } else { 
  51. $caps[] = 'edit_users'; // edit_user maps to edit_users. 
  52. break; 
  53. case 'delete_post': 
  54. case 'delete_page': 
  55. $post = get_post( $args[0] ); 
  56. if ( ! $post ) { 
  57. $caps[] = 'do_not_allow'; 
  58. break; 
  59.  
  60. if ( 'revision' == $post->post_type ) { 
  61. $post = get_post( $post->post_parent ); 
  62. if ( ! $post ) { 
  63. $caps[] = 'do_not_allow'; 
  64. break; 
  65.  
  66. if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) { 
  67. $caps[] = 'manage_options'; 
  68. break; 
  69.  
  70. $post_type = get_post_type_object( $post->post_type ); 
  71. if ( ! $post_type ) { 
  72. /** translators: 1: post type, 2: capability name */ 
  73. _doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' ); 
  74. $caps[] = 'edit_others_posts'; 
  75. break; 
  76.  
  77. if ( ! $post_type->map_meta_cap ) { 
  78. $caps[] = $post_type->cap->$cap; 
  79. // Prior to 3.1 we would re-call map_meta_cap here. 
  80. if ( 'delete_post' == $cap ) 
  81. $cap = $post_type->cap->$cap; 
  82. break; 
  83.  
  84. // If the post author is set and the user is the author... 
  85. if ( $post->post_author && $user_id == $post->post_author ) { 
  86. // If the post is published or scheduled... 
  87. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { 
  88. $caps[] = $post_type->cap->delete_published_posts; 
  89. } elseif ( 'trash' == $post->post_status ) { 
  90. $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true ); 
  91. if ( in_array( $status, array( 'publish', 'future' ), true ) ) { 
  92. $caps[] = $post_type->cap->delete_published_posts; 
  93. } else { 
  94. $caps[] = $post_type->cap->delete_posts; 
  95. } else { 
  96. // If the post is draft... 
  97. $caps[] = $post_type->cap->delete_posts; 
  98. } else { 
  99. // The user is trying to edit someone else's post. 
  100. $caps[] = $post_type->cap->delete_others_posts; 
  101. // The post is published or scheduled, extra cap required. 
  102. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { 
  103. $caps[] = $post_type->cap->delete_published_posts; 
  104. } elseif ( 'private' == $post->post_status ) { 
  105. $caps[] = $post_type->cap->delete_private_posts; 
  106. break; 
  107. // edit_post breaks down to edit_posts, edit_published_posts, or 
  108. // edit_others_posts 
  109. case 'edit_post': 
  110. case 'edit_page': 
  111. $post = get_post( $args[0] ); 
  112. if ( ! $post ) { 
  113. $caps[] = 'do_not_allow'; 
  114. break; 
  115.  
  116. if ( 'revision' == $post->post_type ) { 
  117. $post = get_post( $post->post_parent ); 
  118. if ( ! $post ) { 
  119. $caps[] = 'do_not_allow'; 
  120. break; 
  121.  
  122. $post_type = get_post_type_object( $post->post_type ); 
  123. if ( ! $post_type ) { 
  124. /** translators: 1: post type, 2: capability name */ 
  125. _doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' ); 
  126. $caps[] = 'edit_others_posts'; 
  127. break; 
  128.  
  129. if ( ! $post_type->map_meta_cap ) { 
  130. $caps[] = $post_type->cap->$cap; 
  131. // Prior to 3.1 we would re-call map_meta_cap here. 
  132. if ( 'edit_post' == $cap ) 
  133. $cap = $post_type->cap->$cap; 
  134. break; 
  135.  
  136. // If the post author is set and the user is the author... 
  137. if ( $post->post_author && $user_id == $post->post_author ) { 
  138. // If the post is published or scheduled... 
  139. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { 
  140. $caps[] = $post_type->cap->edit_published_posts; 
  141. } elseif ( 'trash' == $post->post_status ) { 
  142. $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true ); 
  143. if ( in_array( $status, array( 'publish', 'future' ), true ) ) { 
  144. $caps[] = $post_type->cap->edit_published_posts; 
  145. } else { 
  146. $caps[] = $post_type->cap->edit_posts; 
  147. } else { 
  148. // If the post is draft... 
  149. $caps[] = $post_type->cap->edit_posts; 
  150. } else { 
  151. // The user is trying to edit someone else's post. 
  152. $caps[] = $post_type->cap->edit_others_posts; 
  153. // The post is published or scheduled, extra cap required. 
  154. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) { 
  155. $caps[] = $post_type->cap->edit_published_posts; 
  156. } elseif ( 'private' == $post->post_status ) { 
  157. $caps[] = $post_type->cap->edit_private_posts; 
  158. break; 
  159. case 'read_post': 
  160. case 'read_page': 
  161. $post = get_post( $args[0] ); 
  162. if ( ! $post ) { 
  163. $caps[] = 'do_not_allow'; 
  164. break; 
  165.  
  166. if ( 'revision' == $post->post_type ) { 
  167. $post = get_post( $post->post_parent ); 
  168. if ( ! $post ) { 
  169. $caps[] = 'do_not_allow'; 
  170. break; 
  171.  
  172. $post_type = get_post_type_object( $post->post_type ); 
  173. if ( ! $post_type ) { 
  174. /** translators: 1: post type, 2: capability name */ 
  175. _doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' ); 
  176. $caps[] = 'edit_others_posts'; 
  177. break; 
  178.  
  179. if ( ! $post_type->map_meta_cap ) { 
  180. $caps[] = $post_type->cap->$cap; 
  181. // Prior to 3.1 we would re-call map_meta_cap here. 
  182. if ( 'read_post' == $cap ) 
  183. $cap = $post_type->cap->$cap; 
  184. break; 
  185.  
  186. $status_obj = get_post_status_object( $post->post_status ); 
  187. if ( $status_obj->public ) { 
  188. $caps[] = $post_type->cap->read; 
  189. break; 
  190.  
  191. if ( $post->post_author && $user_id == $post->post_author ) { 
  192. $caps[] = $post_type->cap->read; 
  193. } elseif ( $status_obj->private ) { 
  194. $caps[] = $post_type->cap->read_private_posts; 
  195. } else { 
  196. $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 
  197. break; 
  198. case 'publish_post': 
  199. $post = get_post( $args[0] ); 
  200. if ( ! $post ) { 
  201. $caps[] = 'do_not_allow'; 
  202. break; 
  203.  
  204. $post_type = get_post_type_object( $post->post_type ); 
  205. if ( ! $post_type ) { 
  206. /** translators: 1: post type, 2: capability name */ 
  207. _doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' ); 
  208. $caps[] = 'edit_others_posts'; 
  209. break; 
  210.  
  211. $caps[] = $post_type->cap->publish_posts; 
  212. break; 
  213. case 'edit_post_meta': 
  214. case 'delete_post_meta': 
  215. case 'add_post_meta': 
  216. case 'edit_comment_meta': 
  217. case 'delete_comment_meta': 
  218. case 'add_comment_meta': 
  219. case 'edit_term_meta': 
  220. case 'delete_term_meta': 
  221. case 'add_term_meta': 
  222. case 'edit_user_meta': 
  223. case 'delete_user_meta': 
  224. case 'add_user_meta': 
  225. list( $_, $object_type, $_ ) = explode( '_', $cap ); 
  226. $object_id = (int) $args[0]; 
  227.  
  228. switch ( $object_type ) { 
  229. case 'post': 
  230. $post = get_post( $object_id ); 
  231. if ( ! $post ) { 
  232. break; 
  233.  
  234. $sub_type = get_post_type( $post ); 
  235. break; 
  236.  
  237. case 'comment': 
  238. $comment = get_comment( $object_id ); 
  239. if ( ! $comment ) { 
  240. break; 
  241.  
  242. $sub_type = empty( $comment->comment_type ) ? 'comment' : $comment->comment_type; 
  243. break; 
  244.  
  245. case 'term': 
  246. $term = get_term( $object_id ); 
  247. if ( ! $term ) { 
  248. break; 
  249.  
  250. $sub_type = $term->taxonomy; 
  251. break; 
  252.  
  253. case 'user': 
  254. $user = get_user_by( 'id', $object_id ); 
  255. if ( ! $user ) { 
  256. break; 
  257.  
  258. $sub_type = 'user'; 
  259. break; 
  260.  
  261. if ( empty( $sub_type ) ) { 
  262. $caps[] = 'do_not_allow'; 
  263. break; 
  264.  
  265. $caps = map_meta_cap( "edit_{$object_type}", $user_id, $object_id ); 
  266.  
  267. $meta_key = isset( $args[1] ) ? $args[1] : false; 
  268.  
  269. $has_filter = has_filter( "auth_{$object_type}_meta_{$meta_key}" ) || has_filter( "auth_{$object_type}_{$sub_type}_meta_{$meta_key}" ); 
  270. if ( $meta_key && $has_filter ) { 
  271. /** This filter is documented in wp-includes/meta.php */ 
  272. $allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}", false, $meta_key, $object_id, $user_id, $cap, $caps ); 
  273.  
  274. /** This filter is documented in wp-includes/meta.php */ 
  275. $allowed = apply_filters( "auth_{$object_type}_{$sub_type}_meta_{$meta_key}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps ); 
  276.  
  277. if ( ! $allowed ) { 
  278. $caps[] = $cap; 
  279. } elseif ( $meta_key && is_protected_meta( $meta_key, $object_type ) ) { 
  280. $caps[] = $cap; 
  281. break; 
  282. case 'edit_comment': 
  283. $comment = get_comment( $args[0] ); 
  284. if ( ! $comment ) { 
  285. $caps[] = 'do_not_allow'; 
  286. break; 
  287.  
  288. $post = get_post( $comment->comment_post_ID ); 
  289.  
  290. /** 
  291. * If the post doesn't exist, we have an orphaned comment. 
  292. * Fall back to the edit_posts capability, instead. 
  293. */ 
  294. if ( $post ) { 
  295. $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 
  296. } else { 
  297. $caps = map_meta_cap( 'edit_posts', $user_id ); 
  298. break; 
  299. case 'unfiltered_upload': 
  300. if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) ) 
  301. $caps[] = $cap; 
  302. else 
  303. $caps[] = 'do_not_allow'; 
  304. break; 
  305. case 'edit_css' : 
  306. case 'unfiltered_html' : 
  307. // Disallow unfiltered_html for all users, even admins and super admins. 
  308. if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) 
  309. $caps[] = 'do_not_allow'; 
  310. elseif ( is_multisite() && ! is_super_admin( $user_id ) ) 
  311. $caps[] = 'do_not_allow'; 
  312. else 
  313. $caps[] = 'unfiltered_html'; 
  314. break; 
  315. case 'edit_files': 
  316. case 'edit_plugins': 
  317. case 'edit_themes': 
  318. // Disallow the file editors. 
  319. if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) 
  320. $caps[] = 'do_not_allow'; 
  321. elseif ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) 
  322. $caps[] = 'do_not_allow'; 
  323. elseif ( is_multisite() && ! is_super_admin( $user_id ) ) 
  324. $caps[] = 'do_not_allow'; 
  325. else 
  326. $caps[] = $cap; 
  327. break; 
  328. case 'update_plugins': 
  329. case 'delete_plugins': 
  330. case 'install_plugins': 
  331. case 'upload_plugins': 
  332. case 'update_themes': 
  333. case 'delete_themes': 
  334. case 'install_themes': 
  335. case 'upload_themes': 
  336. case 'update_core': 
  337. // Disallow anything that creates, deletes, or updates core, plugin, or theme files. 
  338. // Files in uploads are excepted. 
  339. if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) { 
  340. $caps[] = 'do_not_allow'; 
  341. } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) { 
  342. $caps[] = 'do_not_allow'; 
  343. } elseif ( 'upload_themes' === $cap ) { 
  344. $caps[] = 'install_themes'; 
  345. } elseif ( 'upload_plugins' === $cap ) { 
  346. $caps[] = 'install_plugins'; 
  347. } else { 
  348. $caps[] = $cap; 
  349. break; 
  350. case 'activate_plugins': 
  351. $caps[] = $cap; 
  352. if ( is_multisite() ) { 
  353. // update_, install_, and delete_ are handled above with is_super_admin(). 
  354. $menu_perms = get_site_option( 'menu_items', array() ); 
  355. if ( empty( $menu_perms['plugins'] ) ) 
  356. $caps[] = 'manage_network_plugins'; 
  357. break; 
  358. case 'delete_user': 
  359. case 'delete_users': 
  360. // If multisite only super admins can delete users. 
  361. if ( is_multisite() && ! is_super_admin( $user_id ) ) 
  362. $caps[] = 'do_not_allow'; 
  363. else 
  364. $caps[] = 'delete_users'; // delete_user maps to delete_users. 
  365. break; 
  366. case 'create_users': 
  367. if ( !is_multisite() ) 
  368. $caps[] = $cap; 
  369. elseif ( is_super_admin( $user_id ) || get_site_option( 'add_new_users' ) ) 
  370. $caps[] = $cap; 
  371. else 
  372. $caps[] = 'do_not_allow'; 
  373. break; 
  374. case 'manage_links' : 
  375. if ( get_option( 'link_manager_enabled' ) ) 
  376. $caps[] = $cap; 
  377. else 
  378. $caps[] = 'do_not_allow'; 
  379. break; 
  380. case 'customize' : 
  381. $caps[] = 'edit_theme_options'; 
  382. break; 
  383. case 'delete_site': 
  384. $caps[] = 'manage_options'; 
  385. break; 
  386. case 'edit_term': 
  387. case 'delete_term': 
  388. case 'assign_term': 
  389. $term_id = (int) $args[0]; 
  390. $term = get_term( $term_id ); 
  391. if ( ! $term || is_wp_error( $term ) ) { 
  392. $caps[] = 'do_not_allow'; 
  393. break; 
  394.  
  395. $tax = get_taxonomy( $term->taxonomy ); 
  396. if ( ! $tax ) { 
  397. $caps[] = 'do_not_allow'; 
  398. break; 
  399.  
  400. if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) { 
  401. $caps[] = 'do_not_allow'; 
  402. break; 
  403.  
  404. $taxo_cap = $cap . 's'; 
  405.  
  406. $caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id ); 
  407.  
  408. break; 
  409. case 'manage_post_tags': 
  410. case 'edit_categories': 
  411. case 'edit_post_tags': 
  412. case 'delete_categories': 
  413. case 'delete_post_tags': 
  414. $caps[] = 'manage_categories'; 
  415. break; 
  416. case 'assign_categories': 
  417. case 'assign_post_tags': 
  418. $caps[] = 'edit_posts'; 
  419. break; 
  420. case 'create_sites': 
  421. case 'delete_sites': 
  422. case 'manage_network': 
  423. case 'manage_sites': 
  424. case 'manage_network_users': 
  425. case 'manage_network_plugins': 
  426. case 'manage_network_themes': 
  427. case 'manage_network_options': 
  428. $caps[] = $cap; 
  429. break; 
  430. default: 
  431. // Handle meta capabilities for custom post types. 
  432. global $post_type_meta_caps; 
  433. if ( isset( $post_type_meta_caps[ $cap ] ) ) { 
  434. $args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args ); 
  435. return call_user_func_array( 'map_meta_cap', $args ); 
  436.  
  437. // If no meta caps match, return the original cap. 
  438. $caps[] = $cap; 
  439.  
  440. /** 
  441. * Filters a user's capabilities depending on specific context and/or privilege. 
  442. * 
  443. * @since 2.8.0 
  444. * 
  445. * @param array $caps Returns the user's actual capabilities. 
  446. * @param string $cap Capability name. 
  447. * @param int $user_id The user ID. 
  448. * @param array $args Adds the context to the cap. Typically the object ID. 
  449. */ 
  450. return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args ); 
  451.  
  452. /** 
  453. * Whether the current user has a specific capability. 
  454. * 
  455. * While checking against particular roles in place of a capability is supported 
  456. * in part, this practice is discouraged as it may produce unreliable results. 
  457. * 
  458. * Note: Will always return true if the current user is a super admin, unless specifically denied. 
  459. * 
  460. * @since 2.0.0 
  461. * 
  462. * @see WP_User::has_cap() 
  463. * @see map_meta_cap() 
  464. * 
  465. * @param string $capability Capability name. 
  466. * @param int $object_id Optional. ID of the specific object to check against if `$capability` is a "meta" cap. 
  467. * "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used 
  468. * by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',  
  469. * 'edit_others_posts', etc. Accessed via func_get_args() and passed to WP_User::has_cap(),  
  470. * then map_meta_cap(). 
  471. * @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is 
  472. * passed, whether the current user has the given meta capability for the given object. 
  473. */ 
  474. function current_user_can( $capability ) { 
  475. $current_user = wp_get_current_user(); 
  476.  
  477. if ( empty( $current_user ) ) 
  478. return false; 
  479.  
  480. $args = array_slice( func_get_args(), 1 ); 
  481. $args = array_merge( array( $capability ), $args ); 
  482.  
  483. return call_user_func_array( array( $current_user, 'has_cap' ), $args ); 
  484.  
  485. /** 
  486. * Whether current user has a capability or role for a given site. 
  487. * 
  488. * @since 3.0.0 
  489. * 
  490. * @param int $blog_id Site ID. 
  491. * @param string $capability Capability or role name. 
  492. * @return bool 
  493. */ 
  494. function current_user_can_for_blog( $blog_id, $capability ) { 
  495. $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; 
  496.  
  497. $current_user = wp_get_current_user(); 
  498.  
  499. if ( empty( $current_user ) ) { 
  500. if ( $switched ) { 
  501. restore_current_blog(); 
  502. return false; 
  503.  
  504. $args = array_slice( func_get_args(), 2 ); 
  505. $args = array_merge( array( $capability ), $args ); 
  506.  
  507. $can = call_user_func_array( array( $current_user, 'has_cap' ), $args ); 
  508.  
  509. if ( $switched ) { 
  510. restore_current_blog(); 
  511.  
  512. return $can; 
  513.  
  514. /** 
  515. * Whether author of supplied post has capability or role. 
  516. * 
  517. * @since 2.9.0 
  518. * 
  519. * @param int|object $post Post ID or post object. 
  520. * @param string $capability Capability or role name. 
  521. * @return bool 
  522. */ 
  523. function author_can( $post, $capability ) { 
  524. if ( !$post = get_post($post) ) 
  525. return false; 
  526.  
  527. $author = get_userdata( $post->post_author ); 
  528.  
  529. if ( ! $author ) 
  530. return false; 
  531.  
  532. $args = array_slice( func_get_args(), 2 ); 
  533. $args = array_merge( array( $capability ), $args ); 
  534.  
  535. return call_user_func_array( array( $author, 'has_cap' ), $args ); 
  536.  
  537. /** 
  538. * Whether a particular user has capability or role. 
  539. * 
  540. * @since 3.1.0 
  541. * 
  542. * @param int|object $user User ID or object. 
  543. * @param string $capability Capability or role name. 
  544. * @return bool 
  545. */ 
  546. function user_can( $user, $capability ) { 
  547. if ( ! is_object( $user ) ) 
  548. $user = get_userdata( $user ); 
  549.  
  550. if ( ! $user || ! $user->exists() ) 
  551. return false; 
  552.  
  553. $args = array_slice( func_get_args(), 2 ); 
  554. $args = array_merge( array( $capability ), $args ); 
  555.  
  556. return call_user_func_array( array( $user, 'has_cap' ), $args ); 
  557.  
  558. /** 
  559. * Retrieves the global WP_Roles instance and instantiates it if necessary. 
  560. * 
  561. * @since 4.3.0 
  562. * 
  563. * @global WP_Roles $wp_roles WP_Roles global instance. 
  564. * 
  565. * @return WP_Roles WP_Roles global instance if not already instantiated. 
  566. */ 
  567. function wp_roles() { 
  568. global $wp_roles; 
  569.  
  570. if ( ! isset( $wp_roles ) ) { 
  571. $wp_roles = new WP_Roles(); 
  572. return $wp_roles; 
  573.  
  574. /** 
  575. * Retrieve role object. 
  576. * 
  577. * @since 2.0.0 
  578. * 
  579. * @param string $role Role name. 
  580. * @return WP_Role|null WP_Role object if found, null if the role does not exist. 
  581. */ 
  582. function get_role( $role ) { 
  583. return wp_roles()->get_role( $role ); 
  584.  
  585. /** 
  586. * Add role, if it does not exist. 
  587. * 
  588. * @since 2.0.0 
  589. * 
  590. * @param string $role Role name. 
  591. * @param string $display_name Display name for role. 
  592. * @param array $capabilities List of capabilities, e.g. array( 'edit_posts' => true, 'delete_posts' => false ); 
  593. * @return WP_Role|null WP_Role object if role is added, null if already exists. 
  594. */ 
  595. function add_role( $role, $display_name, $capabilities = array() ) { 
  596. if ( empty( $role ) ) { 
  597. return; 
  598. return wp_roles()->add_role( $role, $display_name, $capabilities ); 
  599.  
  600. /** 
  601. * Remove role, if it exists. 
  602. * 
  603. * @since 2.0.0 
  604. * 
  605. * @param string $role Role name. 
  606. */ 
  607. function remove_role( $role ) { 
  608. wp_roles()->remove_role( $role ); 
  609.  
  610. /** 
  611. * Retrieve a list of super admins. 
  612. * 
  613. * @since 3.0.0 
  614. * 
  615. * @global array $super_admins 
  616. * 
  617. * @return array List of super admin logins 
  618. */ 
  619. function get_super_admins() { 
  620. global $super_admins; 
  621.  
  622. if ( isset($super_admins) ) 
  623. return $super_admins; 
  624. else 
  625. return get_site_option( 'site_admins', array('admin') ); 
  626.  
  627. /** 
  628. * Determine if user is a site admin. 
  629. * 
  630. * @since 3.0.0 
  631. * 
  632. * @param int $user_id (Optional) The ID of a user. Defaults to the current user. 
  633. * @return bool True if the user is a site admin. 
  634. */ 
  635. function is_super_admin( $user_id = false ) { 
  636. if ( ! $user_id || $user_id == get_current_user_id() ) 
  637. $user = wp_get_current_user(); 
  638. else 
  639. $user = get_userdata( $user_id ); 
  640.  
  641. if ( ! $user || ! $user->exists() ) 
  642. return false; 
  643.  
  644. if ( is_multisite() ) { 
  645. $super_admins = get_super_admins(); 
  646. if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) 
  647. return true; 
  648. } else { 
  649. if ( $user->has_cap('delete_users') ) 
  650. return true; 
  651.  
  652. return false; 
  653.  
  654. /** 
  655. * Grants Super Admin privileges. 
  656. * 
  657. * @since 3.0.0 
  658. * 
  659. * @global array $super_admins 
  660. * 
  661. * @param int $user_id ID of the user to be granted Super Admin privileges. 
  662. * @return bool True on success, false on failure. This can fail when the user is 
  663. * already a super admin or when the `$super_admins` global is defined. 
  664. */ 
  665. function grant_super_admin( $user_id ) { 
  666. // If global super_admins override is defined, there is nothing to do here. 
  667. if ( isset( $GLOBALS['super_admins'] ) || ! is_multisite() ) { 
  668. return false; 
  669.  
  670. /** 
  671. * Fires before the user is granted Super Admin privileges. 
  672. * 
  673. * @since 3.0.0 
  674. * 
  675. * @param int $user_id ID of the user that is about to be granted Super Admin privileges. 
  676. */ 
  677. do_action( 'grant_super_admin', $user_id ); 
  678.  
  679. // Directly fetch site_admins instead of using get_super_admins() 
  680. $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); 
  681.  
  682. $user = get_userdata( $user_id ); 
  683. if ( $user && ! in_array( $user->user_login, $super_admins ) ) { 
  684. $super_admins[] = $user->user_login; 
  685. update_site_option( 'site_admins' , $super_admins ); 
  686.  
  687. /** 
  688. * Fires after the user is granted Super Admin privileges. 
  689. * 
  690. * @since 3.0.0 
  691. * 
  692. * @param int $user_id ID of the user that was granted Super Admin privileges. 
  693. */ 
  694. do_action( 'granted_super_admin', $user_id ); 
  695. return true; 
  696. return false; 
  697.  
  698. /** 
  699. * Revokes Super Admin privileges. 
  700. * 
  701. * @since 3.0.0 
  702. * 
  703. * @global array $super_admins 
  704. * 
  705. * @param int $user_id ID of the user Super Admin privileges to be revoked from. 
  706. * @return bool True on success, false on failure. This can fail when the user's email 
  707. * is the network admin email or when the `$super_admins` global is defined. 
  708. */ 
  709. function revoke_super_admin( $user_id ) { 
  710. // If global super_admins override is defined, there is nothing to do here. 
  711. if ( isset( $GLOBALS['super_admins'] ) || ! is_multisite() ) { 
  712. return false; 
  713.  
  714. /** 
  715. * Fires before the user's Super Admin privileges are revoked. 
  716. * 
  717. * @since 3.0.0 
  718. * 
  719. * @param int $user_id ID of the user Super Admin privileges are being revoked from. 
  720. */ 
  721. do_action( 'revoke_super_admin', $user_id ); 
  722.  
  723. // Directly fetch site_admins instead of using get_super_admins() 
  724. $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); 
  725.  
  726. $user = get_userdata( $user_id ); 
  727. if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) { 
  728. if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) { 
  729. unset( $super_admins[$key] ); 
  730. update_site_option( 'site_admins', $super_admins ); 
  731.  
  732. /** 
  733. * Fires after the user's Super Admin privileges are revoked. 
  734. * 
  735. * @since 3.0.0 
  736. * 
  737. * @param int $user_id ID of the user Super Admin privileges were revoked from. 
  738. */ 
  739. do_action( 'revoked_super_admin', $user_id ); 
  740. return true; 
  741. return false; 
.