capabilities.php 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
  1. <?php
  2. /**
  3. * Core User Role & Capabilities API
  4. *
  5. * @package WordPress
  6. * @subpackage Users
  7. */
  8. /**
  9. * Maps a capability to the primitive capabilities required of the given user to
  10. * satisfy the capability being checked.
  11. *
  12. * This function also accepts an ID of an object to map against if the capability is a meta capability. Meta
  13. * capabilities such as `edit_post` and `edit_user` are capabilities used by this function to map to primitive
  14. * capabilities that a user or role requires, such as `edit_posts` and `edit_others_posts`.
  15. *
  16. * Example usage:
  17. *
  18. * map_meta_cap( 'edit_posts', $user->ID );
  19. * map_meta_cap( 'edit_post', $user->ID, $post->ID );
  20. * map_meta_cap( 'edit_post_meta', $user->ID, $post->ID, $meta_key );
  21. *
  22. * This function does not check whether the user has the required capabilities,
  23. * it just returns what the required capabilities are.
  24. *
  25. * @since 2.0.0
  26. * @since 4.9.6 Added the `export_others_personal_data`, `erase_others_personal_data`,
  27. * and `manage_privacy_options` capabilities.
  28. * @since 5.1.0 Added the `update_php` capability.
  29. * @since 5.2.0 Added the `resume_plugin` and `resume_theme` capabilities.
  30. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
  31. * by adding it to the function signature.
  32. * @since 5.7.0 Added the `create_app_password`, `list_app_passwords`, `read_app_password`,
  33. * `edit_app_password`, `delete_app_passwords`, `delete_app_password`,
  34. * and `update_https` capabilities.
  35. *
  36. * @global array $post_type_meta_caps Used to get post type meta capabilities.
  37. *
  38. * @param string $cap Capability being checked.
  39. * @param int $user_id User ID.
  40. * @param mixed ...$args Optional further parameters, typically starting with an object ID.
  41. * @return string[] Primitive capabilities required of the user.
  42. */
  43. function map_meta_cap( $cap, $user_id, ...$args ) {
  44. $caps = array();
  45. switch ( $cap ) {
  46. case 'remove_user':
  47. // In multisite the user must be a super admin to remove themselves.
  48. if ( isset( $args[0] ) && $user_id == $args[0] && ! is_super_admin( $user_id ) ) {
  49. $caps[] = 'do_not_allow';
  50. } else {
  51. $caps[] = 'remove_users';
  52. }
  53. break;
  54. case 'promote_user':
  55. case 'add_users':
  56. $caps[] = 'promote_users';
  57. break;
  58. case 'edit_user':
  59. case 'edit_users':
  60. // Allow user to edit themselves.
  61. if ( 'edit_user' === $cap && isset( $args[0] ) && $user_id == $args[0] ) {
  62. break;
  63. }
  64. // In multisite the user must have manage_network_users caps. If editing a super admin, the user must be a super admin.
  65. if ( is_multisite() && ( ( ! is_super_admin( $user_id ) && 'edit_user' === $cap && is_super_admin( $args[0] ) ) || ! user_can( $user_id, 'manage_network_users' ) ) ) {
  66. $caps[] = 'do_not_allow';
  67. } else {
  68. $caps[] = 'edit_users'; // edit_user maps to edit_users.
  69. }
  70. break;
  71. case 'delete_post':
  72. case 'delete_page':
  73. if ( ! isset( $args[0] ) ) {
  74. if ( 'delete_post' === $cap ) {
  75. /* translators: %s: Capability name. */
  76. $message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
  77. } else {
  78. /* translators: %s: Capability name. */
  79. $message = __( 'When checking for the %s capability, you must always check it against a specific page.' );
  80. }
  81. _doing_it_wrong(
  82. __FUNCTION__,
  83. sprintf( $message, '<code>' . $cap . '</code>' ),
  84. '6.1.0'
  85. );
  86. $caps[] = 'do_not_allow';
  87. break;
  88. }
  89. $post = get_post( $args[0] );
  90. if ( ! $post ) {
  91. $caps[] = 'do_not_allow';
  92. break;
  93. }
  94. if ( 'revision' === $post->post_type ) {
  95. $caps[] = 'do_not_allow';
  96. break;
  97. }
  98. if ( ( get_option( 'page_for_posts' ) == $post->ID ) || ( get_option( 'page_on_front' ) == $post->ID ) ) {
  99. $caps[] = 'manage_options';
  100. break;
  101. }
  102. $post_type = get_post_type_object( $post->post_type );
  103. if ( ! $post_type ) {
  104. /* translators: 1: Post type, 2: Capability name. */
  105. $message = __( '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.' );
  106. _doing_it_wrong(
  107. __FUNCTION__,
  108. sprintf(
  109. $message,
  110. '<code>' . $post->post_type . '</code>',
  111. '<code>' . $cap . '</code>'
  112. ),
  113. '4.4.0'
  114. );
  115. $caps[] = 'edit_others_posts';
  116. break;
  117. }
  118. if ( ! $post_type->map_meta_cap ) {
  119. $caps[] = $post_type->cap->$cap;
  120. // Prior to 3.1 we would re-call map_meta_cap here.
  121. if ( 'delete_post' === $cap ) {
  122. $cap = $post_type->cap->$cap;
  123. }
  124. break;
  125. }
  126. // If the post author is set and the user is the author...
  127. if ( $post->post_author && $user_id == $post->post_author ) {
  128. // If the post is published or scheduled...
  129. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
  130. $caps[] = $post_type->cap->delete_published_posts;
  131. } elseif ( 'trash' === $post->post_status ) {
  132. $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
  133. if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
  134. $caps[] = $post_type->cap->delete_published_posts;
  135. } else {
  136. $caps[] = $post_type->cap->delete_posts;
  137. }
  138. } else {
  139. // If the post is draft...
  140. $caps[] = $post_type->cap->delete_posts;
  141. }
  142. } else {
  143. // The user is trying to edit someone else's post.
  144. $caps[] = $post_type->cap->delete_others_posts;
  145. // The post is published or scheduled, extra cap required.
  146. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
  147. $caps[] = $post_type->cap->delete_published_posts;
  148. } elseif ( 'private' === $post->post_status ) {
  149. $caps[] = $post_type->cap->delete_private_posts;
  150. }
  151. }
  152. /*
  153. * Setting the privacy policy page requires `manage_privacy_options`,
  154. * so deleting it should require that too.
  155. */
  156. if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
  157. $caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
  158. }
  159. break;
  160. // edit_post breaks down to edit_posts, edit_published_posts, or
  161. // edit_others_posts.
  162. case 'edit_post':
  163. case 'edit_page':
  164. if ( ! isset( $args[0] ) ) {
  165. if ( 'edit_post' === $cap ) {
  166. /* translators: %s: Capability name. */
  167. $message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
  168. } else {
  169. /* translators: %s: Capability name. */
  170. $message = __( 'When checking for the %s capability, you must always check it against a specific page.' );
  171. }
  172. _doing_it_wrong(
  173. __FUNCTION__,
  174. sprintf( $message, '<code>' . $cap . '</code>' ),
  175. '6.1.0'
  176. );
  177. $caps[] = 'do_not_allow';
  178. break;
  179. }
  180. $post = get_post( $args[0] );
  181. if ( ! $post ) {
  182. $caps[] = 'do_not_allow';
  183. break;
  184. }
  185. if ( 'revision' === $post->post_type ) {
  186. $post = get_post( $post->post_parent );
  187. if ( ! $post ) {
  188. $caps[] = 'do_not_allow';
  189. break;
  190. }
  191. }
  192. $post_type = get_post_type_object( $post->post_type );
  193. if ( ! $post_type ) {
  194. /* translators: 1: Post type, 2: Capability name. */
  195. $message = __( '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.' );
  196. _doing_it_wrong(
  197. __FUNCTION__,
  198. sprintf(
  199. $message,
  200. '<code>' . $post->post_type . '</code>',
  201. '<code>' . $cap . '</code>'
  202. ),
  203. '4.4.0'
  204. );
  205. $caps[] = 'edit_others_posts';
  206. break;
  207. }
  208. if ( ! $post_type->map_meta_cap ) {
  209. $caps[] = $post_type->cap->$cap;
  210. // Prior to 3.1 we would re-call map_meta_cap here.
  211. if ( 'edit_post' === $cap ) {
  212. $cap = $post_type->cap->$cap;
  213. }
  214. break;
  215. }
  216. // If the post author is set and the user is the author...
  217. if ( $post->post_author && $user_id == $post->post_author ) {
  218. // If the post is published or scheduled...
  219. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
  220. $caps[] = $post_type->cap->edit_published_posts;
  221. } elseif ( 'trash' === $post->post_status ) {
  222. $status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
  223. if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
  224. $caps[] = $post_type->cap->edit_published_posts;
  225. } else {
  226. $caps[] = $post_type->cap->edit_posts;
  227. }
  228. } else {
  229. // If the post is draft...
  230. $caps[] = $post_type->cap->edit_posts;
  231. }
  232. } else {
  233. // The user is trying to edit someone else's post.
  234. $caps[] = $post_type->cap->edit_others_posts;
  235. // The post is published or scheduled, extra cap required.
  236. if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
  237. $caps[] = $post_type->cap->edit_published_posts;
  238. } elseif ( 'private' === $post->post_status ) {
  239. $caps[] = $post_type->cap->edit_private_posts;
  240. }
  241. }
  242. /*
  243. * Setting the privacy policy page requires `manage_privacy_options`,
  244. * so editing it should require that too.
  245. */
  246. if ( (int) get_option( 'wp_page_for_privacy_policy' ) === $post->ID ) {
  247. $caps = array_merge( $caps, map_meta_cap( 'manage_privacy_options', $user_id ) );
  248. }
  249. break;
  250. case 'read_post':
  251. case 'read_page':
  252. if ( ! isset( $args[0] ) ) {
  253. if ( 'read_post' === $cap ) {
  254. /* translators: %s: Capability name. */
  255. $message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
  256. } else {
  257. /* translators: %s: Capability name. */
  258. $message = __( 'When checking for the %s capability, you must always check it against a specific page.' );
  259. }
  260. _doing_it_wrong(
  261. __FUNCTION__,
  262. sprintf( $message, '<code>' . $cap . '</code>' ),
  263. '6.1.0'
  264. );
  265. $caps[] = 'do_not_allow';
  266. break;
  267. }
  268. $post = get_post( $args[0] );
  269. if ( ! $post ) {
  270. $caps[] = 'do_not_allow';
  271. break;
  272. }
  273. if ( 'revision' === $post->post_type ) {
  274. $post = get_post( $post->post_parent );
  275. if ( ! $post ) {
  276. $caps[] = 'do_not_allow';
  277. break;
  278. }
  279. }
  280. $post_type = get_post_type_object( $post->post_type );
  281. if ( ! $post_type ) {
  282. /* translators: 1: Post type, 2: Capability name. */
  283. $message = __( '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.' );
  284. _doing_it_wrong(
  285. __FUNCTION__,
  286. sprintf(
  287. $message,
  288. '<code>' . $post->post_type . '</code>',
  289. '<code>' . $cap . '</code>'
  290. ),
  291. '4.4.0'
  292. );
  293. $caps[] = 'edit_others_posts';
  294. break;
  295. }
  296. if ( ! $post_type->map_meta_cap ) {
  297. $caps[] = $post_type->cap->$cap;
  298. // Prior to 3.1 we would re-call map_meta_cap here.
  299. if ( 'read_post' === $cap ) {
  300. $cap = $post_type->cap->$cap;
  301. }
  302. break;
  303. }
  304. $status_obj = get_post_status_object( get_post_status( $post ) );
  305. if ( ! $status_obj ) {
  306. /* translators: 1: Post status, 2: Capability name. */
  307. $message = __( 'The post status %1$s is not registered, so it may not be reliable to check the capability %2$s against a post with that status.' );
  308. _doing_it_wrong(
  309. __FUNCTION__,
  310. sprintf(
  311. $message,
  312. '<code>' . get_post_status( $post ) . '</code>',
  313. '<code>' . $cap . '</code>'
  314. ),
  315. '5.4.0'
  316. );
  317. $caps[] = 'edit_others_posts';
  318. break;
  319. }
  320. if ( $status_obj->public ) {
  321. $caps[] = $post_type->cap->read;
  322. break;
  323. }
  324. if ( $post->post_author && $user_id == $post->post_author ) {
  325. $caps[] = $post_type->cap->read;
  326. } elseif ( $status_obj->private ) {
  327. $caps[] = $post_type->cap->read_private_posts;
  328. } else {
  329. $caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
  330. }
  331. break;
  332. case 'publish_post':
  333. if ( ! isset( $args[0] ) ) {
  334. /* translators: %s: Capability name. */
  335. $message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
  336. _doing_it_wrong(
  337. __FUNCTION__,
  338. sprintf( $message, '<code>' . $cap . '</code>' ),
  339. '6.1.0'
  340. );
  341. $caps[] = 'do_not_allow';
  342. break;
  343. }
  344. $post = get_post( $args[0] );
  345. if ( ! $post ) {
  346. $caps[] = 'do_not_allow';
  347. break;
  348. }
  349. $post_type = get_post_type_object( $post->post_type );
  350. if ( ! $post_type ) {
  351. /* translators: 1: Post type, 2: Capability name. */
  352. $message = __( '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.' );
  353. _doing_it_wrong(
  354. __FUNCTION__,
  355. sprintf(
  356. $message,
  357. '<code>' . $post->post_type . '</code>',
  358. '<code>' . $cap . '</code>'
  359. ),
  360. '4.4.0'
  361. );
  362. $caps[] = 'edit_others_posts';
  363. break;
  364. }
  365. $caps[] = $post_type->cap->publish_posts;
  366. break;
  367. case 'edit_post_meta':
  368. case 'delete_post_meta':
  369. case 'add_post_meta':
  370. case 'edit_comment_meta':
  371. case 'delete_comment_meta':
  372. case 'add_comment_meta':
  373. case 'edit_term_meta':
  374. case 'delete_term_meta':
  375. case 'add_term_meta':
  376. case 'edit_user_meta':
  377. case 'delete_user_meta':
  378. case 'add_user_meta':
  379. $object_type = explode( '_', $cap )[1];
  380. if ( ! isset( $args[0] ) ) {
  381. if ( 'post' === $object_type ) {
  382. /* translators: %s: Capability name. */
  383. $message = __( 'When checking for the %s capability, you must always check it against a specific post.' );
  384. } elseif ( 'comment' === $object_type ) {
  385. /* translators: %s: Capability name. */
  386. $message = __( 'When checking for the %s capability, you must always check it against a specific comment.' );
  387. } elseif ( 'term' === $object_type ) {
  388. /* translators: %s: Capability name. */
  389. $message = __( 'When checking for the %s capability, you must always check it against a specific term.' );
  390. } else {
  391. /* translators: %s: Capability name. */
  392. $message = __( 'When checking for the %s capability, you must always check it against a specific user.' );
  393. }
  394. _doing_it_wrong(
  395. __FUNCTION__,
  396. sprintf( $message, '<code>' . $cap . '</code>' ),
  397. '6.1.0'
  398. );
  399. $caps[] = 'do_not_allow';
  400. break;
  401. }
  402. $object_id = (int) $args[0];
  403. $object_subtype = get_object_subtype( $object_type, $object_id );
  404. if ( empty( $object_subtype ) ) {
  405. $caps[] = 'do_not_allow';
  406. break;
  407. }
  408. $caps = map_meta_cap( "edit_{$object_type}", $user_id, $object_id );
  409. $meta_key = isset( $args[1] ) ? $args[1] : false;
  410. if ( $meta_key ) {
  411. $allowed = ! is_protected_meta( $meta_key, $object_type );
  412. if ( ! empty( $object_subtype ) && has_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
  413. /**
  414. * Filters whether the user is allowed to edit a specific meta key of a specific object type and subtype.
  415. *
  416. * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
  417. * and `$object_subtype`, refer to the metadata object type (comment, post, term or user),
  418. * the meta key value, and the object subtype respectively.
  419. *
  420. * @since 4.9.8
  421. *
  422. * @param bool $allowed Whether the user can add the object meta. Default false.
  423. * @param string $meta_key The meta key.
  424. * @param int $object_id Object ID.
  425. * @param int $user_id User ID.
  426. * @param string $cap Capability name.
  427. * @param string[] $caps Array of the user's capabilities.
  428. */
  429. $allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps );
  430. } else {
  431. /**
  432. * Filters whether the user is allowed to edit a specific meta key of a specific object type.
  433. *
  434. * Return true to have the mapped meta caps from `edit_{$object_type}` apply.
  435. *
  436. * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered.
  437. * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
  438. *
  439. * @since 3.3.0 As `auth_post_meta_{$meta_key}`.
  440. * @since 4.6.0
  441. *
  442. * @param bool $allowed Whether the user can add the object meta. Default false.
  443. * @param string $meta_key The meta key.
  444. * @param int $object_id Object ID.
  445. * @param int $user_id User ID.
  446. * @param string $cap Capability name.
  447. * @param string[] $caps Array of the user's capabilities.
  448. */
  449. $allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps );
  450. }
  451. if ( ! empty( $object_subtype ) ) {
  452. /**
  453. * Filters whether the user is allowed to edit meta for specific object types/subtypes.
  454. *
  455. * Return true to have the mapped meta caps from `edit_{$object_type}` apply.
  456. *
  457. * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered.
  458. * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered.
  459. * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap().
  460. *
  461. * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`.
  462. * @since 4.7.0 Renamed from `auth_post_{$post_type}_meta_{$meta_key}` to
  463. * `auth_{$object_type}_{$object_subtype}_meta_{$meta_key}`.
  464. * @deprecated 4.9.8 Use {@see 'auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}'} instead.
  465. *
  466. * @param bool $allowed Whether the user can add the object meta. Default false.
  467. * @param string $meta_key The meta key.
  468. * @param int $object_id Object ID.
  469. * @param int $user_id User ID.
  470. * @param string $cap Capability name.
  471. * @param string[] $caps Array of the user's capabilities.
  472. */
  473. $allowed = apply_filters_deprecated(
  474. "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}",
  475. array( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ),
  476. '4.9.8',
  477. "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}"
  478. );
  479. }
  480. if ( ! $allowed ) {
  481. $caps[] = $cap;
  482. }
  483. }
  484. break;
  485. case 'edit_comment':
  486. if ( ! isset( $args[0] ) ) {
  487. /* translators: %s: Capability name. */
  488. $message = __( 'When checking for the %s capability, you must always check it against a specific comment.' );
  489. _doing_it_wrong(
  490. __FUNCTION__,
  491. sprintf( $message, '<code>' . $cap . '</code>' ),
  492. '6.1.0'
  493. );
  494. $caps[] = 'do_not_allow';
  495. break;
  496. }
  497. $comment = get_comment( $args[0] );
  498. if ( ! $comment ) {
  499. $caps[] = 'do_not_allow';
  500. break;
  501. }
  502. $post = get_post( $comment->comment_post_ID );
  503. /*
  504. * If the post doesn't exist, we have an orphaned comment.
  505. * Fall back to the edit_posts capability, instead.
  506. */
  507. if ( $post ) {
  508. $caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
  509. } else {
  510. $caps = map_meta_cap( 'edit_posts', $user_id );
  511. }
  512. break;
  513. case 'unfiltered_upload':
  514. if ( defined( 'ALLOW_UNFILTERED_UPLOADS' ) && ALLOW_UNFILTERED_UPLOADS && ( ! is_multisite() || is_super_admin( $user_id ) ) ) {
  515. $caps[] = $cap;
  516. } else {
  517. $caps[] = 'do_not_allow';
  518. }
  519. break;
  520. case 'edit_css':
  521. case 'unfiltered_html':
  522. // Disallow unfiltered_html for all users, even admins and super admins.
  523. if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) {
  524. $caps[] = 'do_not_allow';
  525. } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
  526. $caps[] = 'do_not_allow';
  527. } else {
  528. $caps[] = 'unfiltered_html';
  529. }
  530. break;
  531. case 'edit_files':
  532. case 'edit_plugins':
  533. case 'edit_themes':
  534. // Disallow the file editors.
  535. if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) {
  536. $caps[] = 'do_not_allow';
  537. } elseif ( ! wp_is_file_mod_allowed( 'capability_edit_themes' ) ) {
  538. $caps[] = 'do_not_allow';
  539. } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
  540. $caps[] = 'do_not_allow';
  541. } else {
  542. $caps[] = $cap;
  543. }
  544. break;
  545. case 'update_plugins':
  546. case 'delete_plugins':
  547. case 'install_plugins':
  548. case 'upload_plugins':
  549. case 'update_themes':
  550. case 'delete_themes':
  551. case 'install_themes':
  552. case 'upload_themes':
  553. case 'update_core':
  554. // Disallow anything that creates, deletes, or updates core, plugin, or theme files.
  555. // Files in uploads are excepted.
  556. if ( ! wp_is_file_mod_allowed( 'capability_update_core' ) ) {
  557. $caps[] = 'do_not_allow';
  558. } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
  559. $caps[] = 'do_not_allow';
  560. } elseif ( 'upload_themes' === $cap ) {
  561. $caps[] = 'install_themes';
  562. } elseif ( 'upload_plugins' === $cap ) {
  563. $caps[] = 'install_plugins';
  564. } else {
  565. $caps[] = $cap;
  566. }
  567. break;
  568. case 'install_languages':
  569. case 'update_languages':
  570. if ( ! wp_is_file_mod_allowed( 'can_install_language_pack' ) ) {
  571. $caps[] = 'do_not_allow';
  572. } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
  573. $caps[] = 'do_not_allow';
  574. } else {
  575. $caps[] = 'install_languages';
  576. }
  577. break;
  578. case 'activate_plugins':
  579. case 'deactivate_plugins':
  580. case 'activate_plugin':
  581. case 'deactivate_plugin':
  582. $caps[] = 'activate_plugins';
  583. if ( is_multisite() ) {
  584. // update_, install_, and delete_ are handled above with is_super_admin().
  585. $menu_perms = get_site_option( 'menu_items', array() );
  586. if ( empty( $menu_perms['plugins'] ) ) {
  587. $caps[] = 'manage_network_plugins';
  588. }
  589. }
  590. break;
  591. case 'resume_plugin':
  592. $caps[] = 'resume_plugins';
  593. break;
  594. case 'resume_theme':
  595. $caps[] = 'resume_themes';
  596. break;
  597. case 'delete_user':
  598. case 'delete_users':
  599. // If multisite only super admins can delete users.
  600. if ( is_multisite() && ! is_super_admin( $user_id ) ) {
  601. $caps[] = 'do_not_allow';
  602. } else {
  603. $caps[] = 'delete_users'; // delete_user maps to delete_users.
  604. }
  605. break;
  606. case 'create_users':
  607. if ( ! is_multisite() ) {
  608. $caps[] = $cap;
  609. } elseif ( is_super_admin( $user_id ) || get_site_option( 'add_new_users' ) ) {
  610. $caps[] = $cap;
  611. } else {
  612. $caps[] = 'do_not_allow';
  613. }
  614. break;
  615. case 'manage_links':
  616. if ( get_option( 'link_manager_enabled' ) ) {
  617. $caps[] = $cap;
  618. } else {
  619. $caps[] = 'do_not_allow';
  620. }
  621. break;
  622. case 'customize':
  623. $caps[] = 'edit_theme_options';
  624. break;
  625. case 'delete_site':
  626. if ( is_multisite() ) {
  627. $caps[] = 'manage_options';
  628. } else {
  629. $caps[] = 'do_not_allow';
  630. }
  631. break;
  632. case 'edit_term':
  633. case 'delete_term':
  634. case 'assign_term':
  635. if ( ! isset( $args[0] ) ) {
  636. /* translators: %s: Capability name. */
  637. $message = __( 'When checking for the %s capability, you must always check it against a specific term.' );
  638. _doing_it_wrong(
  639. __FUNCTION__,
  640. sprintf( $message, '<code>' . $cap . '</code>' ),
  641. '6.1.0'
  642. );
  643. $caps[] = 'do_not_allow';
  644. break;
  645. }
  646. $term_id = (int) $args[0];
  647. $term = get_term( $term_id );
  648. if ( ! $term || is_wp_error( $term ) ) {
  649. $caps[] = 'do_not_allow';
  650. break;
  651. }
  652. $tax = get_taxonomy( $term->taxonomy );
  653. if ( ! $tax ) {
  654. $caps[] = 'do_not_allow';
  655. break;
  656. }
  657. if ( 'delete_term' === $cap
  658. && ( get_option( 'default_' . $term->taxonomy ) == $term->term_id
  659. || get_option( 'default_term_' . $term->taxonomy ) == $term->term_id )
  660. ) {
  661. $caps[] = 'do_not_allow';
  662. break;
  663. }
  664. $taxo_cap = $cap . 's';
  665. $caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id );
  666. break;
  667. case 'manage_post_tags':
  668. case 'edit_categories':
  669. case 'edit_post_tags':
  670. case 'delete_categories':
  671. case 'delete_post_tags':
  672. $caps[] = 'manage_categories';
  673. break;
  674. case 'assign_categories':
  675. case 'assign_post_tags':
  676. $caps[] = 'edit_posts';
  677. break;
  678. case 'create_sites':
  679. case 'delete_sites':
  680. case 'manage_network':
  681. case 'manage_sites':
  682. case 'manage_network_users':
  683. case 'manage_network_plugins':
  684. case 'manage_network_themes':
  685. case 'manage_network_options':
  686. case 'upgrade_network':
  687. $caps[] = $cap;
  688. break;
  689. case 'setup_network':
  690. if ( is_multisite() ) {
  691. $caps[] = 'manage_network_options';
  692. } else {
  693. $caps[] = 'manage_options';
  694. }
  695. break;
  696. case 'update_php':
  697. if ( is_multisite() && ! is_super_admin( $user_id ) ) {
  698. $caps[] = 'do_not_allow';
  699. } else {
  700. $caps[] = 'update_core';
  701. }
  702. break;
  703. case 'update_https':
  704. if ( is_multisite() && ! is_super_admin( $user_id ) ) {
  705. $caps[] = 'do_not_allow';
  706. } else {
  707. $caps[] = 'manage_options';
  708. $caps[] = 'update_core';
  709. }
  710. break;
  711. case 'export_others_personal_data':
  712. case 'erase_others_personal_data':
  713. case 'manage_privacy_options':
  714. $caps[] = is_multisite() ? 'manage_network' : 'manage_options';
  715. break;
  716. case 'create_app_password':
  717. case 'list_app_passwords':
  718. case 'read_app_password':
  719. case 'edit_app_password':
  720. case 'delete_app_passwords':
  721. case 'delete_app_password':
  722. $caps = map_meta_cap( 'edit_user', $user_id, $args[0] );
  723. break;
  724. default:
  725. // Handle meta capabilities for custom post types.
  726. global $post_type_meta_caps;
  727. if ( isset( $post_type_meta_caps[ $cap ] ) ) {
  728. return map_meta_cap( $post_type_meta_caps[ $cap ], $user_id, ...$args );
  729. }
  730. // Block capabilities map to their post equivalent.
  731. $block_caps = array(
  732. 'edit_blocks',
  733. 'edit_others_blocks',
  734. 'publish_blocks',
  735. 'read_private_blocks',
  736. 'delete_blocks',
  737. 'delete_private_blocks',
  738. 'delete_published_blocks',
  739. 'delete_others_blocks',
  740. 'edit_private_blocks',
  741. 'edit_published_blocks',
  742. );
  743. if ( in_array( $cap, $block_caps, true ) ) {
  744. $cap = str_replace( '_blocks', '_posts', $cap );
  745. }
  746. // If no meta caps match, return the original cap.
  747. $caps[] = $cap;
  748. }
  749. /**
  750. * Filters the primitive capabilities required of the given user to satisfy the
  751. * capability being checked.
  752. *
  753. * @since 2.8.0
  754. *
  755. * @param string[] $caps Primitive capabilities required of the user.
  756. * @param string $cap Capability being checked.
  757. * @param int $user_id The user ID.
  758. * @param array $args Adds context to the capability check, typically
  759. * starting with an object ID.
  760. */
  761. return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args );
  762. }
  763. /**
  764. * Returns whether the current user has the specified capability.
  765. *
  766. * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
  767. * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
  768. * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
  769. *
  770. * Example usage:
  771. *
  772. * current_user_can( 'edit_posts' );
  773. * current_user_can( 'edit_post', $post->ID );
  774. * current_user_can( 'edit_post_meta', $post->ID, $meta_key );
  775. *
  776. * While checking against particular roles in place of a capability is supported
  777. * in part, this practice is discouraged as it may produce unreliable results.
  778. *
  779. * Note: Will always return true if the current user is a super admin, unless specifically denied.
  780. *
  781. * @since 2.0.0
  782. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
  783. * by adding it to the function signature.
  784. * @since 5.8.0 Converted to wrapper for the user_can() function.
  785. *
  786. * @see WP_User::has_cap()
  787. * @see map_meta_cap()
  788. *
  789. * @param string $capability Capability name.
  790. * @param mixed ...$args Optional further parameters, typically starting with an object ID.
  791. * @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is
  792. * passed, whether the current user has the given meta capability for the given object.
  793. */
  794. function current_user_can( $capability, ...$args ) {
  795. return user_can( wp_get_current_user(), $capability, ...$args );
  796. }
  797. /**
  798. * Returns whether the current user has the specified capability for a given site.
  799. *
  800. * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
  801. * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
  802. * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
  803. *
  804. * Example usage:
  805. *
  806. * current_user_can_for_blog( $blog_id, 'edit_posts' );
  807. * current_user_can_for_blog( $blog_id, 'edit_post', $post->ID );
  808. * current_user_can_for_blog( $blog_id, 'edit_post_meta', $post->ID, $meta_key );
  809. *
  810. * @since 3.0.0
  811. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
  812. * by adding it to the function signature.
  813. * @since 5.8.0 Wraps current_user_can() after switching to blog.
  814. *
  815. * @param int $blog_id Site ID.
  816. * @param string $capability Capability name.
  817. * @param mixed ...$args Optional further parameters, typically starting with an object ID.
  818. * @return bool Whether the user has the given capability.
  819. */
  820. function current_user_can_for_blog( $blog_id, $capability, ...$args ) {
  821. $switched = is_multisite() ? switch_to_blog( $blog_id ) : false;
  822. $can = current_user_can( $capability, ...$args );
  823. if ( $switched ) {
  824. restore_current_blog();
  825. }
  826. return $can;
  827. }
  828. /**
  829. * Returns whether the author of the supplied post has the specified capability.
  830. *
  831. * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
  832. * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
  833. * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
  834. *
  835. * Example usage:
  836. *
  837. * author_can( $post, 'edit_posts' );
  838. * author_can( $post, 'edit_post', $post->ID );
  839. * author_can( $post, 'edit_post_meta', $post->ID, $meta_key );
  840. *
  841. * @since 2.9.0
  842. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
  843. * by adding it to the function signature.
  844. *
  845. * @param int|WP_Post $post Post ID or post object.
  846. * @param string $capability Capability name.
  847. * @param mixed ...$args Optional further parameters, typically starting with an object ID.
  848. * @return bool Whether the post author has the given capability.
  849. */
  850. function author_can( $post, $capability, ...$args ) {
  851. $post = get_post( $post );
  852. if ( ! $post ) {
  853. return false;
  854. }
  855. $author = get_userdata( $post->post_author );
  856. if ( ! $author ) {
  857. return false;
  858. }
  859. return $author->has_cap( $capability, ...$args );
  860. }
  861. /**
  862. * Returns whether a particular user has the specified capability.
  863. *
  864. * This function also accepts an ID of an object to check against if the capability is a meta capability. Meta
  865. * capabilities such as `edit_post` and `edit_user` are capabilities used by the `map_meta_cap()` function to
  866. * map to primitive capabilities that a user or role has, such as `edit_posts` and `edit_others_posts`.
  867. *
  868. * Example usage:
  869. *
  870. * user_can( $user->ID, 'edit_posts' );
  871. * user_can( $user->ID, 'edit_post', $post->ID );
  872. * user_can( $user->ID, 'edit_post_meta', $post->ID, $meta_key );
  873. *
  874. * @since 3.1.0
  875. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
  876. * by adding it to the function signature.
  877. *
  878. * @param int|WP_User $user User ID or object.
  879. * @param string $capability Capability name.
  880. * @param mixed ...$args Optional further parameters, typically starting with an object ID.
  881. * @return bool Whether the user has the given capability.
  882. */
  883. function user_can( $user, $capability, ...$args ) {
  884. if ( ! is_object( $user ) ) {
  885. $user = get_userdata( $user );
  886. }
  887. if ( empty( $user ) ) {
  888. // User is logged out, create anonymous user object.
  889. $user = new WP_User( 0 );
  890. $user->init( new stdClass );
  891. }
  892. return $user->has_cap( $capability, ...$args );
  893. }
  894. /**
  895. * Retrieves the global WP_Roles instance and instantiates it if necessary.
  896. *
  897. * @since 4.3.0
  898. *
  899. * @global WP_Roles $wp_roles WordPress role management object.
  900. *
  901. * @return WP_Roles WP_Roles global instance if not already instantiated.
  902. */
  903. function wp_roles() {
  904. global $wp_roles;
  905. if ( ! isset( $wp_roles ) ) {
  906. $wp_roles = new WP_Roles();
  907. }
  908. return $wp_roles;
  909. }
  910. /**
  911. * Retrieves role object.
  912. *
  913. * @since 2.0.0
  914. *
  915. * @param string $role Role name.
  916. * @return WP_Role|null WP_Role object if found, null if the role does not exist.
  917. */
  918. function get_role( $role ) {
  919. return wp_roles()->get_role( $role );
  920. }
  921. /**
  922. * Adds a role, if it does not exist.
  923. *
  924. * @since 2.0.0
  925. *
  926. * @param string $role Role name.
  927. * @param string $display_name Display name for role.
  928. * @param bool[] $capabilities List of capabilities keyed by the capability name,
  929. * e.g. array( 'edit_posts' => true, 'delete_posts' => false ).
  930. * @return WP_Role|void WP_Role object, if the role is added.
  931. */
  932. function add_role( $role, $display_name, $capabilities = array() ) {
  933. if ( empty( $role ) ) {
  934. return;
  935. }
  936. return wp_roles()->add_role( $role, $display_name, $capabilities );
  937. }
  938. /**
  939. * Removes a role, if it exists.
  940. *
  941. * @since 2.0.0
  942. *
  943. * @param string $role Role name.
  944. */
  945. function remove_role( $role ) {
  946. wp_roles()->remove_role( $role );
  947. }
  948. /**
  949. * Retrieves a list of super admins.
  950. *
  951. * @since 3.0.0
  952. *
  953. * @global array $super_admins
  954. *
  955. * @return string[] List of super admin logins.
  956. */
  957. function get_super_admins() {
  958. global $super_admins;
  959. if ( isset( $super_admins ) ) {
  960. return $super_admins;
  961. } else {
  962. return get_site_option( 'site_admins', array( 'admin' ) );
  963. }
  964. }
  965. /**
  966. * Determines whether user is a site admin.
  967. *
  968. * @since 3.0.0
  969. *
  970. * @param int|false $user_id Optional. The ID of a user. Defaults to false, to check the current user.
  971. * @return bool Whether the user is a site admin.
  972. */
  973. function is_super_admin( $user_id = false ) {
  974. if ( ! $user_id ) {
  975. $user = wp_get_current_user();
  976. } else {
  977. $user = get_userdata( $user_id );
  978. }
  979. if ( ! $user || ! $user->exists() ) {
  980. return false;
  981. }
  982. if ( is_multisite() ) {
  983. $super_admins = get_super_admins();
  984. if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins, true ) ) {
  985. return true;
  986. }
  987. } else {
  988. if ( $user->has_cap( 'delete_users' ) ) {
  989. return true;
  990. }
  991. }
  992. return false;
  993. }
  994. /**
  995. * Grants Super Admin privileges.
  996. *
  997. * @since 3.0.0
  998. *
  999. * @global array $super_admins
  1000. *
  1001. * @param int $user_id ID of the user to be granted Super Admin privileges.
  1002. * @return bool True on success, false on failure. This can fail when the user is
  1003. * already a super admin or when the `$super_admins` global is defined.
  1004. */
  1005. function grant_super_admin( $user_id ) {
  1006. // If global super_admins override is defined, there is nothing to do here.
  1007. if ( isset( $GLOBALS['super_admins'] ) || ! is_multisite() ) {
  1008. return false;
  1009. }
  1010. /**
  1011. * Fires before the user is granted Super Admin privileges.
  1012. *
  1013. * @since 3.0.0
  1014. *
  1015. * @param int $user_id ID of the user that is about to be granted Super Admin privileges.
  1016. */
  1017. do_action( 'grant_super_admin', $user_id );
  1018. // Directly fetch site_admins instead of using get_super_admins().
  1019. $super_admins = get_site_option( 'site_admins', array( 'admin' ) );
  1020. $user = get_userdata( $user_id );
  1021. if ( $user && ! in_array( $user->user_login, $super_admins, true ) ) {
  1022. $super_admins[] = $user->user_login;
  1023. update_site_option( 'site_admins', $super_admins );
  1024. /**
  1025. * Fires after the user is granted Super Admin privileges.
  1026. *
  1027. * @since 3.0.0
  1028. *
  1029. * @param int $user_id ID of the user that was granted Super Admin privileges.
  1030. */
  1031. do_action( 'granted_super_admin', $user_id );
  1032. return true;
  1033. }
  1034. return false;
  1035. }
  1036. /**
  1037. * Revokes Super Admin privileges.
  1038. *
  1039. * @since 3.0.0
  1040. *
  1041. * @global array $super_admins
  1042. *
  1043. * @param int $user_id ID of the user Super Admin privileges to be revoked from.
  1044. * @return bool True on success, false on failure. This can fail when the user's email
  1045. * is the network admin email or when the `$super_admins` global is defined.
  1046. */
  1047. function revoke_super_admin( $user_id ) {
  1048. // If global super_admins override is defined, there is nothing to do here.
  1049. if ( isset( $GLOBALS['super_admins'] ) || ! is_multisite() ) {
  1050. return false;
  1051. }
  1052. /**
  1053. * Fires before the user's Super Admin privileges are revoked.
  1054. *
  1055. * @since 3.0.0
  1056. *
  1057. * @param int $user_id ID of the user Super Admin privileges are being revoked from.
  1058. */
  1059. do_action( 'revoke_super_admin', $user_id );
  1060. // Directly fetch site_admins instead of using get_super_admins().
  1061. $super_admins = get_site_option( 'site_admins', array( 'admin' ) );
  1062. $user = get_userdata( $user_id );
  1063. if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) {
  1064. $key = array_search( $user->user_login, $super_admins, true );
  1065. if ( false !== $key ) {
  1066. unset( $super_admins[ $key ] );
  1067. update_site_option( 'site_admins', $super_admins );
  1068. /**
  1069. * Fires after the user's Super Admin privileges are revoked.
  1070. *
  1071. * @since 3.0.0
  1072. *
  1073. * @param int $user_id ID of the user Super Admin privileges were revoked from.
  1074. */
  1075. do_action( 'revoked_super_admin', $user_id );
  1076. return true;
  1077. }
  1078. }
  1079. return false;
  1080. }
  1081. /**
  1082. * Filters the user capabilities to grant the 'install_languages' capability as necessary.
  1083. *
  1084. * A user must have at least one out of the 'update_core', 'install_plugins', and
  1085. * 'install_themes' capabilities to qualify for 'install_languages'.
  1086. *
  1087. * @since 4.9.0
  1088. *
  1089. * @param bool[] $allcaps An array of all the user's capabilities.
  1090. * @return bool[] Filtered array of the user's capabilities.
  1091. */
  1092. function wp_maybe_grant_install_languages_cap( $allcaps ) {
  1093. if ( ! empty( $allcaps['update_core'] ) || ! empty( $allcaps['install_plugins'] ) || ! empty( $allcaps['install_themes'] ) ) {
  1094. $allcaps['install_languages'] = true;
  1095. }
  1096. return $allcaps;
  1097. }
  1098. /**
  1099. * Filters the user capabilities to grant the 'resume_plugins' and 'resume_themes' capabilities as necessary.
  1100. *
  1101. * @since 5.2.0
  1102. *
  1103. * @param bool[] $allcaps An array of all the user's capabilities.
  1104. * @return bool[] Filtered array of the user's capabilities.
  1105. */
  1106. function wp_maybe_grant_resume_extensions_caps( $allcaps ) {
  1107. // Even in a multisite, regular administrators should be able to resume plugins.
  1108. if ( ! empty( $allcaps['activate_plugins'] ) ) {
  1109. $allcaps['resume_plugins'] = true;
  1110. }
  1111. // Even in a multisite, regular administrators should be able to resume themes.
  1112. if ( ! empty( $allcaps['switch_themes'] ) ) {
  1113. $allcaps['resume_themes'] = true;
  1114. }
  1115. return $allcaps;
  1116. }
  1117. /**
  1118. * Filters the user capabilities to grant the 'view_site_health_checks' capabilities as necessary.
  1119. *
  1120. * @since 5.2.2
  1121. *
  1122. * @param bool[] $allcaps An array of all the user's capabilities.
  1123. * @param string[] $caps Required primitive capabilities for the requested capability.
  1124. * @param array $args {
  1125. * Arguments that accompany the requested capability check.
  1126. *
  1127. * @type string $0 Requested capability.
  1128. * @type int $1 Concerned user ID.
  1129. * @type mixed ...$2 Optional second and further parameters, typically object ID.
  1130. * }
  1131. * @param WP_User $user The user object.
  1132. * @return bool[] Filtered array of the user's capabilities.
  1133. */
  1134. function wp_maybe_grant_site_health_caps( $allcaps, $caps, $args, $user ) {
  1135. if ( ! empty( $allcaps['install_plugins'] ) && ( ! is_multisite() || is_super_admin( $user->ID ) ) ) {
  1136. $allcaps['view_site_health_checks'] = true;
  1137. }
  1138. return $allcaps;
  1139. }
  1140. return;
  1141. // Dummy gettext calls to get strings in the catalog.
  1142. /* translators: User role for administrators. */
  1143. _x( 'Administrator', 'User role' );
  1144. /* translators: User role for editors. */
  1145. _x( 'Editor', 'User role' );
  1146. /* translators: User role for authors. */
  1147. _x( 'Author', 'User role' );
  1148. /* translators: User role for contributors. */
  1149. _x( 'Contributor', 'User role' );
  1150. /* translators: User role for subscribers. */
  1151. _x( 'Subscriber', 'User role' );