home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress2 / wp-admin / includes / class-wp-users-list-table.php < prev    next >
Encoding:
PHP Script  |  2017-10-04  |  16.7 KB  |  581 lines

  1. <?php
  2. /**
  3.  * List Table API: WP_Users_List_Table class
  4.  *
  5.  * @package WordPress
  6.  * @subpackage Administration
  7.  * @since 3.1.0
  8.  */
  9.  
  10. /**
  11.  * Core class used to implement displaying users in a list table.
  12.  *
  13.  * @since 3.1.0
  14.  * @access private
  15.  *
  16.  * @see WP_List_Table
  17.  */
  18. class WP_Users_List_Table extends WP_List_Table {
  19.  
  20.     /**
  21.      * Site ID to generate the Users list table for.
  22.      *
  23.      * @since 3.1.0
  24.      * @var int
  25.      */
  26.     public $site_id;
  27.  
  28.     /**
  29.      * Whether or not the current Users list table is for Multisite.
  30.      *
  31.      * @since 3.1.0
  32.      * @var bool
  33.      */
  34.     public $is_site_users;
  35.  
  36.     /**
  37.      * Constructor.
  38.      *
  39.      * @since 3.1.0
  40.      *
  41.      * @see WP_List_Table::__construct() for more information on default arguments.
  42.      *
  43.      * @param array $args An associative array of arguments.
  44.      */
  45.     public function __construct( $args = array() ) {
  46.         parent::__construct( array(
  47.             'singular' => 'user',
  48.             'plural'   => 'users',
  49.             'screen'   => isset( $args['screen'] ) ? $args['screen'] : null,
  50.         ) );
  51.  
  52.         $this->is_site_users = 'site-users-network' === $this->screen->id;
  53.  
  54.         if ( $this->is_site_users )
  55.             $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
  56.     }
  57.  
  58.     /**
  59.      * Check the current user's permissions.
  60.      *
  61.       * @since 3.1.0
  62.      *
  63.      * @return bool
  64.      */
  65.     public function ajax_user_can() {
  66.         if ( $this->is_site_users )
  67.             return current_user_can( 'manage_sites' );
  68.         else
  69.             return current_user_can( 'list_users' );
  70.     }
  71.  
  72.     /**
  73.      * Prepare the users list for display.
  74.      *
  75.      * @since 3.1.0
  76.      *
  77.      * @global string $role
  78.      * @global string $usersearch
  79.      */
  80.     public function prepare_items() {
  81.         global $role, $usersearch;
  82.  
  83.         $usersearch = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : '';
  84.  
  85.         $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : '';
  86.  
  87.         $per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page';
  88.         $users_per_page = $this->get_items_per_page( $per_page );
  89.  
  90.         $paged = $this->get_pagenum();
  91.  
  92.         if ( 'none' === $role ) {
  93.             $args = array(
  94.                 'number' => $users_per_page,
  95.                 'offset' => ( $paged-1 ) * $users_per_page,
  96.                 'include' => wp_get_users_with_no_role( $this->site_id ),
  97.                 'search' => $usersearch,
  98.                 'fields' => 'all_with_meta'
  99.             );
  100.         } else {
  101.             $args = array(
  102.                 'number' => $users_per_page,
  103.                 'offset' => ( $paged-1 ) * $users_per_page,
  104.                 'role' => $role,
  105.                 'search' => $usersearch,
  106.                 'fields' => 'all_with_meta'
  107.             );
  108.         }
  109.  
  110.         if ( '' !== $args['search'] )
  111.             $args['search'] = '*' . $args['search'] . '*';
  112.  
  113.         if ( $this->is_site_users )
  114.             $args['blog_id'] = $this->site_id;
  115.  
  116.         if ( isset( $_REQUEST['orderby'] ) )
  117.             $args['orderby'] = $_REQUEST['orderby'];
  118.  
  119.         if ( isset( $_REQUEST['order'] ) )
  120.             $args['order'] = $_REQUEST['order'];
  121.  
  122.         /**
  123.          * Filters the query arguments used to retrieve users for the current users list table.
  124.          *
  125.          * @since 4.4.0
  126.          *
  127.          * @param array $args Arguments passed to WP_User_Query to retrieve items for the current
  128.          *                    users list table.
  129.          */
  130.         $args = apply_filters( 'users_list_table_query_args', $args );
  131.  
  132.         // Query the user IDs for this page
  133.         $wp_user_search = new WP_User_Query( $args );
  134.  
  135.         $this->items = $wp_user_search->get_results();
  136.  
  137.         $this->set_pagination_args( array(
  138.             'total_items' => $wp_user_search->get_total(),
  139.             'per_page' => $users_per_page,
  140.         ) );
  141.     }
  142.  
  143.     /**
  144.      * Output 'no users' message.
  145.      *
  146.      * @since 3.1.0
  147.      */
  148.     public function no_items() {
  149.         _e( 'No users found.' );
  150.     }
  151.  
  152.     /**
  153.      * Return an associative array listing all the views that can be used
  154.      * with this table.
  155.      *
  156.      * Provides a list of roles and user count for that role for easy
  157.      * Filtersing of the user table.
  158.      *
  159.      * @since  3.1.0
  160.      *
  161.      * @global string $role
  162.      *
  163.      * @return array An array of HTML links, one for each view.
  164.      */
  165.     protected function get_views() {
  166.         global $role;
  167.  
  168.         $wp_roles = wp_roles();
  169.  
  170.         if ( $this->is_site_users ) {
  171.             $url = 'site-users.php?id=' . $this->site_id;
  172.             switch_to_blog( $this->site_id );
  173.             $users_of_blog = count_users( 'time', $this->site_id );
  174.             restore_current_blog();
  175.         } else {
  176.             $url = 'users.php';
  177.             $users_of_blog = count_users();
  178.         }
  179.  
  180.         $total_users = $users_of_blog['total_users'];
  181.         $avail_roles =& $users_of_blog['avail_roles'];
  182.         unset($users_of_blog);
  183.  
  184.         $current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : '';
  185.  
  186.         $role_links = array();
  187.         $role_links['all'] = "<a href='$url'$current_link_attributes>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>';
  188.         foreach ( $wp_roles->get_names() as $this_role => $name ) {
  189.             if ( !isset($avail_roles[$this_role]) )
  190.                 continue;
  191.  
  192.             $current_link_attributes = '';
  193.  
  194.             if ( $this_role === $role ) {
  195.                 $current_link_attributes = ' class="current" aria-current="page"';
  196.             }
  197.  
  198.             $name = translate_user_role( $name );
  199.             /* translators: User role name with count */
  200.             $name = sprintf( __('%1$s <span class="count">(%2$s)</span>'), $name, number_format_i18n( $avail_roles[$this_role] ) );
  201.             $role_links[$this_role] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$current_link_attributes>$name</a>";
  202.         }
  203.  
  204.         if ( ! empty( $avail_roles['none' ] ) ) {
  205.  
  206.             $current_link_attributes = '';
  207.  
  208.             if ( 'none' === $role ) {
  209.                 $current_link_attributes = ' class="current" aria-current="page"';
  210.             }
  211.  
  212.             $name = __( 'No role' );
  213.             /* translators: User role name with count */
  214.             $name = sprintf( __('%1$s <span class="count">(%2$s)</span>'), $name, number_format_i18n( $avail_roles['none' ] ) );
  215.             $role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$current_link_attributes>$name</a>";
  216.  
  217.         }
  218.  
  219.         return $role_links;
  220.     }
  221.  
  222.     /**
  223.      * Retrieve an associative array of bulk actions available on this table.
  224.      *
  225.      * @since  3.1.0
  226.      *
  227.      * @return array Array of bulk actions.
  228.      */
  229.     protected function get_bulk_actions() {
  230.         $actions = array();
  231.  
  232.         if ( is_multisite() ) {
  233.             if ( current_user_can( 'remove_users' ) )
  234.                 $actions['remove'] = __( 'Remove' );
  235.         } else {
  236.             if ( current_user_can( 'delete_users' ) )
  237.                 $actions['delete'] = __( 'Delete' );
  238.         }
  239.  
  240.         return $actions;
  241.     }
  242.  
  243.     /**
  244.      * Output the controls to allow user roles to be changed in bulk.
  245.      *
  246.      * @since 3.1.0
  247.      *
  248.      * @param string $which Whether this is being invoked above ("top")
  249.      *                      or below the table ("bottom").
  250.      */
  251.     protected function extra_tablenav( $which ) {
  252.         $id = 'bottom' === $which ? 'new_role2' : 'new_role';
  253.         $button_id = 'bottom' === $which ? 'changeit2' : 'changeit';
  254.     ?>
  255.     <div class="alignleft actions">
  256.         <?php if ( current_user_can( 'promote_users' ) && $this->has_items() ) : ?>
  257.         <label class="screen-reader-text" for="<?php echo $id ?>"><?php _e( 'Change role to…' ) ?></label>
  258.         <select name="<?php echo $id ?>" id="<?php echo $id ?>">
  259.             <option value=""><?php _e( 'Change role to…' ) ?></option>
  260.             <?php wp_dropdown_roles(); ?>
  261.         </select>
  262.     <?php
  263.             submit_button( __( 'Change' ), '', $button_id, false );
  264.         endif;
  265.  
  266.         /**
  267.          * Fires just before the closing div containing the bulk role-change controls
  268.          * in the Users list table.
  269.          *
  270.          * @since 3.5.0
  271.          * @since 4.6.0 The `$which` parameter was added.
  272.          *
  273.          * @param string $which The location of the extra table nav markup: 'top' or 'bottom'.
  274.          */
  275.         do_action( 'restrict_manage_users', $which );
  276.     ?>
  277.         </div>
  278.     <?php
  279.         /**
  280.          * Fires immediately following the closing "actions" div in the tablenav for the users
  281.          * list table.
  282.          *
  283.          * @since 4.9.0
  284.          *
  285.          * @param string $which The location of the extra table nav markup: 'top' or 'bottom'.
  286.          */
  287.         do_action( 'manage_users_extra_tablenav', $which );
  288.     }
  289.  
  290.     /**
  291.      * Capture the bulk action required, and return it.
  292.      *
  293.      * Overridden from the base class implementation to capture
  294.      * the role change drop-down.
  295.      *
  296.      * @since  3.1.0
  297.      *
  298.      * @return string The bulk action required.
  299.      */
  300.     public function current_action() {
  301.         if ( ( isset( $_REQUEST['changeit'] ) || isset( $_REQUEST['changeit2'] ) ) &&
  302.             ( ! empty( $_REQUEST['new_role'] ) || ! empty( $_REQUEST['new_role2'] ) ) ) {
  303.             return 'promote';
  304.         }
  305.  
  306.         return parent::current_action();
  307.     }
  308.  
  309.     /**
  310.      * Get a list of columns for the list table.
  311.      *
  312.      * @since  3.1.0
  313.      *
  314.      * @return array Array in which the key is the ID of the column,
  315.      *               and the value is the description.
  316.      */
  317.     public function get_columns() {
  318.         $c = array(
  319.             'cb'       => '<input type="checkbox" />',
  320.             'username' => __( 'Username' ),
  321.             'name'     => __( 'Name' ),
  322.             'email'    => __( 'Email' ),
  323.             'role'     => __( 'Role' ),
  324.             'posts'    => __( 'Posts' )
  325.         );
  326.  
  327.         if ( $this->is_site_users )
  328.             unset( $c['posts'] );
  329.  
  330.         return $c;
  331.     }
  332.  
  333.     /**
  334.      * Get a list of sortable columns for the list table.
  335.      *
  336.      * @since 3.1.0
  337.      *
  338.      * @return array Array of sortable columns.
  339.      */
  340.     protected function get_sortable_columns() {
  341.         $c = array(
  342.             'username' => 'login',
  343.             'email'    => 'email',
  344.         );
  345.  
  346.         return $c;
  347.     }
  348.  
  349.     /**
  350.      * Generate the list table rows.
  351.      *
  352.      * @since 3.1.0
  353.      */
  354.     public function display_rows() {
  355.         // Query the post counts for this page
  356.         if ( ! $this->is_site_users )
  357.             $post_counts = count_many_users_posts( array_keys( $this->items ) );
  358.  
  359.         foreach ( $this->items as $userid => $user_object ) {
  360.             echo "\n\t" . $this->single_row( $user_object, '', '', isset( $post_counts ) ? $post_counts[ $userid ] : 0 );
  361.         }
  362.     }
  363.  
  364.     /**
  365.      * Generate HTML for a single row on the users.php admin panel.
  366.      *
  367.      * @since 3.1.0
  368.      * @since 4.2.0 The `$style` parameter was deprecated.
  369.      * @since 4.4.0 The `$role` parameter was deprecated.
  370.      *
  371.      * @param WP_User $user_object The current user object.
  372.      * @param string  $style       Deprecated. Not used.
  373.      * @param string  $role        Deprecated. Not used.
  374.      * @param int     $numposts    Optional. Post count to display for this user. Defaults
  375.      *                             to zero, as in, a new user has made zero posts.
  376.      * @return string Output for a single row.
  377.      */
  378.     public function single_row( $user_object, $style = '', $role = '', $numposts = 0 ) {
  379.         if ( ! ( $user_object instanceof WP_User ) ) {
  380.             $user_object = get_userdata( (int) $user_object );
  381.         }
  382.         $user_object->filter = 'display';
  383.         $email = $user_object->user_email;
  384.  
  385.         if ( $this->is_site_users )
  386.             $url = "site-users.php?id={$this->site_id}&";
  387.         else
  388.             $url = 'users.php?';
  389.  
  390.         $user_roles = $this->get_role_list( $user_object );
  391.  
  392.         // Set up the hover actions for this user
  393.         $actions = array();
  394.         $checkbox = '';
  395.         $super_admin = '';
  396.  
  397.         if ( is_multisite() && current_user_can( 'manage_network_users' ) ) {
  398.             if ( in_array( $user_object->user_login, get_super_admins(), true ) ) {
  399.                 $super_admin = ' — ' . __( 'Super Admin' );
  400.             }
  401.         }
  402.  
  403.         // Check if the user for this row is editable
  404.         if ( current_user_can( 'list_users' ) ) {
  405.             // Set up the user editing link
  406.             $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user_object->ID ) ) );
  407.  
  408.             if ( current_user_can( 'edit_user',  $user_object->ID ) ) {
  409.                 $edit = "<strong><a href=\"{$edit_link}\">{$user_object->user_login}</a>{$super_admin}</strong><br />";
  410.                 $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
  411.             } else {
  412.                 $edit = "<strong>{$user_object->user_login}{$super_admin}</strong><br />";
  413.             }
  414.  
  415.             if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) )
  416.                 $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . "</a>";
  417.             if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) )
  418.                 $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url."action=remove&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . "</a>";
  419.  
  420.             // Add a link to the user's author archive, if not empty.
  421.             $author_posts_url = get_author_posts_url( $user_object->ID );
  422.             if ( $author_posts_url ) {
  423.                 $actions['view'] = sprintf(
  424.                     '<a href="%s" aria-label="%s">%s</a>',
  425.                     esc_url( $author_posts_url ),
  426.                     /* translators: %s: author's display name */
  427.                     esc_attr( sprintf( __( 'View posts by %s' ), $user_object->display_name ) ),
  428.                     __( 'View' )
  429.                 );
  430.             }
  431.  
  432.             /**
  433.              * Filters the action links displayed under each user in the Users list table.
  434.              *
  435.              * @since 2.8.0
  436.              *
  437.              * @param array   $actions     An array of action links to be displayed.
  438.              *                             Default 'Edit', 'Delete' for single site, and
  439.              *                             'Edit', 'Remove' for Multisite.
  440.              * @param WP_User $user_object WP_User object for the currently-listed user.
  441.              */
  442.             $actions = apply_filters( 'user_row_actions', $actions, $user_object );
  443.  
  444.             // Role classes.
  445.             $role_classes = esc_attr( implode( ' ', array_keys( $user_roles ) ) );
  446.  
  447.             // Set up the checkbox ( because the user is editable, otherwise it's empty )
  448.             $checkbox = '<label class="screen-reader-text" for="user_' . $user_object->ID . '">' . sprintf( __( 'Select %s' ), $user_object->user_login ) . '</label>'
  449.                         . "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='{$role_classes}' value='{$user_object->ID}' />";
  450.  
  451.         } else {
  452.             $edit = "<strong>{$user_object->user_login}{$super_admin}</strong>";
  453.         }
  454.         $avatar = get_avatar( $user_object->ID, 32 );
  455.  
  456.         // Comma-separated list of user roles.
  457.         $roles_list = implode( ', ', $user_roles );
  458.  
  459.         $r = "<tr id='user-$user_object->ID'>";
  460.  
  461.         list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
  462.  
  463.         foreach ( $columns as $column_name => $column_display_name ) {
  464.             $classes = "$column_name column-$column_name";
  465.             if ( $primary === $column_name ) {
  466.                 $classes .= ' has-row-actions column-primary';
  467.             }
  468.             if ( 'posts' === $column_name ) {
  469.                 $classes .= ' num'; // Special case for that column
  470.             }
  471.  
  472.             if ( in_array( $column_name, $hidden ) ) {
  473.                 $classes .= ' hidden';
  474.             }
  475.  
  476.             $data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"';
  477.  
  478.             $attributes = "class='$classes' $data";
  479.  
  480.             if ( 'cb' === $column_name ) {
  481.                 $r .= "<th scope='row' class='check-column'>$checkbox</th>";
  482.             } else {
  483.                 $r .= "<td $attributes>";
  484.                 switch ( $column_name ) {
  485.                     case 'username':
  486.                         $r .= "$avatar $edit";
  487.                         break;
  488.                     case 'name':
  489.                         if ( $user_object->first_name && $user_object->last_name ) {
  490.                             $r .= "$user_object->first_name $user_object->last_name";
  491.                         } else {
  492.                             $r .= '<span aria-hidden="true">—</span><span class="screen-reader-text">' . _x( 'Unknown', 'name' ) . '</span>';
  493.                         }
  494.                         break;
  495.                     case 'email':
  496.                         $r .= "<a href='" . esc_url( "mailto:$email" ) . "'>$email</a>";
  497.                         break;
  498.                     case 'role':
  499.                         $r .= esc_html( $roles_list );
  500.                         break;
  501.                     case 'posts':
  502.                         if ( $numposts > 0 ) {
  503.                             $r .= "<a href='edit.php?author=$user_object->ID' class='edit'>";
  504.                             $r .= '<span aria-hidden="true">' . $numposts . '</span>';
  505.                             $r .= '<span class="screen-reader-text">' . sprintf( _n( '%s post by this author', '%s posts by this author', $numposts ), number_format_i18n( $numposts ) ) . '</span>';
  506.                             $r .= '</a>';
  507.                         } else {
  508.                             $r .= 0;
  509.                         }
  510.                         break;
  511.                     default:
  512.                         /**
  513.                          * Filters the display output of custom columns in the Users list table.
  514.                          *
  515.                          * @since 2.8.0
  516.                          *
  517.                          * @param string $output      Custom column output. Default empty.
  518.                          * @param string $column_name Column name.
  519.                          * @param int    $user_id     ID of the currently-listed user.
  520.                          */
  521.                         $r .= apply_filters( 'manage_users_custom_column', '', $column_name, $user_object->ID );
  522.                 }
  523.  
  524.                 if ( $primary === $column_name ) {
  525.                     $r .= $this->row_actions( $actions );
  526.                 }
  527.                 $r .= "</td>";
  528.             }
  529.         }
  530.         $r .= '</tr>';
  531.  
  532.         return $r;
  533.     }
  534.  
  535.     /**
  536.      * Gets the name of the default primary column.
  537.      *
  538.      * @since 4.3.0
  539.      *
  540.      * @return string Name of the default primary column, in this case, 'username'.
  541.      */
  542.     protected function get_default_primary_column_name() {
  543.         return 'username';
  544.     }
  545.  
  546.     /**
  547.      * Returns an array of user roles for a given user object.
  548.      *
  549.      * @since 4.4.0
  550.      *
  551.      * @param WP_User $user_object The WP_User object.
  552.      * @return array An array of user roles.
  553.      */
  554.     protected function get_role_list( $user_object ) {
  555.         $wp_roles = wp_roles();
  556.  
  557.         $role_list = array();
  558.  
  559.         foreach ( $user_object->roles as $role ) {
  560.             if ( isset( $wp_roles->role_names[ $role ] ) ) {
  561.                 $role_list[ $role ] = translate_user_role( $wp_roles->role_names[ $role ] );
  562.             }
  563.         }
  564.  
  565.         if ( empty( $role_list ) ) {
  566.             $role_list['none'] = _x( 'None', 'no user roles' );
  567.         }
  568.  
  569.         /**
  570.          * Filters the returned array of roles for a user.
  571.          *
  572.          * @since 4.4.0
  573.          *
  574.          * @param array   $role_list   An array of user roles.
  575.          * @param WP_User $user_object A WP_User object.
  576.          */
  577.         return apply_filters( 'get_role_list', $role_list, $user_object );
  578.     }
  579.  
  580. }
  581.