home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / capabilities.php < prev    next >
Encoding:
PHP Script  |  2018-01-24  |  26.4 KB  |  899 lines

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