WordPress/wp-admin/includes/class-wp-users-list-table.php
Andrew Nacin d88922565e Less insane multiple role handling in the users list table.
If the user has more than one role, opt to show the first role that is
'editable', if present. Otherwise, fall back to the remaining roles.

In the future, we should show a comma-separated list of all roles,
editable or otherwise, and this list should be filterable, either by user,
or by the roles which can appear. Probably both.

In multisite, only hide users that have no capabilities (in case they
possess a leftover, empty wp_xx_capabilities key from the MU days),
not users that have no role, as they may have a cap but no role.

see #22361. fixes #17860.



git-svn-id: http://core.svn.wordpress.org/trunk@22686 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-19 19:16:31 +00:00

325 lines
9.8 KiB
PHP

<?php
/**
* Users List Table class.
*
* @package WordPress
* @subpackage List_Table
* @since 3.1.0
* @access private
*/
class WP_Users_List_Table extends WP_List_Table {
var $site_id;
var $is_site_users;
function __construct( $args = array() ) {
parent::__construct( array(
'singular' => 'user',
'plural' => 'users',
'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
) );
$this->is_site_users = 'site-users-network' == $this->screen->id;
if ( $this->is_site_users )
$this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
}
function ajax_user_can() {
if ( $this->is_site_users )
return current_user_can( 'manage_sites' );
else
return current_user_can( 'list_users' );
}
function prepare_items() {
global $role, $usersearch;
$usersearch = isset( $_REQUEST['s'] ) ? trim( $_REQUEST['s'] ) : '';
$role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : '';
$per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page';
$users_per_page = $this->get_items_per_page( $per_page );
$paged = $this->get_pagenum();
$args = array(
'number' => $users_per_page,
'offset' => ( $paged-1 ) * $users_per_page,
'role' => $role,
'search' => $usersearch,
'fields' => 'all_with_meta'
);
if ( '' !== $args['search'] )
$args['search'] = '*' . $args['search'] . '*';
if ( $this->is_site_users )
$args['blog_id'] = $this->site_id;
if ( isset( $_REQUEST['orderby'] ) )
$args['orderby'] = $_REQUEST['orderby'];
if ( isset( $_REQUEST['order'] ) )
$args['order'] = $_REQUEST['order'];
// Query the user IDs for this page
$wp_user_search = new WP_User_Query( $args );
$this->items = $wp_user_search->get_results();
$this->set_pagination_args( array(
'total_items' => $wp_user_search->get_total(),
'per_page' => $users_per_page,
) );
}
function no_items() {
_e( 'No matching users were found.' );
}
function get_views() {
global $wp_roles, $role;
if ( $this->is_site_users ) {
$url = 'site-users.php?id=' . $this->site_id;
switch_to_blog( $this->site_id );
$users_of_blog = count_users();
restore_current_blog();
} else {
$url = 'users.php';
$users_of_blog = count_users();
}
$total_users = $users_of_blog['total_users'];
$avail_roles =& $users_of_blog['avail_roles'];
unset($users_of_blog);
$current_role = false;
$class = empty($role) ? ' class="current"' : '';
$role_links = array();
$role_links['all'] = "<a href='$url'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>';
foreach ( $wp_roles->get_names() as $this_role => $name ) {
if ( !isset($avail_roles[$this_role]) )
continue;
$class = '';
if ( $this_role == $role ) {
$current_role = $role;
$class = ' class="current"';
}
$name = translate_user_role( $name );
/* translators: User role name with count */
$name = sprintf( __('%1$s <span class="count">(%2$s)</span>'), $name, number_format_i18n( $avail_roles[$this_role] ) );
$role_links[$this_role] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$class>$name</a>";
}
return $role_links;
}
function get_bulk_actions() {
$actions = array();
if ( is_multisite() ) {
if ( current_user_can( 'remove_users' ) )
$actions['remove'] = __( 'Remove' );
} else {
if ( current_user_can( 'delete_users' ) )
$actions['delete'] = __( 'Delete' );
}
return $actions;
}
function extra_tablenav( $which ) {
if ( 'top' != $which )
return;
?>
<div class="alignleft actions">
<?php if ( current_user_can( 'promote_users' ) ) : ?>
<label class="screen-reader-text" for="new_role"><?php _e( 'Change role to&hellip;' ) ?></label>
<select name="new_role" id="new_role">
<option value=''><?php _e( 'Change role to&hellip;' ) ?></option>
<?php wp_dropdown_roles(); ?>
</select>
<?php
submit_button( __( 'Change' ), 'button', 'changeit', false );
endif;
do_action( 'restrict_manage_users' );
echo '</div>';
}
function current_action() {
if ( isset($_REQUEST['changeit']) && !empty($_REQUEST['new_role']) )
return 'promote';
return parent::current_action();
}
function get_columns() {
$c = array(
'cb' => '<input type="checkbox" />',
'username' => __( 'Username' ),
'name' => __( 'Name' ),
'email' => __( 'E-mail' ),
'role' => __( 'Role' ),
'posts' => __( 'Posts' )
);
if ( $this->is_site_users )
unset( $c['posts'] );
return $c;
}
function get_sortable_columns() {
$c = array(
'username' => 'login',
'name' => 'name',
'email' => 'email',
);
if ( $this->is_site_users )
unset( $c['posts'] );
return $c;
}
function display_rows() {
// Query the post counts for this page
if ( ! $this->is_site_users )
$post_counts = count_many_users_posts( array_keys( $this->items ) );
$editable_roles = array_keys( get_editable_roles() );
$style = '';
foreach ( $this->items as $userid => $user_object ) {
if ( count( $user_object->roles ) <= 1 ) {
$role = reset( $user_object->roles );
} elseif ( $roles = array_intersect( array_values( $user_object->roles ), $editable_roles ) ) {
$role = reset( $roles );
} else {
$role = reset( $user_object->roles );
}
if ( is_multisite() && empty( $role->allcaps ) )
continue;
$style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"';
echo "\n\t", $this->single_row( $user_object, $style, $role, isset( $post_counts ) ? $post_counts[ $userid ] : 0 );
}
}
/**
* Generate HTML for a single row on the users.php admin panel.
*
* @since 2.1.0
*
* @param object $user_object
* @param string $style Optional. Attributes added to the TR element. Must be sanitized.
* @param string $role Key for the $wp_roles array.
* @param int $numposts Optional. Post count to display for this user. Defaults to zero, as in, a new user has made zero posts.
* @return string
*/
function single_row( $user_object, $style = '', $role = '', $numposts = 0 ) {
global $wp_roles;
if ( !( is_object( $user_object ) && is_a( $user_object, 'WP_User' ) ) )
$user_object = get_userdata( (int) $user_object );
$user_object->filter = 'display';
$email = $user_object->user_email;
if ( $this->is_site_users )
$url = "site-users.php?id={$this->site_id}&amp;";
else
$url = 'users.php?';
$checkbox = '';
// Check if the user for this row is editable
if ( current_user_can( 'list_users' ) ) {
// Set up the user editing link
$edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( stripslashes( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user_object->ID ) ) );
// Set up the hover actions for this user
$actions = array();
if ( current_user_can( 'edit_user', $user_object->ID ) ) {
$edit = "<strong><a href=\"$edit_link\">$user_object->user_login</a></strong><br />";
$actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
} else {
$edit = "<strong>$user_object->user_login</strong><br />";
}
if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) )
$actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&amp;user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . "</a>";
if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) )
$actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url."action=remove&amp;user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . "</a>";
$actions = apply_filters( 'user_row_actions', $actions, $user_object );
$edit .= $this->row_actions( $actions );
// Set up the checkbox ( because the user is editable, otherwise its empty )
$checkbox = '<label class="screen-reader-text" for="cb-select-' . $user_object->ID . '">' . sprintf( __( 'Select %s' ), $user_object->user_login ) . '</label>'
. "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='$role' value='{$user_object->ID}' />";
} else {
$edit = '<strong>' . $user_object->user_login . '</strong>';
}
$role_name = isset( $wp_roles->role_names[$role] ) ? translate_user_role( $wp_roles->role_names[$role] ) : __( 'None' );
$avatar = get_avatar( $user_object->ID, 32 );
$r = "<tr id='user-$user_object->ID'$style>";
list( $columns, $hidden ) = $this->get_column_info();
foreach ( $columns as $column_name => $column_display_name ) {
$class = "class=\"$column_name column-$column_name\"";
$style = '';
if ( in_array( $column_name, $hidden ) )
$style = ' style="display:none;"';
$attributes = "$class$style";
switch ( $column_name ) {
case 'cb':
$r .= "<th scope='row' class='check-column'>$checkbox</th>";
break;
case 'username':
$r .= "<td $attributes>$avatar $edit</td>";
break;
case 'name':
$r .= "<td $attributes>$user_object->first_name $user_object->last_name</td>";
break;
case 'email':
$r .= "<td $attributes><a href='mailto:$email' title='" . esc_attr( sprintf( __( 'E-mail: %s' ), $email ) ) . "'>$email</a></td>";
break;
case 'role':
$r .= "<td $attributes>$role_name</td>";
break;
case 'posts':
$attributes = 'class="posts column-posts num"' . $style;
$r .= "<td $attributes>";
if ( $numposts > 0 ) {
$r .= "<a href='edit.php?author=$user_object->ID' title='" . esc_attr__( 'View posts by this author' ) . "' class='edit'>";
$r .= $numposts;
$r .= '</a>';
} else {
$r .= 0;
}
$r .= "</td>";
break;
default:
$r .= "<td $attributes>";
$r .= apply_filters( 'manage_users_custom_column', '', $column_name, $user_object->ID );
$r .= "</td>";
}
}
$r .= '</tr>';
return $r;
}
}