[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-includes/ -> capabilities.php (source)

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


Generated: Tue Oct 22 08:20:01 2019 Cross-referenced by PHPXref 0.7